Implement the handler for ibus signals
This commit is contained in:
parent
9c48e4965c
commit
d875d7baed
15
glfw/dbus_glfw.c
vendored
15
glfw/dbus_glfw.c
vendored
@ -273,3 +273,18 @@ glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const cha
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, interface);
|
||||
int ans = -1, num = -1;
|
||||
while(1) {
|
||||
num++;
|
||||
const char *name = va_arg(ap, const char*);
|
||||
if (!name) break;
|
||||
if (dbus_message_is_signal(msg, interface, name)) { ans = num; break; }
|
||||
}
|
||||
va_end(ap);
|
||||
return ans;
|
||||
}
|
||||
|
||||
1
glfw/dbus_glfw.h
vendored
1
glfw/dbus_glfw.h
vendored
@ -47,3 +47,4 @@ GLFWbool
|
||||
glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, dbus_pending_callback callback, void *user_data, ...);
|
||||
void glfw_dbus_dispatch(DBusConnection *);
|
||||
GLFWbool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...);
|
||||
int glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...);
|
||||
|
||||
64
glfw/ibus_glfw.c
vendored
64
glfw/ibus_glfw.c
vendored
@ -58,14 +58,78 @@ MIN(size_t a, size_t b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
static const char*
|
||||
get_ibus_text_from_message(DBusMessage *msg) {
|
||||
/* The message structure is (from dbus-monitor)
|
||||
variant struct {
|
||||
string "IBusText"
|
||||
array [
|
||||
]
|
||||
string "ash "
|
||||
variant struct {
|
||||
string "IBusAttrList"
|
||||
array [
|
||||
]
|
||||
array [
|
||||
]
|
||||
}
|
||||
}
|
||||
*/
|
||||
const char *text = NULL;
|
||||
const char *struct_id = NULL;
|
||||
DBusMessageIter iter, sub1, sub2;
|
||||
dbus_message_iter_init(msg, &iter);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) return NULL;
|
||||
|
||||
dbus_message_iter_recurse(&iter, &sub1);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&sub1) != DBUS_TYPE_STRUCT) return NULL;
|
||||
|
||||
dbus_message_iter_recurse(&sub1, &sub2);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) return NULL;
|
||||
|
||||
dbus_message_iter_get_basic(&sub2, &struct_id);
|
||||
if (!struct_id || strncmp(struct_id, "IBusText", sizeof("IBusText")) != 0) return NULL;
|
||||
|
||||
dbus_message_iter_next(&sub2);
|
||||
dbus_message_iter_next(&sub2);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) return NULL;
|
||||
|
||||
dbus_message_iter_get_basic(&sub2, &text);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
// Connection handling {{{
|
||||
static void set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h);
|
||||
|
||||
static DBusHandlerResult
|
||||
message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) {
|
||||
// To monitor signals from IBUS, use
|
||||
// dbus-monitor --address `ibus address` "type='signal',interface='org.freedesktop.IBus.InputContext'"
|
||||
_GLFWIBUSData *ibus = (_GLFWIBUSData*)user_data;
|
||||
(void)ibus;
|
||||
const char *text;
|
||||
switch(glfw_dbus_match_signal(msg, IBUS_INPUT_INTERFACE, "CommitText", "UpdatePreeditText", "HidePreeditText", "ShowPreeditText")) {
|
||||
case 0:
|
||||
text = get_ibus_text_from_message(msg);
|
||||
debug("IBUS: CommitText: '%s'\n", text ? text : "(nil)");
|
||||
break;
|
||||
case 1:
|
||||
text = get_ibus_text_from_message(msg);
|
||||
debug("IBUS: UpdatePreeditText: '%s'\n", text ? text : "(nil)");
|
||||
break;
|
||||
case 2:
|
||||
debug("IBUS: HidePreeditText\n");
|
||||
break;
|
||||
case 3:
|
||||
debug("IBUS: ShowPreeditText\n");
|
||||
break;
|
||||
}
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user