Fix remaining sync BUS calls
Also work on IBUS integration
This commit is contained in:
37
glfw/dbus_glfw.c
vendored
37
glfw/dbus_glfw.c
vendored
@@ -180,38 +180,6 @@ glfw_dbus_close_connection(DBusConnection *conn) {
|
|||||||
dbus_connection_unref(conn);
|
dbus_connection_unref(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLFWbool
|
|
||||||
call_void_method(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, va_list ap) {
|
|
||||||
GLFWbool retval = GLFW_FALSE;
|
|
||||||
|
|
||||||
if (conn) {
|
|
||||||
DBusMessage *msg = dbus_message_new_method_call(node, path, interface, method);
|
|
||||||
if (msg) {
|
|
||||||
int firstarg = va_arg(ap, int);
|
|
||||||
if ((firstarg == DBUS_TYPE_INVALID) || dbus_message_append_args_valist(msg, firstarg, ap)) {
|
|
||||||
if (dbus_connection_send(conn, msg, NULL)) {
|
|
||||||
dbus_connection_flush(conn);
|
|
||||||
retval = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dbus_message_unref(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool
|
|
||||||
glfw_dbus_call_void_method(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) {
|
|
||||||
GLFWbool retval;
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, method);
|
|
||||||
retval = call_void_method(conn, node, path, interface, method, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool
|
GLFWbool
|
||||||
glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...) {
|
glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...) {
|
||||||
DBusError err;
|
DBusError err;
|
||||||
@@ -267,11 +235,14 @@ call_method(DBusConnection *conn, const char *node, const char *path, const char
|
|||||||
DBusPendingCall *pending = NULL;
|
DBusPendingCall *pending = NULL;
|
||||||
if (dbus_connection_send_with_reply(conn, msg, &pending, DBUS_TIMEOUT_USE_DEFAULT)) {
|
if (dbus_connection_send_with_reply(conn, msg, &pending, DBUS_TIMEOUT_USE_DEFAULT)) {
|
||||||
dbus_pending_call_set_notify(pending, method_reply_received, res, free);
|
dbus_pending_call_set_notify(pending, method_reply_received, res, free);
|
||||||
|
retval = GLFW_TRUE;
|
||||||
} else {
|
} else {
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s out of memory", method, node, interface);
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s out of memory", method, node, interface);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!dbus_connection_send(conn, msg, NULL)) {
|
if (dbus_connection_send(conn, msg, NULL)) {
|
||||||
|
retval = GLFW_TRUE;
|
||||||
|
} else {
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s out of memory", method, node, interface);
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s out of memory", method, node, interface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
glfw/dbus_glfw.h
vendored
1
glfw/dbus_glfw.h
vendored
@@ -41,7 +41,6 @@ GLFWbool glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld);
|
|||||||
void glfw_dbus_terminate(_GLFWDBUSData *dbus);
|
void glfw_dbus_terminate(_GLFWDBUSData *dbus);
|
||||||
DBusConnection* glfw_dbus_connect_to(const char *path, const char* err_msg, const char* name);
|
DBusConnection* glfw_dbus_connect_to(const char *path, const char* err_msg, const char* name);
|
||||||
void glfw_dbus_close_connection(DBusConnection *conn);
|
void glfw_dbus_close_connection(DBusConnection *conn);
|
||||||
GLFWbool glfw_dbus_call_void_method(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
|
|
||||||
GLFWbool
|
GLFWbool
|
||||||
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
|
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
|
||||||
GLFWbool
|
GLFWbool
|
||||||
|
|||||||
91
glfw/ibus_glfw.c
vendored
91
glfw/ibus_glfw.c
vendored
@@ -164,8 +164,12 @@ input_context_created(DBusMessage *msg, const char* errmsg, void *data) {
|
|||||||
_GLFWIBUSData *ibus = (_GLFWIBUSData*)data;
|
_GLFWIBUSData *ibus = (_GLFWIBUSData*)data;
|
||||||
free((void*)ibus->input_ctx_path);
|
free((void*)ibus->input_ctx_path);
|
||||||
ibus->input_ctx_path = strdup(path);
|
ibus->input_ctx_path = strdup(path);
|
||||||
|
if (!ibus->input_ctx_path) return;
|
||||||
|
dbus_bus_add_match(ibus->conn, "type='signal',interface='org.freedesktop.IBus.InputContext'", NULL);
|
||||||
|
DBusObjectPathVTable ibus_vtable = {.message_function = message_handler};
|
||||||
|
dbus_connection_try_register_object_path(ibus->conn, ibus->input_ctx_path, &ibus_vtable, ibus, NULL);
|
||||||
enum Capabilities caps = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT;
|
enum Capabilities caps = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT;
|
||||||
if (!glfw_dbus_call_void_method(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "SetCapabilities", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID)) return;
|
if (!glfw_dbus_call_method_no_reply(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "SetCapabilities", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID)) return;
|
||||||
ibus->ok = GLFW_TRUE;
|
ibus->ok = GLFW_TRUE;
|
||||||
glfw_ibus_set_focused(ibus, GLFW_FALSE);
|
glfw_ibus_set_focused(ibus, GLFW_FALSE);
|
||||||
set_cursor_geometry(ibus, 0, 0, 0, 0);
|
set_cursor_geometry(ibus, 0, 0, 0, 0);
|
||||||
@@ -195,10 +199,6 @@ setup_connection(_GLFWIBUSData *ibus) {
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
dbus_connection_flush(ibus->conn);
|
dbus_connection_flush(ibus->conn);
|
||||||
dbus_bus_add_match(ibus->conn, "type='signal',interface='org.freedesktop.IBus.InputContext'", NULL);
|
|
||||||
DBusObjectPathVTable ibus_vtable = {.message_function = message_handler};
|
|
||||||
dbus_connection_try_register_object_path(ibus->conn, ibus->input_ctx_path, &ibus_vtable, ibus, NULL);
|
|
||||||
dbus_connection_flush(ibus->conn);
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ glfw_ibus_dispatch(_GLFWIBUSData *ibus) {
|
|||||||
static void
|
static void
|
||||||
simple_message(_GLFWIBUSData *ibus, const char *method) {
|
simple_message(_GLFWIBUSData *ibus, const char *method) {
|
||||||
if (check_connection(ibus)) {
|
if (check_connection(ibus)) {
|
||||||
glfw_dbus_call_void_method(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, method, DBUS_TYPE_INVALID);
|
glfw_dbus_call_method_no_reply(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, method, DBUS_TYPE_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,3 +266,82 @@ set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h) {
|
|||||||
DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &w, DBUS_TYPE_INT32, &h, DBUS_TYPE_INVALID);
|
DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &w, DBUS_TYPE_INT32, &h, DBUS_TYPE_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
IBUS_SHIFT_MASK = 1 << 0,
|
||||||
|
IBUS_LOCK_MASK = 1 << 1,
|
||||||
|
IBUS_CONTROL_MASK = 1 << 2,
|
||||||
|
IBUS_MOD1_MASK = 1 << 3,
|
||||||
|
IBUS_MOD2_MASK = 1 << 4,
|
||||||
|
IBUS_MOD3_MASK = 1 << 5,
|
||||||
|
IBUS_MOD4_MASK = 1 << 6,
|
||||||
|
IBUS_MOD5_MASK = 1 << 7,
|
||||||
|
IBUS_BUTTON1_MASK = 1 << 8,
|
||||||
|
IBUS_BUTTON2_MASK = 1 << 9,
|
||||||
|
IBUS_BUTTON3_MASK = 1 << 10,
|
||||||
|
IBUS_BUTTON4_MASK = 1 << 11,
|
||||||
|
IBUS_BUTTON5_MASK = 1 << 12,
|
||||||
|
|
||||||
|
/* The next few modifiers are used by XKB, so we skip to the end.
|
||||||
|
* Bits 15 - 23 are currently unused. Bit 29 is used internally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ibus mask */
|
||||||
|
IBUS_HANDLED_MASK = 1 << 24,
|
||||||
|
IBUS_FORWARD_MASK = 1 << 25,
|
||||||
|
IBUS_IGNORED_MASK = IBUS_FORWARD_MASK,
|
||||||
|
|
||||||
|
IBUS_SUPER_MASK = 1 << 26,
|
||||||
|
IBUS_HYPER_MASK = 1 << 27,
|
||||||
|
IBUS_META_MASK = 1 << 28,
|
||||||
|
|
||||||
|
IBUS_RELEASE_MASK = 1 << 30,
|
||||||
|
|
||||||
|
IBUS_MODIFIER_MASK = 0x5f001fff
|
||||||
|
} IBusModifierType;
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
ibus_key_state(unsigned int glfw_modifiers, int action) {
|
||||||
|
uint32_t ans = action == GLFW_RELEASE ? IBUS_RELEASE_MASK : 0;
|
||||||
|
#define M(g, i) if(glfw_modifiers & GLFW_MOD_##g) ans |= i
|
||||||
|
M(SHIFT, IBUS_SHIFT_MASK);
|
||||||
|
M(CAPS_LOCK, IBUS_LOCK_MASK);
|
||||||
|
M(CONTROL, IBUS_CONTROL_MASK);
|
||||||
|
M(ALT, IBUS_MOD1_MASK);
|
||||||
|
M(NUM_LOCK, IBUS_MOD2_MASK);
|
||||||
|
M(SUPER, IBUS_MOD4_MASK);
|
||||||
|
#undef M
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
key_event_processed(DBusMessage *msg, const char* errmsg, void *data) {
|
||||||
|
if (errmsg) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t handled;
|
||||||
|
if (!glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) return;
|
||||||
|
KeyEvent *ev = (KeyEvent*)data;
|
||||||
|
free(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool
|
||||||
|
process_key(const KeyEvent *ev_) {
|
||||||
|
if (!check_connection(ev_->ibus)) return GLFW_FALSE;
|
||||||
|
KeyEvent *ev = malloc(sizeof(KeyEvent));
|
||||||
|
if (!ev) return GLFW_FALSE;
|
||||||
|
memcpy(ev, ev_, sizeof(KeyEvent));
|
||||||
|
uint32_t state = ibus_key_state(ev->glfw_modifiers, ev->action);
|
||||||
|
if (!glfw_dbus_call_method_with_reply(
|
||||||
|
ev->ibus->conn, IBUS_SERVICE, ev->ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
|
||||||
|
key_event_processed, ev,
|
||||||
|
DBUS_TYPE_UINT32, &ev->keysym, DBUS_TYPE_UINT32, &ev->keycode, DBUS_TYPE_UINT32,
|
||||||
|
&state, DBUS_TYPE_INVALID)) {
|
||||||
|
free(ev);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|||||||
10
glfw/ibus_glfw.h
vendored
10
glfw/ibus_glfw.h
vendored
@@ -28,6 +28,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dbus_glfw.h"
|
#include "dbus_glfw.h"
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GLFWbool ok, inited;
|
GLFWbool ok, inited;
|
||||||
@@ -36,7 +37,16 @@ typedef struct {
|
|||||||
const char *input_ctx_path, *address_file_name, *address;
|
const char *input_ctx_path, *address_file_name, *address;
|
||||||
} _GLFWIBUSData;
|
} _GLFWIBUSData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
xkb_keycode_t keycode;
|
||||||
|
xkb_keysym_t keysym;
|
||||||
|
unsigned int glfw_modifiers;
|
||||||
|
int action;
|
||||||
|
_GLFWIBUSData *ibus;
|
||||||
|
} KeyEvent;
|
||||||
|
|
||||||
void glfw_connect_to_ibus(_GLFWIBUSData *ibus);
|
void glfw_connect_to_ibus(_GLFWIBUSData *ibus);
|
||||||
void glfw_ibus_terminate(_GLFWIBUSData *ibus);
|
void glfw_ibus_terminate(_GLFWIBUSData *ibus);
|
||||||
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused);
|
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused);
|
||||||
void glfw_ibus_dispatch(_GLFWIBUSData *ibus);
|
void glfw_ibus_dispatch(_GLFWIBUSData *ibus);
|
||||||
|
GLFWbool process_key(const KeyEvent *ev_);
|
||||||
|
|||||||
4
glfw/xkb_glfw.c
vendored
4
glfw/xkb_glfw.c
vendored
@@ -408,6 +408,7 @@ format_xkb_mods(_GLFWXKBData *xkb, const char* name, xkb_mod_mask_t mods) {
|
|||||||
void
|
void
|
||||||
glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action) {
|
glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action) {
|
||||||
const xkb_keysym_t *syms, *clean_syms, *default_syms;
|
const xkb_keysym_t *syms, *clean_syms, *default_syms;
|
||||||
|
static KeyEvent ev;
|
||||||
xkb_keysym_t glfw_sym;
|
xkb_keysym_t glfw_sym;
|
||||||
xkb_keycode_t code_for_sym = scancode;
|
xkb_keycode_t code_for_sym = scancode;
|
||||||
#ifdef _GLFW_WAYLAND
|
#ifdef _GLFW_WAYLAND
|
||||||
@@ -425,6 +426,9 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
|
|||||||
}
|
}
|
||||||
glfw_sym = clean_syms[0];
|
glfw_sym = clean_syms[0];
|
||||||
debug("clean_sym: %s ", glfw_xkb_keysym_name(clean_syms[0]));
|
debug("clean_sym: %s ", glfw_xkb_keysym_name(clean_syms[0]));
|
||||||
|
ev.action = action; ev.glfw_modifiers = xkb->modifiers; ev.keycode = scancode; ev.keysym = glfw_sym;
|
||||||
|
ev.ibus = &xkb->ibus;
|
||||||
|
process_key(&ev);
|
||||||
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
|
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
|
||||||
const char *text_type = "composed_text";
|
const char *text_type = "composed_text";
|
||||||
glfw_sym = compose_symbol(xkb, syms[0]);
|
glfw_sym = compose_symbol(xkb, syms[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user