Beispiel #1
0
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
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}