Should solve https://github.com/termux/termux-x11/issues/25.
This commit is contained in:
parent
f7f7c858fe
commit
5a07a2fadb
@ -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));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
||||||
};
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user