ibus/gtk2/ibusimclient.c

1350 строки
40 KiB
C
Исходник Обычный вид История

2008-05-12 11:18:48 +04:00
/* vim:set et ts=4: */
2008-06-19 11:48:09 +04:00
/* IBus - The Input Bus
* Copyright (C) 2008-2009 Huang Peng <shawn.p.huang@gmail.com>
2008-05-12 11:18:48 +04:00
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
2008-08-06 19:45:47 +04:00
#include <unistd.h>
2008-05-12 11:18:48 +04:00
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <string.h>
#include <stdarg.h>
2008-06-01 20:02:16 +04:00
#include <glib/gstdio.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
2008-06-25 06:51:52 +04:00
#ifdef HAVE_SYS_INOTIFY_H
#define HAVE_INOTIFY
# include <sys/inotify.h>
#endif
2008-06-25 06:51:52 +04:00
2008-06-19 11:48:09 +04:00
#include "ibusimclient.h"
2008-05-12 11:18:48 +04:00
2008-08-06 19:45:47 +04:00
enum {
CONNECTED,
DISCONNECTED,
LAST_SIGNAL,
};
2008-05-12 11:18:48 +04:00
#define IBUS_NAME "org.freedesktop.IBus"
#define IBUS_IFACE "org.freedesktop.IBus"
#define IBUS_PATH "/org/freedesktop/IBus"
2008-08-06 19:45:47 +04:00
#define I_(string) g_intern_static_string (string)
2008-06-19 11:48:09 +04:00
/* IBusIMClientPriv */
struct _IBusIMClientPrivate {
2008-05-12 11:18:48 +04:00
#if USE_DBUS_SESSION_BUS
DBusConnection *dbus;
#endif
#ifdef HAVE_INOTIFY
2008-06-01 20:02:16 +04:00
/* inotify */
gint inotify_wd;
2008-07-16 12:53:51 +04:00
GIOChannel *inotify_channel;
2008-06-01 20:02:16 +04:00
guint inotify_source;
#endif
2008-06-01 20:02:16 +04:00
2008-07-16 12:53:51 +04:00
DBusConnection *ibus;
2008-05-12 11:18:48 +04:00
2008-07-16 12:53:51 +04:00
GHashTable *ic_table;
GList *contexts;
2008-05-12 11:18:48 +04:00
};
2008-08-06 19:45:47 +04:00
/* variables */
static guint client_signals[LAST_SIGNAL] = { 0 };
2008-05-12 11:18:48 +04:00
/* functions prototype */
2008-07-16 12:53:51 +04:00
static void ibus_im_client_class_init (IBusIMClientClass *klass);
static void ibus_im_client_init (IBusIMClient *client);
static void ibus_im_client_finalize (GObject *obj);
2008-08-06 19:45:47 +04:00
static void ibus_im_client_connected (IBusIMClient *client);
static void ibus_im_client_disconnected (IBusIMClient *client);
2008-07-16 12:53:51 +04:00
static const gchar *
_ibus_im_client_create_input_context
(IBusIMClient *client);
static void _ibus_im_client_ibus_open (IBusIMClient *client);
static void _ibus_im_client_ibus_close (IBusIMClient *client);
2008-07-16 12:53:51 +04:00
2008-05-12 11:18:48 +04:00
static gboolean _ibus_call_with_reply_and_block
(DBusConnection *connection,
const gchar *method,
int first_arg_type,
2008-05-12 11:18:48 +04:00
...);
static gboolean _ibus_call_with_reply (DBusConnection *connection,
2008-05-12 11:18:48 +04:00
const gchar *method,
DBusPendingCallNotifyFunction
function,
void *data,
DBusFreeFunction free_function,
int first_arg_type,
2008-05-12 11:18:48 +04:00
...);
static gboolean _dbus_call_with_reply_and_block
2008-05-12 11:18:48 +04:00
(DBusConnection *connection,
const gchar *dest,
const gchar *path,
const gchar *iface,
const char *method,
2008-07-16 12:53:51 +04:00
int first_arg_type,
2008-05-12 11:18:48 +04:00
...);
2008-07-16 12:53:51 +04:00
static GtkIMContext *
_ibus_client_ic_to_context (IBusIMClient *client,
const gchar *ic);
2008-05-12 11:18:48 +04:00
/* callback functions */
static DBusHandlerResult
2008-06-19 11:48:09 +04:00
_ibus_im_client_message_filter_cb
2008-07-16 12:53:51 +04:00
(DBusConnection *connection,
DBusMessage *message,
void *user_data);
2008-05-12 11:18:48 +04:00
2008-07-16 12:53:51 +04:00
static void _dbus_name_owner_changed_cb
(DBusGProxy *proxy,
const gchar *name,
const gchar *old_name,
const gchar *new_name,
IBusIMClient *client);
2008-05-12 11:18:48 +04:00
2008-07-16 14:28:55 +04:00
static GType ibus_type_im_client = 0;
static GtkObjectClass *parent_class = NULL;
2008-05-12 11:18:48 +04:00
GType
2008-06-19 11:48:09 +04:00
ibus_im_client_get_type (void)
2008-05-12 11:18:48 +04:00
{
if (ibus_type_im_client == 0) {
ibus_im_client_register_type (NULL);
}
2008-06-19 11:48:09 +04:00
g_assert (ibus_type_im_client != 0);
return ibus_type_im_client;
2008-05-12 11:18:48 +04:00
}
void
2008-06-19 11:48:09 +04:00
ibus_im_client_register_type (GTypeModule *type_module)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
static const GTypeInfo ibus_im_client_info = {
sizeof (IBusIMClientClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) ibus_im_client_class_init,
NULL, /* class finialize */
NULL, /* class data */
2008-06-19 11:48:09 +04:00
sizeof (IBusIMClient),
2008-05-12 11:18:48 +04:00
0,
(GInstanceInitFunc) ibus_im_client_init,
2008-05-12 11:18:48 +04:00
};
2008-06-19 11:48:09 +04:00
if (! ibus_type_im_client ) {
2008-07-23 10:12:55 +04:00
if (type_module) {
ibus_type_im_client =
g_type_module_register_type (type_module,
GTK_TYPE_OBJECT,
"IBusIMClient",
&ibus_im_client_info,
(GTypeFlags)0);
}
else {
ibus_type_im_client =
g_type_register_static (GTK_TYPE_OBJECT,
"IBusIMClient",
&ibus_im_client_info,
(GTypeFlags)0);
}
2008-05-12 11:18:48 +04:00
}
}
2008-06-19 11:48:09 +04:00
IBusIMClient *
2008-07-16 12:53:51 +04:00
ibus_im_client_new (void)
2008-05-12 11:18:48 +04:00
{
2008-07-16 12:53:51 +04:00
IBusIMClient *client;
2008-07-16 12:53:51 +04:00
client = IBUS_IM_CLIENT(g_object_new (IBUS_TYPE_IM_CLIENT, NULL));
2008-05-12 11:18:48 +04:00
2008-07-16 12:53:51 +04:00
return client;
}
2008-05-12 11:18:48 +04:00
static void
2008-06-19 11:48:09 +04:00
ibus_im_client_class_init (IBusIMClientClass *klass)
2008-05-12 11:18:48 +04:00
{
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
parent_class = (GtkObjectClass *) g_type_class_peek_parent (klass);
2008-06-19 11:48:09 +04:00
g_type_class_add_private (klass, sizeof (IBusIMClientPrivate));
2008-05-12 11:18:48 +04:00
2008-07-22 05:53:08 +04:00
gobject_class->finalize = ibus_im_client_finalize;
2008-08-06 19:45:47 +04:00
klass->connected = ibus_im_client_connected;
klass->disconnected = ibus_im_client_disconnected;
client_signals[CONNECTED] =
g_signal_new (I_("connected"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (IBusIMClientClass, connected),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
client_signals[DISCONNECTED] =
g_signal_new (I_("disconnected"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (IBusIMClientClass, disconnected),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
2008-05-12 11:18:48 +04:00
}
2008-08-06 19:45:47 +04:00
void ibus_im_client_connected (IBusIMClient *client)
{
/* do nothing */
2008-08-06 19:45:47 +04:00
}
2008-08-06 19:45:47 +04:00
void ibus_im_client_disconnected (IBusIMClient *client)
{
/* do nothing */
2008-08-06 19:45:47 +04:00
}
2008-07-16 14:28:55 +04:00
/*
* open ibus connection
*/
2008-05-12 11:18:48 +04:00
static void
2008-06-19 11:48:09 +04:00
_ibus_im_client_ibus_open (IBusIMClient *client)
2008-05-12 11:18:48 +04:00
{
2008-06-01 20:02:16 +04:00
gchar *ibus_addr = NULL;
2008-05-12 11:18:48 +04:00
DBusError error;
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-06-01 20:02:16 +04:00
if (priv->ibus != NULL)
return;
2008-05-12 11:18:48 +04:00
#if USE_DBUS_SESSION_BUS
dbus_connection_setup_with_g_main (priv->dbus, NULL);
if (!_dbus_call_with_reply_and_block (priv->dbus,
2008-05-12 11:18:48 +04:00
IBUS_NAME, IBUS_PATH, IBUS_IFACE,
"GetIBusAddress",
DBUS_TYPE_INVALID,
DBUS_TYPE_STRING, &ibus_addr,
DBUS_TYPE_INVALID
)) {
g_warning ("Can not get ibus address");
return;
}
#endif
if (ibus_addr == NULL) {
gchar *display;
gchar *hostname = "";
gchar *displaynumber = "0";
gchar *screennumber = "0";
gchar *username = NULL;
gchar *p;
display = g_strdup (g_getenv ("DISPLAY"));
if (display == NULL) {
g_warning ("DISPLAY is empty! We use default DISPLAY (:0.0)");
}
else {
p = display;
hostname = display;
for (; *p != ':' && *p != '\0'; p++);
if (*p == ':') {
*p = '\0';
p++;
displaynumber = p;
}
for (; *p != '.' && *p != '\0'; p++);
if (*p == '.') {
*p = '\0';
p++;
screennumber = p;
}
}
2008-08-06 19:45:47 +04:00
username = g_strdup (getlogin());
if (username == NULL)
2008-08-06 19:45:47 +04:00
username = g_strdup (g_getenv("LOGNAME"));
if (username == NULL)
2008-08-06 19:45:47 +04:00
username = g_strdup (g_getenv("USER"));
if (username == NULL)
2008-08-06 19:45:47 +04:00
username = g_strdup (g_getenv("LNAME"));
if (username == NULL)
2008-08-06 19:45:47 +04:00
username = g_strdup (g_getenv("USERNAME"));
ibus_addr = g_strdup_printf (
"unix:path=/tmp/ibus-%s/ibus-%s-%s.%s",
username, hostname, displaynumber, screennumber);
g_free (display);
2008-08-06 19:45:47 +04:00
g_free (username);
}
2008-05-12 11:18:48 +04:00
/*
* Init ibus and proxy object
*/
dbus_error_init (&error);
2008-06-01 20:02:16 +04:00
priv->ibus = dbus_connection_open_private (ibus_addr, &error);
g_free (ibus_addr);
2008-05-12 11:18:48 +04:00
if (priv->ibus == NULL) {
g_warning ("Error: %s", error.message);
dbus_error_free (&error);
return;
}
if (!dbus_connection_add_filter (priv->ibus,
2008-06-19 11:48:09 +04:00
_ibus_im_client_message_filter_cb,
2008-05-12 11:18:48 +04:00
client, NULL)) {
g_warning ("Out of memory");
return;
}
dbus_connection_setup_with_g_main (priv->ibus, NULL);
2008-07-16 12:53:51 +04:00
g_signal_emit (client, client_signals[CONNECTED], 0);
2008-07-16 12:53:51 +04:00
GList *p;
for (p = priv->contexts; p != NULL; p = g_list_next (p)) {
2008-07-16 13:01:05 +04:00
IBusIMContext *context = IBUS_IM_CONTEXT (p->data);
2008-07-16 12:53:51 +04:00
const gchar *ic = _ibus_im_client_create_input_context (client);
if (ic == NULL) {
_ibus_im_client_ibus_close (client);
return;
}
2008-07-16 13:01:05 +04:00
g_hash_table_insert (priv->ic_table, g_strdup (ic), context);
ibus_im_context_set_ic (context, ic);
2008-07-16 12:53:51 +04:00
}
2008-05-12 11:18:48 +04:00
}
2008-07-16 14:28:55 +04:00
/*
* close ibus connection
*/
2008-05-12 11:18:48 +04:00
static void
2008-06-19 11:48:09 +04:00
_ibus_im_client_ibus_close (IBusIMClient *client)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
GList *p;
for (p = priv->contexts; p != NULL; p = g_list_next (p)) {
IBusIMContext *ctx = IBUS_IM_CONTEXT (p->data);
ibus_im_context_set_ic (ctx, NULL);
}
g_hash_table_remove_all (priv->ic_table);
2008-05-12 11:18:48 +04:00
if (priv->ibus) {
dbus_connection_close (priv->ibus);
dbus_connection_unref (priv->ibus);
2008-06-01 20:02:16 +04:00
priv->ibus = NULL;
g_signal_emit (client, client_signals[DISCONNECTED], 0);
2008-06-01 20:02:16 +04:00
}
2008-07-16 12:53:51 +04:00
}
2008-07-16 14:28:55 +04:00
/*
* create an im context
*/
2008-07-16 12:53:51 +04:00
IBusIMContext *
ibus_im_client_create_im_context (IBusIMClient *client)
{
IBusIMContext *context;
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
context = IBUS_IM_CONTEXT (ibus_im_context_new ());
priv->contexts = g_list_append (priv->contexts, context);
2008-07-16 12:53:51 +04:00
const gchar *ic = _ibus_im_client_create_input_context (client);
ibus_im_context_set_ic (context, ic);
if (ic) {
g_hash_table_insert (priv->ic_table, (gpointer)g_strdup (ic), context);
}
2008-07-16 12:53:51 +04:00
return context;
}
2008-07-16 14:28:55 +04:00
/*
* create a ibus input context
*/
2008-07-16 12:53:51 +04:00
static const gchar *
_ibus_im_client_create_input_context (IBusIMClient *client)
{
IBusIMClientPrivate *priv = client->priv;
if (priv->ibus == NULL)
return NULL;
2008-07-16 12:53:51 +04:00
const gchar *app_name = g_get_application_name ();
gchar *ic = NULL;
_ibus_call_with_reply_and_block (priv->ibus, "CreateInputContext",
DBUS_TYPE_STRING, &app_name,
DBUS_TYPE_INVALID,
DBUS_TYPE_STRING, &ic,
DBUS_TYPE_INVALID);
return ic;
2008-06-01 20:02:16 +04:00
}
#ifdef HAVE_INOTIFY
2008-06-01 20:02:16 +04:00
static gboolean
2008-06-19 11:48:09 +04:00
_ibus_im_client_inotify_cb (GIOChannel *source, GIOCondition condition, IBusIMClient *client)
2008-06-01 20:02:16 +04:00
{
struct inotify_event *p = NULL;
gchar *name;
2008-06-01 20:02:16 +04:00
gsize n;
if (condition & G_IO_IN == 0)
return TRUE;
p = g_malloc0 (sizeof (struct inotify_event) + 1024);
g_io_channel_read_chars (source, (gchar *) p, sizeof (struct inotify_event), &n, NULL);
g_io_channel_read_chars (source, ((gchar *)p) + sizeof (struct inotify_event), p->len, &n, NULL);
name = g_strdup_printf ("ibus-%s", g_getenv ("DISPLAY"));
for (n = 0; name[n] != 0; n++) {
if (name[n] != ':')
continue;
name[n] = '-';
break;
}
if (g_strcmp0 (p->name, name) == 0) {
2008-06-01 20:02:16 +04:00
if (p->mask & IN_CREATE) {
g_usleep (1000);
2008-06-19 11:48:09 +04:00
_ibus_im_client_ibus_open (client);
2008-06-01 20:02:16 +04:00
}
2008-05-12 11:18:48 +04:00
}
g_free (name);
2008-06-01 20:02:16 +04:00
g_free (p);
2008-05-12 11:18:48 +04:00
}
#endif
2008-05-12 11:18:48 +04:00
static void
2008-06-19 11:48:09 +04:00
ibus_im_client_init (IBusIMClient *obj)
2008-05-12 11:18:48 +04:00
{
DEBUG_FUNCTION_IN;
DBusError error;
2008-06-19 11:48:09 +04:00
IBusIMClient *client = IBUS_IM_CLIENT (obj);
IBusIMClientPrivate *priv;
2008-06-01 20:02:16 +04:00
gchar *watch_path;
struct stat stat_buf;
2008-06-06 07:27:30 +04:00
#ifdef HAVE_INOTIFY
gint inotify_fd = inotify_init ();
#endif
2008-06-19 11:48:09 +04:00
priv = G_TYPE_INSTANCE_GET_PRIVATE (client, IBUS_TYPE_IM_CLIENT, IBusIMClientPrivate);
2008-05-12 11:18:48 +04:00
client->priv = priv;
2008-07-16 12:53:51 +04:00
priv->ic_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
priv->contexts = NULL;
2008-05-12 11:18:48 +04:00
2008-06-01 20:02:16 +04:00
watch_path = g_strdup_printf ("/tmp/ibus-%s", g_get_user_name ());
if (g_stat (watch_path, &stat_buf) != 0) {
g_mkdir (watch_path, 0750);
}
2008-06-06 07:27:30 +04:00
#ifdef HAVE_INOTIFY
/* init inotify */
2008-06-01 20:02:16 +04:00
priv->inotify_wd = inotify_add_watch (inotify_fd, watch_path, IN_CREATE | IN_DELETE);
priv->inotify_channel = g_io_channel_unix_new (inotify_fd);
g_io_channel_set_close_on_unref (priv->inotify_channel, TRUE);
priv->inotify_source = g_io_add_watch (priv->inotify_channel,
G_IO_IN,
2008-06-19 11:48:09 +04:00
(GIOFunc)_ibus_im_client_inotify_cb,
2008-06-01 20:02:16 +04:00
(gpointer)client);
#endif
2008-06-06 07:27:30 +04:00
g_free (watch_path);
2008-06-01 20:02:16 +04:00
#if USE_DBUS_SESSION_BUS
2008-05-12 11:18:48 +04:00
/*
* Init dbus
2008-05-12 11:18:48 +04:00
*/
dbus_error_init (&error);
priv->dbus = dbus_bus_get (DBUS_BUS_SESSION, &error);
if (priv->dbus == NULL) {
g_warning ("Error: %s", error.message);
dbus_error_free (&error);
return;
}
#endif
2008-06-19 11:48:09 +04:00
_ibus_im_client_ibus_open (client);
2008-05-12 11:18:48 +04:00
#if USE_DBUS_SESSION_BUS
if (!dbus_connection_add_filter (priv->dbus,
2008-06-19 11:48:09 +04:00
_ibus_im_client_message_filter_cb,
2008-05-12 11:18:48 +04:00
client, NULL)) {
g_warning ("Out of memory");
return;
}
gchar *rule =
2008-05-12 11:18:48 +04:00
"type='signal',"
"sender='" DBUS_SERVICE_DBUS "',"
"interface='" DBUS_INTERFACE_DBUS "',"
"member='NameOwnerChanged',"
"path='" DBUS_PATH_DBUS "',"
"arg0='" IBUS_NAME "'";
if (!_dbus_call_with_reply_and_block (priv->dbus,
2008-05-12 11:18:48 +04:00
DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
"AddMatch",
DBUS_TYPE_STRING, &rule,
DBUS_TYPE_INVALID,
DBUS_TYPE_INVALID
)) {
g_warning ("Can not get ibus address");
return;
}
#endif
#if 0
2008-05-12 11:18:48 +04:00
/* get dbus proxy */
priv->dbus = dbus_g_proxy_new_for_name (priv->ibus,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
g_assert (priv->dbus != NULL);
2008-05-12 11:18:48 +04:00
/* connect NameOwnerChanged signal */
dbus_g_proxy_add_signal (priv->dbus, "NameOwnerChanged",
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->dbus, "NameOwnerChanged",
2008-05-12 11:18:48 +04:00
G_CALLBACK (_dbus_name_owner_changed_cb),
(gpointer)client, NULL);
dbus_bus_add_match ((DBusConnection *)dbus_g_connection_get_connection (priv->ibus),
"type='signal',"
"sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',path='" DBUS_PATH_DBUS
"',member='NameOwnerChanged',"
2008-06-19 11:48:09 +04:00
"arg0='" IBUS_DBUS_SERVICE "'",
2008-05-12 11:18:48 +04:00
&dbus_error);
2008-06-19 11:48:09 +04:00
_ibus_im_client_reinit_imm (client);
2008-05-12 11:18:48 +04:00
#endif
2008-05-12 11:18:48 +04:00
}
static void
2008-06-19 11:48:09 +04:00
ibus_im_client_finalize (GObject *obj)
2008-05-12 11:18:48 +04:00
{
DEBUG_FUNCTION_IN;
2008-06-19 11:48:09 +04:00
IBusIMClient *client = IBUS_IM_CLIENT (obj);
IBusIMClientPrivate *priv = client->priv;
2008-05-12 11:18:48 +04:00
g_assert (client == _client);
#ifdef HAVE_INOTIFY
2008-06-01 20:02:16 +04:00
g_source_remove (priv->inotify_source);
g_io_channel_unref (priv->inotify_channel);
#endif
2008-06-01 20:02:16 +04:00
2008-05-12 11:18:48 +04:00
#if USE_DBUS_SESSION_BUS
if (priv->dbus) {
dbus_connection_unref (priv->dbus);
}
#endif
2008-06-19 11:48:09 +04:00
_ibus_im_client_ibus_close (client);
2008-05-12 11:18:48 +04:00
G_OBJECT_CLASS(parent_class)->finalize (obj);
2008-05-12 11:18:48 +04:00
_client = NULL;
}
static void
2008-07-16 12:53:51 +04:00
ibus_im_client_commit_string (IBusIMClient *client, const gchar *ic, const gchar *string)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
IBusIMContext *context = g_hash_table_lookup (priv->ic_table, (gpointer)ic);
2008-05-12 11:18:48 +04:00
2008-07-16 12:53:51 +04:00
if (context == NULL) {
g_debug ("Can not find context assocate with ic(%s)", ic);
return;
2008-05-12 11:18:48 +04:00
}
2008-07-16 12:53:51 +04:00
g_signal_emit_by_name (G_OBJECT (context), "commit", string);
2008-05-12 11:18:48 +04:00
}
static void
2008-07-16 12:53:51 +04:00
ibus_im_client_update_preedit (IBusIMClient *client, const gchar *ic, const gchar *string,
2008-07-20 08:42:57 +04:00
PangoAttrList *attrs, gint cursor_pos, gboolean visible)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
IBusIMContext *context = g_hash_table_lookup (priv->ic_table, (gpointer)ic);
2008-05-12 11:18:48 +04:00
2008-07-16 12:53:51 +04:00
if (context == NULL) {
g_debug ("Can not find context assocate with ic(%s)", ic);
return;
2008-05-12 11:18:48 +04:00
}
2008-07-20 08:42:57 +04:00
ibus_im_context_update_preedit (context, string, attrs, cursor_pos, visible);
2008-05-12 11:18:48 +04:00
}
static void
2008-06-19 11:48:09 +04:00
_ibus_signal_commit_string_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
2008-05-12 11:18:48 +04:00
{
/* Handle CommitString signal */
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-05-12 11:18:48 +04:00
DBusError error = {0};
gchar *ic = NULL;
2008-05-12 11:18:48 +04:00
gchar *string = NULL;
2008-05-12 11:18:48 +04:00
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &ic,
DBUS_TYPE_STRING, &string,
DBUS_TYPE_INVALID)) {
2008-05-12 11:18:48 +04:00
g_warning ("%s", error.message);
dbus_error_free (&error);
}
else {
2008-07-16 12:53:51 +04:00
IBusIMContext *context = g_hash_table_lookup (priv->ic_table, (gpointer)ic);
if (context == NULL) {
g_debug ("Can not find context assocate with ic(%s)", ic);
return;
}
2008-07-16 12:53:51 +04:00
ibus_im_context_commit_string (context, string);
2008-05-12 11:18:48 +04:00
}
}
static void
2008-06-19 11:48:09 +04:00
_ibus_signal_update_preedit_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
2008-05-12 11:18:48 +04:00
{
2008-05-30 13:55:14 +04:00
/* Handle UpdatePreedit signal */
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-05-12 11:18:48 +04:00
DBusError error = {0};
DBusMessageIter iter, sub_iter;
2008-07-01 15:41:23 +04:00
int type, sub_type;
2008-05-30 13:55:14 +04:00
gchar *ic = NULL;
2008-05-30 13:55:14 +04:00
gchar *string = NULL;
2008-05-12 11:18:48 +04:00
PangoAttrList *attrs = NULL;
2008-07-01 15:41:23 +04:00
int cursor = 0;
2008-07-20 08:42:57 +04:00
gboolean visible = False;
2008-05-12 11:18:48 +04:00
if (!dbus_message_iter_init (message, &iter)) {
2008-05-30 13:55:14 +04:00
g_warning ("The UpdatePreedit signal does have args!");
2008-05-12 11:18:48 +04:00
return;
}
type = dbus_message_iter_get_arg_type (&iter);
if (type != DBUS_TYPE_STRING) {
g_warning ("The 1st argument of UpdatePreedit signal must be a String");
return;
}
dbus_message_iter_get_basic (&iter, &ic);
dbus_message_iter_next (&iter);
type = dbus_message_iter_get_arg_type (&iter);
if (type != DBUS_TYPE_STRING) {
g_warning ("The 2nd argument of UpdatePreedit signal must be a String");
2008-05-12 11:18:48 +04:00
return;
}
dbus_message_iter_get_basic (&iter, &string);
dbus_message_iter_next (&iter);
2008-05-12 11:18:48 +04:00
type = dbus_message_iter_get_arg_type (&iter);
if (type != DBUS_TYPE_ARRAY) {
g_warning ("The 3rd argument of UpdatePreedit signal must be a Struct Array");
2008-05-12 11:18:48 +04:00
return;
}
2008-05-12 11:18:48 +04:00
dbus_message_iter_recurse (&iter, &sub_iter);
if (dbus_message_iter_get_arg_type (&sub_iter) != DBUS_TYPE_INVALID) {
if (dbus_message_iter_get_arg_type (&sub_iter) != DBUS_TYPE_ARRAY ||
2008-06-12 06:44:06 +04:00
dbus_message_iter_get_element_type (&sub_iter) != DBUS_TYPE_UINT32 ) {
g_warning ("The 3rd argument of UpdatePreedit signal must be a Struct Array");
return;
2008-05-12 11:18:48 +04:00
}
attrs = pango_attr_list_new ();
2008-05-12 11:18:48 +04:00
while ((sub_type = dbus_message_iter_get_arg_type (&sub_iter) != DBUS_TYPE_INVALID)) {
PangoAttribute *attr;
DBusMessageIter sub_sub_iter;
guint *values = NULL;
gint length = 0;
dbus_message_iter_recurse (&sub_iter, &sub_sub_iter);
dbus_message_iter_get_fixed_array (&sub_sub_iter, &values, &length);
if (length <= 0) {
g_warning ("The element of the 3rd argument of UpdatePreedit should not be a empty array");
continue;
}
switch (values[0]) {
case 1: /* Underline */
attr = pango_attr_underline_new (values[1]);
attr->start_index = g_utf8_offset_to_pointer (string, values[2]) - string;
attr->end_index = g_utf8_offset_to_pointer (string, values[3]) - string;
pango_attr_list_insert (attrs, attr);
break;
case 2: /* Foreground Color */
attr = pango_attr_foreground_new (
(values[1] & 0xff0000) >> 8,
(values[1] & 0x00ff00),
(values[1] & 0x0000ff) << 8
);
attr->start_index = g_utf8_offset_to_pointer (string, values[2]) - string;
attr->end_index = g_utf8_offset_to_pointer (string, values[3]) - string;
pango_attr_list_insert (attrs, attr);
break;
case 3: /* Background Color */
attr = pango_attr_background_new (
(values[1] & 0xff0000) >> 8,
(values[1] & 0x00ff00),
(values[1] & 0x0000ff) << 8
);
attr->start_index = g_utf8_offset_to_pointer (string, values[2]) - string;
attr->end_index = g_utf8_offset_to_pointer (string, values[3]) - string;
pango_attr_list_insert (attrs, attr);
break;
default:
g_warning ("Unkown type attribute type = %d", values[0]);
}
2008-05-12 11:18:48 +04:00
dbus_message_iter_next (&sub_iter);
2008-05-12 11:18:48 +04:00
}
2008-05-12 11:18:48 +04:00
}
dbus_message_iter_next (&iter);
type = dbus_message_iter_get_arg_type (&iter);
if (type != DBUS_TYPE_INT32) {
g_warning ("The 4th argument of UpdatePreedit signal must be an Int32 %c", type);
2008-05-12 11:18:48 +04:00
pango_attr_list_unref (attrs);
return;
}
dbus_message_iter_get_basic (&iter, &cursor);
dbus_message_iter_next (&iter);
2008-05-30 13:55:14 +04:00
type = dbus_message_iter_get_arg_type (&iter);
if (type != DBUS_TYPE_BOOLEAN) {
g_warning ("The 4th argument of UpdatePreedit signal must be an Int32 %c", type);
2008-05-30 13:55:14 +04:00
pango_attr_list_unref (attrs);
return;
}
2008-07-20 08:42:57 +04:00
dbus_message_iter_get_basic (&iter, &visible);
2008-05-30 13:55:14 +04:00
dbus_message_iter_next (&iter);
2008-07-16 12:53:51 +04:00
{
IBusIMContext *context = g_hash_table_lookup (priv->ic_table, (gpointer)ic);
if (context == NULL) {
g_debug ("Can not find context assocate with ic(%s)", ic);
return;
}
2008-07-20 08:42:57 +04:00
ibus_im_context_update_preedit (context, string, attrs, cursor, visible);
2008-07-16 12:53:51 +04:00
}
2008-05-12 11:18:48 +04:00
pango_attr_list_unref (attrs);
}
2008-07-20 08:42:57 +04:00
static void
_ibus_signal_show_preedit_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
{
/* Handle CommitString signal */
IBusIMClientPrivate *priv = client->priv;
DBusError error = {0};
gchar *ic = NULL;
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &ic,
DBUS_TYPE_INVALID)) {
g_warning ("%s", error.message);
dbus_error_free (&error);
}
else {
IBusIMContext *context = g_hash_table_lookup (priv->ic_table, (gpointer)ic);
if (context == NULL) {
g_debug ("Can not find context assocate with ic(%s)", ic);
return;
}
ibus_im_context_show_preedit (context);
}
}
static void
_ibus_signal_hide_preedit_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
{
/* Handle CommitString signal */
IBusIMClientPrivate *priv = client->priv;
DBusError error = {0};
gchar *ic = NULL;
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &ic,
DBUS_TYPE_INVALID)) {
g_warning ("%s", error.message);
dbus_error_free (&error);
}
else {
IBusIMContext *context = g_hash_table_lookup (priv->ic_table, (gpointer)ic);
if (context == NULL) {
g_debug ("Can not find context assocate with ic(%s)", ic);
return;
}
ibus_im_context_hide_preedit (context);
}
}
2008-06-01 20:02:16 +04:00
#ifdef USE_DBUS_SESSION_BUS
2008-05-12 11:18:48 +04:00
static void
2008-06-19 11:48:09 +04:00
_ibus_signal_name_owner_changed_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-05-12 11:18:48 +04:00
gchar *name = NULL;
gchar *old_name = NULL;
gchar *new_name = NULL;
DBusError error = {0};
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &name,
2008-05-12 11:18:48 +04:00
DBUS_TYPE_STRING, &old_name,
DBUS_TYPE_STRING, &new_name,
DBUS_TYPE_INVALID)) {
g_warning ("%s", error.message);
dbus_error_free (&error);
}
g_return_if_fail (strcmp (name, IBUS_NAME) == 0);
2008-06-01 20:02:16 +04:00
if (g_strcmp0 (new_name, "") == 0) {
2008-06-19 11:48:09 +04:00
_ibus_im_client_ibus_close (client);
2008-05-12 11:18:48 +04:00
priv->enable = FALSE;
}
else {
2008-06-19 11:48:09 +04:00
_ibus_im_client_ibus_open (client);
2008-05-12 11:18:48 +04:00
priv->enable = TRUE;
}
}
2008-06-01 20:02:16 +04:00
#endif
static void
2008-06-19 11:48:09 +04:00
_ibus_signal_disconnected_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
2008-06-01 20:02:16 +04:00
{
2008-06-19 11:48:09 +04:00
_ibus_im_client_ibus_close (client);
2008-06-01 20:02:16 +04:00
}
2008-05-12 11:18:48 +04:00
static void
2008-06-19 11:48:09 +04:00
_ibus_signal_enabled_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
2008-05-12 11:18:48 +04:00
{
DEBUG_FUNCTION_IN;
2008-07-16 12:53:51 +04:00
/* Handle CommitString signal */
IBusIMClientPrivate *priv = client->priv;
DBusError error = {0};
gchar *ic = NULL;
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &ic,
DBUS_TYPE_INVALID)) {
g_warning ("%s", error.message);
dbus_error_free (&error);
}
else {
IBusIMContext *context = g_hash_table_lookup (priv->ic_table, (gpointer)ic);
if (context == NULL) {
g_debug ("Can not find context assocate with ic(%s)", ic);
return;
}
ibus_im_context_enable (context);
}
2008-05-12 11:18:48 +04:00
}
static void
2008-06-19 11:48:09 +04:00
_ibus_signal_disabled_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
2008-05-12 11:18:48 +04:00
{
DEBUG_FUNCTION_IN;
2008-07-16 12:53:51 +04:00
/* Handle CommitString signal */
IBusIMClientPrivate *priv = client->priv;
DBusError error = {0};
gchar *ic = NULL;
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &ic,
DBUS_TYPE_INVALID)) {
g_warning ("%s", error.message);
dbus_error_free (&error);
}
else {
IBusIMContext *context = g_hash_table_lookup (priv->ic_table, (gpointer)ic);
if (context == NULL) {
g_debug ("Can not find context assocate with ic(%s)", ic);
return;
}
ibus_im_context_disable (context);
}
2008-05-12 11:18:48 +04:00
}
2008-07-16 12:53:51 +04:00
2008-05-12 11:18:48 +04:00
static DBusHandlerResult
2008-06-19 11:48:09 +04:00
_ibus_im_client_message_filter_cb (DBusConnection *connection, DBusMessage *message, void *user_data)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClient *client = (IBusIMClient *) user_data;
2008-05-12 11:18:48 +04:00
static struct SIGNAL_HANDLER {
const gchar *iface;
const gchar *name;
2008-06-19 11:48:09 +04:00
void (* handler) (DBusConnection *, DBusMessage *, IBusIMClient *);
2008-05-12 11:18:48 +04:00
} handlers[] = {
2008-06-01 20:02:16 +04:00
#ifdef USE_DBUS_SESSION_BUS
2008-06-19 11:48:09 +04:00
{ DBUS_INTERFACE_DBUS, "NameOwnerChanged", _ibus_signal_name_owner_changed_handler },
2008-06-01 20:02:16 +04:00
#endif
2008-06-19 11:48:09 +04:00
{ DBUS_INTERFACE_LOCAL, "Disconnected", _ibus_signal_disconnected_handler },
{ IBUS_IFACE, "CommitString", _ibus_signal_commit_string_handler },
{ IBUS_IFACE, "UpdatePreedit", _ibus_signal_update_preedit_handler },
2008-07-20 08:42:57 +04:00
{ IBUS_IFACE, "ShowPreedit", _ibus_signal_show_preedit_handler },
{ IBUS_IFACE, "HidePreedit", _ibus_signal_hide_preedit_handler },
2008-06-19 11:48:09 +04:00
{ IBUS_IFACE, "Enabled", _ibus_signal_enabled_handler },
{ IBUS_IFACE, "Disabled", _ibus_signal_disabled_handler },
2008-05-12 11:18:48 +04:00
{0},
};
gint i;
for (i = 0; handlers[i].iface != NULL; i++) {
if (dbus_message_is_signal (message, handlers[i].iface, handlers[i].name)) {
handlers[i].handler (connection, message, client);
return DBUS_HANDLER_RESULT_HANDLED;
2008-05-12 11:18:48 +04:00
}
}
2008-07-20 08:42:57 +04:00
g_debug ("Unknown message %s", dbus_message_get_member (message));
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2008-05-12 11:18:48 +04:00
}
inline static gboolean
_dbus_call_with_reply_and_block_valist (DBusConnection *connection,
const gchar *dest, const gchar *path, const gchar* iface, const char *method,
2008-07-01 15:41:23 +04:00
int first_arg_type, va_list args)
2008-05-12 11:18:48 +04:00
{
2008-07-01 15:41:23 +04:00
2008-05-12 11:18:48 +04:00
DBusMessage *message, *reply;
DBusError error = {0};
int type;
2008-07-01 15:41:23 +04:00
va_list tmp;
2008-05-12 11:18:48 +04:00
2008-06-01 20:02:16 +04:00
if (connection == NULL)
return FALSE;
message = dbus_message_new_method_call (dest,
2008-05-12 11:18:48 +04:00
path, iface, method);
if (!message) {
g_warning ("Out of memory!");
return FALSE;
}
2008-07-01 15:41:23 +04:00
va_copy (tmp, args);
if (!dbus_message_append_args_valist (message, first_arg_type, tmp)) {
2008-05-12 11:18:48 +04:00
dbus_message_unref (message);
g_warning ("Can not create call message");
return FALSE;
}
reply = dbus_connection_send_with_reply_and_block (connection,
2008-05-12 11:18:48 +04:00
message, -1, &error);
dbus_message_unref (message);
if (!reply) {
g_warning ("%s", error.message);
dbus_error_free (&error);
return FALSE;
}
type = first_arg_type;
while (type != DBUS_TYPE_INVALID) {
if (type == DBUS_TYPE_ARRAY) {
va_arg (args, int);
va_arg (args, void *);
va_arg (args, int);
}
else {
2008-07-01 15:41:23 +04:00
va_arg (args, void *);
2008-05-12 11:18:48 +04:00
}
type = va_arg (args, int);
}
type = va_arg (args, int);
if (!dbus_message_get_args_valist (reply, &error, type, args)) {
g_warning ("%s", error.message);
dbus_error_free (&error);
dbus_message_unref (reply);
return FALSE;
}
dbus_message_unref (reply);
2008-05-12 11:18:48 +04:00
return TRUE;
}
inline static gboolean
_dbus_call_with_reply_and_block (DBusConnection *connection,
const gchar *dest, const gchar *path, const gchar* iface, const char *method,
2008-05-12 11:18:48 +04:00
gint first_arg_type, ...)
{
va_list args;
gboolean retval;
2008-06-01 20:02:16 +04:00
if (connection == NULL)
return FALSE;
2008-05-12 11:18:48 +04:00
va_start (args, first_arg_type);
retval = _dbus_call_with_reply_and_block_valist (connection,
2008-05-12 11:18:48 +04:00
dest, path, iface, method, first_arg_type, args);
va_end (args);
return TRUE;
}
static gboolean
_ibus_call_with_reply_and_block (DBusConnection *connection, const gchar *method, int first_arg_type, ...)
{
va_list args;
gboolean retval;
2008-06-01 20:02:16 +04:00
if (connection == NULL)
return FALSE;
2008-05-12 11:18:48 +04:00
va_start (args, first_arg_type);
retval = _dbus_call_with_reply_and_block_valist (connection,
2008-05-12 11:18:48 +04:00
IBUS_NAME, IBUS_PATH, IBUS_IFACE, method, first_arg_type, args);
va_end (args);
return retval;
}
inline static gboolean
_dbus_call_with_reply_valist (DBusConnection *connection,
const gchar *dest, const gchar *path, const gchar* iface, const char *method,
DBusPendingCallNotifyFunction notify_function,
2008-05-12 11:18:48 +04:00
void *user_data, DBusFreeFunction free_function,
gint first_arg_type, va_list args)
{
DBusMessage *message = NULL;
DBusPendingCall *pendingcall = NULL;
DBusError error = {0};
int type;
if (connection == NULL) {
goto error;
}
message = dbus_message_new_method_call (dest,
2008-05-12 11:18:48 +04:00
path, iface, method);
if (!message) {
g_warning ("Out of memory!");
goto error;
}
2008-05-12 11:18:48 +04:00
if (!dbus_message_append_args_valist (message, first_arg_type, args)) {
g_warning ("Can not create call message");
goto error;
}
if (!dbus_connection_send_with_reply (connection,
2008-05-12 11:18:48 +04:00
message, &pendingcall, -1)) {
g_warning ("Out of memory!");
goto error;
}
if (!dbus_pending_call_set_notify (pendingcall, notify_function,
user_data, free_function)) {
g_warning ("Out of memory!");
goto error;
}
dbus_message_unref (message);
return TRUE;
2008-05-12 11:18:48 +04:00
error:
if (message)
dbus_message_unref (message);
if (pendingcall)
2008-05-15 07:06:07 +04:00
dbus_pending_call_cancel (pendingcall);
2008-05-12 11:18:48 +04:00
if (user_data && free_function)
free_function (user_data);
return False;
}
inline static gboolean
_dbus_call_with_reply (DBusConnection *connection,
2008-05-12 11:18:48 +04:00
const gchar *dest, const gchar *path, const gchar* iface, const char *method,
DBusPendingCallNotifyFunction notify_function,
2008-05-12 11:18:48 +04:00
void *user_data, DBusFreeFunction free_function,
gint first_arg_type, ...)
{
va_list args;
gboolean retval;
2008-06-01 20:02:16 +04:00
if (connection == NULL)
return FALSE;
2008-05-12 11:18:48 +04:00
va_start (args, first_arg_type);
retval = _dbus_call_with_reply_valist (connection,
2008-05-12 11:18:48 +04:00
dest, path, iface, method,
notify_function,
user_data, free_function,
first_arg_type, args);
va_end (args);
return TRUE;
}
static gboolean
_ibus_call_with_reply (DBusConnection *connection, const gchar *method,
DBusPendingCallNotifyFunction notify_function,
2008-05-12 11:18:48 +04:00
void *user_data, DBusFreeFunction free_function,
int first_arg_type, ...)
{
va_list args;
gboolean retval;
2008-06-01 20:02:16 +04:00
if (connection == NULL)
return FALSE;
2008-05-12 11:18:48 +04:00
va_start (args, first_arg_type);
retval = _dbus_call_with_reply_valist (connection,
IBUS_NAME, IBUS_PATH, IBUS_IFACE,
method, notify_function,
user_data, free_function,
2008-05-12 11:18:48 +04:00
first_arg_type, args);
va_end (args);
return retval;
}
static void
2008-06-19 11:48:09 +04:00
_ibus_filter_keypress_reply_cb (DBusPendingCall *pending, void *user_data)
2008-05-12 11:18:48 +04:00
{
DBusMessage *reply;
DBusError error = {0};
GdkEvent *event = (GdkEvent *) user_data;
gboolean retval;
2008-05-12 11:18:48 +04:00
reply = dbus_pending_call_steal_reply (pending);
dbus_pending_call_unref (pending);
if (dbus_set_error_from_message (&error, reply)) {
g_warning ("%s", error.message);
dbus_error_free (&error);
retval = FALSE;
}
else {
if (!dbus_message_get_args (reply, &error,
2008-05-12 11:18:48 +04:00
DBUS_TYPE_BOOLEAN, &retval, DBUS_TYPE_INVALID)) {
g_warning ("%s", error.message);
dbus_error_free (&error);
retval = FALSE;
}
}
if (!retval) {
event->any.send_event = TRUE;
gdk_event_put (event);
}
}
gboolean
2008-07-16 12:53:51 +04:00
ibus_im_client_filter_keypress (IBusIMClient *client, IBusIMContext *context, GdkEventKey *event)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
gchar *ic = ibus_im_context_get_ic (context);
2008-07-16 14:36:24 +04:00
if (ic == NULL)
return FALSE;
2008-05-12 11:18:48 +04:00
guint state = event->state & GDK_MODIFIER_MASK;
gboolean is_press = event->type == GDK_KEY_PRESS;
2008-05-12 11:18:48 +04:00
if (event->send_event) {
return FALSE;
}
/* Call IBus ProcessKeyEvent method */
if (!_ibus_call_with_reply (priv->ibus,
2008-05-12 11:18:48 +04:00
"ProcessKeyEvent",
2008-06-19 11:48:09 +04:00
_ibus_filter_keypress_reply_cb,
2008-05-12 11:18:48 +04:00
gdk_event_copy ((GdkEvent *)event),
(DBusFreeFunction)gdk_event_free,
2008-07-16 12:53:51 +04:00
DBUS_TYPE_STRING, &ic,
2008-05-12 11:18:48 +04:00
DBUS_TYPE_UINT32, &event->keyval,
DBUS_TYPE_BOOLEAN, &is_press,
DBUS_TYPE_UINT32, &state,
DBUS_TYPE_INVALID))
return FALSE;
2008-05-12 11:18:48 +04:00
return TRUE;
}
void
2008-07-16 12:53:51 +04:00
ibus_im_client_focus_in (IBusIMClient *client, IBusIMContext *context)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
gchar *ic = ibus_im_context_get_ic (context);
2008-07-16 14:36:24 +04:00
if (ic == NULL)
return;
2008-07-16 12:53:51 +04:00
2008-05-12 11:18:48 +04:00
/* Call IBus FocusIn method */
2008-07-16 12:53:51 +04:00
_ibus_call_with_reply_and_block (priv->ibus,
"FocusIn",
2008-07-16 12:53:51 +04:00
DBUS_TYPE_STRING, &ic,
2008-05-12 11:18:48 +04:00
DBUS_TYPE_INVALID,
DBUS_TYPE_INVALID);
}
void
2008-07-16 12:53:51 +04:00
ibus_im_client_focus_out (IBusIMClient *client, IBusIMContext *context)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
gchar *ic = ibus_im_context_get_ic (context);
2008-07-16 14:36:24 +04:00
if (ic == NULL)
return;
2008-07-16 12:53:51 +04:00
2008-05-12 11:18:48 +04:00
/* Call IBus FocusOut method */
2008-07-16 12:53:51 +04:00
_ibus_call_with_reply_and_block (priv->ibus,
"FocusOut",
2008-07-16 12:53:51 +04:00
DBUS_TYPE_STRING, &ic,
2008-05-12 11:18:48 +04:00
DBUS_TYPE_INVALID,
DBUS_TYPE_INVALID);
}
void
2008-07-16 12:53:51 +04:00
ibus_im_client_reset (IBusIMClient *client, IBusIMContext *context)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
gchar *ic = ibus_im_context_get_ic (context);
2008-07-16 14:36:24 +04:00
if (ic == NULL)
return;
2008-07-16 12:53:51 +04:00
2008-05-12 11:18:48 +04:00
/* Call IBus Reset method */
2008-07-16 12:53:51 +04:00
_ibus_call_with_reply_and_block (priv->ibus,
"Reset",
2008-07-16 12:53:51 +04:00
DBUS_TYPE_STRING, &ic,
2008-05-12 11:18:48 +04:00
DBUS_TYPE_INVALID,
DBUS_TYPE_INVALID);
}
void
2008-07-16 12:53:51 +04:00
ibus_im_client_set_cursor_location (IBusIMClient *client, IBusIMContext *context, GdkRectangle *area)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
gchar *ic = ibus_im_context_get_ic (context);
2008-07-16 14:36:24 +04:00
if (ic == NULL)
return;
2008-05-12 11:18:48 +04:00
_ibus_call_with_reply_and_block (client->priv->ibus,
2008-05-12 11:18:48 +04:00
"SetCursorLocation",
2008-07-16 12:53:51 +04:00
DBUS_TYPE_STRING, &ic,
2008-05-12 11:18:48 +04:00
DBUS_TYPE_INT32, &area->x,
DBUS_TYPE_INT32, &area->y,
DBUS_TYPE_INT32, &area->width,
DBUS_TYPE_INT32, &area->height,
DBUS_TYPE_INVALID,
DBUS_TYPE_INVALID);
}
2008-07-23 11:12:48 +04:00
void
ibus_im_client_set_use_preedit (IBusIMClient *client, IBusIMContext *context, gboolean use_preedit)
{
IBusIMClientPrivate *priv = client->priv;
gchar *ic = ibus_im_context_get_ic (context);
if (ic == NULL)
return;
_ibus_call_with_reply_and_block (client->priv->ibus,
"SetCapabilities",
DBUS_TYPE_STRING, &ic,
DBUS_TYPE_INT32, &use_preedit,
DBUS_TYPE_INVALID,
DBUS_TYPE_INVALID);
}
2008-05-12 11:18:48 +04:00
2008-07-16 12:53:51 +04:00
void
ibus_im_client_release_im_context (IBusIMClient *client, IBusIMContext *context)
2008-05-12 11:18:48 +04:00
{
2008-06-19 11:48:09 +04:00
IBusIMClientPrivate *priv = client->priv;
2008-07-16 12:53:51 +04:00
gchar *ic = ibus_im_context_get_ic (context);
priv->contexts = g_list_remove (priv->contexts, context);
if (ic) {
g_hash_table_remove (priv->ic_table, ic);
_ibus_call_with_reply_and_block (priv->ibus, "ReleaseInputContext",
DBUS_TYPE_STRING, &ic,
DBUS_TYPE_INVALID,
DBUS_TYPE_INVALID);
2008-05-12 11:18:48 +04:00
}
2008-05-12 11:18:48 +04:00
}
2008-08-07 06:52:10 +04:00
void
ibus_im_client_kill_daemon (IBusIMClient *client)
{
IBusIMClientPrivate *priv = client->priv;
_ibus_call_with_reply_and_block (priv->ibus, "Kill",
DBUS_TYPE_INVALID,
DBUS_TYPE_INVALID);
}
gboolean
ibus_im_client_get_connected (IBusIMClient *client)
{
IBusIMClientPrivate *priv = client->priv;
if (priv->ibus == NULL)
return FALSE;
return dbus_connection_get_is_connected (priv->ibus);
}