Add IBus IME Support, move DBus code to its own file. (v3.3 squashed)
authorAlex Baines <alex@abaines.me.uk>
Wed, 18 Jun 2014 20:11:39 +0100
changeset 888926a6243b27c2
parent 8888 75c7095a5e8e
child 8890 d9a2fa86cd97
Add IBus IME Support, move DBus code to its own file. (v3.3 squashed)
configure.in
include/SDL_config.h.in
src/core/linux/SDL_dbus.c
src/core/linux/SDL_dbus.h
src/core/linux/SDL_ibus.c
src/core/linux/SDL_ibus.h
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11keyboard.c
src/video/x11/SDL_x11keyboard.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
     1.1 --- a/configure.in	Sat Jun 21 11:52:53 2014 -0700
     1.2 +++ b/configure.in	Wed Jun 18 20:11:39 2014 +0100
     1.3 @@ -2130,6 +2130,43 @@
     1.4              if test x$have_dbus_dbus_h_hdr = xyes; then
     1.5                  AC_DEFINE(HAVE_DBUS_DBUS_H, 1, [ ])
     1.6                  EXTRA_CFLAGS="$EXTRA_CFLAGS $DBUS_CFLAGS"
     1.7 +                SOURCES="$SOURCES $srcdir/src/core/linux/SDL_dbus.c"
     1.8 +            fi
     1.9 +        fi
    1.10 +    fi
    1.11 +}
    1.12 +
    1.13 +dnl See if the platform has libibus IME support.
    1.14 +CheckIBus()
    1.15 +{
    1.16 +    AC_ARG_ENABLE(ibus,
    1.17 +AC_HELP_STRING([--enable-ibus], [enable IBus support [[default=yes]]]),
    1.18 +                  , enable_ibus=yes)
    1.19 +    if test x$enable_ibus = xyes; then
    1.20 +        AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
    1.21 +        if test x$PKG_CONFIG != xno; then
    1.22 +            IBUS_CFLAGS=`$PKG_CONFIG --cflags ibus-1.0`
    1.23 +            save_CFLAGS="$CFLAGS"
    1.24 +            CFLAGS="$save_CFLAGS $IBUS_CFLAGS"
    1.25 +            AC_CHECK_HEADER(ibus-1.0/ibus.h,
    1.26 +                            have_ibus_ibus_h_hdr=yes,
    1.27 +                            have_ibus_ibus_h_hdr=no)
    1.28 +            AC_CHECK_HEADER(sys/inotify.h,
    1.29 +                            have_inotify_inotify_h_hdr=yes,
    1.30 +                            have_inotify_inotify_h_hdr=no)
    1.31 +            CFLAGS="$save_CFLAGS"
    1.32 +            if test x$have_ibus_ibus_h_hdr = xyes; then
    1.33 +                if test x$enable_dbus != xyes; then
    1.34 +                    AC_MSG_WARN([DBus support is required for IBus.])
    1.35 +                    have_ibus_ibus_h_hdr=no
    1.36 +                elif test x$have_inotify_inotify_h_hdr != xyes; then
    1.37 +                    AC_MSG_WARN([INotify support is required for IBus.])
    1.38 +                    have_ibus_ibus_h_hdr=no
    1.39 +                else
    1.40 +                    AC_DEFINE(HAVE_IBUS_IBUS_H, 1, [ ])
    1.41 +                    EXTRA_CFLAGS="$EXTRA_CFLAGS $IBUS_CFLAGS"
    1.42 +                    SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ibus.c"
    1.43 +               fi
    1.44              fi
    1.45          fi
    1.46      fi
    1.47 @@ -2732,6 +2769,7 @@
    1.48          CheckWayland
    1.49          CheckLibUDev
    1.50          CheckDBus
    1.51 +        CheckIBus
    1.52          CheckInputEvents
    1.53          CheckInputKD
    1.54          CheckTslib
    1.55 @@ -3347,6 +3385,11 @@
    1.56  else
    1.57      SUMMARY="${SUMMARY}Using dbus      : NO\n"
    1.58  fi
    1.59 +if test x$have_ibus_ibus_h_hdr = xyes; then
    1.60 +    SUMMARY="${SUMMARY}Using ibus      : YES\n"
    1.61 +else
    1.62 +    SUMMARY="${SUMMARY}Using ibus      : NO\n"
    1.63 +fi
    1.64  AC_CONFIG_COMMANDS([summary], [echo -en "$SUMMARY"], [SUMMARY="$SUMMARY"])
    1.65  
    1.66  AC_OUTPUT
     2.1 --- a/include/SDL_config.h.in	Sat Jun 21 11:52:53 2014 -0700
     2.2 +++ b/include/SDL_config.h.in	Wed Jun 18 20:11:39 2014 +0100
     2.3 @@ -78,6 +78,7 @@
     2.4  #undef HAVE_PTHREAD_NP_H
     2.5  #undef HAVE_LIBUDEV_H
     2.6  #undef HAVE_DBUS_DBUS_H
     2.7 +#undef HAVE_IBUS_IBUS_H
     2.8  
     2.9  /* C library functions */
    2.10  #undef HAVE_MALLOC
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/core/linux/SDL_dbus.c	Wed Jun 18 20:11:39 2014 +0100
     3.3 @@ -0,0 +1,236 @@
     3.4 +/*
     3.5 +  Simple DirectMedia Layer
     3.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     3.7 +
     3.8 +  This software is provided 'as-is', without any express or implied
     3.9 +  warranty.  In no event will the authors be held liable for any damages
    3.10 +  arising from the use of this software.
    3.11 +
    3.12 +  Permission is granted to anyone to use this software for any purpose,
    3.13 +  including commercial applications, and to alter it and redistribute it
    3.14 +  freely, subject to the following restrictions:
    3.15 +
    3.16 +  1. The origin of this software must not be misrepresented; you must not
    3.17 +     claim that you wrote the original software. If you use this software
    3.18 +     in a product, an acknowledgment in the product documentation would be
    3.19 +     appreciated but is not required.
    3.20 +  2. Altered source versions must be plainly marked as such, and must not be
    3.21 +     misrepresented as being the original software.
    3.22 +  3. This notice may not be removed or altered from any source distribution.
    3.23 +*/
    3.24 +#include "../../SDL_internal.h"
    3.25 +#include "SDL_dbus.h"
    3.26 +
    3.27 +#if SDL_USE_LIBDBUS
    3.28 +/* we never link directly to libdbus. */
    3.29 +#include "SDL_loadso.h"
    3.30 +static const char *dbus_library = "libdbus-1.so.3";
    3.31 +static void *dbus_handle = NULL;
    3.32 +static unsigned int screensaver_cookie = 0;
    3.33 +static SDL_DBusContext dbus = {0};
    3.34 +
    3.35 +static int
    3.36 +load_dbus_syms(void)
    3.37 +{
    3.38 +    #define SDL_DBUS_SYM2(x, y) \
    3.39 +        if (!(dbus.x = SDL_LoadFunction(dbus_handle, #y))) return -1
    3.40 +        
    3.41 +    #define SDL_DBUS_SYM(x) \
    3.42 +        SDL_DBUS_SYM2(x, dbus_##x)
    3.43 +
    3.44 +    SDL_DBUS_SYM(bus_get_private);
    3.45 +    SDL_DBUS_SYM(bus_register);
    3.46 +    SDL_DBUS_SYM(bus_add_match);
    3.47 +    SDL_DBUS_SYM(connection_open_private);
    3.48 +    SDL_DBUS_SYM(connection_set_exit_on_disconnect);
    3.49 +    SDL_DBUS_SYM(connection_get_is_connected);
    3.50 +    SDL_DBUS_SYM(connection_add_filter);
    3.51 +    SDL_DBUS_SYM(connection_send);
    3.52 +    SDL_DBUS_SYM(connection_send_with_reply_and_block);
    3.53 +    SDL_DBUS_SYM(connection_close);
    3.54 +    SDL_DBUS_SYM(connection_unref);
    3.55 +    SDL_DBUS_SYM(connection_flush);
    3.56 +    SDL_DBUS_SYM(connection_read_write);
    3.57 +    SDL_DBUS_SYM(connection_dispatch);
    3.58 +    SDL_DBUS_SYM(message_is_signal);
    3.59 +    SDL_DBUS_SYM(message_new_method_call);
    3.60 +    SDL_DBUS_SYM(message_append_args);
    3.61 +    SDL_DBUS_SYM(message_get_args);
    3.62 +    SDL_DBUS_SYM(message_iter_init);
    3.63 +    SDL_DBUS_SYM(message_iter_next);
    3.64 +    SDL_DBUS_SYM(message_iter_get_basic);
    3.65 +    SDL_DBUS_SYM(message_iter_get_arg_type);
    3.66 +    SDL_DBUS_SYM(message_iter_recurse);
    3.67 +    SDL_DBUS_SYM(message_unref);
    3.68 +    SDL_DBUS_SYM(error_init);
    3.69 +    SDL_DBUS_SYM(error_is_set);
    3.70 +    SDL_DBUS_SYM(error_free);
    3.71 +    SDL_DBUS_SYM(get_local_machine_id);
    3.72 +    SDL_DBUS_SYM(free);
    3.73 +
    3.74 +    #undef SDL_DBUS_SYM
    3.75 +    #undef SDL_DBUS_SYM2
    3.76 +
    3.77 +    return 0;
    3.78 +}
    3.79 +
    3.80 +static void
    3.81 +UnloadDBUSLibrary(void)
    3.82 +{
    3.83 +    if (dbus_handle != NULL) {
    3.84 +        SDL_UnloadObject(dbus_handle);
    3.85 +        dbus_handle = NULL;
    3.86 +    }
    3.87 +}
    3.88 +
    3.89 +static int
    3.90 +LoadDBUSLibrary(void)
    3.91 +{
    3.92 +    int retval = 0;
    3.93 +    if (dbus_handle == NULL) {
    3.94 +        dbus_handle = SDL_LoadObject(dbus_library);
    3.95 +        if (dbus_handle == NULL) {
    3.96 +            retval = -1;
    3.97 +            /* Don't call SDL_SetError(): SDL_LoadObject already did. */
    3.98 +        } else {
    3.99 +            retval = load_dbus_syms();
   3.100 +            if (retval < 0) {
   3.101 +                UnloadDBUSLibrary();
   3.102 +            }
   3.103 +        }
   3.104 +    }
   3.105 +
   3.106 +    return retval;
   3.107 +}
   3.108 +
   3.109 +void
   3.110 +SDL_DBus_Init(void)
   3.111 +{
   3.112 +    if (LoadDBUSLibrary() != -1) {
   3.113 +        DBusError err;
   3.114 +        dbus.error_init(&err);
   3.115 +        dbus.session_conn = dbus.bus_get_private(DBUS_BUS_SESSION, &err);
   3.116 +        if (dbus.error_is_set(&err)) {
   3.117 +            dbus.error_free(&err);
   3.118 +            if (dbus.session_conn) {
   3.119 +                dbus.connection_unref(dbus.session_conn);
   3.120 +                dbus.session_conn = NULL;
   3.121 +            }
   3.122 +            return;  /* oh well */
   3.123 +        }
   3.124 +        dbus.connection_set_exit_on_disconnect(dbus.session_conn, 0);
   3.125 +    }
   3.126 +}
   3.127 +
   3.128 +void
   3.129 +SDL_DBus_Quit(void)
   3.130 +{
   3.131 +    if (dbus.session_conn) {
   3.132 +        dbus.connection_close(dbus.session_conn);
   3.133 +        dbus.connection_unref(dbus.session_conn);
   3.134 +        SDL_memset(&dbus, 0, sizeof(dbus));
   3.135 +    }
   3.136 +    UnloadDBUSLibrary();
   3.137 +}
   3.138 +
   3.139 +SDL_DBusContext *
   3.140 +SDL_DBus_GetContext(void)
   3.141 +{
   3.142 +    if(!dbus_handle || !dbus.session_conn){
   3.143 +        SDL_DBus_Init();
   3.144 +    }
   3.145 +    
   3.146 +    if(dbus_handle && dbus.session_conn){
   3.147 +        return &dbus;
   3.148 +    } else {
   3.149 +        return NULL;
   3.150 +    }
   3.151 +}
   3.152 +
   3.153 +void
   3.154 +SDL_DBus_ScreensaverTickle(void)
   3.155 +{
   3.156 +    DBusConnection *conn = dbus.session_conn;
   3.157 +    if (conn != NULL) {
   3.158 +        DBusMessage *msg = dbus.message_new_method_call("org.gnome.ScreenSaver",
   3.159 +                                                        "/org/gnome/ScreenSaver",
   3.160 +                                                        "org.gnome.ScreenSaver",
   3.161 +                                                        "SimulateUserActivity");
   3.162 +        if (msg != NULL) {
   3.163 +            if (dbus.connection_send(conn, msg, NULL)) {
   3.164 +                dbus.connection_flush(conn);
   3.165 +            }
   3.166 +            dbus.message_unref(msg);
   3.167 +        }
   3.168 +    }
   3.169 +}
   3.170 +
   3.171 +SDL_bool
   3.172 +SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
   3.173 +{
   3.174 +    DBusConnection *conn = dbus.session_conn;
   3.175 +
   3.176 +    if (conn == NULL)
   3.177 +        return SDL_FALSE;
   3.178 +
   3.179 +    if (inhibit &&
   3.180 +        screensaver_cookie != 0)
   3.181 +        return SDL_TRUE;
   3.182 +    if (!inhibit &&
   3.183 +        screensaver_cookie == 0)
   3.184 +        return SDL_TRUE;
   3.185 +
   3.186 +    if (inhibit) {
   3.187 +        const char *app = "My SDL application";
   3.188 +        const char *reason = "Playing a game";
   3.189 +
   3.190 +        DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
   3.191 +                                                         "/org/freedesktop/ScreenSaver",
   3.192 +                                                         "org.freedesktop.ScreenSaver",
   3.193 +                                                         "Inhibit");
   3.194 +        if (msg != NULL) {
   3.195 +            dbus.message_append_args (msg,
   3.196 +                                      DBUS_TYPE_STRING, &app,
   3.197 +                                      DBUS_TYPE_STRING, &reason,
   3.198 +                                      DBUS_TYPE_INVALID);
   3.199 +        }
   3.200 +
   3.201 +        if (msg != NULL) {
   3.202 +            DBusMessage *reply;
   3.203 +
   3.204 +            reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
   3.205 +            if (reply) {
   3.206 +                if (!dbus.message_get_args(reply, NULL,
   3.207 +                                           DBUS_TYPE_UINT32, &screensaver_cookie,
   3.208 +                                           DBUS_TYPE_INVALID))
   3.209 +                    screensaver_cookie = 0;
   3.210 +                dbus.message_unref(reply);
   3.211 +            }
   3.212 +
   3.213 +            dbus.message_unref(msg);
   3.214 +        }
   3.215 +
   3.216 +        if (screensaver_cookie == 0) {
   3.217 +            return SDL_FALSE;
   3.218 +        }
   3.219 +        return SDL_TRUE;
   3.220 +    } else {
   3.221 +        DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
   3.222 +                                                        "/org/freedesktop/ScreenSaver",
   3.223 +                                                        "org.freedesktop.ScreenSaver",
   3.224 +                                                        "UnInhibit");
   3.225 +        dbus.message_append_args (msg,
   3.226 +                                  DBUS_TYPE_UINT32, &screensaver_cookie,
   3.227 +                                  DBUS_TYPE_INVALID);
   3.228 +        if (msg != NULL) {
   3.229 +            if (dbus.connection_send(conn, msg, NULL)) {
   3.230 +                dbus.connection_flush(conn);
   3.231 +            }
   3.232 +            dbus.message_unref(msg);
   3.233 +        }
   3.234 +
   3.235 +        screensaver_cookie = 0;
   3.236 +        return SDL_TRUE;
   3.237 +    }
   3.238 +}
   3.239 +#endif
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/core/linux/SDL_dbus.h	Wed Jun 18 20:11:39 2014 +0100
     4.3 @@ -0,0 +1,79 @@
     4.4 +/*
     4.5 +  Simple DirectMedia Layer
     4.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     4.7 +
     4.8 +  This software is provided 'as-is', without any express or implied
     4.9 +  warranty.  In no event will the authors be held liable for any damages
    4.10 +  arising from the use of this software.
    4.11 +
    4.12 +  Permission is granted to anyone to use this software for any purpose,
    4.13 +  including commercial applications, and to alter it and redistribute it
    4.14 +  freely, subject to the following restrictions:
    4.15 +
    4.16 +  1. The origin of this software must not be misrepresented; you must not
    4.17 +     claim that you wrote the original software. If you use this software
    4.18 +     in a product, an acknowledgment in the product documentation would be
    4.19 +     appreciated but is not required.
    4.20 +  2. Altered source versions must be plainly marked as such, and must not be
    4.21 +     misrepresented as being the original software.
    4.22 +  3. This notice may not be removed or altered from any source distribution.
    4.23 +*/
    4.24 +
    4.25 +#include "../../SDL_internal.h"
    4.26 +
    4.27 +#ifndef _SDL_dbus_h
    4.28 +#define _SDL_dbus_h
    4.29 +
    4.30 +#ifdef HAVE_DBUS_DBUS_H
    4.31 +#define SDL_USE_LIBDBUS 1
    4.32 +#include "SDL_stdinc.h"
    4.33 +#include <dbus/dbus.h>
    4.34 +
    4.35 +
    4.36 +typedef struct SDL_DBusContext {
    4.37 +    DBusConnection *session_conn;
    4.38 +
    4.39 +    DBusConnection *(*bus_get_private)(DBusBusType, DBusError *);
    4.40 +    dbus_bool_t (*bus_register)(DBusConnection *, DBusError *);
    4.41 +    void (*bus_add_match)(DBusConnection *, const char *, DBusError *);
    4.42 +    DBusConnection * (*connection_open_private)(const char *, DBusError *);
    4.43 +    void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t);
    4.44 +    dbus_bool_t (*connection_get_is_connected)(DBusConnection *); 	
    4.45 +    dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction,
    4.46 +	    void *, DBusFreeFunction);
    4.47 +    dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *);
    4.48 +    DBusMessage *(*connection_send_with_reply_and_block)(DBusConnection *, DBusMessage *, int, DBusError *);
    4.49 +    void (*connection_close)(DBusConnection *);
    4.50 +    void (*connection_unref)(DBusConnection *);
    4.51 +    void (*connection_flush)(DBusConnection *);
    4.52 +    dbus_bool_t (*connection_read_write)(DBusConnection *, int);
    4.53 +    DBusDispatchStatus (*connection_dispatch)(DBusConnection *);
    4.54 +    dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); 	
    4.55 +    DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *);
    4.56 +    dbus_bool_t (*message_append_args)(DBusMessage *, int, ...);
    4.57 +    dbus_bool_t (*message_get_args)(DBusMessage *, DBusError *, int, ...);
    4.58 +    dbus_bool_t (*message_iter_init)(DBusMessage *, DBusMessageIter *);
    4.59 +    dbus_bool_t (*message_iter_next)(DBusMessageIter *);
    4.60 +    void (*message_iter_get_basic)(DBusMessageIter *, void *);
    4.61 +    int (*message_iter_get_arg_type)(DBusMessageIter *);
    4.62 +    void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *); 	 	
    4.63 +    void (*message_unref)(DBusMessage *);
    4.64 +    void (*error_init)(DBusError *);
    4.65 +    dbus_bool_t (*error_is_set)(const DBusError *);
    4.66 +    void (*error_free)(DBusError *);
    4.67 +    char *(*get_local_machine_id)(void);
    4.68 +    void (*free)(void *); 	 	
    4.69 +
    4.70 +} SDL_DBusContext;
    4.71 +
    4.72 +extern void SDL_DBus_Init(void);
    4.73 +extern void SDL_DBus_Quit(void);
    4.74 +extern SDL_DBusContext * SDL_DBus_GetContext(void);
    4.75 +extern void SDL_DBus_ScreensaverTickle(void);
    4.76 +extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit);
    4.77 +
    4.78 +#endif /* HAVE_DBUS_DBUS_H */
    4.79 +
    4.80 +#endif /* _SDL_dbus_h */
    4.81 +
    4.82 +/* vi: set ts=4 sw=4 expandtab: */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/core/linux/SDL_ibus.c	Wed Jun 18 20:11:39 2014 +0100
     5.3 @@ -0,0 +1,593 @@
     5.4 +/*
     5.5 +  Simple DirectMedia Layer
     5.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     5.7 +
     5.8 +  This software is provided 'as-is', without any express or implied
     5.9 +  warranty.  In no event will the authors be held liable for any damages
    5.10 +  arising from the use of this software.
    5.11 +
    5.12 +  Permission is granted to anyone to use this software for any purpose,
    5.13 +  including commercial applications, and to alter it and redistribute it
    5.14 +  freely, subject to the following restrictions:
    5.15 +
    5.16 +  1. The origin of this software must not be misrepresented; you must not
    5.17 +     claim that you wrote the original software. If you use this software
    5.18 +     in a product, an acknowledgment in the product documentation would be
    5.19 +     appreciated but is not required.
    5.20 +  2. Altered source versions must be plainly marked as such, and must not be
    5.21 +     misrepresented as being the original software.
    5.22 +  3. This notice may not be removed or altered from any source distribution.
    5.23 +*/
    5.24 +#include "../../SDL_internal.h"
    5.25 +
    5.26 +#ifdef HAVE_IBUS_IBUS_H
    5.27 +#include "SDL.h"
    5.28 +#include "SDL_ibus.h"
    5.29 +#include "SDL_dbus.h"
    5.30 +#include "../../video/SDL_sysvideo.h"
    5.31 +#include "../../events/SDL_keyboard_c.h"
    5.32 +#include <sys/inotify.h>
    5.33 +#include <unistd.h>
    5.34 +#include <fcntl.h>
    5.35 +
    5.36 +static const char IBUS_SERVICE[]         = "org.freedesktop.IBus";
    5.37 +static const char IBUS_PATH[]            = "/org/freedesktop/IBus";
    5.38 +static const char IBUS_INTERFACE[]       = "org.freedesktop.IBus";
    5.39 +static const char IBUS_INPUT_INTERFACE[] = "org.freedesktop.IBus.InputContext";
    5.40 +
    5.41 +static char *input_ctx_path = NULL;
    5.42 +static SDL_Rect ibus_cursor_rect = {0};
    5.43 +static DBusConnection *ibus_conn = NULL;
    5.44 +static char *ibus_addr_file = NULL;
    5.45 +int inotify_fd = -1;
    5.46 +
    5.47 +static Uint32
    5.48 +IBus_ModState(void)
    5.49 +{
    5.50 +    Uint32 ibus_mods = 0;
    5.51 +    SDL_Keymod sdl_mods = SDL_GetModState();
    5.52 +    
    5.53 +    /* Not sure about MOD3, MOD4 and HYPER mappings */
    5.54 +    if(sdl_mods & KMOD_LSHIFT) ibus_mods |= IBUS_SHIFT_MASK;
    5.55 +    if(sdl_mods & KMOD_CAPS)   ibus_mods |= IBUS_LOCK_MASK;
    5.56 +    if(sdl_mods & KMOD_LCTRL)  ibus_mods |= IBUS_CONTROL_MASK;
    5.57 +    if(sdl_mods & KMOD_LALT)   ibus_mods |= IBUS_MOD1_MASK;
    5.58 +    if(sdl_mods & KMOD_NUM)    ibus_mods |= IBUS_MOD2_MASK;
    5.59 +    if(sdl_mods & KMOD_MODE)   ibus_mods |= IBUS_MOD5_MASK;
    5.60 +    if(sdl_mods & KMOD_LGUI)   ibus_mods |= IBUS_SUPER_MASK;
    5.61 +    if(sdl_mods & KMOD_RGUI)   ibus_mods |= IBUS_META_MASK;
    5.62 +
    5.63 +    return ibus_mods;
    5.64 +}
    5.65 +
    5.66 +static const char *
    5.67 +IBus_GetVariantText(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus)
    5.68 +{
    5.69 +    /* The text we need is nested weirdly, use dbus-monitor to see the structure better */
    5.70 +    const char *text = NULL;
    5.71 +    DBusMessageIter sub1, sub2;
    5.72 +
    5.73 +    if(dbus->message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT){
    5.74 +        return NULL;
    5.75 +    }
    5.76 +    
    5.77 +    dbus->message_iter_recurse(iter, &sub1);
    5.78 +    
    5.79 +    if(dbus->message_iter_get_arg_type(&sub1) != DBUS_TYPE_STRUCT){
    5.80 +        return NULL;
    5.81 +    }
    5.82 +    
    5.83 +    dbus->message_iter_recurse(&sub1, &sub2);
    5.84 +    
    5.85 +    if(dbus->message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING){
    5.86 +        return NULL;
    5.87 +    }
    5.88 +    
    5.89 +    const char *struct_id = NULL;
    5.90 +    dbus->message_iter_get_basic(&sub2, &struct_id);
    5.91 +    if(!struct_id || SDL_strncmp(struct_id, "IBusText", sizeof("IBusText")) != 0){
    5.92 +        return NULL;
    5.93 +    }
    5.94 +    
    5.95 +    dbus->message_iter_next(&sub2);
    5.96 +    dbus->message_iter_next(&sub2);
    5.97 +    
    5.98 +    if(dbus->message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING){
    5.99 +        return NULL;
   5.100 +    }
   5.101 +    
   5.102 +    dbus->message_iter_get_basic(&sub2, &text);
   5.103 +    
   5.104 +    return text;
   5.105 +}
   5.106 +
   5.107 +static size_t 
   5.108 +IBus_utf8_strlen(const char *str)
   5.109 +{
   5.110 +    size_t utf8_len = 0;
   5.111 +    const char *p;
   5.112 +    
   5.113 +    for(p = str; *p; ++p){
   5.114 +        if(!((*p & 0x80) && !(*p & 0x40))){
   5.115 +            ++utf8_len;
   5.116 +        }
   5.117 +    }
   5.118 +    
   5.119 +    return utf8_len;
   5.120 +}
   5.121 +
   5.122 +static DBusHandlerResult
   5.123 +IBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *user_data)
   5.124 +{
   5.125 +    SDL_DBusContext *dbus = (SDL_DBusContext *)user_data;
   5.126 +        
   5.127 +    if(dbus->message_is_signal(msg, IBUS_INPUT_INTERFACE, "CommitText")){
   5.128 +        DBusMessageIter iter;
   5.129 +        dbus->message_iter_init(msg, &iter);
   5.130 +        
   5.131 +        const char *text = IBus_GetVariantText(conn, &iter, dbus);
   5.132 +        if(text && *text){
   5.133 +            char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
   5.134 +            size_t text_bytes = SDL_strlen(text), i = 0;
   5.135 +            
   5.136 +            while(i < text_bytes){
   5.137 +                size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf));
   5.138 +                SDL_SendKeyboardText(buf);
   5.139 +                
   5.140 +                i += sz;
   5.141 +            }
   5.142 +        }
   5.143 +        
   5.144 +        return DBUS_HANDLER_RESULT_HANDLED;
   5.145 +    }
   5.146 +    
   5.147 +    if(dbus->message_is_signal(msg, IBUS_INPUT_INTERFACE, "UpdatePreeditText")){
   5.148 +        DBusMessageIter iter;
   5.149 +        dbus->message_iter_init(msg, &iter);
   5.150 +        const char *text = IBus_GetVariantText(conn, &iter, dbus);
   5.151 +        
   5.152 +        if(text && *text){
   5.153 +            char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
   5.154 +            size_t text_bytes = SDL_strlen(text), i = 0;
   5.155 +            size_t cursor = 0;
   5.156 +            
   5.157 +            while(i < text_bytes){
   5.158 +                size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf));
   5.159 +                size_t chars = IBus_utf8_strlen(buf);
   5.160 +                
   5.161 +                SDL_SendEditingText(buf, cursor, chars);
   5.162 +
   5.163 +                i += sz;
   5.164 +                cursor += chars;
   5.165 +            }
   5.166 +        } else {
   5.167 +            SDL_SendEditingText("", 0, 0);
   5.168 +        }
   5.169 +        
   5.170 +        SDL_IBus_UpdateTextRect(NULL);
   5.171 +        
   5.172 +        return DBUS_HANDLER_RESULT_HANDLED;
   5.173 +    }
   5.174 +    
   5.175 +    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
   5.176 +}
   5.177 +
   5.178 +static char *
   5.179 +IBus_ReadAddressFromFile(const char *file_path)
   5.180 +{
   5.181 +    FILE *addr_file = fopen(file_path, "r");
   5.182 +    if(!addr_file){
   5.183 +        return NULL;
   5.184 +    }
   5.185 +
   5.186 +    char addr_buf[1024];
   5.187 +    SDL_bool success = SDL_FALSE;
   5.188 +
   5.189 +    while(fgets(addr_buf, sizeof(addr_buf), addr_file)){
   5.190 +        if(SDL_strncmp(addr_buf, "IBUS_ADDRESS=", sizeof("IBUS_ADDRESS=")-1) == 0){
   5.191 +            size_t sz = SDL_strlen(addr_buf);
   5.192 +            if(addr_buf[sz-1] == '\n') addr_buf[sz-1] = 0;
   5.193 +            if(addr_buf[sz-2] == '\r') addr_buf[sz-2] = 0;
   5.194 +            success = SDL_TRUE;
   5.195 +            break;
   5.196 +        }
   5.197 +    }
   5.198 +
   5.199 +    fclose(addr_file);
   5.200 +
   5.201 +    if(success){
   5.202 +        return SDL_strdup(addr_buf + (sizeof("IBUS_ADDRESS=") - 1));
   5.203 +    } else {
   5.204 +        return NULL;
   5.205 +    }
   5.206 +}
   5.207 +
   5.208 +static char *
   5.209 +IBus_GetDBusAddressFilename(void)
   5.210 +{
   5.211 +    if(ibus_addr_file){
   5.212 +        return SDL_strdup(ibus_addr_file);
   5.213 +    }
   5.214 +    
   5.215 +    SDL_DBusContext *dbus = SDL_DBus_GetContext();
   5.216 +    
   5.217 +    if(!dbus){
   5.218 +        return NULL;
   5.219 +    }
   5.220 +    
   5.221 +    /* Use this environment variable if it exists. */
   5.222 +    const char *addr = SDL_getenv("IBUS_ADDRESS");
   5.223 +    if(addr && *addr){
   5.224 +        return SDL_strdup(addr);
   5.225 +    }
   5.226 +    
   5.227 +    /* Otherwise, we have to get the hostname, display, machine id, config dir
   5.228 +       and look up the address from a filepath using all those bits, eek. */
   5.229 +    const char *disp_env = SDL_getenv("DISPLAY");
   5.230 +    char *display = NULL;
   5.231 +    
   5.232 +    if(!disp_env || !*disp_env){
   5.233 +        display = SDL_strdup(":0.0");
   5.234 +    } else {
   5.235 +        display = SDL_strdup(disp_env);
   5.236 +    }
   5.237 +    
   5.238 +    const char *host = display;
   5.239 +    char *disp_num   = SDL_strrchr(display, ':'), 
   5.240 +         *screen_num = SDL_strrchr(display, '.');
   5.241 +    
   5.242 +    if(!disp_num){
   5.243 +        SDL_free(display);
   5.244 +        return NULL;
   5.245 +    }
   5.246 +    
   5.247 +    *disp_num = 0;
   5.248 +    disp_num++;
   5.249 +    
   5.250 +    if(screen_num){
   5.251 +        *screen_num = 0;
   5.252 +    }
   5.253 +    
   5.254 +    if(!*host){
   5.255 +        host = "unix";
   5.256 +    }
   5.257 +        
   5.258 +    char config_dir[PATH_MAX];
   5.259 +    SDL_memset(config_dir, 0, sizeof(config_dir));
   5.260 +    
   5.261 +    const char *conf_env = SDL_getenv("XDG_CONFIG_HOME");
   5.262 +    if(conf_env && *conf_env){
   5.263 +        SDL_strlcpy(config_dir, conf_env, sizeof(config_dir));
   5.264 +    } else {
   5.265 +        const char *home_env = SDL_getenv("HOME");
   5.266 +        if(!home_env || !*home_env){
   5.267 +            SDL_free(display);
   5.268 +            return NULL;
   5.269 +        }
   5.270 +        SDL_snprintf(config_dir, sizeof(config_dir), "%s/.config", home_env);
   5.271 +    }
   5.272 +    
   5.273 +    char *key = dbus->get_local_machine_id();
   5.274 +    
   5.275 +    char file_path[PATH_MAX];
   5.276 +    SDL_memset(file_path, 0, sizeof(file_path));
   5.277 +    SDL_snprintf(file_path, sizeof(file_path), "%s/ibus/bus/%s-%s-%s", 
   5.278 +                                               config_dir, key, host, disp_num);
   5.279 +    dbus->free(key);
   5.280 +    SDL_free(display);
   5.281 +    
   5.282 +    return SDL_strdup(file_path);
   5.283 +}
   5.284 +
   5.285 +static SDL_bool
   5.286 +IBus_SetupConnection(SDL_DBusContext *dbus, const char* addr)
   5.287 +{
   5.288 +    const char *path = NULL;
   5.289 +    SDL_bool result = SDL_FALSE;
   5.290 +    
   5.291 +    ibus_conn = dbus->connection_open_private(addr, NULL);
   5.292 +
   5.293 +    if(!ibus_conn){
   5.294 +        return SDL_FALSE;
   5.295 +    }
   5.296 +
   5.297 +    dbus->connection_flush(ibus_conn);
   5.298 +    
   5.299 +    if(!dbus->bus_register(ibus_conn, NULL)){
   5.300 +        ibus_conn = NULL;
   5.301 +        return SDL_FALSE;
   5.302 +    }
   5.303 +    
   5.304 +    dbus->connection_flush(ibus_conn);
   5.305 +
   5.306 +    DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE,
   5.307 +                                                     IBUS_PATH,
   5.308 +                                                     IBUS_INTERFACE,
   5.309 +                                                     "CreateInputContext");
   5.310 +    if(msg){
   5.311 +        const char *client_name = "SDL2_Application";
   5.312 +        dbus->message_append_args(msg,
   5.313 +                                  DBUS_TYPE_STRING, &client_name,
   5.314 +                                  DBUS_TYPE_INVALID);
   5.315 +    }
   5.316 +    
   5.317 +    if(msg){
   5.318 +        DBusMessage *reply;
   5.319 +        
   5.320 +        reply = dbus->connection_send_with_reply_and_block(ibus_conn, msg, 1000, NULL);
   5.321 +        if(reply){
   5.322 +            if(dbus->message_get_args(reply, NULL,
   5.323 +                                       DBUS_TYPE_OBJECT_PATH, &path,
   5.324 +                                       DBUS_TYPE_INVALID)){
   5.325 +                if(input_ctx_path){
   5.326 +                    SDL_free(input_ctx_path);
   5.327 +                }
   5.328 +                input_ctx_path = SDL_strdup(path);
   5.329 +                result = SDL_TRUE;                          
   5.330 +            }
   5.331 +            dbus->message_unref(reply);
   5.332 +        }
   5.333 +        dbus->message_unref(msg);
   5.334 +    }
   5.335 +
   5.336 +    if(result){
   5.337 +        DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE,
   5.338 +                                                         input_ctx_path,
   5.339 +                                                         IBUS_INPUT_INTERFACE,
   5.340 +                                                         "SetCapabilities");
   5.341 +        if(msg){
   5.342 +            Uint32 caps = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT;
   5.343 +            dbus->message_append_args(msg,
   5.344 +                                      DBUS_TYPE_UINT32, &caps,
   5.345 +                                      DBUS_TYPE_INVALID);
   5.346 +        }
   5.347 +        
   5.348 +        if(msg){
   5.349 +            if(dbus->connection_send(ibus_conn, msg, NULL)){
   5.350 +                dbus->connection_flush(ibus_conn);
   5.351 +            }
   5.352 +            dbus->message_unref(msg);
   5.353 +        }
   5.354 +        
   5.355 +        dbus->bus_add_match(ibus_conn, "type='signal',interface='org.freedesktop.IBus.InputContext'", NULL);
   5.356 +        dbus->connection_add_filter(ibus_conn, &IBus_MessageFilter, dbus, NULL);
   5.357 +        dbus->connection_flush(ibus_conn);
   5.358 +    }
   5.359 +
   5.360 +    SDL_IBus_SetFocus(SDL_GetFocusWindow() != NULL);
   5.361 +    SDL_IBus_UpdateTextRect(NULL);
   5.362 +    
   5.363 +    return result;
   5.364 +}
   5.365 +
   5.366 +static SDL_bool
   5.367 +IBus_CheckConnection(SDL_DBusContext *dbus)
   5.368 +{
   5.369 +    if(!dbus) return SDL_FALSE;
   5.370 +    
   5.371 +    if(ibus_conn && dbus->connection_get_is_connected(ibus_conn)){
   5.372 +        return SDL_TRUE;
   5.373 +    }
   5.374 +    
   5.375 +    if(inotify_fd != -1){
   5.376 +        char buf[1024];
   5.377 +        ssize_t readsize = read(inotify_fd, buf, sizeof(buf));
   5.378 +        if(readsize > 0){
   5.379 +        
   5.380 +            char *p;
   5.381 +            SDL_bool file_updated = SDL_FALSE;
   5.382 +            
   5.383 +            for(p = buf; p < buf + readsize; /**/){
   5.384 +                struct inotify_event *event = (struct inotify_event*) p;
   5.385 +                if(event->len > 0){
   5.386 +                    char *addr_file_no_path = SDL_strrchr(ibus_addr_file, '/');
   5.387 +                    if(!addr_file_no_path) return SDL_FALSE;
   5.388 +                 
   5.389 +                    if(SDL_strcmp(addr_file_no_path + 1, event->name) == 0){
   5.390 +                        file_updated = SDL_TRUE;
   5.391 +                        break;
   5.392 +                    }
   5.393 +                }
   5.394 +                
   5.395 +                p += sizeof(struct inotify_event) + event->len;
   5.396 +            }
   5.397 +            
   5.398 +            if(file_updated){
   5.399 +                char *addr = IBus_ReadAddressFromFile(ibus_addr_file);
   5.400 +                if(addr){
   5.401 +                    SDL_bool result = IBus_SetupConnection(dbus, addr);
   5.402 +                    SDL_free(addr);
   5.403 +                    return result;
   5.404 +                }
   5.405 +            }
   5.406 +        }
   5.407 +    }
   5.408 +    
   5.409 +    return SDL_FALSE;
   5.410 +}
   5.411 +
   5.412 +SDL_bool
   5.413 +SDL_IBus_Init(void)
   5.414 +{
   5.415 +    SDL_bool result = SDL_FALSE;
   5.416 +    SDL_DBusContext *dbus = SDL_DBus_GetContext();
   5.417 +    
   5.418 +    if(dbus){
   5.419 +        char *addr_file = IBus_GetDBusAddressFilename();
   5.420 +        if(!addr_file){
   5.421 +            return SDL_FALSE;
   5.422 +        }
   5.423 +        
   5.424 +        ibus_addr_file = SDL_strdup(addr_file);
   5.425 +        
   5.426 +        char *addr = IBus_ReadAddressFromFile(addr_file);
   5.427 +        
   5.428 +        inotify_fd = inotify_init();
   5.429 +        fcntl(inotify_fd, F_SETFL, O_NONBLOCK);
   5.430 +        
   5.431 +        char *addr_file_dir = SDL_strrchr(addr_file, '/');
   5.432 +        if(addr_file_dir){
   5.433 +            *addr_file_dir = 0;
   5.434 +        }
   5.435 +        
   5.436 +        inotify_add_watch(inotify_fd, addr_file, IN_CREATE | IN_MODIFY);
   5.437 +        SDL_free(addr_file);
   5.438 +        
   5.439 +        result = IBus_SetupConnection(dbus, addr);
   5.440 +        SDL_free(addr);
   5.441 +    }
   5.442 +    
   5.443 +    return result;
   5.444 +}
   5.445 +
   5.446 +void
   5.447 +SDL_IBus_Quit(void)
   5.448 +{   
   5.449 +    if(input_ctx_path){
   5.450 +        SDL_free(input_ctx_path);
   5.451 +        input_ctx_path = NULL;
   5.452 +    }
   5.453 +    
   5.454 +    if(ibus_addr_file){
   5.455 +        SDL_free(ibus_addr_file);
   5.456 +        ibus_addr_file = NULL;
   5.457 +    }
   5.458 +    
   5.459 +    SDL_DBusContext *dbus = SDL_DBus_GetContext();
   5.460 +    
   5.461 +    if(dbus && ibus_conn){
   5.462 +        dbus->connection_close(ibus_conn);
   5.463 +        dbus->connection_unref(ibus_conn);
   5.464 +    }
   5.465 +    
   5.466 +    SDL_memset(&ibus_cursor_rect, 0, sizeof(ibus_cursor_rect));
   5.467 +}
   5.468 +
   5.469 +static void
   5.470 +IBus_SimpleMessage(const char *method)
   5.471 +{   
   5.472 +    SDL_DBusContext *dbus = SDL_DBus_GetContext();
   5.473 +    
   5.474 +    if(IBus_CheckConnection(dbus)){
   5.475 +        DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE,
   5.476 +                                                         input_ctx_path,
   5.477 +                                                         IBUS_INPUT_INTERFACE,
   5.478 +                                                         method);
   5.479 +        if(msg){
   5.480 +            if(dbus->connection_send(ibus_conn, msg, NULL)){
   5.481 +                dbus->connection_flush(ibus_conn);
   5.482 +            }
   5.483 +            dbus->message_unref(msg);
   5.484 +        }
   5.485 +    }
   5.486 +}
   5.487 +
   5.488 +void
   5.489 +SDL_IBus_SetFocus(SDL_bool focused)
   5.490 +{ 
   5.491 +    const char *method = focused ? "FocusIn" : "FocusOut";
   5.492 +    IBus_SimpleMessage(method);
   5.493 +}
   5.494 +
   5.495 +void
   5.496 +SDL_IBus_Reset(void)
   5.497 +{
   5.498 +    IBus_SimpleMessage("Reset");
   5.499 +}
   5.500 +
   5.501 +SDL_bool
   5.502 +SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
   5.503 +{ 
   5.504 +    SDL_bool result = SDL_FALSE;   
   5.505 +    SDL_DBusContext *dbus = SDL_DBus_GetContext();
   5.506 +    
   5.507 +    if(IBus_CheckConnection(dbus)){
   5.508 +        DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE,
   5.509 +                                                         input_ctx_path,
   5.510 +                                                         IBUS_INPUT_INTERFACE,
   5.511 +                                                         "ProcessKeyEvent");
   5.512 +        if(msg){
   5.513 +            Uint32 mods = IBus_ModState();
   5.514 +            dbus->message_append_args(msg,
   5.515 +                                      DBUS_TYPE_UINT32, &keysym,
   5.516 +                                      DBUS_TYPE_UINT32, &keycode,
   5.517 +                                      DBUS_TYPE_UINT32, &mods,
   5.518 +                                      DBUS_TYPE_INVALID);
   5.519 +        }
   5.520 +        
   5.521 +        if(msg){
   5.522 +            DBusMessage *reply;
   5.523 +            
   5.524 +            reply = dbus->connection_send_with_reply_and_block(ibus_conn, msg, 300, NULL);
   5.525 +            if(reply){
   5.526 +                if(!dbus->message_get_args(reply, NULL,
   5.527 +                                           DBUS_TYPE_BOOLEAN, &result,
   5.528 +                                           DBUS_TYPE_INVALID)){
   5.529 +                    result = SDL_FALSE;                         
   5.530 +                }
   5.531 +                dbus->message_unref(reply);
   5.532 +            }
   5.533 +            dbus->message_unref(msg);
   5.534 +        }
   5.535 +        
   5.536 +    }
   5.537 +    
   5.538 +    return result;
   5.539 +}
   5.540 +
   5.541 +void
   5.542 +SDL_IBus_UpdateTextRect(SDL_Rect *rect)
   5.543 +{
   5.544 +    if(rect){
   5.545 +        SDL_memcpy(&ibus_cursor_rect, rect, sizeof(ibus_cursor_rect));
   5.546 +    }
   5.547 +    
   5.548 +    SDL_Window *focused_win = SDL_GetFocusWindow();
   5.549 +
   5.550 +    if(!focused_win) return;
   5.551 +
   5.552 +    int x = 0, y = 0;
   5.553 +    SDL_GetWindowPosition(focused_win, &x, &y);
   5.554 +    x += ibus_cursor_rect.x;
   5.555 +    y += ibus_cursor_rect.y;
   5.556 +        
   5.557 +    SDL_DBusContext *dbus = SDL_DBus_GetContext();
   5.558 +    
   5.559 +    if(IBus_CheckConnection(dbus)){
   5.560 +        DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE,
   5.561 +                                                         input_ctx_path,
   5.562 +                                                         IBUS_INPUT_INTERFACE,
   5.563 +                                                         "SetCursorLocation");
   5.564 +        if(msg){
   5.565 +            dbus->message_append_args(msg,
   5.566 +                                      DBUS_TYPE_INT32, &x,
   5.567 +                                      DBUS_TYPE_INT32, &y,
   5.568 +                                      DBUS_TYPE_INT32, &ibus_cursor_rect.w,
   5.569 +                                      DBUS_TYPE_INT32, &ibus_cursor_rect.h,
   5.570 +                                      DBUS_TYPE_INVALID);
   5.571 +        }
   5.572 +        
   5.573 +        if(msg){
   5.574 +            if(dbus->connection_send(ibus_conn, msg, NULL)){
   5.575 +                dbus->connection_flush(ibus_conn);
   5.576 +            }
   5.577 +            dbus->message_unref(msg);
   5.578 +        }
   5.579 +    }
   5.580 +}
   5.581 +
   5.582 +void
   5.583 +SDL_IBus_PumpEvents(void)
   5.584 +{
   5.585 +    SDL_DBusContext *dbus = SDL_DBus_GetContext();
   5.586 +    
   5.587 +    if(IBus_CheckConnection(dbus)){
   5.588 +        dbus->connection_read_write(ibus_conn, 0);
   5.589 +    
   5.590 +        while(dbus->connection_dispatch(ibus_conn) == DBUS_DISPATCH_DATA_REMAINS){
   5.591 +            /* Do nothing, actual work happens in IBus_MessageFilter */
   5.592 +        }
   5.593 +    }
   5.594 +}
   5.595 +
   5.596 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/core/linux/SDL_ibus.h	Wed Jun 18 20:11:39 2014 +0100
     6.3 @@ -0,0 +1,58 @@
     6.4 +/*
     6.5 +  Simple DirectMedia Layer
     6.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     6.7 +
     6.8 +  This software is provided 'as-is', without any express or implied
     6.9 +  warranty.  In no event will the authors be held liable for any damages
    6.10 +  arising from the use of this software.
    6.11 +
    6.12 +  Permission is granted to anyone to use this software for any purpose,
    6.13 +  including commercial applications, and to alter it and redistribute it
    6.14 +  freely, subject to the following restrictions:
    6.15 +
    6.16 +  1. The origin of this software must not be misrepresented; you must not
    6.17 +     claim that you wrote the original software. If you use this software
    6.18 +     in a product, an acknowledgment in the product documentation would be
    6.19 +     appreciated but is not required.
    6.20 +  2. Altered source versions must be plainly marked as such, and must not be
    6.21 +     misrepresented as being the original software.
    6.22 +  3. This notice may not be removed or altered from any source distribution.
    6.23 +*/
    6.24 +
    6.25 +#include "../../SDL_internal.h"
    6.26 +
    6.27 +#ifndef _SDL_ibus_h
    6.28 +#define _SDL_ibus_h
    6.29 +
    6.30 +#ifdef HAVE_IBUS_IBUS_H
    6.31 +#define SDL_USE_IBUS 1
    6.32 +#include "SDL_stdinc.h"
    6.33 +#include <ibus-1.0/ibus.h>
    6.34 +
    6.35 +extern SDL_bool SDL_IBus_Init(void);
    6.36 +extern void SDL_IBus_Quit(void);
    6.37 +
    6.38 +/* Lets the IBus server know about changes in window focus */
    6.39 +extern void SDL_IBus_SetFocus(SDL_bool focused);
    6.40 +
    6.41 +/* Closes the candidate list and resets any text currently being edited */
    6.42 +extern void SDL_IBus_Reset(void);
    6.43 +
    6.44 +/* Sends a keypress event to IBus, returns SDL_TRUE if IBus used this event to
    6.45 +   update its candidate list or change input methods. PumpEvents should be
    6.46 +   called some time after this, to recieve the TextInput / TextEditing event back. */
    6.47 +extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
    6.48 +
    6.49 +/* Update the position of IBus' candidate list. If rect is NULL then this will 
    6.50 +   just reposition it relative to the focused window's new position. */
    6.51 +extern void SDL_IBus_UpdateTextRect(SDL_Rect *window_relative_rect);
    6.52 +
    6.53 +/* Checks DBus for new IBus events, and calls SDL_SendKeyboardText / 
    6.54 +   SDL_SendEditingText for each event it finds */
    6.55 +extern void SDL_IBus_PumpEvents();
    6.56 +
    6.57 +#endif /* HAVE_IBUS_IBUS_H */
    6.58 +
    6.59 +#endif /* _SDL_ibus_h */
    6.60 +
    6.61 +/* vi: set ts=4 sw=4 expandtab: */
     7.1 --- a/src/video/x11/SDL_x11events.c	Sat Jun 21 11:52:53 2014 -0700
     7.2 +++ b/src/video/x11/SDL_x11events.c	Wed Jun 18 20:11:39 2014 +0100
     7.3 @@ -493,6 +493,11 @@
     7.4  #ifdef DEBUG_XEVENTS
     7.5              printf("window %p: FocusIn!\n", data);
     7.6  #endif
     7.7 +#ifdef SDL_USE_IBUS
     7.8 +            if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
     7.9 +                SDL_IBus_SetFocus(SDL_TRUE);
    7.10 +            }
    7.11 +#endif
    7.12              if (data->pending_focus == PENDING_FOCUS_OUT &&
    7.13                  data->window == SDL_GetKeyboardFocus()) {
    7.14                  /* We want to reset the keyboard here, because we may have
    7.15 @@ -530,6 +535,11 @@
    7.16  #ifdef DEBUG_XEVENTS
    7.17              printf("window %p: FocusOut!\n", data);
    7.18  #endif
    7.19 +#ifdef SDL_USE_IBUS
    7.20 +            if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
    7.21 +                SDL_IBus_SetFocus(SDL_FALSE);
    7.22 +            }
    7.23 +#endif
    7.24              data->pending_focus = PENDING_FOCUS_OUT;
    7.25              data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_OUT_TIME;
    7.26          }
    7.27 @@ -561,11 +571,14 @@
    7.28              KeySym keysym = NoSymbol;
    7.29              char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
    7.30              Status status = 0;
    7.31 +            Bool handled = False;
    7.32  
    7.33  #ifdef DEBUG_XEVENTS
    7.34              printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
    7.35  #endif
    7.36 +#ifndef SDL_USE_IBUS
    7.37              SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
    7.38 +#endif
    7.39  #if 1
    7.40              if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) {
    7.41                  int min_keycode, max_keycode;
    7.42 @@ -591,9 +604,21 @@
    7.43  #else
    7.44              XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
    7.45  #endif
    7.46 -            if (*text) {
    7.47 -                SDL_SendKeyboardText(text);
    7.48 +#ifdef SDL_USE_IBUS
    7.49 +            if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
    7.50 +                if(!(handled = SDL_IBus_ProcessKeyEvent(keysym, keycode))){
    7.51 +#endif
    7.52 +                    if(*text){
    7.53 +                        SDL_SendKeyboardText(text);
    7.54 +                    }
    7.55 +#ifdef SDL_USE_IBUS
    7.56 +                }
    7.57              }
    7.58 +
    7.59 +            if (!handled) {
    7.60 +                SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
    7.61 +            }
    7.62 +#endif
    7.63          }
    7.64          break;
    7.65  
    7.66 @@ -663,6 +688,12 @@
    7.67                  SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED,
    7.68                                      xevent.xconfigure.x - border_left,
    7.69                                      xevent.xconfigure.y - border_top);
    7.70 +#ifdef SDL_USE_IBUS
    7.71 +                if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
    7.72 +                    /* Update IBus candidate list position */
    7.73 +                    SDL_IBus_UpdateTextRect(NULL);
    7.74 +                }
    7.75 +#endif
    7.76              }
    7.77              if (xevent.xconfigure.width != data->last_xconfigure.width ||
    7.78                  xevent.xconfigure.height != data->last_xconfigure.height) {
    7.79 @@ -1079,14 +1110,20 @@
    7.80              SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
    7.81              X11_XResetScreenSaver(data->display);
    7.82  
    7.83 -            #if SDL_USE_LIBDBUS
    7.84 -            SDL_dbus_screensaver_tickle(_this);
    7.85 -            #endif
    7.86 +#if SDL_USE_LIBDBUS
    7.87 +            SDL_DBus_ScreensaverTickle();
    7.88 +#endif
    7.89  
    7.90              data->screensaver_activity = now;
    7.91          }
    7.92      }
    7.93  
    7.94 +#ifdef SDL_USE_IBUS
    7.95 +    if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
    7.96 +        SDL_IBus_PumpEvents();
    7.97 +    }
    7.98 +#endif
    7.99 +
   7.100      /* Keep processing pending events */
   7.101      while (X11_Pending(data->display)) {
   7.102          X11_DispatchEvent(_this);
   7.103 @@ -1107,12 +1144,12 @@
   7.104  #endif /* SDL_VIDEO_DRIVER_X11_XSCRNSAVER */
   7.105  
   7.106  #if SDL_USE_LIBDBUS
   7.107 -    if (SDL_dbus_screensaver_inhibit(_this)) {
   7.108 +    if (SDL_DBus_ScreensaverInhibit(_this->suspend_screensaver)) {
   7.109          return;
   7.110      }
   7.111  
   7.112      if (_this->suspend_screensaver) {
   7.113 -        SDL_dbus_screensaver_tickle(_this);
   7.114 +        SDL_DBus_ScreensaverTickle();
   7.115      }
   7.116  #endif
   7.117  
     8.1 --- a/src/video/x11/SDL_x11keyboard.c	Sat Jun 21 11:52:53 2014 -0700
     8.2 +++ b/src/video/x11/SDL_x11keyboard.c	Wed Jun 18 20:11:39 2014 +0100
     8.3 @@ -287,6 +287,10 @@
     8.4  
     8.5      SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
     8.6  
     8.7 +#ifdef SDL_USE_IBUS
     8.8 +    SDL_IBus_Init();
     8.9 +#endif
    8.10 +
    8.11      return 0;
    8.12  }
    8.13  
    8.14 @@ -320,6 +324,38 @@
    8.15  void
    8.16  X11_QuitKeyboard(_THIS)
    8.17  {
    8.18 +#ifdef SDL_USE_IBUS
    8.19 +    SDL_IBus_Quit();
    8.20 +#endif
    8.21 +}
    8.22 +
    8.23 +void
    8.24 +X11_StartTextInput(_THIS)
    8.25 +{
    8.26 +#ifdef SDL_USE_IBUS
    8.27 +    SDL_IBus_SetFocus(SDL_GetFocusWindow() != NULL);
    8.28 +#endif
    8.29 +}
    8.30 +
    8.31 +void
    8.32 +X11_StopTextInput(_THIS)
    8.33 +{
    8.34 +#ifdef SDL_USE_IBUS
    8.35 +    SDL_IBus_Reset();
    8.36 +#endif
    8.37 +}
    8.38 +
    8.39 +void
    8.40 +X11_SetTextInputRect(_THIS, SDL_Rect *rect)
    8.41 +{
    8.42 +    if (!rect) {
    8.43 +        SDL_InvalidParamError("rect");
    8.44 +        return;
    8.45 +    }
    8.46 +       
    8.47 +#ifdef SDL_USE_IBUS
    8.48 +    SDL_IBus_UpdateTextRect(rect);
    8.49 +#endif
    8.50  }
    8.51  
    8.52  #endif /* SDL_VIDEO_DRIVER_X11 */
     9.1 --- a/src/video/x11/SDL_x11keyboard.h	Sat Jun 21 11:52:53 2014 -0700
     9.2 +++ b/src/video/x11/SDL_x11keyboard.h	Wed Jun 18 20:11:39 2014 +0100
     9.3 @@ -26,6 +26,9 @@
     9.4  extern int X11_InitKeyboard(_THIS);
     9.5  extern void X11_UpdateKeymap(_THIS);
     9.6  extern void X11_QuitKeyboard(_THIS);
     9.7 +extern void X11_StartTextInput(_THIS);
     9.8 +extern void X11_StopTextInput(_THIS);
     9.9 +extern void X11_SetTextInputRect(_THIS, SDL_Rect *rect);
    9.10  
    9.11  #endif /* _SDL_x11keyboard_h */
    9.12  
    10.1 --- a/src/video/x11/SDL_x11video.c	Sat Jun 21 11:52:53 2014 -0700
    10.2 +++ b/src/video/x11/SDL_x11video.c	Wed Jun 18 20:11:39 2014 +0100
    10.3 @@ -39,220 +39,6 @@
    10.4  #include "SDL_x11opengles.h"
    10.5  #endif
    10.6  
    10.7 -/* !!! FIXME: move dbus stuff to somewhere under src/core/linux ... */
    10.8 -#if SDL_USE_LIBDBUS
    10.9 -/* we never link directly to libdbus. */
   10.10 -#include "SDL_loadso.h"
   10.11 -static const char *dbus_library = "libdbus-1.so.3";
   10.12 -static void *dbus_handle = NULL;
   10.13 -static unsigned int screensaver_cookie = 0;
   10.14 -
   10.15 -/* !!! FIXME: this is kinda ugly. */
   10.16 -static SDL_bool
   10.17 -load_dbus_sym(const char *fn, void **addr)
   10.18 -{
   10.19 -    *addr = SDL_LoadFunction(dbus_handle, fn);
   10.20 -    if (*addr == NULL) {
   10.21 -        /* Don't call SDL_SetError(): SDL_LoadFunction already did. */
   10.22 -        return SDL_FALSE;
   10.23 -    }
   10.24 -
   10.25 -    return SDL_TRUE;
   10.26 -}
   10.27 -
   10.28 -/* libdbus entry points... */
   10.29 -static DBusConnection *(*DBUS_dbus_bus_get_private)(DBusBusType, DBusError *) = NULL;
   10.30 -static void (*DBUS_dbus_connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t) = NULL;
   10.31 -static dbus_bool_t (*DBUS_dbus_connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *) = NULL;
   10.32 -static DBusMessage *(*DBUS_dbus_connection_send_with_reply_and_block)(DBusConnection *, DBusMessage *, int, DBusError *) = NULL;
   10.33 -static void (*DBUS_dbus_connection_close)(DBusConnection *) = NULL;
   10.34 -static void (*DBUS_dbus_connection_unref)(DBusConnection *) = NULL;
   10.35 -static void (*DBUS_dbus_connection_flush)(DBusConnection *) = NULL;
   10.36 -static DBusMessage *(*DBUS_dbus_message_new_method_call)(const char *, const char *, const char *, const char *) = NULL;
   10.37 -static dbus_bool_t (*DBUS_dbus_message_append_args)(DBusMessage *, int, ...) = NULL;
   10.38 -static dbus_bool_t (*DBUS_dbus_message_get_args)(DBusMessage *, DBusError *, int, ...) = NULL;
   10.39 -static void (*DBUS_dbus_message_unref)(DBusMessage *) = NULL;
   10.40 -static void (*DBUS_dbus_error_init)(DBusError *) = NULL;
   10.41 -static dbus_bool_t (*DBUS_dbus_error_is_set)(const DBusError *) = NULL;
   10.42 -static void (*DBUS_dbus_error_free)(DBusError *) = NULL;
   10.43 -
   10.44 -static int
   10.45 -load_dbus_syms(void)
   10.46 -{
   10.47 -    /* cast funcs to char* first, to please GCC's strict aliasing rules. */
   10.48 -    #define SDL_DBUS_SYM(x) \
   10.49 -        if (!load_dbus_sym(#x, (void **) (char *) &DBUS_##x)) return -1
   10.50 -
   10.51 -    SDL_DBUS_SYM(dbus_bus_get_private);
   10.52 -    SDL_DBUS_SYM(dbus_connection_set_exit_on_disconnect);
   10.53 -    SDL_DBUS_SYM(dbus_connection_send);
   10.54 -    SDL_DBUS_SYM(dbus_connection_send_with_reply_and_block);
   10.55 -    SDL_DBUS_SYM(dbus_connection_close);
   10.56 -    SDL_DBUS_SYM(dbus_connection_unref);
   10.57 -    SDL_DBUS_SYM(dbus_connection_flush);
   10.58 -    SDL_DBUS_SYM(dbus_message_append_args);
   10.59 -    SDL_DBUS_SYM(dbus_message_get_args);
   10.60 -    SDL_DBUS_SYM(dbus_message_new_method_call);
   10.61 -    SDL_DBUS_SYM(dbus_message_unref);
   10.62 -    SDL_DBUS_SYM(dbus_error_init);
   10.63 -    SDL_DBUS_SYM(dbus_error_is_set);
   10.64 -    SDL_DBUS_SYM(dbus_error_free);
   10.65 -
   10.66 -    #undef SDL_DBUS_SYM
   10.67 -
   10.68 -    return 0;
   10.69 -}
   10.70 -
   10.71 -static void
   10.72 -UnloadDBUSLibrary(void)
   10.73 -{
   10.74 -    if (dbus_handle != NULL) {
   10.75 -        SDL_UnloadObject(dbus_handle);
   10.76 -        dbus_handle = NULL;
   10.77 -    }
   10.78 -}
   10.79 -
   10.80 -static int
   10.81 -LoadDBUSLibrary(void)
   10.82 -{
   10.83 -    int retval = 0;
   10.84 -    if (dbus_handle == NULL) {
   10.85 -        dbus_handle = SDL_LoadObject(dbus_library);
   10.86 -        if (dbus_handle == NULL) {
   10.87 -            retval = -1;
   10.88 -            /* Don't call SDL_SetError(): SDL_LoadObject already did. */
   10.89 -        } else {
   10.90 -            retval = load_dbus_syms();
   10.91 -            if (retval < 0) {
   10.92 -                UnloadDBUSLibrary();
   10.93 -            }
   10.94 -        }
   10.95 -    }
   10.96 -
   10.97 -    return retval;
   10.98 -}
   10.99 -
  10.100 -static void
  10.101 -X11_InitDBus(_THIS)
  10.102 -{
  10.103 -    if (LoadDBUSLibrary() != -1) {
  10.104 -        SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
  10.105 -        DBusError err;
  10.106 -        DBUS_dbus_error_init(&err);
  10.107 -        data->dbus = DBUS_dbus_bus_get_private(DBUS_BUS_SESSION, &err);
  10.108 -        if (DBUS_dbus_error_is_set(&err)) {
  10.109 -            DBUS_dbus_error_free(&err);
  10.110 -            if (data->dbus) {
  10.111 -                DBUS_dbus_connection_unref(data->dbus);
  10.112 -                data->dbus = NULL;
  10.113 -            }
  10.114 -            return;  /* oh well */
  10.115 -        }
  10.116 -        DBUS_dbus_connection_set_exit_on_disconnect(data->dbus, 0);
  10.117 -    }
  10.118 -}
  10.119 -
  10.120 -static void
  10.121 -X11_QuitDBus(_THIS)
  10.122 -{
  10.123 -    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
  10.124 -    if (data->dbus) {
  10.125 -        DBUS_dbus_connection_close(data->dbus);
  10.126 -        DBUS_dbus_connection_unref(data->dbus);
  10.127 -        data->dbus = NULL;
  10.128 -    }
  10.129 -}
  10.130 -
  10.131 -void
  10.132 -SDL_dbus_screensaver_tickle(_THIS)
  10.133 -{
  10.134 -    const SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
  10.135 -    DBusConnection *conn = data->dbus;
  10.136 -    if (conn != NULL) {
  10.137 -        DBusMessage *msg = DBUS_dbus_message_new_method_call("org.gnome.ScreenSaver",
  10.138 -                                                             "/org/gnome/ScreenSaver",
  10.139 -                                                             "org.gnome.ScreenSaver",
  10.140 -                                                             "SimulateUserActivity");
  10.141 -        if (msg != NULL) {
  10.142 -            if (DBUS_dbus_connection_send(conn, msg, NULL)) {
  10.143 -                DBUS_dbus_connection_flush(conn);
  10.144 -            }
  10.145 -            DBUS_dbus_message_unref(msg);
  10.146 -        }
  10.147 -    }
  10.148 -}
  10.149 -
  10.150 -SDL_bool
  10.151 -SDL_dbus_screensaver_inhibit(_THIS)
  10.152 -{
  10.153 -    const SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
  10.154 -    DBusConnection *conn = data->dbus;
  10.155 -
  10.156 -    if (conn == NULL)
  10.157 -        return SDL_FALSE;
  10.158 -
  10.159 -    if (_this->suspend_screensaver &&
  10.160 -        screensaver_cookie != 0)
  10.161 -        return SDL_TRUE;
  10.162 -    if (!_this->suspend_screensaver &&
  10.163 -        screensaver_cookie == 0)
  10.164 -        return SDL_TRUE;
  10.165 -
  10.166 -    if (_this->suspend_screensaver) {
  10.167 -        const char *app = "My SDL application";
  10.168 -        const char *reason = "Playing a game";
  10.169 -
  10.170 -        DBusMessage *msg = DBUS_dbus_message_new_method_call("org.freedesktop.ScreenSaver",
  10.171 -                                                             "/org/freedesktop/ScreenSaver",
  10.172 -                                                             "org.freedesktop.ScreenSaver",
  10.173 -                                                             "Inhibit");
  10.174 -        if (msg != NULL) {
  10.175 -            DBUS_dbus_message_append_args (msg,
  10.176 -                                           DBUS_TYPE_STRING, &app,
  10.177 -                                           DBUS_TYPE_STRING, &reason,
  10.178 -                                           DBUS_TYPE_INVALID);
  10.179 -        }
  10.180 -
  10.181 -        if (msg != NULL) {
  10.182 -            DBusMessage *reply;
  10.183 -
  10.184 -            reply = DBUS_dbus_connection_send_with_reply_and_block(conn, msg, 300, NULL);
  10.185 -            if (reply) {
  10.186 -                if (!DBUS_dbus_message_get_args(reply, NULL,
  10.187 -                                                DBUS_TYPE_UINT32, &screensaver_cookie,
  10.188 -                                                DBUS_TYPE_INVALID))
  10.189 -                    screensaver_cookie = 0;
  10.190 -                DBUS_dbus_message_unref(reply);
  10.191 -            }
  10.192 -
  10.193 -            DBUS_dbus_message_unref(msg);
  10.194 -        }
  10.195 -
  10.196 -        if (screensaver_cookie == 0) {
  10.197 -            return SDL_FALSE;
  10.198 -        }
  10.199 -        return SDL_TRUE;
  10.200 -    } else {
  10.201 -        DBusMessage *msg = DBUS_dbus_message_new_method_call("org.freedesktop.ScreenSaver",
  10.202 -                                                             "/org/freedesktop/ScreenSaver",
  10.203 -                                                             "org.freedesktop.ScreenSaver",
  10.204 -                                                             "UnInhibit");
  10.205 -        DBUS_dbus_message_append_args (msg,
  10.206 -                                       DBUS_TYPE_UINT32, &screensaver_cookie,
  10.207 -                                       DBUS_TYPE_INVALID);
  10.208 -        if (msg != NULL) {
  10.209 -            if (DBUS_dbus_connection_send(conn, msg, NULL)) {
  10.210 -                DBUS_dbus_connection_flush(conn);
  10.211 -            }
  10.212 -            DBUS_dbus_message_unref(msg);
  10.213 -        }
  10.214 -
  10.215 -        screensaver_cookie = 0;
  10.216 -        return SDL_TRUE;
  10.217 -    }
  10.218 -}
  10.219 -#endif
  10.220 -
  10.221  /* Initialization/Query functions */
  10.222  static int X11_VideoInit(_THIS);
  10.223  static void X11_VideoQuit(_THIS);
  10.224 @@ -487,7 +273,10 @@
  10.225      device->SetClipboardText = X11_SetClipboardText;
  10.226      device->GetClipboardText = X11_GetClipboardText;
  10.227      device->HasClipboardText = X11_HasClipboardText;
  10.228 -
  10.229 +    device->StartTextInput = X11_StartTextInput;
  10.230 +    device->StopTextInput = X11_StopTextInput;
  10.231 +    device->SetTextInputRect = X11_SetTextInputRect;
  10.232 +    
  10.233      device->free = X11_DeleteDevice;
  10.234  
  10.235      return device;
  10.236 @@ -635,7 +424,7 @@
  10.237      X11_InitTouch(_this);
  10.238  
  10.239  #if SDL_USE_LIBDBUS
  10.240 -    X11_InitDBus(_this);
  10.241 +    SDL_DBus_Init();
  10.242  #endif
  10.243  
  10.244      return 0;
  10.245 @@ -659,7 +448,7 @@
  10.246      X11_QuitTouch(_this);
  10.247  
  10.248  #if SDL_USE_LIBDBUS
  10.249 -    X11_QuitDBus(_this);
  10.250 +    SDL_DBus_Quit();
  10.251  #endif
  10.252  }
  10.253  
    11.1 --- a/src/video/x11/SDL_x11video.h	Sat Jun 21 11:52:53 2014 -0700
    11.2 +++ b/src/video/x11/SDL_x11video.h	Wed Jun 18 20:11:39 2014 +0100
    11.3 @@ -54,8 +54,11 @@
    11.4  #endif
    11.5  
    11.6  #ifdef HAVE_DBUS_DBUS_H
    11.7 -#define SDL_USE_LIBDBUS 1
    11.8 -#include <dbus/dbus.h>
    11.9 +#include "../../core/linux/SDL_dbus.h"
   11.10 +#endif
   11.11 +
   11.12 +#ifdef HAVE_IBUS_IBUS_H
   11.13 +#include "../../core/linux/SDL_ibus.h"
   11.14  #endif
   11.15  
   11.16  #include "SDL_x11dyn.h"
   11.17 @@ -114,16 +117,10 @@
   11.18      SDL_Scancode key_layout[256];
   11.19      SDL_bool selection_waiting;
   11.20  
   11.21 -#if SDL_USE_LIBDBUS
   11.22 -    DBusConnection *dbus;
   11.23 -#endif
   11.24  } SDL_VideoData;
   11.25  
   11.26  extern SDL_bool X11_UseDirectColorVisuals(void);
   11.27  
   11.28 -SDL_bool SDL_dbus_screensaver_inhibit(_THIS);
   11.29 -void SDL_dbus_screensaver_tickle(_THIS);
   11.30 -
   11.31  #endif /* _SDL_x11video_h */
   11.32  
   11.33  /* vi: set ts=4 sw=4 expandtab: */