This commit is contained in:
Twaik Yont 2021-10-10 00:46:40 +03:00
parent f7f7c858fe
commit 5a07a2fadb
5 changed files with 136 additions and 158 deletions

View File

@ -14,6 +14,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <dirent.h> #include <dirent.h>
#pragma ide diagnostic ignored "hicpp-signed-bitwise"
#define unused __attribute__((__unused__)) #define unused __attribute__((__unused__))
#define DEFAULT_WIDTH 480 #define DEFAULT_WIDTH 480
@ -29,11 +30,12 @@ public:
void get_default_proportions(int32_t* width, int32_t* height) override; void get_default_proportions(int32_t* width, int32_t* height) override;
void get_keymap(int *fd, int *size) override; void get_keymap(int *fd, int *size) override;
void window_change_callback(EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height); void window_change_callback(EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height);
void layout_change_callback(char *layout); void layout_change_callback(const char *layout);
void passfd(int fd); void passfd(int fd);
void on_egl_init(); void on_egl_init();
void on_egl_uninit();
void unused on_egl_uninit();
LorieEGLHelper helper; LorieEGLHelper helper;
@ -47,13 +49,11 @@ public:
LorieBackendAndroid::LorieBackendAndroid() LorieBackendAndroid::LorieBackendAndroid()
: self(&LorieCompositor::start, this) {} : self(&LorieCompositor::start, this) {}
void LorieBackendAndroid::on_egl_init() { void LorieBackendAndroid::on_egl_init() {
renderer.init(); renderer.init();
} }
void LorieBackendAndroid::on_egl_uninit() { void unused LorieBackendAndroid::on_egl_uninit() {
renderer.uninit(); renderer.uninit();
} }
@ -62,8 +62,8 @@ void LorieBackendAndroid::backend_init() {
LOGE("Failed to initialize EGL context"); LOGE("Failed to initialize EGL context");
} }
helper.onInit = std::bind(std::mem_fn(&LorieBackendAndroid::on_egl_init), this); helper.onInit = [this](){ on_egl_init(); };
//helper.onUninit = std::bind(std::mem_fn(&LorieBackendAndroid::on_egl_uninit), this); //helper.onUninit = [this](){ on_egl_uninit(); };
if (xkb_context == nullptr) { if (xkb_context == nullptr) {
xkb_context = xkb_context_new((enum xkb_context_flags) 0); xkb_context = xkb_context_new((enum xkb_context_flags) 0);
@ -145,15 +145,17 @@ void LorieBackendAndroid::get_keymap(int *fd, int *size) {
void LorieBackendAndroid::window_change_callback(EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height) { void LorieBackendAndroid::window_change_callback(EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height) {
LOGE("WindowChangeCallback"); LOGE("WindowChangeCallback");
helper.setWindow(win); helper.setWindow(win);
output_resize(width, height, physical_width, physical_height); post([this, width, height, physical_width, physical_height]() {
output_resize(width, height, physical_width, physical_height);
});
} }
void LorieBackendAndroid::layout_change_callback(char *layout) { void LorieBackendAndroid::layout_change_callback(const char *layout) {
xkb_keymap_unref(xkb_keymap); xkb_keymap_unref(xkb_keymap);
xkb_names.layout = layout; xkb_names.layout = layout;
xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0); xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0);
if (xkb_keymap == NULL) { if (xkb_keymap == nullptr) {
LOGE("failed to compile global XKB keymap\n"); LOGE("failed to compile global XKB keymap\n");
LOGE(" tried rules %s, model %s, layout %s, variant %s, " LOGE(" tried rules %s, model %s, layout %s, variant %s, "
"options %s\n", "options %s\n",
@ -163,11 +165,13 @@ void LorieBackendAndroid::layout_change_callback(char *layout) {
return; return;
} }
keyboard_keymap_changed(); post([this]() {
keyboard_keymap_changed();
});
} }
void LorieBackendAndroid::passfd(int fd) { void LorieBackendAndroid::passfd(int fd) {
listen(fd, 128); listen(fd, 128);
wl_display_add_socket_fd(display, fd); wl_display_add_socket_fd(display, fd);
} }
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -190,28 +194,30 @@ static LorieBackendAndroid* fromLong(jlong v) {
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
JNI_DECLARE(LorieService, createLorieThread)(unused JNIEnv *env, unused jobject instance) { JNI_DECLARE(LorieService, createLorieThread)(unused JNIEnv *env, unused jobject instance) {
return (jlong) new LorieBackendAndroid; return (jlong) new LorieBackendAndroid;
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
JNI_DECLARE(LorieService, passWaylandFD)(unused JNIEnv *env, unused jobject instance, jlong jcompositor, jint fd) { JNI_DECLARE(LorieService, passWaylandFD)(unused JNIEnv *env, unused jobject instance, jlong jcompositor, jint fd) {
if (jcompositor == 0) return; if (jcompositor == 0) return;
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
char path[256] = {0}; char path[256] = {0};
char realpath[256] = {0}; char realpath[256] = {0};
sprintf(path, "/proc/self/fd/%d", fd); sprintf(path, "/proc/self/fd/%d", fd);
readlink(path, realpath, sizeof(realpath)); readlink(path, realpath, sizeof(realpath));
LOGI("JNI: got fd %d (%s)", fd, realpath); LOGI("JNI: got fd %d (%s)", fd, realpath);
b->passfd(fd); b->passfd(fd);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
JNI_DECLARE(LorieService, terminate)(unused JNIEnv *env, unused jobject instance, jlong jcompositor) { JNI_DECLARE(LorieService, terminate)(unused JNIEnv *env, unused jobject instance, jlong jcompositor) {
if (jcompositor == 0) return; if (jcompositor == 0) return;
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
LOGI("JNI: requested termination"); LOGI("JNI: requested termination");
b->terminate(); b->post([b](){
b->terminate();
});
b->self.join(); b->self.join();
} }
@ -221,7 +227,9 @@ JNI_DECLARE(LorieService, windowChanged)(JNIEnv *env, unused jobject instance, j
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
EGLNativeWindowType win = ANativeWindow_fromSurface(env, jsurface); EGLNativeWindowType win = ANativeWindow_fromSurface(env, jsurface);
b->queue.call(&LorieBackendAndroid::window_change_callback, b, win, width, height, mmWidth, mmHeight); b->post([b, win, width, height, mmWidth, mmHeight](){
b->window_change_callback(win, width, height, mmWidth, mmHeight);
});
LOGV("JNI: window is changed: %p(%p) %dx%d (%dmm x %dmm)", win, jsurface, width, height, mmWidth, mmHeight); LOGV("JNI: window is changed: %p(%p) %dx%d (%dmm x %dmm)", win, jsurface, width, height, mmWidth, mmHeight);
} }
@ -232,7 +240,9 @@ JNI_DECLARE(LorieService, touchDown)(unused JNIEnv *env, unused jobject instance
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: touch down"); LOGV("JNI: touch down");
b->touch_down(static_cast<uint32_t>(id), static_cast<uint32_t>(x), static_cast<uint32_t>(y)); b->post([b, id, x, y]() {
b->touch_down(static_cast<uint32_t>(id), static_cast<uint32_t>(x), static_cast<uint32_t>(y));
});
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -241,7 +251,10 @@ JNI_DECLARE(LorieService, touchMotion)(unused JNIEnv *env, unused jobject instan
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: touch motion"); LOGV("JNI: touch motion");
b->touch_motion(static_cast<uint32_t>(id), static_cast<uint32_t>(x), static_cast<uint32_t>(y)); b->post([b, id, x, y]() {
b->touch_motion(static_cast<uint32_t>(id), static_cast<uint32_t>(x),
static_cast<uint32_t>(y));
});
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -250,7 +263,9 @@ JNI_DECLARE(LorieService, touchUp)(unused JNIEnv *env, unused jobject instance,
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: touch up"); LOGV("JNI: touch up");
b->touch_up(static_cast<uint32_t>(id)); b->post([b, id]() {
b->touch_up(static_cast<uint32_t>(id));
});
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -259,7 +274,9 @@ JNI_DECLARE(LorieService, touchFrame)(unused JNIEnv *env, unused jobject instanc
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: touch frame"); LOGV("JNI: touch frame");
b->touch_frame(); b->post([b]() {
b->touch_frame();
});
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -268,7 +285,9 @@ JNI_DECLARE(LorieService, pointerMotion)(unused JNIEnv *env, unused jobject inst
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: pointer motion %dx%d", x, y); LOGV("JNI: pointer motion %dx%d", x, y);
b->pointer_motion(static_cast<uint32_t>(x), static_cast<uint32_t>(y)); b->post([b, x, y](){
b->pointer_motion(static_cast<uint32_t>(x), static_cast<uint32_t>(y));
});
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -277,7 +296,9 @@ JNI_DECLARE(LorieService, pointerScroll)(unused JNIEnv *env, unused jobject inst
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: pointer scroll %d %f", axis, value); LOGV("JNI: pointer scroll %d %f", axis, value);
b->pointer_scroll(static_cast<uint32_t>(axis), value); b->post([b, axis, value]() {
b->pointer_scroll(static_cast<uint32_t>(axis), value);
});
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -286,7 +307,9 @@ JNI_DECLARE(LorieService, pointerButton)(unused JNIEnv *env, unused jobject inst
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
LOGV("JNI: pointer button %d type %d", button, type); LOGV("JNI: pointer button %d type %d", button, type);
b->pointer_button(static_cast<uint32_t>(button), static_cast<uint32_t>(type)); b->post([b, button, type]() {
b->pointer_button(static_cast<uint32_t>(button), static_cast<uint32_t>(type));
});
} }
extern "C" void get_character_data(char** layout, int *shift, int *ec, char *ch); extern "C" void get_character_data(char** layout, int *shift, int *ec, char *ch);
@ -300,23 +323,29 @@ JNI_DECLARE(LorieService, keyboardKey)(JNIEnv *env, unused jobject instance,
if (jcompositor == 0) return; if (jcompositor == 0) return;
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
char *characters = NULL; char *characters = nullptr;
int event_code = 0; int event_code = 0;
int shift = jshift; int shift = jshift;
if (characters_ != NULL) characters = (char*) env->GetStringUTFChars(characters_, 0); if (characters_ != nullptr) characters = (char*) env->GetStringUTFChars(characters_, nullptr);
if (key_code && !characters) { if (key_code && !characters) {
android_keycode_get_eventcode(key_code, &event_code, &shift); android_keycode_get_eventcode(key_code, &event_code, &shift);
LOGE("kc: %d ec: %d", key_code, event_code); LOGE("kc: %d ec: %d", key_code, event_code);
if (strcmp(b->xkb_names.layout, "us") && event_code != 0) { if (strcmp(b->xkb_names.layout, "us") != 0) {
b->queue.call(&LorieBackendAndroid::layout_change_callback, b, (char*)"us"); if (event_code != 0) {
} b->post([b](){
b->layout_change_callback((char *) "us");
});
}
}
} }
if (!key_code && characters) { if (!key_code && characters) {
char *layout = NULL; char *layout = nullptr;
get_character_data(&layout, &shift, &event_code, characters); get_character_data(&layout, &shift, &event_code, characters);
if (layout && b->xkb_names.layout != layout) { if (layout && b->xkb_names.layout != layout) {
b->queue.call(&LorieBackendAndroid::layout_change_callback, b, layout); b->post([b, layout](){
b->layout_change_callback(layout);
});
} }
} }
LOGE("Keyboard input: keyCode: %d; eventCode: %d; characters: %s; shift: %d, type: %d", key_code, event_code, characters, shift, type); LOGE("Keyboard input: keyCode: %d; eventCode: %d; characters: %s; shift: %d, type: %d", key_code, event_code, characters, shift, type);
@ -330,18 +359,26 @@ JNI_DECLARE(LorieService, keyboardKey)(JNIEnv *env, unused jobject instance,
//} //}
if (shift || jshift) if (shift || jshift)
b->keyboard_key(42, WL_KEYBOARD_KEY_STATE_PRESSED); // Send KEY_LEFTSHIFT b->post([b]() {
b->keyboard_key(42, WL_KEYBOARD_KEY_STATE_PRESSED); // Send KEY_LEFTSHIFT
});
// For some reason Android do not send ACTION_DOWN for non-English characters // For some reason Android do not send ACTION_DOWN for non-English characters
if (characters) if (characters)
b->keyboard_key(static_cast<uint32_t>(event_code), WL_KEYBOARD_KEY_STATE_PRESSED); b->post([b, event_code]() {
b->keyboard_key(static_cast<uint32_t>(event_code), WL_KEYBOARD_KEY_STATE_PRESSED);
});
b->keyboard_key(static_cast<uint32_t>(event_code), static_cast<uint32_t>(type)); b->post([b, event_code, type]() {
b->keyboard_key(static_cast<uint32_t>(event_code), static_cast<uint32_t>(type));
});
if (shift || jshift) if (shift || jshift)
b->keyboard_key(42, WL_KEYBOARD_KEY_STATE_RELEASED); // Send KEY_LEFTSHIFT b->post([b]() {
b->keyboard_key(42, WL_KEYBOARD_KEY_STATE_RELEASED); // Send KEY_LEFTSHIFT
});
if (characters_ != NULL) env->ReleaseStringUTFChars(characters_, characters); if (characters_ != nullptr) env->ReleaseStringUTFChars(characters_, characters);
} }
static bool sameUid(int pid) { static bool sameUid(int pid) {
@ -357,12 +394,12 @@ static void killAllLogcats() {
struct dirent* dir_elem; struct dirent* dir_elem;
char path[64] = {0}, link[64] = {0}; char path[64] = {0}, link[64] = {0};
pid_t pid, self = getpid(); pid_t pid, self = getpid();
if ((proc = opendir("/proc")) == NULL) { if ((proc = opendir("/proc")) == nullptr) {
LOGE("opendir: %s", strerror(errno)); LOGE("opendir: %s", strerror(errno));
return; return;
} }
while((dir_elem = readdir(proc)) != NULL) { while((dir_elem = readdir(proc)) != nullptr) {
if (!(pid = (pid_t) atoi (dir_elem->d_name)) || pid == self || !sameUid(pid)) if (!(pid = (pid_t) atoi (dir_elem->d_name)) || pid == self || !sameUid(pid))
continue; continue;
@ -373,7 +410,7 @@ static void killAllLogcats() {
LOGE("readlink %s: %s", path, strerror(errno)); LOGE("readlink %s: %s", path, strerror(errno));
continue; continue;
} }
if (strstr(link, "/logcat") != NULL) { if (strstr(link, "/logcat") != nullptr) {
if (kill(pid, SIGKILL) < 0) { if (kill(pid, SIGKILL) < 0) {
LOGE("kill %d (%s): %s", pid, link, strerror); LOGE("kill %d (%s): %s", pid, link, strerror);
} }
@ -390,19 +427,19 @@ void fork(std::function<void()> f) {
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_com_termux_x11_LorieService_startLogcatForFd(unused JNIEnv *env, unused jobject thiz, jint fd) { Java_com_termux_x11_LorieService_startLogcatForFd(unused JNIEnv *env, unused jclass clazz, jint fd) {
killAllLogcats(); killAllLogcats();
LOGI("Starting logcat with output to given fd"); LOGI("Starting logcat with output to given fd");
fork([]() { fork([]() {
execl("/system/bin/logcat", "logcat", "-c", NULL); execl("/system/bin/logcat", "logcat", "-c", nullptr);
LOGE("exec logcat: %s", strerror(errno)); LOGE("exec logcat: %s", strerror(errno));
}); });
fork([fd]() { fork([fd]() {
dup2(fd, 1); dup2(fd, 1);
dup2(fd, 2); dup2(fd, 2);
execl("/system/bin/logcat", "logcat", NULL); execl("/system/bin/logcat", "logcat", nullptr);
LOGE("exec logcat: %s", strerror(errno)); LOGE("exec logcat: %s", strerror(errno));
}); });
} }

View File

@ -10,23 +10,6 @@
#define LOGV(fmt ...) #define LOGV(fmt ...)
LorieCompositor::LorieCompositor() : LorieCompositor::LorieCompositor() :
#define wrapper(name) \
name(&LorieCompositor::real_ ## name, this, queue)
wrapper(terminate),
wrapper(output_redraw),
wrapper(output_resize),
wrapper(touch_down),
wrapper(touch_motion),
wrapper(touch_up),
wrapper(touch_frame),
wrapper(pointer_motion),
wrapper(pointer_scroll),
wrapper(pointer_button),
wrapper(keyboard_key),
wrapper(keyboard_key_modifiers),
wrapper(keyboard_keymap_changed),
#undef wrapper
renderer(*this), renderer(*this),
toplevel(renderer.toplevel_surface), toplevel(renderer.toplevel_surface),
cursor(renderer.cursor_surface), cursor(renderer.cursor_surface),
@ -61,6 +44,10 @@ void LorieCompositor::start() {
wl_display_run(display); wl_display_run(display);
} }
void LorieCompositor::post(std::function<void()> f) {
queue.write(f);
}
struct wl_event_source* LorieCompositor::add_fd_listener(int fd, uint32_t mask, wl_event_loop_fd_func_t func, void *data) { struct wl_event_source* LorieCompositor::add_fd_listener(int fd, uint32_t mask, wl_event_loop_fd_func_t func, void *data) {
LOGV("Adding fd %d to event loop", fd); LOGV("Adding fd %d to event loop", fd);
struct wl_event_loop* loop = nullptr; struct wl_event_loop* loop = nullptr;
@ -73,7 +60,7 @@ struct wl_event_source* LorieCompositor::add_fd_listener(int fd, uint32_t mask,
return nullptr; return nullptr;
} }
void LorieCompositor::real_terminate() { void LorieCompositor::terminate() {
LOGV("Terminating compositor"); LOGV("Terminating compositor");
if (display != nullptr) if (display != nullptr)
wl_display_terminate(display); wl_display_terminate(display);
@ -87,19 +74,21 @@ void LorieCompositor::set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint
renderer.set_cursor(surface, hotspot_x, hotspot_y); renderer.set_cursor(surface, hotspot_x, hotspot_y);
} }
void LorieCompositor::real_output_redraw() { void LorieCompositor::output_redraw() {
LOGV("Requested redraw"); LOGV("Requested redraw");
renderer.requestRedraw(); renderer.requestRedraw();
} }
void LorieCompositor::real_output_resize(uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height) { void LorieCompositor::output_resize(uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height) {
// Xwayland segfaults without that line // Xwayland segfaults without that line
if (width == 0 || height == 0 || physical_width == 0 || physical_height == 0) return; if (width == 0 || height == 0 || physical_width == 0 || physical_height == 0) return;
renderer.resize(width, height, physical_width, physical_height); renderer.resize(width, height, physical_width, physical_height);
output_redraw(); post([this]() {
output_redraw();
});
} }
void LorieCompositor::real_touch_down(uint32_t id, uint32_t x, uint32_t y) { void LorieCompositor::touch_down(uint32_t id, uint32_t x, uint32_t y) {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (toplevel == nullptr || client == nullptr) return; if (toplevel == nullptr || client == nullptr) return;
@ -110,7 +99,7 @@ void LorieCompositor::real_touch_down(uint32_t id, uint32_t x, uint32_t y) {
renderer.setCursorVisibility(false); renderer.setCursorVisibility(false);
} }
void LorieCompositor::real_touch_motion(uint32_t id, uint32_t x, uint32_t y) { void LorieCompositor::touch_motion(uint32_t id, uint32_t x, uint32_t y) {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (toplevel == nullptr || client == nullptr) return; if (toplevel == nullptr || client == nullptr) return;
@ -121,7 +110,7 @@ void LorieCompositor::real_touch_motion(uint32_t id, uint32_t x, uint32_t y) {
renderer.setCursorVisibility(false); renderer.setCursorVisibility(false);
} }
void LorieCompositor::real_touch_up(uint32_t id) { void LorieCompositor::touch_up(uint32_t id) {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (toplevel == nullptr || client == nullptr) return; if (toplevel == nullptr || client == nullptr) return;
@ -129,7 +118,7 @@ void LorieCompositor::real_touch_up(uint32_t id) {
renderer.setCursorVisibility(false); renderer.setCursorVisibility(false);
} }
void LorieCompositor::real_touch_frame() { void LorieCompositor::touch_frame() {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (toplevel == nullptr || client == nullptr) return; if (toplevel == nullptr || client == nullptr) return;
@ -137,7 +126,7 @@ void LorieCompositor::real_touch_frame() {
renderer.setCursorVisibility(false); renderer.setCursorVisibility(false);
} }
void LorieCompositor::real_pointer_motion(uint32_t x, uint32_t y) { void LorieCompositor::pointer_motion(uint32_t x, uint32_t y) {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (client == nullptr) return; if (client == nullptr) return;
@ -151,7 +140,7 @@ void LorieCompositor::real_pointer_motion(uint32_t x, uint32_t y) {
renderer.cursorMove(x, y); renderer.cursorMove(x, y);
} }
void LorieCompositor::real_pointer_scroll(uint32_t axis, float value) { void LorieCompositor::pointer_scroll(uint32_t axis, float value) {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (client == nullptr) return; if (client == nullptr) return;
@ -163,7 +152,7 @@ void LorieCompositor::real_pointer_scroll(uint32_t axis, float value) {
renderer.setCursorVisibility(true); renderer.setCursorVisibility(true);
} }
void LorieCompositor::real_pointer_button(uint32_t button, uint32_t state) { void LorieCompositor::pointer_button(uint32_t button, uint32_t state) {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (client == nullptr) return; if (client == nullptr) return;
@ -173,14 +162,14 @@ void LorieCompositor::real_pointer_button(uint32_t button, uint32_t state) {
renderer.setCursorVisibility(true); renderer.setCursorVisibility(true);
} }
void LorieCompositor::real_keyboard_key(uint32_t key, uint32_t state) { void LorieCompositor::keyboard_key(uint32_t key, uint32_t state) {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (client == nullptr) return; if (client == nullptr) return;
client->keyboard.send_key (next_serial(), LorieUtils::timestamp(), key, state); client->keyboard.send_key (next_serial(), LorieUtils::timestamp(), key, state);
} }
void LorieCompositor::real_keyboard_key_modifiers(uint8_t depressed, uint8_t latched, uint8_t locked, uint8_t group) { void LorieCompositor::keyboard_key_modifiers(uint8_t depressed, uint8_t latched, uint8_t locked, uint8_t group) {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (client == nullptr) return; if (client == nullptr) return;
@ -197,7 +186,7 @@ void LorieCompositor::real_keyboard_key_modifiers(uint8_t depressed, uint8_t lat
client->keyboard.send_modifiers (next_serial(), depressed, latched, locked, group); client->keyboard.send_modifiers (next_serial(), depressed, latched, locked, group);
} }
void LorieCompositor::real_keyboard_keymap_changed() { void LorieCompositor::keyboard_keymap_changed() {
LorieClient *client = get_toplevel_client(); LorieClient *client = get_toplevel_client();
if (client == nullptr) return; if (client == nullptr) return;

View File

@ -17,42 +17,26 @@ public:
LorieCompositor(); LorieCompositor();
// compositor features // compositor features
void start(); void start();
void post(std::function<void()> f);
struct wl_event_source* add_fd_listener(int fd, uint32_t mask, wl_event_loop_fd_func_t func, void *data); struct wl_event_source* add_fd_listener(int fd, uint32_t mask, wl_event_loop_fd_func_t func, void *data);
void set_toplevel(LorieSurface *surface); void set_toplevel(LorieSurface *surface);
void set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint32_t hotspot_y); void set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint32_t hotspot_y);
void real_terminate(); void terminate();
void real_output_redraw(); void output_redraw();
void real_output_resize(uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height); void output_resize(uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height);
void real_touch_down(uint32_t id, uint32_t x, uint32_t y); void touch_down(uint32_t id, uint32_t x, uint32_t y);
void real_touch_motion(uint32_t id, uint32_t x, uint32_t y); void touch_motion(uint32_t id, uint32_t x, uint32_t y);
void real_touch_up(uint32_t id); void touch_up(uint32_t id);
void real_touch_frame(); void touch_frame();
void real_pointer_motion(uint32_t x, uint32_t y); // absolute values void pointer_motion(uint32_t x, uint32_t y); // absolute values
void real_pointer_scroll(uint32_t axis, float value); void pointer_scroll(uint32_t axis, float value);
void real_pointer_button(uint32_t button, uint32_t state); void pointer_button(uint32_t button, uint32_t state);
void real_keyboard_key(uint32_t key, uint32_t state); void keyboard_key(uint32_t key, uint32_t state);
void real_keyboard_key_modifiers(uint8_t depressed, uint8_t latched, uint8_t locked, uint8_t group); void keyboard_key_modifiers(uint8_t depressed, uint8_t latched, uint8_t locked, uint8_t group);
void real_keyboard_keymap_changed(); void keyboard_keymap_changed();
#define wrapper(name) \
LorieFuncWrapperType<decltype(&LorieCompositor::real_ ## name)> name;
wrapper(terminate);
wrapper(output_redraw);
wrapper(output_resize);
wrapper(touch_down);
wrapper(touch_motion);
wrapper(touch_up);
wrapper(touch_frame);
wrapper(pointer_motion);
wrapper(pointer_scroll);
wrapper(pointer_button);
wrapper(keyboard_key);
wrapper(keyboard_key_modifiers);
wrapper(keyboard_keymap_changed);
#undef wrapper
LorieRenderer renderer; LorieRenderer renderer;

View File

@ -1,51 +1,17 @@
#pragma once #pragma once
#include <functional> #include <functional>
#include <queue> #include <queue>
#include <pthread.h> #include <mutex>
class LorieMessageQueue { class LorieMessageQueue {
public: public:
LorieMessageQueue(); LorieMessageQueue();
void write(std::function<void()> func); void write(std::function<void()> func);
template<typename Ret, typename Class, typename ... Args>
void call(Ret Class::* __pm, Args&& ... args) {
write(std::bind(std::mem_fn(__pm), args...));
};
void run(); void run();
int get_fd(); int get_fd();
private: private:
int fd; int fd;
pthread_mutex_t write_mutex; std::mutex mutex;
pthread_mutex_t read_mutex;
std::queue<std::function<void()>> queue; std::queue<std::function<void()>> queue;
}; };
template<class Class, class T, class... Args>
struct LorieFuncWrapper {
using TFn = T (Class::*)(Args...);
LorieFuncWrapper(TFn fn, Class* cl, LorieMessageQueue& q): cl(cl), ptr(fn), q(q) {};
Class* cl;
TFn ptr;
LorieMessageQueue& q;
T operator()(Args... params) {
q.call(ptr, cl, params...);
//return (cl->*ptr)(params...);
}
};
template<class R, class... A>
struct LorieFuncWrapperTypeHelper;
template<class R, class C, class... A>
struct LorieFuncWrapperTypeHelper<R(C::*)(A...)> {
using type = LorieFuncWrapper<C, R, A...>;
};
template <class F>
using LorieFuncWrapperType = typename LorieFuncWrapperTypeHelper<F>::type;
template<typename Ret, typename Class, typename ... Args>
LorieFuncWrapper<Class, Ret, Args...> LorieFuncWrap(Ret(Class::*F)(Args...), Class* c) {
return LorieFuncWrapper<Class, Ret, Args...>(F, c);
};

View File

@ -1,13 +1,13 @@
#include <lorie-compositor.hpp> #include <lorie-compositor.hpp>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <cstring>
#include <errno.h> #include <cerrno>
#include <sys/eventfd.h> #include <sys/eventfd.h>
#include <mutex>
LorieMessageQueue::LorieMessageQueue() { LorieMessageQueue::LorieMessageQueue() {
pthread_mutex_init(&write_mutex, nullptr); std::unique_lock<std::mutex> lock(mutex);
pthread_mutex_init(&read_mutex, nullptr);
fd = eventfd(0, EFD_CLOEXEC); fd = eventfd(0, EFD_CLOEXEC);
if (fd == -1) { if (fd == -1) {
@ -18,21 +18,23 @@ LorieMessageQueue::LorieMessageQueue() {
void LorieMessageQueue::write(std::function<void()> func) { void LorieMessageQueue::write(std::function<void()> func) {
static uint64_t i = 1; static uint64_t i = 1;
pthread_mutex_lock(&write_mutex); std::unique_lock<std::mutex> lock(mutex);
queue.push(func); queue.push(func);
pthread_mutex_unlock(&write_mutex);
::write(fd, &i, sizeof(uint64_t)); ::write(fd, &i, sizeof(uint64_t));
} }
void LorieMessageQueue::run() { void LorieMessageQueue::run() {
static uint64_t i = 0; static uint64_t i = 0;
std::unique_lock<std::mutex> lock(mutex);
std::function<void()> fn;
::read(fd, &i, sizeof(uint64_t)); ::read(fd, &i, sizeof(uint64_t));
while(!queue.empty()){ while(!queue.empty()){
queue.front()(); fn = queue.front();
pthread_mutex_lock(&read_mutex);
queue.pop(); queue.pop();
pthread_mutex_unlock(&read_mutex);
lock.unlock();
fn();
lock.lock();
} }
} }