Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Add IBus IME Support, move DBus code to its own file. (v3.3 squashed)
- Loading branch information
Showing
with
1,104 additions
and 232 deletions.
- +43 −0 configure.in
- +1 −0 include/SDL_config.h.in
- +236 −0 src/core/linux/SDL_dbus.c
- +79 −0 src/core/linux/SDL_dbus.h
- +593 −0 src/core/linux/SDL_ibus.c
- +58 −0 src/core/linux/SDL_ibus.h
- +44 −7 src/video/x11/SDL_x11events.c
- +36 −0 src/video/x11/SDL_x11keyboard.c
- +3 −0 src/video/x11/SDL_x11keyboard.h
- +6 −217 src/video/x11/SDL_x11video.c
- +5 −8 src/video/x11/SDL_x11video.h
@@ -0,0 +1,236 @@ | ||
/* | ||
Simple DirectMedia Layer | ||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org> | ||
This software is provided 'as-is', without any express or implied | ||
warranty. In no event will the authors be held liable for any damages | ||
arising from the use of this software. | ||
Permission is granted to anyone to use this software for any purpose, | ||
including commercial applications, and to alter it and redistribute it | ||
freely, subject to the following restrictions: | ||
1. The origin of this software must not be misrepresented; you must not | ||
claim that you wrote the original software. If you use this software | ||
in a product, an acknowledgment in the product documentation would be | ||
appreciated but is not required. | ||
2. Altered source versions must be plainly marked as such, and must not be | ||
misrepresented as being the original software. | ||
3. This notice may not be removed or altered from any source distribution. | ||
*/ | ||
#include "../../SDL_internal.h" | ||
#include "SDL_dbus.h" | ||
|
||
#if SDL_USE_LIBDBUS | ||
/* we never link directly to libdbus. */ | ||
#include "SDL_loadso.h" | ||
static const char *dbus_library = "libdbus-1.so.3"; | ||
static void *dbus_handle = NULL; | ||
static unsigned int screensaver_cookie = 0; | ||
static SDL_DBusContext dbus = {0}; | ||
|
||
static int | ||
load_dbus_syms(void) | ||
{ | ||
#define SDL_DBUS_SYM2(x, y) \ | ||
if (!(dbus.x = SDL_LoadFunction(dbus_handle, #y))) return -1 | ||
|
||
#define SDL_DBUS_SYM(x) \ | ||
SDL_DBUS_SYM2(x, dbus_##x) | ||
|
||
SDL_DBUS_SYM(bus_get_private); | ||
SDL_DBUS_SYM(bus_register); | ||
SDL_DBUS_SYM(bus_add_match); | ||
SDL_DBUS_SYM(connection_open_private); | ||
SDL_DBUS_SYM(connection_set_exit_on_disconnect); | ||
SDL_DBUS_SYM(connection_get_is_connected); | ||
SDL_DBUS_SYM(connection_add_filter); | ||
SDL_DBUS_SYM(connection_send); | ||
SDL_DBUS_SYM(connection_send_with_reply_and_block); | ||
SDL_DBUS_SYM(connection_close); | ||
SDL_DBUS_SYM(connection_unref); | ||
SDL_DBUS_SYM(connection_flush); | ||
SDL_DBUS_SYM(connection_read_write); | ||
SDL_DBUS_SYM(connection_dispatch); | ||
SDL_DBUS_SYM(message_is_signal); | ||
SDL_DBUS_SYM(message_new_method_call); | ||
SDL_DBUS_SYM(message_append_args); | ||
SDL_DBUS_SYM(message_get_args); | ||
SDL_DBUS_SYM(message_iter_init); | ||
SDL_DBUS_SYM(message_iter_next); | ||
SDL_DBUS_SYM(message_iter_get_basic); | ||
SDL_DBUS_SYM(message_iter_get_arg_type); | ||
SDL_DBUS_SYM(message_iter_recurse); | ||
SDL_DBUS_SYM(message_unref); | ||
SDL_DBUS_SYM(error_init); | ||
SDL_DBUS_SYM(error_is_set); | ||
SDL_DBUS_SYM(error_free); | ||
SDL_DBUS_SYM(get_local_machine_id); | ||
SDL_DBUS_SYM(free); | ||
|
||
#undef SDL_DBUS_SYM | ||
#undef SDL_DBUS_SYM2 | ||
|
||
return 0; | ||
} | ||
|
||
static void | ||
UnloadDBUSLibrary(void) | ||
{ | ||
if (dbus_handle != NULL) { | ||
SDL_UnloadObject(dbus_handle); | ||
dbus_handle = NULL; | ||
} | ||
} | ||
|
||
static int | ||
LoadDBUSLibrary(void) | ||
{ | ||
int retval = 0; | ||
if (dbus_handle == NULL) { | ||
dbus_handle = SDL_LoadObject(dbus_library); | ||
if (dbus_handle == NULL) { | ||
retval = -1; | ||
/* Don't call SDL_SetError(): SDL_LoadObject already did. */ | ||
} else { | ||
retval = load_dbus_syms(); | ||
if (retval < 0) { | ||
UnloadDBUSLibrary(); | ||
} | ||
} | ||
} | ||
|
||
return retval; | ||
} | ||
|
||
void | ||
SDL_DBus_Init(void) | ||
{ | ||
if (LoadDBUSLibrary() != -1) { | ||
DBusError err; | ||
dbus.error_init(&err); | ||
dbus.session_conn = dbus.bus_get_private(DBUS_BUS_SESSION, &err); | ||
if (dbus.error_is_set(&err)) { | ||
dbus.error_free(&err); | ||
if (dbus.session_conn) { | ||
dbus.connection_unref(dbus.session_conn); | ||
dbus.session_conn = NULL; | ||
} | ||
return; /* oh well */ | ||
} | ||
dbus.connection_set_exit_on_disconnect(dbus.session_conn, 0); | ||
} | ||
} | ||
|
||
void | ||
SDL_DBus_Quit(void) | ||
{ | ||
if (dbus.session_conn) { | ||
dbus.connection_close(dbus.session_conn); | ||
dbus.connection_unref(dbus.session_conn); | ||
SDL_memset(&dbus, 0, sizeof(dbus)); | ||
} | ||
UnloadDBUSLibrary(); | ||
} | ||
|
||
SDL_DBusContext * | ||
SDL_DBus_GetContext(void) | ||
{ | ||
if(!dbus_handle || !dbus.session_conn){ | ||
SDL_DBus_Init(); | ||
} | ||
|
||
if(dbus_handle && dbus.session_conn){ | ||
return &dbus; | ||
} else { | ||
return NULL; | ||
} | ||
} | ||
|
||
void | ||
SDL_DBus_ScreensaverTickle(void) | ||
{ | ||
DBusConnection *conn = dbus.session_conn; | ||
if (conn != NULL) { | ||
DBusMessage *msg = dbus.message_new_method_call("org.gnome.ScreenSaver", | ||
"/org/gnome/ScreenSaver", | ||
"org.gnome.ScreenSaver", | ||
"SimulateUserActivity"); | ||
if (msg != NULL) { | ||
if (dbus.connection_send(conn, msg, NULL)) { | ||
dbus.connection_flush(conn); | ||
} | ||
dbus.message_unref(msg); | ||
} | ||
} | ||
} | ||
|
||
SDL_bool | ||
SDL_DBus_ScreensaverInhibit(SDL_bool inhibit) | ||
{ | ||
DBusConnection *conn = dbus.session_conn; | ||
|
||
if (conn == NULL) | ||
return SDL_FALSE; | ||
|
||
if (inhibit && | ||
screensaver_cookie != 0) | ||
return SDL_TRUE; | ||
if (!inhibit && | ||
screensaver_cookie == 0) | ||
return SDL_TRUE; | ||
|
||
if (inhibit) { | ||
const char *app = "My SDL application"; | ||
const char *reason = "Playing a game"; | ||
|
||
DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver", | ||
"/org/freedesktop/ScreenSaver", | ||
"org.freedesktop.ScreenSaver", | ||
"Inhibit"); | ||
if (msg != NULL) { | ||
dbus.message_append_args (msg, | ||
DBUS_TYPE_STRING, &app, | ||
DBUS_TYPE_STRING, &reason, | ||
DBUS_TYPE_INVALID); | ||
} | ||
|
||
if (msg != NULL) { | ||
DBusMessage *reply; | ||
|
||
reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL); | ||
if (reply) { | ||
if (!dbus.message_get_args(reply, NULL, | ||
DBUS_TYPE_UINT32, &screensaver_cookie, | ||
DBUS_TYPE_INVALID)) | ||
screensaver_cookie = 0; | ||
dbus.message_unref(reply); | ||
} | ||
|
||
dbus.message_unref(msg); | ||
} | ||
|
||
if (screensaver_cookie == 0) { | ||
return SDL_FALSE; | ||
} | ||
return SDL_TRUE; | ||
} else { | ||
DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver", | ||
"/org/freedesktop/ScreenSaver", | ||
"org.freedesktop.ScreenSaver", | ||
"UnInhibit"); | ||
dbus.message_append_args (msg, | ||
DBUS_TYPE_UINT32, &screensaver_cookie, | ||
DBUS_TYPE_INVALID); | ||
if (msg != NULL) { | ||
if (dbus.connection_send(conn, msg, NULL)) { | ||
dbus.connection_flush(conn); | ||
} | ||
dbus.message_unref(msg); | ||
} | ||
|
||
screensaver_cookie = 0; | ||
return SDL_TRUE; | ||
} | ||
} | ||
#endif |
@@ -0,0 +1,79 @@ | ||
/* | ||
Simple DirectMedia Layer | ||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org> | ||
This software is provided 'as-is', without any express or implied | ||
warranty. In no event will the authors be held liable for any damages | ||
arising from the use of this software. | ||
Permission is granted to anyone to use this software for any purpose, | ||
including commercial applications, and to alter it and redistribute it | ||
freely, subject to the following restrictions: | ||
1. The origin of this software must not be misrepresented; you must not | ||
claim that you wrote the original software. If you use this software | ||
in a product, an acknowledgment in the product documentation would be | ||
appreciated but is not required. | ||
2. Altered source versions must be plainly marked as such, and must not be | ||
misrepresented as being the original software. | ||
3. This notice may not be removed or altered from any source distribution. | ||
*/ | ||
|
||
#include "../../SDL_internal.h" | ||
|
||
#ifndef _SDL_dbus_h | ||
#define _SDL_dbus_h | ||
|
||
#ifdef HAVE_DBUS_DBUS_H | ||
#define SDL_USE_LIBDBUS 1 | ||
#include "SDL_stdinc.h" | ||
#include <dbus/dbus.h> | ||
|
||
|
||
typedef struct SDL_DBusContext { | ||
DBusConnection *session_conn; | ||
|
||
DBusConnection *(*bus_get_private)(DBusBusType, DBusError *); | ||
dbus_bool_t (*bus_register)(DBusConnection *, DBusError *); | ||
void (*bus_add_match)(DBusConnection *, const char *, DBusError *); | ||
DBusConnection * (*connection_open_private)(const char *, DBusError *); | ||
void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t); | ||
dbus_bool_t (*connection_get_is_connected)(DBusConnection *); | ||
dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, | ||
void *, DBusFreeFunction); | ||
dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *); | ||
DBusMessage *(*connection_send_with_reply_and_block)(DBusConnection *, DBusMessage *, int, DBusError *); | ||
void (*connection_close)(DBusConnection *); | ||
void (*connection_unref)(DBusConnection *); | ||
void (*connection_flush)(DBusConnection *); | ||
dbus_bool_t (*connection_read_write)(DBusConnection *, int); | ||
DBusDispatchStatus (*connection_dispatch)(DBusConnection *); | ||
dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); | ||
DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *); | ||
dbus_bool_t (*message_append_args)(DBusMessage *, int, ...); | ||
dbus_bool_t (*message_get_args)(DBusMessage *, DBusError *, int, ...); | ||
dbus_bool_t (*message_iter_init)(DBusMessage *, DBusMessageIter *); | ||
dbus_bool_t (*message_iter_next)(DBusMessageIter *); | ||
void (*message_iter_get_basic)(DBusMessageIter *, void *); | ||
int (*message_iter_get_arg_type)(DBusMessageIter *); | ||
void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *); | ||
void (*message_unref)(DBusMessage *); | ||
void (*error_init)(DBusError *); | ||
dbus_bool_t (*error_is_set)(const DBusError *); | ||
void (*error_free)(DBusError *); | ||
char *(*get_local_machine_id)(void); | ||
void (*free)(void *); | ||
|
||
} SDL_DBusContext; | ||
|
||
extern void SDL_DBus_Init(void); | ||
extern void SDL_DBus_Quit(void); | ||
extern SDL_DBusContext * SDL_DBus_GetContext(void); | ||
extern void SDL_DBus_ScreensaverTickle(void); | ||
extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit); | ||
|
||
#endif /* HAVE_DBUS_DBUS_H */ | ||
|
||
#endif /* _SDL_dbus_h */ | ||
|
||
/* vi: set ts=4 sw=4 expandtab: */ |
Oops, something went wrong.