linux: Simplify D-Bus interface, remove lots of boilerplate.

This commit is contained in:
Ryan C. Gordon 2017-05-28 07:11:52 -04:00
parent 191f578b57
commit b3f94acbf9
5 changed files with 215 additions and 323 deletions

View File

@ -56,7 +56,9 @@ LoadDBUSSyms(void)
SDL_DBUS_SYM(message_is_signal); SDL_DBUS_SYM(message_is_signal);
SDL_DBUS_SYM(message_new_method_call); SDL_DBUS_SYM(message_new_method_call);
SDL_DBUS_SYM(message_append_args); SDL_DBUS_SYM(message_append_args);
SDL_DBUS_SYM(message_append_args_valist);
SDL_DBUS_SYM(message_get_args); SDL_DBUS_SYM(message_get_args);
SDL_DBUS_SYM(message_get_args_valist);
SDL_DBUS_SYM(message_iter_init); SDL_DBUS_SYM(message_iter_init);
SDL_DBUS_SYM(message_iter_next); SDL_DBUS_SYM(message_iter_next);
SDL_DBUS_SYM(message_iter_get_basic); SDL_DBUS_SYM(message_iter_get_basic);
@ -157,91 +159,170 @@ SDL_DBus_GetContext(void)
} }
} }
void static SDL_bool
SDL_DBus_ScreensaverTickle(void) SDL_DBus_CallMethodInternal(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, va_list ap)
{ {
DBusConnection *conn = dbus.session_conn; SDL_bool retval = SDL_FALSE;
if (conn != NULL) {
DBusMessage *msg = dbus.message_new_method_call("org.gnome.ScreenSaver", if (conn) {
"/org/gnome/ScreenSaver", DBusMessage *msg = dbus.message_new_method_call(node, path, interface, method);
"org.gnome.ScreenSaver", if (msg) {
"SimulateUserActivity"); int firstarg = va_arg(ap, int);
if (msg != NULL) { if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_append_args_valist(msg, firstarg, ap)) {
if (dbus.connection_send(conn, msg, NULL)) { DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
dbus.connection_flush(conn); if (reply) {
firstarg = va_arg(ap, int);
if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_get_args_valist(reply, NULL, firstarg, ap)) {
retval = SDL_TRUE;
}
dbus.message_unref(reply);
}
} }
dbus.message_unref(msg); dbus.message_unref(msg);
} }
} }
return retval;
}
SDL_bool
SDL_DBus_CallMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...)
{
SDL_bool retval;
va_list ap;
va_start(ap, method);
retval = SDL_DBus_CallMethodInternal(conn, node, path, interface, method, ap);
va_end(ap);
return retval;
}
SDL_bool
SDL_DBus_CallMethod(const char *node, const char *path, const char *interface, const char *method, ...)
{
SDL_bool retval;
va_list ap;
va_start(ap, method);
retval = SDL_DBus_CallMethodInternal(dbus.session_conn, node, path, interface, method, ap);
va_end(ap);
return retval;
}
static SDL_bool
SDL_DBus_CallVoidMethodInternal(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, va_list ap)
{
SDL_bool retval = SDL_FALSE;
if (conn) {
DBusMessage *msg = dbus.message_new_method_call(node, path, interface, method);
if (msg) {
int firstarg = va_arg(ap, int);
if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_append_args_valist(msg, firstarg, ap)) {
if (dbus.connection_send(conn, msg, NULL)) {
dbus.connection_flush(conn);
retval = SDL_TRUE;
}
}
dbus.message_unref(msg);
}
}
return retval;
}
SDL_bool
SDL_DBus_CallVoidMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...)
{
SDL_bool retval;
va_list ap;
va_start(ap, method);
retval = SDL_DBus_CallVoidMethodInternal(conn, node, path, interface, method, ap);
va_end(ap);
return retval;
}
SDL_bool
SDL_DBus_CallVoidMethod(const char *node, const char *path, const char *interface, const char *method, ...)
{
SDL_bool retval;
va_list ap;
va_start(ap, method);
retval = SDL_DBus_CallVoidMethodInternal(dbus.session_conn, node, path, interface, method, ap);
va_end(ap);
return retval;
}
SDL_bool
SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *property, const int expectedtype, void *result)
{
SDL_bool retval = SDL_FALSE;
if (conn) {
DBusMessage *msg = dbus.message_new_method_call(node, path, "org.freedesktop.DBus.Properties", "Get");
if (msg) {
if (dbus.message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) {
DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
if (reply) {
DBusMessageIter iter, sub;
dbus.message_iter_init(reply, &iter);
if (dbus.message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) {
dbus.message_iter_recurse(&iter, &sub);
if (dbus.message_iter_get_arg_type(&sub) == expectedtype) {
dbus.message_iter_get_basic(&sub, result);
retval = SDL_TRUE;
}
}
dbus.message_unref(reply);
}
}
dbus.message_unref(msg);
}
}
return retval;
}
SDL_bool
SDL_DBus_QueryProperty(const char *node, const char *path, const char *interface, const char *property, const int expectedtype, void *result)
{
return SDL_DBus_QueryPropertyOnConnection(dbus.session_conn, node, path, interface, property, expectedtype, result);
}
void
SDL_DBus_ScreensaverTickle(void)
{
SDL_DBus_CallVoidMethod("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver", "SimulateUserActivity", DBUS_TYPE_INVALID);
} }
SDL_bool SDL_bool
SDL_DBus_ScreensaverInhibit(SDL_bool inhibit) SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
{ {
DBusConnection *conn = dbus.session_conn; if ( (inhibit && (screensaver_cookie != 0)) || (!inhibit && (screensaver_cookie == 0)) ) {
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; return SDL_TRUE;
} else { } else {
DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver", const char *node = "org.freedesktop.ScreenSaver";
"/org/freedesktop/ScreenSaver", const char *path = "/org/freedesktop/ScreenSaver";
"org.freedesktop.ScreenSaver", const char *interface = "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; if (inhibit) {
return SDL_TRUE; const char *app = "My SDL application";
const char *reason = "Playing a game";
if (!SDL_DBus_CallMethod(node, path, interface, "Inhibit",
DBUS_TYPE_STRING, &app, DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID,
DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) {
return SDL_FALSE;
}
return (screensaver_cookie != 0) ? SDL_TRUE : SDL_FALSE;
} else {
if (!SDL_DBus_CallVoidMethod(node, path, interface, "UnInhibit", DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) {
return SDL_FALSE;
}
screensaver_cookie = 0;
}
} }
return SDL_TRUE;
} }
#endif #endif

View File

@ -54,7 +54,9 @@ typedef struct SDL_DBusContext {
dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *);
DBusMessage *(*message_new_method_call)(const char *, const char *, 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_append_args)(DBusMessage *, int, ...);
dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list);
dbus_bool_t (*message_get_args)(DBusMessage *, DBusError *, int, ...); dbus_bool_t (*message_get_args)(DBusMessage *, DBusError *, int, ...);
dbus_bool_t (*message_get_args_valist)(DBusMessage *, DBusError *, int, va_list);
dbus_bool_t (*message_iter_init)(DBusMessage *, DBusMessageIter *); dbus_bool_t (*message_iter_init)(DBusMessage *, DBusMessageIter *);
dbus_bool_t (*message_iter_next)(DBusMessageIter *); dbus_bool_t (*message_iter_next)(DBusMessageIter *);
void (*message_iter_get_basic)(DBusMessageIter *, void *); void (*message_iter_get_basic)(DBusMessageIter *, void *);
@ -73,6 +75,17 @@ typedef struct SDL_DBusContext {
extern void SDL_DBus_Init(void); extern void SDL_DBus_Init(void);
extern void SDL_DBus_Quit(void); extern void SDL_DBus_Quit(void);
extern SDL_DBusContext * SDL_DBus_GetContext(void); extern SDL_DBusContext * SDL_DBus_GetContext(void);
/* These use the built-in Session connection. */
extern SDL_bool SDL_DBus_CallMethod(const char *node, const char *path, const char *interface, const char *method, ...);
extern SDL_bool SDL_DBus_CallVoidMethod(const char *node, const char *path, const char *interface, const char *method, ...);
extern SDL_bool SDL_DBus_QueryProperty(const char *node, const char *path, const char *interface, const char *property, const int expectedtype, void *result);
/* These use whatever connection you like. */
extern SDL_bool SDL_DBus_CallMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
extern SDL_bool SDL_DBus_CallVoidMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
extern SDL_bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *property, const int expectedtype, void *result);
extern void SDL_DBus_ScreensaverTickle(void); extern void SDL_DBus_ScreensaverTickle(void);
extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit); extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit);

View File

@ -231,33 +231,10 @@ DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
} }
static DBusMessage*
FcitxClientICNewMethod(FcitxClient *client,
const char *method)
{
SDL_DBusContext *dbus = client->dbus;
return dbus->message_new_method_call(
client->servicename,
client->icname,
FCITX_IC_DBUS_INTERFACE,
method);
}
static void static void
FcitxClientICCallMethod(FcitxClient *client, FcitxClientICCallMethod(FcitxClient *client, const char *method)
const char *method)
{ {
SDL_DBusContext *dbus = client->dbus; SDL_DBus_CallVoidMethod(client->servicename, client->icname, FCITX_IC_DBUS_INTERFACE, method, DBUS_TYPE_INVALID);
DBusMessage *msg = FcitxClientICNewMethod(client, method);
if (msg == NULL)
return ;
if (dbus->connection_send(dbus->session_conn, msg, NULL)) {
dbus->connection_flush(dbus->session_conn);
}
dbus->message_unref(msg);
} }
static void static void
@ -267,80 +244,35 @@ Fcitx_SetCapabilities(void *data,
const char *internal_editing) const char *internal_editing)
{ {
FcitxClient *client = (FcitxClient *)data; FcitxClient *client = (FcitxClient *)data;
SDL_DBusContext *dbus = client->dbus;
Uint32 caps = CAPACITY_NONE; Uint32 caps = CAPACITY_NONE;
DBusMessage *msg = FcitxClientICNewMethod(client, "SetCapacity");
if (msg == NULL)
return ;
if (!(internal_editing && *internal_editing == '1')) { if (!(internal_editing && *internal_editing == '1')) {
caps |= CAPACITY_PREEDIT; caps |= CAPACITY_PREEDIT;
} }
dbus->message_append_args(msg, SDL_DBus_CallVoidMethod(client->servicename, client->icname, FCITX_IC_DBUS_INTERFACE, "SetCapacity", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID);
DBUS_TYPE_UINT32, &caps,
DBUS_TYPE_INVALID);
if (dbus->connection_send(dbus->session_conn, msg, NULL)) {
dbus->connection_flush(dbus->session_conn);
}
dbus->message_unref(msg);
} }
static void static void
FcitxClientCreateIC(FcitxClient *client) FcitxClientCreateIC(FcitxClient *client)
{ {
char *appname = NULL; char *appname = GetAppName();
pid_t pid = 0; pid_t pid = getpid();
int id = 0; int id = -1;
SDL_bool enable; Uint32 enable, arg1, arg2, arg3, arg4;
Uint32 arg1, arg2, arg3, arg4;
SDL_DBusContext *dbus = client->dbus; SDL_DBus_CallMethod(client->servicename, FCITX_IM_DBUS_PATH, FCITX_IM_DBUS_INTERFACE, "CreateICv3",
DBusMessage *reply = NULL; DBUS_TYPE_STRING, &appname, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID,
DBusMessage *msg = dbus->message_new_method_call( DBUS_TYPE_INT32, &id, DBUS_TYPE_BOOLEAN, &enable, DBUS_TYPE_UINT32, &arg1, DBUS_TYPE_UINT32, &arg2, DBUS_TYPE_UINT32, &arg3, DBUS_TYPE_UINT32, &arg4, DBUS_TYPE_INVALID);
client->servicename,
FCITX_IM_DBUS_PATH,
FCITX_IM_DBUS_INTERFACE,
"CreateICv3"
);
if (msg == NULL) SDL_free(appname);
return ;
appname = GetAppName(); if (id >= 0) {
pid = getpid(); SDL_DBusContext *dbus = client->dbus;
dbus->message_append_args(msg,
DBUS_TYPE_STRING, &appname,
DBUS_TYPE_INT32, &pid,
DBUS_TYPE_INVALID);
do {
reply = dbus->connection_send_with_reply_and_block(
dbus->session_conn,
msg,
DBUS_TIMEOUT,
NULL);
if (!reply)
break;
if (!dbus->message_get_args(reply, NULL,
DBUS_TYPE_INT32, &id,
DBUS_TYPE_BOOLEAN, &enable,
DBUS_TYPE_UINT32, &arg1,
DBUS_TYPE_UINT32, &arg2,
DBUS_TYPE_UINT32, &arg3,
DBUS_TYPE_UINT32, &arg4,
DBUS_TYPE_INVALID))
break;
if (id < 0)
break;
client->id = id; client->id = id;
SDL_snprintf(client->icname, IC_NAME_MAX, SDL_snprintf(client->icname, IC_NAME_MAX, FCITX_IC_DBUS_PATH, client->id);
FCITX_IC_DBUS_PATH, client->id);
dbus->bus_add_match(dbus->session_conn, dbus->bus_add_match(dbus->session_conn,
"type='signal', interface='org.fcitx.Fcitx.InputContext'", "type='signal', interface='org.fcitx.Fcitx.InputContext'",
@ -352,12 +284,6 @@ FcitxClientCreateIC(FcitxClient *client)
SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, &Fcitx_SetCapabilities, client); SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, &Fcitx_SetCapabilities, client);
} }
while (0);
if (reply)
dbus->message_unref(reply);
dbus->message_unref(msg);
SDL_free(appname);
} }
static Uint32 static Uint32
@ -422,47 +348,21 @@ SDL_Fcitx_Reset(void)
SDL_bool SDL_bool
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
{ {
DBusMessage *msg = NULL; Uint32 state = Fcitx_ModState();
DBusMessage *reply = NULL; Uint32 handled = SDL_FALSE;
SDL_DBusContext *dbus = fcitx_client.dbus;
Uint32 state = 0;
SDL_bool handled = SDL_FALSE;
int type = FCITX_PRESS_KEY; int type = FCITX_PRESS_KEY;
Uint32 event_time = 0; Uint32 event_time = 0;
msg = FcitxClientICNewMethod(&fcitx_client, "ProcessKeyEvent"); if (SDL_DBus_CallMethod(fcitx_client.servicename, fcitx_client.icname, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent",
if (msg == NULL) DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INT32, &type, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
return SDL_FALSE; DBUS_TYPE_INT32, &handled, DBUS_TYPE_INVALID)) {
if (handled) {
state = Fcitx_ModState(); SDL_Fcitx_UpdateTextRect(NULL);
dbus->message_append_args(msg, return SDL_TRUE;
DBUS_TYPE_UINT32, &keysym, }
DBUS_TYPE_UINT32, &keycode,
DBUS_TYPE_UINT32, &state,
DBUS_TYPE_INT32, &type,
DBUS_TYPE_UINT32, &event_time,
DBUS_TYPE_INVALID);
reply = dbus->connection_send_with_reply_and_block(dbus->session_conn,
msg,
-1,
NULL);
if (reply) {
dbus->message_get_args(reply,
NULL,
DBUS_TYPE_INT32, &handled,
DBUS_TYPE_INVALID);
dbus->message_unref(reply);
} }
if (handled) { return SDL_FALSE;
SDL_Fcitx_UpdateTextRect(NULL);
}
return handled;
} }
void void
@ -473,10 +373,6 @@ SDL_Fcitx_UpdateTextRect(SDL_Rect *rect)
int x = 0, y = 0; int x = 0, y = 0;
SDL_Rect *cursor = &fcitx_client.cursor_rect; SDL_Rect *cursor = &fcitx_client.cursor_rect;
SDL_DBusContext *dbus = fcitx_client.dbus;
DBusMessage *msg = NULL;
DBusConnection *conn;
if (rect) { if (rect) {
SDL_memcpy(cursor, rect, sizeof(SDL_Rect)); SDL_memcpy(cursor, rect, sizeof(SDL_Rect));
} }
@ -516,22 +412,8 @@ SDL_Fcitx_UpdateTextRect(SDL_Rect *rect)
x += cursor->x; x += cursor->x;
y += cursor->y; y += cursor->y;
msg = FcitxClientICNewMethod(&fcitx_client, "SetCursorRect"); SDL_DBus_CallVoidMethod(fcitx_client.servicename, fcitx_client.icname, FCITX_IC_DBUS_INTERFACE, "SetCursorRect",
if (msg == NULL) DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &cursor->w, DBUS_TYPE_INT32, &cursor->h, DBUS_TYPE_INVALID);
return ;
dbus->message_append_args(msg,
DBUS_TYPE_INT32, &x,
DBUS_TYPE_INT32, &y,
DBUS_TYPE_INT32, &cursor->w,
DBUS_TYPE_INT32, &cursor->h,
DBUS_TYPE_INVALID);
conn = dbus->session_conn;
if (dbus->connection_send(conn, msg, NULL))
dbus->connection_flush(conn);
dbus->message_unref(msg);
} }
void void

View File

@ -309,28 +309,13 @@ IBus_SetCapabilities(void *data, const char *name, const char *old_val,
SDL_DBusContext *dbus = SDL_DBus_GetContext(); SDL_DBusContext *dbus = SDL_DBus_GetContext();
if (IBus_CheckConnection(dbus)) { if (IBus_CheckConnection(dbus)) {
Uint32 caps = IBUS_CAP_FOCUS;
if (!(internal_editing && *internal_editing == '1')) {
caps |= IBUS_CAP_PREEDIT_TEXT;
}
DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE, SDL_DBus_CallVoidMethod(IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "SetCapabilities",
input_ctx_path, DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID);
IBUS_INPUT_INTERFACE,
"SetCapabilities");
if (msg) {
Uint32 caps = IBUS_CAP_FOCUS;
if (!(internal_editing && *internal_editing == '1')) {
caps |= 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);
}
} }
} }
@ -338,9 +323,9 @@ IBus_SetCapabilities(void *data, const char *name, const char *old_val,
static SDL_bool static SDL_bool
IBus_SetupConnection(SDL_DBusContext *dbus, const char* addr) IBus_SetupConnection(SDL_DBusContext *dbus, const char* addr)
{ {
const char *client_name = "SDL2_Application";
const char *path = NULL; const char *path = NULL;
SDL_bool result = SDL_FALSE; SDL_bool result = SDL_FALSE;
DBusMessage *msg;
DBusObjectPathVTable ibus_vtable; DBusObjectPathVTable ibus_vtable;
SDL_zero(ibus_vtable); SDL_zero(ibus_vtable);
@ -361,34 +346,11 @@ IBus_SetupConnection(SDL_DBusContext *dbus, const char* addr)
dbus->connection_flush(ibus_conn); dbus->connection_flush(ibus_conn);
msg = dbus->message_new_method_call(IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext"); if (SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext",
if (msg) { DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID,
const char *client_name = "SDL2_Application"; DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
dbus->message_append_args(msg, SDL_free(input_ctx_path);
DBUS_TYPE_STRING, &client_name, input_ctx_path = SDL_strdup(path);
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); 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->bus_add_match(ibus_conn, "type='signal',interface='org.freedesktop.IBus.InputContext'", NULL);
@ -532,16 +494,7 @@ IBus_SimpleMessage(const char *method)
SDL_DBusContext *dbus = SDL_DBus_GetContext(); SDL_DBusContext *dbus = SDL_DBus_GetContext();
if (IBus_CheckConnection(dbus)) { if (IBus_CheckConnection(dbus)) {
DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE, SDL_DBus_CallVoidMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, method);
input_ctx_path,
IBUS_INPUT_INTERFACE,
method);
if (msg) {
if (dbus->connection_send(ibus_conn, msg, NULL)) {
dbus->connection_flush(ibus_conn);
}
dbus->message_unref(msg);
}
} }
} }
@ -561,43 +514,21 @@ SDL_IBus_Reset(void)
SDL_bool SDL_bool
SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
{ {
SDL_bool result = SDL_FALSE; Uint32 result = 0;
SDL_DBusContext *dbus = SDL_DBus_GetContext(); SDL_DBusContext *dbus = SDL_DBus_GetContext();
if (IBus_CheckConnection(dbus)) { if (IBus_CheckConnection(dbus)) {
DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE, Uint32 mods = IBus_ModState();
input_ctx_path, if (!SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
IBUS_INPUT_INTERFACE, DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
"ProcessKeyEvent"); DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) {
if (msg) { result = 0;
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); SDL_IBus_UpdateTextRect(NULL);
return result; return result ? SDL_TRUE : SDL_FALSE;
} }
void void
@ -643,25 +574,8 @@ SDL_IBus_UpdateTextRect(SDL_Rect *rect)
dbus = SDL_DBus_GetContext(); dbus = SDL_DBus_GetContext();
if (IBus_CheckConnection(dbus)) { if (IBus_CheckConnection(dbus)) {
DBusMessage *msg = dbus->message_new_method_call(IBUS_SERVICE, SDL_DBus_CallVoidMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "SetCursorLocation",
input_ctx_path, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &ibus_cursor_rect.w, DBUS_TYPE_INT32, &ibus_cursor_rect.h, DBUS_TYPE_INVALID);
IBUS_INPUT_INTERFACE,
"SetCursorLocation");
if (msg) {
dbus->message_append_args(msg,
DBUS_TYPE_INT32, &x,
DBUS_TYPE_INT32, &y,
DBUS_TYPE_INT32, &ibus_cursor_rect.w,
DBUS_TYPE_INT32, &ibus_cursor_rect.h,
DBUS_TYPE_INVALID);
}
if (msg) {
if (dbus->connection_send(ibus_conn, msg, NULL)) {
dbus->connection_flush(ibus_conn);
}
dbus->message_unref(msg);
}
} }
} }

View File

@ -461,6 +461,8 @@ X11_VideoQuit(_THIS)
X11_QuitMouse(_this); X11_QuitMouse(_this);
X11_QuitTouch(_this); X11_QuitTouch(_this);
/* !!! FIXME: other subsystems use D-Bus, so we shouldn't quit it here;
have SDL.c do this at a higher level, or add refcounting. */
#if SDL_USE_LIBDBUS #if SDL_USE_LIBDBUS
SDL_DBus_Quit(); SDL_DBus_Quit();
#endif #endif