diff options
author | Huang Peng <shawn.p.huang@gmail.com> | 2009-02-05 10:39:56 +0800 |
---|---|---|
committer | Huang Peng <shawn.p.huang@gmail.com> | 2009-02-05 10:39:56 +0800 |
commit | aedad1ea0a7fef604aa27f4b58433fd8f2ece29e (patch) | |
tree | ffcb531d8474bde18b90341bcd4eb639edd74525 /client | |
parent | 41ad46305a88637dd99f00a2d2a3f455505d357b (diff) | |
download | ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.tar.gz ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.tar.xz ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.zip |
re-implement ibus in c language.
Diffstat (limited to 'client')
-rw-r--r-- | client/Makefile.am | 2 | ||||
-rw-r--r-- | client/gtk2/Makefile.am | 12 | ||||
-rw-r--r-- | client/gtk2/ibusim.c | 25 | ||||
-rw-r--r-- | client/gtk2/ibusimcontext.c | 508 | ||||
-rw-r--r-- | client/x11/.gitignore | 1 | ||||
-rw-r--r-- | client/x11/Makefile.am | 14 | ||||
-rw-r--r-- | client/x11/main.c | 254 |
7 files changed, 444 insertions, 372 deletions
diff --git a/client/Makefile.am b/client/Makefile.am index c7bd313..0eaf3dc 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -21,6 +21,6 @@ SUBDIRS = \ gtk2 \ - qt4 \ x11 \ + qt4 \ $(NULL) diff --git a/client/gtk2/Makefile.am b/client/gtk2/Makefile.am index b5c251b..2a4eb8b 100644 --- a/client/gtk2/Makefile.am +++ b/client/gtk2/Makefile.am @@ -19,10 +19,10 @@ # Free Software Foundation, Inc., 59 Temple Place, Suite 330, # Boston, MA 02111-1307 USA -libibus_gtk = $(top_builddir)/lib/gtk2/libibus-gtk.la +libibus = $(top_builddir)/src/libibus.la INCLUDES = \ - -I$(top_srcdir)/lib/gtk2 \ + -I$(top_srcdir)/src \ $(NULL) immoduledir = @GTK_IM_MODULEDIR@ @@ -34,8 +34,8 @@ im_ibus_la_SOURCES = \ ibusimcontext.h \ $(NULL) -im_ibus_la_DEPENDENCIES = $(libibus_gtk) -im_ibus_la_LIBADD = $(libibus_gtk) +im_ibus_la_DEPENDENCIES = $(libibus) +im_ibus_la_LIBADD = $(libibus) im_ibus_la_CFLAGS = \ @GTK2_CFLAGS@ \ @@ -50,8 +50,8 @@ im_ibus_la_LDFLAGS = \ -module \ $(NULL) -$(libibus_gtk): - (cd $(top_builddir)/lib/gtk2; make ) +$(libibus): + (cd $(top_builddir)/src; make ) EXTRA_DIST = \ $(NULL) diff --git a/client/gtk2/ibusim.c b/client/gtk2/ibusim.c index 30d84b8..c2951ca 100644 --- a/client/gtk2/ibusim.c +++ b/client/gtk2/ibusim.c @@ -21,7 +21,7 @@ #include <glib/gprintf.h> #include <gtk/gtk.h> #include <gtk/gtkimmodule.h> -#include "ibusimclient.h" +#include <ibus.h> #include "ibusimcontext.h" #define IBUS_LOCALDIR "" @@ -38,19 +38,22 @@ static const GtkIMContextInfo * info_list[] = { }; +G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module); +const gchar* +g_module_check_init (GModule *module) +{ + return glib_check_version (GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION, + GLIB_MICRO_VERSION); +} + void im_module_init (GTypeModule *type_module) { - ibus_im_client_register_type(type_module); - ibus_im_context_register_type(type_module); -#if 0 - gchar **p = environ; - extern gchar **environ; - while (*p != NULL) { - g_fprintf (stderr, "%s\n", *p); - p ++; - } -#endif + /* make module resident */ + g_type_module_use (type_module); + + ibus_im_context_register_type (type_module); } void diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c index 195c9d9..640d0ea 100644 --- a/client/gtk2/ibusimcontext.c +++ b/client/gtk2/ibusimcontext.c @@ -23,9 +23,8 @@ #include <sys/socket.h> #include <sys/time.h> #include <sys/un.h> +#include <ibus.h> #include "ibusimcontext.h" -#include "ibusattribute.h" -#include "ibusimclient.h" /* IBusIMContextPriv */ struct _IBusIMContextPrivate { @@ -34,7 +33,7 @@ struct _IBusIMContextPrivate { /* enabled */ gboolean enable; - gchar *ic; + IBusInputContext *ibus_context; /* preedit status */ gchar *preedit_string; @@ -56,35 +55,37 @@ static guint _signal_delete_surrounding_id = 0; static guint _signal_retrieve_surrounding_id = 0; /* functions prototype */ -static void ibus_im_context_class_init (IBusIMContextClass *klass); -static void ibus_im_context_init (IBusIMContext *obj); -static void ibus_im_context_finalize (GObject *obj); -static void ibus_im_context_reset (GtkIMContext *context); +static void ibus_im_context_class_init (IBusIMContextClass *klass); +static void ibus_im_context_init (GObject *obj); +static void ibus_im_context_finalize (GObject *obj); +static void ibus_im_context_reset (GtkIMContext *context); static gboolean ibus_im_context_filter_keypress - (GtkIMContext *context, - GdkEventKey *key); -static void ibus_im_context_focus_in (GtkIMContext *context); -static void ibus_im_context_focus_out (GtkIMContext *context); + (GtkIMContext *context, + GdkEventKey *key); +static void ibus_im_context_focus_in (GtkIMContext *context); +static void ibus_im_context_focus_out (GtkIMContext *context); static void ibus_im_context_get_preedit_string - (GtkIMContext *context, - gchar **str, - PangoAttrList **attrs, - gint *cursor_pos); + (GtkIMContext *context, + gchar **str, + PangoAttrList **attrs, + gint *cursor_pos); static void ibus_im_context_set_client_window - (GtkIMContext *context, - GdkWindow *client); + (GtkIMContext *context, + GdkWindow *client); static void ibus_im_context_set_cursor_location - (GtkIMContext *context, - GdkRectangle *area); + (GtkIMContext *context, + GdkRectangle *area); static void ibus_im_context_set_use_preedit - (GtkIMContext *context, - gboolean use_preedit); + (GtkIMContext *context, + gboolean use_preedit); /* static methods*/ -static void _init_ibus_client (void); -static void _set_cursor_location_internal +static void _create_input_context (IBusIMContext *context); +static void _set_cursor_location_internal (GtkIMContext *context); +static void _bus_connected_cb (IBusBus *bus, + IBusIMContext *context); /* callback functions for slave context */ static void _slave_commit_cb (GtkIMContext *slave, gchar *string, @@ -109,9 +110,7 @@ static void _slave_delete_surrounding_cb static GType _ibus_type_im_context = 0; static GtkIMContextClass *parent_class = NULL; -static IBusIMClient *_client = NULL; -static GHashTable *_ic_table = NULL; -static GArray *_im_context_array = NULL; +static IBusBus *_bus = NULL; void ibus_im_context_register_type (GTypeModule *type_module) @@ -210,16 +209,16 @@ ibus_im_context_class_init (IBusIMContextClass *klass) _signal_retrieve_surrounding_id = g_signal_lookup ("retrieve-surrounding", G_TYPE_FROM_CLASS (klass)); g_assert (_signal_retrieve_surrounding_id != 0); + } static void -ibus_im_context_init (IBusIMContext *obj) +ibus_im_context_init (GObject *obj) { - _init_ibus_client (); - IBusIMContext *ibus = IBUS_IM_CONTEXT (obj); - IBusIMContextPrivate *priv = ibus->priv = - G_TYPE_INSTANCE_GET_PRIVATE (ibus, IBUS_TYPE_IM_CONTEXT, IBusIMContextPrivate); + IBusIMContext *ibuscontext = IBUS_IM_CONTEXT (obj); + IBusIMContextPrivate *priv = ibuscontext->priv = + G_TYPE_INSTANCE_GET_PRIVATE (ibuscontext, IBUS_TYPE_IM_CONTEXT, IBusIMContextPrivate); priv->client_window = NULL; @@ -238,34 +237,47 @@ ibus_im_context_init (IBusIMContext *obj) priv->cursor_area.width = 0; priv->cursor_area.height = 0; - priv->ic = NULL; + priv->ibus_context = NULL; priv->has_focus = FALSE; - priv->caps = IBUS_CAP_PREEDIT | IBUS_CAP_FOCUS; + priv->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS; // Create slave im context - ibus->priv->slave = gtk_im_context_simple_new (); - g_signal_connect (ibus->priv->slave, - "commit", G_CALLBACK (_slave_commit_cb), obj); - g_signal_connect (ibus->priv->slave, - "preedit-start", G_CALLBACK (_slave_preedit_start_cb), obj); - g_signal_connect (ibus->priv->slave, - "preedit-end", G_CALLBACK (_slave_preedit_end_cb), obj); - g_signal_connect (ibus->priv->slave, - "preedit-changed", G_CALLBACK (_slave_preedit_changed_cb), obj); - g_signal_connect (ibus->priv->slave, - "retrieve-surrounding", G_CALLBACK (_slave_retrieve_surrounding_cb), obj); - g_signal_connect (ibus->priv->slave, - "delete-surrounding", G_CALLBACK (_slave_delete_surrounding_cb), obj); - - g_array_append_val (_im_context_array, obj); - - if (ibus_im_client_get_connected (_client)) { - const gchar *ic = ibus_im_client_create_input_context (_client); - ibus_im_context_set_ic (ibus, ic); - g_hash_table_insert (_ic_table, - (gpointer) ibus_im_context_get_ic (ibus), (gpointer) ibus); - } + priv->slave = gtk_im_context_simple_new (); + g_signal_connect (priv->slave, + "commit", + G_CALLBACK (_slave_commit_cb), + ibuscontext); + g_signal_connect (priv->slave, + "preedit-start", + G_CALLBACK (_slave_preedit_start_cb), + ibuscontext); + g_signal_connect (priv->slave, + "preedit-end", + G_CALLBACK (_slave_preedit_end_cb), + ibuscontext); + g_signal_connect (priv->slave, + "preedit-changed", + G_CALLBACK (_slave_preedit_changed_cb), + ibuscontext); + g_signal_connect (priv->slave, + "retrieve-surrounding", + G_CALLBACK (_slave_retrieve_surrounding_cb), + ibuscontext); + g_signal_connect (priv->slave, + "delete-surrounding", + G_CALLBACK (_slave_delete_surrounding_cb), + ibuscontext); + + /* init bus object */ + if (_bus == NULL) + _bus = ibus_bus_new(); + + if (ibus_bus_is_connected (_bus)) { + _create_input_context (ibuscontext); + } + + g_signal_connect (_bus, "connected", G_CALLBACK (_bus_connected_cb), obj); } static void @@ -277,18 +289,10 @@ ibus_im_context_finalize (GObject *obj) IBusIMContext *ibus = IBUS_IM_CONTEXT (obj); IBusIMContextPrivate *priv = ibus->priv; - gint i; - for (i = 0; i < _im_context_array->len; i++) { - if (obj == g_array_index (_im_context_array, GObject *, i)) { - g_array_remove_index_fast (_im_context_array, i); - break; - } - } + g_signal_handlers_disconnect_by_func (_bus, G_CALLBACK (_bus_connected_cb), obj); - if (priv->ic) { - ibus_im_client_release_input_context (_client, priv->ic); - g_hash_table_remove (_ic_table, priv->ic); - g_free (priv->ic); + if (priv->ibus_context) { + ibus_object_destroy (priv->ibus_context); } g_object_unref (priv->slave); @@ -318,12 +322,26 @@ ibus_im_context_filter_keypress (GtkIMContext *context, IBusIMContext *ibus = IBUS_IM_CONTEXT (context); IBusIMContextPrivate *priv = ibus->priv; - if (priv->ic && priv->has_focus) { + if (priv->ibus_context && priv->has_focus) { /* If context does not have focus, ibus will process key event in sync mode. * It is a workaround for increase search in treeview. */ - gboolean retval = ibus_im_client_filter_keypress (_client, - priv->ic, event, FALSE); + gboolean retval; + switch (event->type) { + case GDK_KEY_RELEASE: + retval = ibus_input_context_process_key_event (priv->ibus_context, + event->keyval, + event->state | IBUS_RELEASE_MASK); + break; + case GDK_KEY_PRESS: + retval = ibus_input_context_process_key_event (priv->ibus_context, + event->keyval, + event->state); + break; + default: + retval = FALSE; + } + if (retval) { return TRUE; } @@ -337,15 +355,17 @@ ibus_im_context_filter_keypress (GtkIMContext *context, static void ibus_im_context_focus_in (GtkIMContext *context) { - g_return_if_fail (context != NULL); - g_return_if_fail (IBUS_IS_IM_CONTEXT (context)); + g_assert (IBUS_IS_IM_CONTEXT (context)); - IBusIMContext *ibus = IBUS_IM_CONTEXT (context); - IBusIMContextPrivate *priv = ibus->priv; + IBusIMContext *ibuscontext; + IBusIMContextPrivate *priv; + + ibuscontext = IBUS_IM_CONTEXT (context); + priv = ibuscontext->priv; priv->has_focus = TRUE; - if (priv->ic) { - ibus_im_client_focus_in (_client, priv->ic); + if (priv->ibus_context) { + ibus_input_context_focus_in (priv->ibus_context); } gtk_im_context_focus_in (priv->slave); @@ -356,15 +376,18 @@ ibus_im_context_focus_in (GtkIMContext *context) static void ibus_im_context_focus_out (GtkIMContext *context) { - g_return_if_fail (context != NULL); - g_return_if_fail (IBUS_IS_IM_CONTEXT (context)); - IBusIMContext *ibus = IBUS_IM_CONTEXT (context); - IBusIMContextPrivate *priv = ibus->priv; + g_assert (IBUS_IS_IM_CONTEXT (context)); + + IBusIMContext *ibuscontext; + IBusIMContextPrivate *priv; + + ibuscontext = IBUS_IM_CONTEXT (context); + priv = ibuscontext->priv; priv->has_focus = FALSE; - if (priv->ic) { - ibus_im_client_focus_out (_client, priv->ic); + if (priv->ibus_context) { + ibus_input_context_focus_out (priv->ibus_context); } gtk_im_context_focus_out (priv->slave); } @@ -372,14 +395,16 @@ ibus_im_context_focus_out (GtkIMContext *context) static void ibus_im_context_reset (GtkIMContext *context) { - g_return_if_fail (context != NULL); - g_return_if_fail (IBUS_IS_IM_CONTEXT (context)); + g_assert (IBUS_IS_IM_CONTEXT (context)); - IBusIMContext *ibus = IBUS_IM_CONTEXT (context); - IBusIMContextPrivate *priv = ibus->priv; + IBusIMContext *ibuscontext; + IBusIMContextPrivate *priv; - if (priv->ic) { - ibus_im_client_reset (_client, priv->ic); + ibuscontext = IBUS_IM_CONTEXT (context); + priv = ibuscontext->priv; + + if (priv->ibus_context) { + ibus_input_context_reset (priv->ibus_context); } gtk_im_context_reset (priv->slave); } @@ -387,15 +412,17 @@ ibus_im_context_reset (GtkIMContext *context) static void ibus_im_context_get_preedit_string (GtkIMContext *context, - gchar **str, - PangoAttrList **attrs, - gint *cursor_pos) + gchar **str, + PangoAttrList **attrs, + gint *cursor_pos) { - g_return_if_fail (context != NULL); - g_return_if_fail (IBUS_IS_IM_CONTEXT (context)); + g_assert (IBUS_IS_IM_CONTEXT (context)); - IBusIMContext *ibus = IBUS_IM_CONTEXT (context); - IBusIMContextPrivate *priv = ibus->priv; + IBusIMContext *ibuscontext; + IBusIMContextPrivate *priv; + + ibuscontext = IBUS_IM_CONTEXT (context); + priv = ibuscontext->priv; if (priv->enable) { if (priv->preedit_visible) { @@ -460,7 +487,7 @@ _set_cursor_location_internal (GtkIMContext *context) GdkRectangle area; gint x, y; - if(priv->client_window == NULL || priv->ic == NULL) { + if(priv->client_window == NULL || priv->ibus_context == NULL) { return; } @@ -475,7 +502,11 @@ _set_cursor_location_internal (GtkIMContext *context) gdk_window_get_origin (priv->client_window, &x, &y); area.x += x; area.y += y; - ibus_im_client_set_cursor_location (_client, priv->ic, &area); + ibus_input_context_set_cursor_location (priv->ibus_context, + area.x, + area.y, + area.width, + area.height); } static void @@ -501,96 +532,84 @@ ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) IBusIMContext *ibus = IBUS_IM_CONTEXT (context); IBusIMContextPrivate *priv = ibus->priv; - if(priv->ic) { + if(priv->ibus_context) { if (use_preedit) { - priv->caps |= IBUS_CAP_PREEDIT; + priv->caps |= IBUS_CAP_PREEDIT_TEXT; } else { - priv->caps &= ~IBUS_CAP_PREEDIT; + priv->caps &= ~IBUS_CAP_PREEDIT_TEXT; } - ibus_im_client_set_capabilities (_client, priv->ic, priv->caps); + ibus_input_context_set_capabilities (priv->ibus_context, priv->caps); } gtk_im_context_set_use_preedit (priv->slave, use_preedit); } static void -_client_connected_cb (IBusIMClient *client, gpointer user_data) -{ - gint i; - const gchar *ic; - IBusIMContext *context; - - for (i = 0; i < _im_context_array->len; i++) { - context = g_array_index (_im_context_array, IBusIMContext *, i); - ic = ibus_im_client_create_input_context (client); - ibus_im_context_set_ic (context, ic); - if (ic == NULL) { - continue; - } - g_hash_table_insert (_ic_table, - (gpointer) ibus_im_context_get_ic (context), (gpointer) context); - } -} - -static void -_client_disconnected_cb (IBusIMClient *client, gpointer user_data) +_bus_connected_cb (IBusBus *bus, + IBusIMContext *context) { - gint i; - IBusIMContext *context; - - g_hash_table_remove_all (_ic_table); - for (i = 0; i < _im_context_array->len; i++) { - context = g_array_index (_im_context_array, IBusIMContext *, i); - ibus_im_context_set_ic (context, NULL); - } + g_assert (IBUS_IS_IM_CONTEXT (context)); + g_assert (context->priv->ibus_context == NULL); + _create_input_context (context); } static void -_client_commit_string_cb (IBusIMClient *client, const gchar *ic, const gchar *string, gpointer user_data) +_ibus_context_commit_text_cb (IBusInputContext *ibus_context, + IBusText *text, + IBusIMContext *context) { - IBusIMContext *context = g_hash_table_lookup (_ic_table, ic); - g_return_if_fail (context != NULL); - - g_signal_emit (context, _signal_commit_id, 0, string); + g_assert (IBUS_IS_INPUT_CONTEXT (ibus_context)); + g_assert (IBUS_IS_TEXT (text)); + g_assert (IBUS_IS_IM_CONTEXT (context)); + g_signal_emit (context, _signal_commit_id, 0, text->text); } static void -_client_forward_event_cb (IBusIMClient *client, const gchar *ic, GdkEvent *event, gpointer user_data) +_ibus_context_forward_key_event_cb (IBusInputContext *ibus_context, + guint keyval, + gboolean is_press, + guint state, + IBusIMContext *context) { - IBusIMContext *context = g_hash_table_lookup (_ic_table, ic); - g_return_if_fail (context != NULL); + g_assert (IBUS_IS_IM_CONTEXT (context)); - if (event->type == GDK_KEY_PRESS || - event->type == GDK_KEY_RELEASE) { - /* - GTimeVal time; - event->key.time = time.tv_sec * 1000 + time.tv_usec / 1000; - */ - event->key.time = GDK_CURRENT_TIME; - } + GdkEventKey *event; + IBusIMContextPrivate *priv; -#if 0 - if (event->any.window != context->priv->client_window) { - GdkWindow *old_window = event->any.window; - event->any.window = context->priv->client_window; - gdk_event_put (event); - event->any.window = old_window; - } - else -#endif - gdk_event_put (event); + priv = context->priv; + event = (GdkEventKey *)gdk_event_new (is_press ? GDK_KEY_PRESS : GDK_KEY_RELEASE); + + event->time = GDK_CURRENT_TIME; + event->window = g_object_ref (priv->client_window); + event->send_event = FALSE; + event->state = state; + event->keyval = keyval; + event->string = gdk_keyval_name (keyval); + event->length = strlen (event->string); + event->hardware_keycode = 0; + event->group = 0; + event->is_modifier = 0; + + gdk_event_put ((GdkEvent *)event); + gdk_event_free ((GdkEvent *)event); } static void -_client_update_preedit_cb (IBusIMClient *client, const gchar *ic, const gchar *string, - IBusAttrList *attr_list, gint cursor_pos, gboolean visible, gpointer user_data) +_ibus_context_update_preedit_text_cb (IBusInputContext *ibus_context, + IBusText *text, + gint cursor_pos, + gboolean visible, + IBusIMContext *context) { - IBusIMContext *context = g_hash_table_lookup (_ic_table, ic); - g_return_if_fail (context != NULL); + g_assert (IBUS_IS_INPUT_CONTEXT (ibus_context)); + g_assert (IBUS_IS_TEXT (text)); + g_assert (IBUS_IS_IM_CONTEXT (context)); - IBusIMContextPrivate *priv = context->priv; + IBusIMContextPrivate *priv; + priv = context->priv; + const gchar *str; if (priv->preedit_string) { g_free (priv->preedit_string); @@ -600,12 +619,13 @@ _client_update_preedit_cb (IBusIMClient *client, const gchar *ic, const gchar *s priv->preedit_attrs = NULL; } - priv->preedit_string = g_strdup (string); - if (attr_list) { + str = text->text; + priv->preedit_string = g_strdup (str); + if (text->attrs) { guint i; priv->preedit_attrs = pango_attr_list_new (); for (i = 0; ; i++) { - IBusAttribute *attr = ibus_attr_list_get (attr_list, i); + IBusAttribute *attr = ibus_attr_list_get (text->attrs, i); if (attr == NULL) { break; } @@ -630,8 +650,8 @@ _client_update_preedit_cb (IBusIMClient *client, const gchar *ic, const gchar *s default: continue; } - pango_attr->start_index = g_utf8_offset_to_pointer (string, attr->start_index) - string; - pango_attr->end_index = g_utf8_offset_to_pointer (string, attr->end_index) - string; + pango_attr->start_index = g_utf8_offset_to_pointer (str, attr->start_index) - str; + pango_attr->end_index = g_utf8_offset_to_pointer (str, attr->end_index) - str; pango_attr_list_insert (priv->preedit_attrs, pango_attr); } } @@ -641,11 +661,10 @@ _client_update_preedit_cb (IBusIMClient *client, const gchar *ic, const gchar *s } static void -_client_show_preedit_cb (IBusIMClient *client, const gchar *ic, gpointer user_data) +_ibus_context_show_preedit_text_cb (IBusInputContext *ibus_context, + IBusIMContext *context) { - IBusIMContext *context = g_hash_table_lookup (_ic_table, ic); - g_return_if_fail (context != NULL); - + g_assert (IBUS_IS_IM_CONTEXT (context)); IBusIMContextPrivate *priv = context->priv; if (priv->preedit_visible == FALSE) { @@ -655,11 +674,10 @@ _client_show_preedit_cb (IBusIMClient *client, const gchar *ic, gpointer user_da } static void -_client_hide_preedit_cb (IBusIMClient *client, const gchar *ic, gpointer user_data) +_ibus_context_hide_preedit_text_cb (IBusInputContext *ibus_context, + IBusIMContext *context) { - IBusIMContext *context = g_hash_table_lookup (_ic_table, ic); - g_return_if_fail (context != NULL); - + g_assert (IBUS_IS_IM_CONTEXT (context)); IBusIMContextPrivate *priv = context->priv; if (priv->preedit_visible == TRUE) { @@ -669,62 +687,88 @@ _client_hide_preedit_cb (IBusIMClient *client, const gchar *ic, gpointer user_da } static void -_client_enabled_cb (IBusIMClient *client, const gchar *ic, gpointer user_data) +_ibus_context_enabled_cb (IBusInputContext *ibus_context, + IBusIMContext *context) { - IBusIMContext *context = g_hash_table_lookup (_ic_table, ic); - g_return_if_fail (context != NULL); - + g_assert (IBUS_IS_IM_CONTEXT (context)); IBusIMContextPrivate *priv = context->priv; - if (priv->enable == FALSE) { - priv->enable = TRUE; - } + priv->enable = TRUE; } static void -_client_disabled_cb (IBusIMClient *client, const gchar *ic, gpointer user_data) +_ibus_context_disabled_cb (IBusInputContext *ibus_context, + IBusIMContext *context) { - IBusIMContext *context = g_hash_table_lookup (_ic_table, ic); - g_return_if_fail (context != NULL); - + g_assert (IBUS_IS_IM_CONTEXT (context)); IBusIMContextPrivate *priv = context->priv; - if (priv->enable == TRUE) { - priv->enable = FALSE; - } + priv->enable = FALSE; } static void -_init_ibus_client (void) +_ibus_context_destroy_cb (IBusInputContext *ibus_context, + IBusIMContext *context) { - if (_client != NULL) { - return; - } + g_assert (IBUS_IS_IM_CONTEXT (context)); - _im_context_array = g_array_new (TRUE, TRUE, sizeof (IBusIMContext *)); - _ic_table = g_hash_table_new (g_str_hash, g_str_equal); + IBusIMContextPrivate *priv = context->priv; - _client = ibus_im_client_new (); + g_assert (priv->ibus_context == ibus_context); - g_signal_connect (_client, "connected", - G_CALLBACK (_client_connected_cb), NULL); - g_signal_connect (_client, "disconnected", - G_CALLBACK (_client_disconnected_cb), NULL); - g_signal_connect (_client, "commit-string", - G_CALLBACK (_client_commit_string_cb), NULL); - g_signal_connect (_client, "forward-event", - G_CALLBACK (_client_forward_event_cb), NULL); - g_signal_connect (_client, "update-preedit", - G_CALLBACK (_client_update_preedit_cb), NULL); - g_signal_connect (_client, "show-preedit", - G_CALLBACK (_client_show_preedit_cb), NULL); - g_signal_connect (_client, "hide-preedit", - G_CALLBACK (_client_hide_preedit_cb), NULL); - g_signal_connect (_client, "enabled", - G_CALLBACK (_client_enabled_cb), NULL); - g_signal_connect (_client, "disabled", - G_CALLBACK (_client_disabled_cb), NULL); + g_object_unref (priv->ibus_context); + priv->ibus_context = NULL; + priv->enable = FALSE; +} +static void +_create_input_context (IBusIMContext *context) +{ + g_assert (IBUS_IS_IM_CONTEXT (context)); + g_assert (context->priv->ibus_context == NULL); + + IBusIMContextPrivate *priv; + priv = context->priv; + + priv->ibus_context = ibus_bus_create_input_context (_bus, "test"); + + g_signal_connect (priv->ibus_context, + "commit-text", + G_CALLBACK (_ibus_context_commit_text_cb), + context); + g_signal_connect (priv->ibus_context, + "forward-key-event", + G_CALLBACK (_ibus_context_forward_key_event_cb), + context); + g_signal_connect (priv->ibus_context, + "update-preedit-text", + G_CALLBACK (_ibus_context_update_preedit_text_cb), + context); + g_signal_connect (priv->ibus_context, + "show-preedit-text", + G_CALLBACK (_ibus_context_show_preedit_text_cb), + context); + g_signal_connect (priv->ibus_context, + "hide-preedit-text", + G_CALLBACK (_ibus_context_hide_preedit_text_cb), + context); + g_signal_connect (priv->ibus_context, + "enabled", + G_CALLBACK (_ibus_context_enabled_cb), + context); + g_signal_connect (priv->ibus_context, + "disabled", + G_CALLBACK (_ibus_context_disabled_cb), + context); + g_signal_connect (priv->ibus_context, "destroy", + G_CALLBACK (_ibus_context_destroy_cb), + context); + + ibus_input_context_set_capabilities (priv->ibus_context, priv->caps); + + if (priv->has_focus) { + ibus_input_context_focus_in (priv->ibus_context); + } } /* Callback functions for slave context */ @@ -750,7 +794,7 @@ _slave_preedit_changed_cb (GtkIMContext *slave, IBusIMContext *context) IBusIMContextPrivate *priv = context->priv; - if (priv->enable && priv->ic) { + if (priv->enable && priv->ibus_context) { return; } @@ -765,7 +809,7 @@ _slave_preedit_start_cb (GtkIMContext *slave, IBusIMContext *context) IBusIMContextPrivate *priv = context->priv; - if (priv->enable && priv->ic) { + if (priv->enable && priv->ibus_context) { return; } g_signal_emit (context, _signal_preedit_start_id, 0); @@ -779,7 +823,7 @@ _slave_preedit_end_cb (GtkIMContext *slave, IBusIMContext *context) IBusIMContextPrivate *priv = context->priv; - if (priv->enable && priv->ic) { + if (priv->enable && priv->ibus_context) { return; } g_signal_emit (context, _signal_preedit_end_id, 0); @@ -793,7 +837,7 @@ _slave_retrieve_surrounding_cb (GtkIMContext *slave, IBusIMContext *context) IBusIMContextPrivate *priv = context->priv; - if (priv->enable && priv->ic) { + if (priv->enable && priv->ibus_context) { return; } g_signal_emit (context, _signal_retrieve_surrounding_id, 0); @@ -807,44 +851,12 @@ _slave_delete_surrounding_cb (GtkIMContext *slave, gint a1, gint a2, IBusIMConte IBusIMContextPrivate *priv = context->priv; - if (priv->enable && priv->ic) { + if (priv->enable && priv->ibus_context) { return; } g_signal_emit (context, _signal_delete_surrounding_id, 0, a1, a2); } -const gchar * -ibus_im_context_get_ic (IBusIMContext *context) -{ - g_return_val_if_fail (context != NULL, NULL); - g_return_val_if_fail (IBUS_IS_IM_CONTEXT (context), NULL); - - IBusIMContextPrivate *priv = context->priv; - return priv->ic; -} - -void -ibus_im_context_set_ic (IBusIMContext *context, const gchar *ic) -{ - g_return_if_fail (context != NULL); - g_return_if_fail (IBUS_IS_IM_CONTEXT (context)); - - IBusIMContextPrivate *priv = context->priv; - - g_free (priv->ic); - priv->ic = g_strdup (ic); - - if (priv->ic == NULL) { - priv->enable = FALSE; - } - else { - ibus_im_client_set_capabilities (_client, priv->ic, priv->caps); - if (priv->has_focus) { - ibus_im_context_focus_in (GTK_IM_CONTEXT (context)); - } - } -} - void ibus_im_context_show_preedit (IBusIMContext *context) { diff --git a/client/x11/.gitignore b/client/x11/.gitignore new file mode 100644 index 0000000..bdff9a1 --- /dev/null +++ b/client/x11/.gitignore @@ -0,0 +1 @@ +ibus-x11 diff --git a/client/x11/Makefile.am b/client/x11/Makefile.am index c50cf7d..bd2efab 100644 --- a/client/x11/Makefile.am +++ b/client/x11/Makefile.am @@ -21,9 +21,9 @@ libIMdkit = $(top_builddir)/util/IMdkit/libIMdkit.la -libibus_gtk = $(top_builddir)/lib/gtk2/libibus-gtk.la +libibus = $(top_builddir)/src/libibus.la -bin_PROGRAMS = ibus-x11 +libexec_PROGRAMS = ibus-x11 ibus_x11_SOURCES = \ main.c \ @@ -32,12 +32,12 @@ ibus_x11_SOURCES = \ ibus_x11_DEPENDENCIES = \ $(libIMdkit) \ - $(libibus_gtk) \ + $(libibus) \ $(NULL) ibus_x11_LDADD = \ $(libIMdkit) \ - $(libibus_gtk) \ + $(libibus) \ $(NULL) ibus_x11_LDFLAGS = \ @@ -48,7 +48,7 @@ ibus_x11_CFLAGS = \ @GTK2_CFLAGS@ \ @DBUS_CFLAGS@ \ -I$(top_srcdir)/util/IMdkit \ - -I$(top_srcdir)/lib/gtk2 \ + -I$(top_srcdir)/src \ $(NULL) noinst_HEADERS = \ @@ -58,6 +58,6 @@ noinst_HEADERS = \ $(IMdkit): (cd $(top_builddir)/util/IMdkit; make) -$(libibus_gtk): - (cd $(top_builddir)/lib/gtk2; make) +$(libibus): + (cd $(top_builddir)/src; make) diff --git a/client/x11/main.c b/client/x11/main.c index 30b5ad8..734c898 100644 --- a/client/x11/main.c +++ b/client/x11/main.c @@ -44,8 +44,7 @@ g_debug (fmt_args); \ } -#include <ibusattribute.h> -#include <ibusimclient.h> +#include <ibus.h> #include "gdk-private.h" struct _X11ICONN { @@ -53,32 +52,53 @@ struct _X11ICONN { }; typedef struct _X11ICONN X11ICONN; +typedef struct _X11IC X11IC; struct _X11IC { - gchar *ibus_ic; - Window client_window; - Window focus_window; - gint32 input_style; - X11ICONN *conn; - gint icid; - gint connect_id; - gchar *lang; - gboolean has_preedit_area; - GdkRectangle preedit_area; + IBusInputContext *context; + Window client_window; + Window focus_window; + gint32 input_style; + X11ICONN *conn; + gint icid; + gint connect_id; + gchar *lang; + gboolean has_preedit_area; + GdkRectangle preedit_area; gchar *preedit_string; IBusAttrList *preedit_attrs; - gint preedit_cursor; - gboolean preedit_visible; - gboolean preedit_started; - gint onspot_preedit_length; + gint preedit_cursor; + gboolean preedit_visible; + gboolean preedit_started; + gint onspot_preedit_length; }; -typedef struct _X11IC X11IC; - -static void _xim_set_cursor_location (X11IC *x11ic); +static void _xim_set_cursor_location (X11IC *x11ic); +static void _context_commit_text_cb (IBusInputContext *context, + IBusText *text, + X11IC *x11ic); +static void _context_forward_key_event_cb + (IBusInputContext *context, + X11IC *x11ic); + +static void _context_update_preedit_text_cb + (IBusInputContext *context, + IBusText *text, + gint cursor_pos, + gboolean visible, + X11IC *x11ic); +static void _context_show_preedit_text_cb + (IBusInputContext *context, + X11IC *x11ic); +static void _context_hide_preedit_text_cb + (IBusInputContext *context, + X11IC *x11ic); +static void _context_enabled_cb (IBusInputContext *context, + X11IC *x11ic); +static void _context_disabled_cb (IBusInputContext *context, + X11IC *x11ic); static GHashTable *_x11_ic_table = NULL; -static GHashTable *_ibus_ic_table = NULL; static GHashTable *_connections = NULL; static XIMS _xims = NULL; static gchar _server_name[128] = "ibus"; @@ -95,9 +115,9 @@ static gchar _locale[1024] = "uk,ur,uz,ve,vi,wa,xh,yi,zh,zu"; static gboolean _kill_daemon = FALSE; -static gint g_debug_level = 0; +static gint g_debug_level = 0; -static IBusIMClient *_client = NULL; +static IBusBus *_bus = NULL; static void _xim_preedit_start (XIMS xims, const X11IC *x11ic) @@ -315,21 +335,35 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data) i = _xim_store_ic_values (x11ic, call_data); - x11ic->ibus_ic = g_strdup (ibus_im_client_create_input_context (_client)); - if (x11ic->ibus_ic == NULL) { + x11ic->context = ibus_bus_create_input_context (_bus, "xim"); + + if (x11ic->context == NULL) { g_slice_free (X11IC, x11ic); g_return_val_if_reached (0); } - g_hash_table_insert (_ibus_ic_table, x11ic->ibus_ic, (gpointer)x11ic); + g_signal_connect (x11ic->context, "commit-text", + G_CALLBACK (_context_commit_text_cb), x11ic); + g_signal_connect (x11ic->context, "forward-key-event", + G_CALLBACK (_context_forward_key_event_cb), x11ic); + + g_signal_connect (x11ic->context, "update-preedit-text", + G_CALLBACK (_context_update_preedit_text_cb), x11ic); + g_signal_connect (x11ic->context, "show-preedit-text", + G_CALLBACK (_context_show_preedit_text_cb), x11ic); + g_signal_connect (x11ic->context, "hide-preedit-text", + G_CALLBACK (_context_hide_preedit_text_cb), x11ic); + g_signal_connect (x11ic->context, "enabled", + G_CALLBACK (_context_enabled_cb), x11ic); + g_signal_connect (x11ic->context, "disabled", + G_CALLBACK (_context_disabled_cb), x11ic); + if (x11ic->input_style & XIMPreeditCallbacks) { - ibus_im_client_set_capabilities (_client, x11ic->ibus_ic, - IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT); + ibus_input_context_set_capabilities (x11ic->context, IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT); } else { - ibus_im_client_set_capabilities (_client, x11ic->ibus_ic, - IBUS_CAP_FOCUS); + ibus_input_context_set_capabilities (x11ic->context, IBUS_CAP_FOCUS); } g_hash_table_insert (_x11_ic_table, @@ -352,16 +386,23 @@ xim_destroy_ic (XIMS xims, IMChangeICStruct *call_data) (gconstpointer)(unsigned long)call_data->icid); g_return_val_if_fail (x11ic != NULL, 0); - ibus_im_client_release_input_context (_client, x11ic->ibus_ic); + if (x11ic->context) { + ibus_object_destroy ((IBusObject *)x11ic->context); + g_object_unref (x11ic->context); + x11ic->context = NULL; + } - g_hash_table_remove (_ibus_ic_table, x11ic->ibus_ic); g_hash_table_remove (_x11_ic_table, (gconstpointer)(unsigned long)call_data->icid); x11ic->conn->clients = g_list_remove (x11ic->conn->clients, (gconstpointer)x11ic); g_free (x11ic->preedit_string); - ibus_attr_list_unref (x11ic->preedit_attrs); - g_free (x11ic->ibus_ic); + x11ic->preedit_string = NULL; + + if (x11ic->preedit_attrs) { + g_object_unref (x11ic->preedit_attrs); + x11ic->preedit_attrs = NULL; + } g_slice_free (X11IC, x11ic); @@ -380,7 +421,7 @@ xim_set_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) (gconstpointer)(unsigned long)call_data->icid); g_return_val_if_fail (x11ic != NULL, 0); - ibus_im_client_focus_in (_client, x11ic->ibus_ic); + ibus_input_context_focus_in (x11ic->context); _xim_set_cursor_location (x11ic); return 1; @@ -398,7 +439,7 @@ xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) (gconstpointer)(unsigned long)call_data->icid); g_return_val_if_fail (x11ic != NULL, 0); - ibus_im_client_focus_out (_client, x11ic->ibus_ic); + ibus_input_context_focus_out (x11ic->context); return 1; @@ -426,8 +467,12 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) event.send_event = xevent->send_event; event.window = NULL; - if (ibus_im_client_filter_keypress (_client, - x11ic->ibus_ic, &event, False)) { + if (event.type == GDK_KEY_RELEASE) { + event.state |= IBUS_RELEASE_MASK; + } + + if (ibus_input_context_process_key_event (x11ic->context, + event.keyval, event.state)) { if (! x11ic->has_preedit_area) { _xim_set_cursor_location (x11ic); } @@ -479,12 +524,19 @@ _free_ic (gpointer data, gpointer user_data) g_return_if_fail (x11ic != NULL); g_free (x11ic->preedit_string); - ibus_attr_list_unref (x11ic->preedit_attrs); - g_free (x11ic->ibus_ic); + + if (x11ic->preedit_attrs) { + g_object_unref (x11ic->preedit_attrs); + x11ic->preedit_attrs = NULL; + } + + if (x11ic->context) { + ibus_object_destroy ((IBusObject *)x11ic->context); + g_object_unref (x11ic->context); + x11ic->context = NULL; + } /* Remove the IC from g_client dictionary */ - g_hash_table_remove (_ibus_ic_table, - (gconstpointer)(unsigned long)x11ic->ibus_ic); g_hash_table_remove (_x11_ic_table, (gconstpointer)(unsigned long)x11ic->icid); @@ -551,8 +603,11 @@ _xim_set_cursor_location (X11IC *x11ic) } } - ibus_im_client_set_cursor_location (_client, - x11ic->ibus_ic, &preedit_area); + ibus_input_context_set_cursor_location (x11ic->context, + preedit_area.x, + preedit_area.y, + preedit_area.width, + preedit_area.height); } @@ -618,7 +673,7 @@ xim_reset_ic (XIMS xims, IMResetICStruct *call_data) (gconstpointer)(unsigned long)call_data->icid); g_return_val_if_fail (x11ic != NULL, 0); - ibus_im_client_reset (_client, x11ic->ibus_ic); + ibus_input_context_reset (x11ic->context); return 1; } @@ -702,23 +757,29 @@ _xim_forward_gdk_event (GdkEventKey *event, X11IC *x11ic) } static void -_client_disconnected_cb (IBusIMClient *client, gpointer user_data) +_bus_disconnected_cb (IBusBus *bus, + gpointer user_data) { g_warning ("Connection closed by ibus-daemon"); + g_object_unref (_bus); + _bus = NULL; exit(EXIT_SUCCESS); } static void -_client_commit_string_cb (IBusIMClient *client, const gchar *ic, const gchar *string, gpointer user_data) +_context_commit_text_cb (IBusInputContext *context, + IBusText *text, + X11IC *x11ic) { - X11IC *x11ic = g_hash_table_lookup (_ibus_ic_table, ic); - g_return_if_fail (x11ic != NULL); + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + g_assert (IBUS_IS_TEXT (text)); + g_assert (x11ic != NULL); XTextProperty tp; IMCommitStruct cms = {0}; Xutf8TextListToTextProperty (GDK_DISPLAY (), - (gchar **)&string, 1, XCompoundTextStyle, &tp); + (gchar **)&(text->text), 1, XCompoundTextStyle, &tp); cms.major_code = XIM_COMMIT; cms.icid = x11ic->icid; @@ -731,12 +792,12 @@ _client_commit_string_cb (IBusIMClient *client, const gchar *ic, const gchar *st } static void -_client_forward_event_cb (IBusIMClient *client, const gchar *ic, GdkEvent *event, gpointer user_data) +_context_forward_key_event_cb (IBusInputContext *context, + X11IC *x11ic) { - X11IC *x11ic = g_hash_table_lookup (_ibus_ic_table, ic); - g_return_if_fail (x11ic != NULL); + g_assert (x11ic); - _xim_forward_gdk_event (&(event->key), x11ic); + // _xim_forward_gdk_event (&(event->key), x11ic); } static void @@ -759,21 +820,27 @@ _update_preedit (X11IC *x11ic) } static void -_client_update_preedit_cb (IBusIMClient *client, const gchar *ic, const gchar *string, - IBusAttrList *attrs, gint cursor_pos, gboolean visible, gpointer user_data) +_context_update_preedit_text_cb (IBusInputContext *context, + IBusText *text, + gint cursor_pos, + gboolean visible, + X11IC *x11ic) { - X11IC *x11ic = g_hash_table_lookup (_ibus_ic_table, ic); - g_return_if_fail (x11ic != NULL); + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + g_assert (IBUS_IS_TEXT (text)); + g_assert (x11ic); if (x11ic->preedit_string) { g_free(x11ic->preedit_string); } - x11ic->preedit_string = g_strdup(string); + x11ic->preedit_string = g_strdup(text->text); if (x11ic->preedit_attrs) { - ibus_attr_list_unref (x11ic->preedit_attrs); + g_object_unref (x11ic->preedit_attrs); } - x11ic->preedit_attrs = ibus_attr_list_ref(attrs); + + g_object_ref(text->attrs); + x11ic->preedit_attrs = text->attrs; x11ic->preedit_cursor = cursor_pos; x11ic->preedit_visible = visible; @@ -782,74 +849,62 @@ _client_update_preedit_cb (IBusIMClient *client, const gchar *ic, const gchar *s } static void -_client_show_preedit_cb (IBusIMClient *client, const gchar *ic, gpointer user_data) +_context_show_preedit_text_cb (IBusInputContext *context, + X11IC *x11ic) { - X11IC *x11ic = g_hash_table_lookup (_ibus_ic_table, ic); - g_return_if_fail (x11ic != NULL); + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + g_assert (x11ic); x11ic->preedit_visible = TRUE; _update_preedit (x11ic); } static void -_client_hide_preedit_cb (IBusIMClient *client, const gchar *ic, gpointer user_data) +_context_hide_preedit_text_cb (IBusInputContext *context, + X11IC *x11ic) { - X11IC *x11ic = g_hash_table_lookup (_ibus_ic_table, ic); - g_return_if_fail (x11ic != NULL); + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + g_assert (x11ic); x11ic->preedit_visible = FALSE; _update_preedit (x11ic); } static void -_client_enabled_cb (IBusIMClient *client, const gchar *ic, gpointer user_data) +_context_enabled_cb (IBusInputContext *context, + X11IC *x11ic) { - X11IC *x11ic = g_hash_table_lookup (_ibus_ic_table, ic); - g_return_if_fail (x11ic != NULL); + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + g_assert (x11ic); _xim_preedit_start (_xims, x11ic); } static void -_client_disabled_cb (IBusIMClient *client, const gchar *ic, gpointer user_data) +_context_disabled_cb (IBusInputContext *context, + X11IC *x11ic) { - X11IC *x11ic = g_hash_table_lookup (_ibus_ic_table, ic); - g_return_if_fail (x11ic != NULL); + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + g_assert (x11ic); _xim_preedit_end (_xims, x11ic); } static void -_init_ibus_client (void) +_init_ibus (void) { - if (_client != NULL) + if (_bus != NULL) return; + ibus_init (); - ibus_im_client_register_type (NULL); - - _client = ibus_im_client_new (); + _bus = ibus_bus_new (); - if (!ibus_im_client_get_connected (_client)) { + if (!ibus_bus_is_connected (_bus)) { g_error ("Can not connect to ibus-daemon!"); } - g_signal_connect (_client, "disconnected", - G_CALLBACK (_client_disconnected_cb), NULL); - g_signal_connect (_client, "commit-string", - G_CALLBACK (_client_commit_string_cb), NULL); - g_signal_connect (_client, "forward-event", - G_CALLBACK (_client_forward_event_cb), NULL); - - g_signal_connect (_client, "update-preedit", - G_CALLBACK (_client_update_preedit_cb), NULL); - g_signal_connect (_client, "show-preedit", - G_CALLBACK (_client_show_preedit_cb), NULL); - g_signal_connect (_client, "hide-preedit", - G_CALLBACK (_client_hide_preedit_cb), NULL); - g_signal_connect (_client, "enabled", - G_CALLBACK (_client_enabled_cb), NULL); - g_signal_connect (_client, "disabled", - G_CALLBACK (_client_disabled_cb), NULL); + g_signal_connect (_bus, "disconnected", + G_CALLBACK (_bus_disconnected_cb), NULL); } static void @@ -915,9 +970,9 @@ _xim_init_IMdkit () IMFilterEventMask, KeyPressMask | KeyReleaseMask, NULL); - _init_ibus_client (); + _init_ibus (); - if (!ibus_im_client_get_connected (_client)) { + if (!ibus_bus_is_connected (_bus)) { g_warning ("Can not connect to ibus daemon"); exit (1); } @@ -926,7 +981,9 @@ _xim_init_IMdkit () static void _atexit_cb () { - ibus_im_client_kill_daemon(_client); + if (_bus) { + ibus_bus_kill(_bus); + } } static void @@ -1021,7 +1078,6 @@ main (int argc, char **argv) } _x11_ic_table = g_hash_table_new (g_direct_hash, g_direct_equal); - _ibus_ic_table = g_hash_table_new (g_str_hash, g_str_equal); _connections = g_hash_table_new (g_direct_hash, g_direct_equal); signal (SIGINT, _sighandler); |