static DBusHandlerResult IBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *user_data) { SDL_DBusContext *dbus = (SDL_DBusContext *)user_data; if(dbus->message_is_signal(msg, IBUS_INPUT_INTERFACE, "CommitText")){ DBusMessageIter iter; dbus->message_iter_init(msg, &iter); const char *text = IBus_GetVariantText(conn, &iter, dbus); if(text && *text){ char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; size_t text_bytes = SDL_strlen(text), i = 0; while(i < text_bytes){ size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf)); SDL_SendKeyboardText(buf); i += sz; } } return DBUS_HANDLER_RESULT_HANDLED; } if(dbus->message_is_signal(msg, IBUS_INPUT_INTERFACE, "UpdatePreeditText")){ DBusMessageIter iter; dbus->message_iter_init(msg, &iter); const char *text = IBus_GetVariantText(conn, &iter, dbus); if(text && *text){ char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; size_t text_bytes = SDL_strlen(text), i = 0; size_t cursor = 0; while(i < text_bytes){ size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf)); size_t chars = IBus_utf8_strlen(buf); SDL_SendEditingText(buf, cursor, chars); i += sz; cursor += chars; } } else { SDL_SendEditingText("", 0, 0); } SDL_IBus_UpdateTextRect(NULL); return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; }
void X11_SetTextInputRect(_THIS, SDL_Rect *rect) { if (!rect) { SDL_InvalidParamError("rect"); return; } #ifdef SDL_USE_IBUS SDL_IBus_UpdateTextRect(rect); #endif }
SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) { Uint32 result = 0; SDL_DBusContext *dbus = SDL_DBus_GetContext(); if (IBus_CheckConnection(dbus)) { Uint32 mods = IBus_ModState(); if (!SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent", DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID, DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) { result = 0; } } SDL_IBus_UpdateTextRect(NULL); return result ? SDL_TRUE : SDL_FALSE; }
static SDL_bool IBus_SetupConnection(SDL_DBusContext *dbus, const char* addr) { const char *client_name = "SDL2_Application"; const char *path = NULL; SDL_bool result = SDL_FALSE; DBusObjectPathVTable ibus_vtable; SDL_zero(ibus_vtable); ibus_vtable.message_function = &IBus_MessageHandler; ibus_conn = dbus->connection_open_private(addr, NULL); if (!ibus_conn) { return SDL_FALSE; } dbus->connection_flush(ibus_conn); if (!dbus->bus_register(ibus_conn, NULL)) { ibus_conn = NULL; return SDL_FALSE; } dbus->connection_flush(ibus_conn); if (SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext", DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) { SDL_free(input_ctx_path); input_ctx_path = SDL_strdup(path); SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, &IBus_SetCapabilities, NULL); dbus->bus_add_match(ibus_conn, "type='signal',interface='org.freedesktop.IBus.InputContext'", NULL); dbus->connection_try_register_object_path(ibus_conn, input_ctx_path, &ibus_vtable, dbus, NULL); dbus->connection_flush(ibus_conn); } SDL_IBus_SetFocus(SDL_GetKeyboardFocus() != NULL); SDL_IBus_UpdateTextRect(NULL); return result; }
SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) { SDL_bool result = SDL_FALSE; SDL_DBusContext *dbus = SDL_DBus_GetContext(); if (IBus_CheckConnection(dbus)) { DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent"); if (msg) { Uint32 mods = IBus_ModState(); dbus->message_append_args(msg, DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID); } if (msg) { DBusMessage *reply; reply = dbus->connection_send_with_reply_and_block(ibus_conn, msg, 300, NULL); if (reply) { if (!dbus->message_get_args(reply, NULL, DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) { result = SDL_FALSE; } dbus->message_unref(reply); } dbus->message_unref(msg); } } SDL_IBus_UpdateTextRect(NULL); return result; }
static SDL_bool IBus_SetupConnection(SDL_DBusContext *dbus, const char* addr) { const char *path = NULL; SDL_bool result = SDL_FALSE; DBusMessage *msg; DBusObjectPathVTable ibus_vtable = {0}; ibus_vtable.message_function = &IBus_MessageHandler; ibus_conn = dbus->connection_open_private(addr, NULL); if (!ibus_conn) { return SDL_FALSE; } dbus->connection_flush(ibus_conn); if (!dbus->bus_register(ibus_conn, NULL)) { ibus_conn = NULL; return SDL_FALSE; } dbus->connection_flush(ibus_conn); msg = dbus->message_new_method_call(IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext"); if (msg) { const char *client_name = "SDL2_Application"; dbus->message_append_args(msg, DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID); } if (msg) { DBusMessage *reply; reply = dbus->connection_send_with_reply_and_block(ibus_conn, msg, 1000, NULL); if (reply) { if (dbus->message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) { if (input_ctx_path) { SDL_free(input_ctx_path); } input_ctx_path = SDL_strdup(path); result = SDL_TRUE; } dbus->message_unref(reply); } dbus->message_unref(msg); } if (result) { SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, &IBus_SetCapabilities, NULL); dbus->bus_add_match(ibus_conn, "type='signal',interface='org.freedesktop.IBus.InputContext'", NULL); dbus->connection_try_register_object_path(ibus_conn, input_ctx_path, &ibus_vtable, dbus, NULL); dbus->connection_flush(ibus_conn); } SDL_IBus_SetFocus(SDL_GetKeyboardFocus() != NULL); SDL_IBus_UpdateTextRect(NULL); return result; }
static SDL_bool IBus_SetupConnection(SDL_DBusContext *dbus, const char* addr) { const char *path = NULL; SDL_bool result = SDL_FALSE; ibus_conn = dbus->connection_open_private(addr, NULL); if(!ibus_conn){ return SDL_FALSE; } dbus->connection_flush(ibus_conn); if(!dbus->bus_register(ibus_conn, NULL)){ ibus_conn = NULL; return SDL_FALSE; } dbus->connection_flush(ibus_conn); DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext"); if(msg){ const char *client_name = "SDL2_Application"; dbus->message_append_args(msg, DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID); } if(msg){ DBusMessage *reply; reply = dbus->connection_send_with_reply_and_block(ibus_conn, msg, 1000, NULL); if(reply){ if(dbus->message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)){ if(input_ctx_path){ SDL_free(input_ctx_path); } input_ctx_path = SDL_strdup(path); result = SDL_TRUE; } dbus->message_unref(reply); } dbus->message_unref(msg); } if(result){ DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "SetCapabilities"); if(msg){ Uint32 caps = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT; dbus->message_append_args(msg, DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID); } if(msg){ if(dbus->connection_send(ibus_conn, msg, NULL)){ dbus->connection_flush(ibus_conn); } dbus->message_unref(msg); } dbus->bus_add_match(ibus_conn, "type='signal',interface='org.freedesktop.IBus.InputContext'", NULL); dbus->connection_add_filter(ibus_conn, &IBus_MessageFilter, dbus, NULL); dbus->connection_flush(ibus_conn); } SDL_IBus_SetFocus(SDL_GetFocusWindow() != NULL); SDL_IBus_UpdateTextRect(NULL); return result; }