Skip to content

Commit

Permalink
Add IBus IME Support, move DBus code to its own file. (v3.3 squashed)
Browse files Browse the repository at this point in the history
  • Loading branch information
baines committed Jun 18, 2014
1 parent 0d67384 commit 41a3983
Show file tree
Hide file tree
Showing 11 changed files with 1,104 additions and 232 deletions.
43 changes: 43 additions & 0 deletions configure.in
Expand Up @@ -2130,6 +2130,43 @@ AC_HELP_STRING([--enable-dbus], [enable D-Bus support [[default=yes]]]),
if test x$have_dbus_dbus_h_hdr = xyes; then
AC_DEFINE(HAVE_DBUS_DBUS_H, 1, [ ])
EXTRA_CFLAGS="$EXTRA_CFLAGS $DBUS_CFLAGS"
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_dbus.c"
fi
fi
fi
}

dnl See if the platform has libibus IME support.
CheckIBus()
{
AC_ARG_ENABLE(ibus,
AC_HELP_STRING([--enable-ibus], [enable IBus support [[default=yes]]]),
, enable_ibus=yes)
if test x$enable_ibus = xyes; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
if test x$PKG_CONFIG != xno; then
IBUS_CFLAGS=`$PKG_CONFIG --cflags ibus-1.0`
save_CFLAGS="$CFLAGS"
CFLAGS="$save_CFLAGS $IBUS_CFLAGS"
AC_CHECK_HEADER(ibus-1.0/ibus.h,
have_ibus_ibus_h_hdr=yes,
have_ibus_ibus_h_hdr=no)
AC_CHECK_HEADER(sys/inotify.h,
have_inotify_inotify_h_hdr=yes,
have_inotify_inotify_h_hdr=no)
CFLAGS="$save_CFLAGS"
if test x$have_ibus_ibus_h_hdr = xyes; then
if test x$enable_dbus != xyes; then
AC_MSG_WARN([DBus support is required for IBus.])
have_ibus_ibus_h_hdr=no
elif test x$have_inotify_inotify_h_hdr != xyes; then
AC_MSG_WARN([INotify support is required for IBus.])
have_ibus_ibus_h_hdr=no
else
AC_DEFINE(HAVE_IBUS_IBUS_H, 1, [ ])
EXTRA_CFLAGS="$EXTRA_CFLAGS $IBUS_CFLAGS"
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ibus.c"
fi
fi
fi
fi
Expand Down Expand Up @@ -2732,6 +2769,7 @@ case "$host" in
CheckWayland
CheckLibUDev
CheckDBus
CheckIBus
CheckInputEvents
CheckInputKD
CheckTslib
Expand Down Expand Up @@ -3347,6 +3385,11 @@ if test x$have_dbus_dbus_h_hdr = xyes; then
else
SUMMARY="${SUMMARY}Using dbus : NO\n"
fi
if test x$have_ibus_ibus_h_hdr = xyes; then
SUMMARY="${SUMMARY}Using ibus : YES\n"
else
SUMMARY="${SUMMARY}Using ibus : NO\n"
fi
AC_CONFIG_COMMANDS([summary], [echo -en "$SUMMARY"], [SUMMARY="$SUMMARY"])

AC_OUTPUT
1 change: 1 addition & 0 deletions include/SDL_config.h.in
Expand Up @@ -78,6 +78,7 @@
#undef HAVE_PTHREAD_NP_H
#undef HAVE_LIBUDEV_H
#undef HAVE_DBUS_DBUS_H
#undef HAVE_IBUS_IBUS_H

/* C library functions */
#undef HAVE_MALLOC
Expand Down
236 changes: 236 additions & 0 deletions src/core/linux/SDL_dbus.c
@@ -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
79 changes: 79 additions & 0 deletions src/core/linux/SDL_dbus.h
@@ -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: */

0 comments on commit 41a3983

Please sign in to comment.