This commit is contained in:
Huang Peng 2008-07-23 14:13:37 +08:00
Родитель 90f1e606a7
Коммит cb388f451b
7 изменённых файлов: 857 добавлений и 89 удалений

Просмотреть файл

@ -29,6 +29,7 @@ SUBDIRS = \
gtk2 \
qt4 \
setup \
x11 \
icons \
m4 \
po \

Просмотреть файл

@ -152,6 +152,8 @@ gconf/ibus-gconf
engine/Makefile
gtk2/Makefile
qt4/Makefile
x11/Makefile
x11/IMdkit/Makefile
setup/Makefile
setup/ibus-setup
setup/ibus-setup.desktop

Просмотреть файл

@ -46,4 +46,4 @@ EXTRA_DIST = \
$(NULL)
test:
$(ENV) PYTHONPATH=$(top_srcdir) $(PYTHON) $(srcdir)/ibusdaemon.py
$(ENV) DBUS_DEBUG=true PYTHONPATH=$(top_srcdir) $(PYTHON) $(srcdir)/ibusdaemon.py

Просмотреть файл

@ -1,97 +1,25 @@
# vim:set noet ts=4:
#
# ibus - The Input Bus
#
# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
#
# 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 program; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307 USA
bin_PROGRAMS = ibus-x11
SUBDIRS = \
IMdkit \
ibus_x11_SOURCES = \
main.c \
gdk-private.c \
$(NULL)
xim_PYTHON = \
engine.py \
factory.py \
main.py \
tables.py \
test.py \
noinst_HEADERS = \
gdk-private.h \
$(NULL)
ximdir = $(datadir)/ibus/xim
IMdkit = $(builddir)/IMdkit/libIMdkit.la
IMdkit_DATA = \
IMdkit.py \
$(NULL)
IMdkit_LTLIBRARIES = _IMdkit.la
IMdkitdir = @pyexecdir@
_IMdkit_la_SOURCES = \
$(NULL)
nodist__IMdkit_la_SOURCES = \
IMdkit_wrap.c \
$(NULL)
_IMdkit_la_CFLAGS = \
@X11_CFLAGS@ \
@GDK2_CFLAGS@ \
@PYGOBJECT2_CFLAGS@ \
@PYGTK2_CFLAGS@ \
@GTK2_CFLAGS@ \
@PYTHON_CFLAGS@ \
-IIMdkit \
$(NULL)
_IMdkit_la_LDFLAGS = \
@X11_LIBS@ \
@GDK2_LIBS@ \
@PYGOBJECT2_LIBS@ \
@PYGTK2_LIBS@ \
ibus_x11_LDADD = \
@GTK2_LIBS@ \
@PYTHON_LIBS@ \
-rpath $(IMdkitdir) \
-avoid-version \
-module \
IMdkit/libIMdkit.la \
$(top_builddir)/gtk2/libibus-gtk.la \
$(IMdkit) \
$(NULL)
ibus_x11_CFLAGS = \
@GTK2_CFLAGS@ \
-I$(srcdir)/IMdkit \
-I$(top_srcdir)/gtk2 \
$(NULL)
#libexec_SCRIPTS = ibus-xim
IMdkit.py IMdkit_wrap.c: IMdkit.i
$(SWIG) -python -I/usr/include -o IMdkit_wrap.c $(srcdir)/IMdkit.i
test: all
$(ENV) PYTHONPATH=$(builddir)/.libs python test.py
test-ipython: all
$(ENV) PYTHONPATH=$(builddir)/.libs ipython
EXTRA_DIST = \
IMdkit.i \
ibus-xim.in \
$(NULL)
CLEANFILES = \
IMdkit.py \
IMdkit_wrap.* \
*.pyc \
$(MULL)
DISTCLEANFILES = \
$(MULL)
SUBDIRS = IMdkit

116
x11/gdk-private.c Normal file
Просмотреть файл

@ -0,0 +1,116 @@
/* xim-on-gtkim
* Copyright (C) 2007 Huang Peng <phuang@redhat.com>
*
* gdk-private.c: Copied some code from gtk2
*
* This tool is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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 <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
void
translate_key_event (GdkDisplay *display,
GdkEvent *event,
XEvent *xevent)
{
GdkKeymap *keymap = gdk_keymap_get_for_display (display);
gunichar c = 0;
gchar buf[7];
event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
event->key.time = xevent->xkey.time;
event->key.state = (GdkModifierType) xevent->xkey.state;
//event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
event->key.group = 0;
event->key.hardware_keycode = xevent->xkey.keycode;
event->key.keyval = GDK_VoidSymbol;
gdk_keymap_translate_keyboard_state (keymap,
event->key.hardware_keycode,
event->key.state,
event->key.group,
&event->key.keyval,
NULL, NULL, NULL);
//_gdk_keymap_add_virtual_modifiers (keymap, &event->key.state);
event->key.is_modifier =
(event->key.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) != 0;
// event->key.is_modifier = _gdk_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
/* Fill in event->string crudely, since various programs
* depend on it.
*/
event->key.string = NULL;
if (event->key.keyval != GDK_VoidSymbol)
c = gdk_keyval_to_unicode (event->key.keyval);
if (c)
{
gsize bytes_written;
gint len;
/* Apply the control key - Taken from Xlib
*/
if (event->key.state & GDK_CONTROL_MASK)
{
if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
else if (c == '2')
{
event->key.string = g_memdup ("\0\0", 2);
event->key.length = 1;
buf[0] = '\0';
goto out;
}
else if (c >= '3' && c <= '7') c -= ('3' - '\033');
else if (c == '8') c = '\177';
else if (c == '/') c = '_' & 0x1F;
}
len = g_unichar_to_utf8 (c, buf);
buf[len] = '\0';
event->key.string = g_locale_from_utf8 (buf, len,
NULL, &bytes_written,
NULL);
if (event->key.string)
event->key.length = bytes_written;
}
else if (event->key.keyval == GDK_Escape)
{
event->key.length = 1;
event->key.string = g_strdup ("\033");
}
else if (event->key.keyval == GDK_Return ||
event->key.keyval == GDK_KP_Enter)
{
event->key.length = 1;
event->key.string = g_strdup ("\r");
}
if (!event->key.string)
{
event->key.length = 0;
event->key.string = g_strdup ("");
}
out:
return;
}

28
x11/gdk-private.h Normal file
Просмотреть файл

@ -0,0 +1,28 @@
/* xim-on-gtkim
* Copyright (C) 2007 Huang Peng <phuang@redhat.com>
*
* gdk-private.h:
*
* This tool is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
#ifndef __GTK_PRIVATE_H_
#define __GTK_PRIVATE_H_
void
translate_key_event (GdkDisplay *display,
GdkEvent *event,
XEvent *xevent);
#endif

693
x11/main.c Normal file
Просмотреть файл

@ -0,0 +1,693 @@
/* xim-on-gtkim
* Copyright (C) 2007 Huang Peng <phuang@redhat.com>
*
* main.c:
*
* This tool is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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 <X11/Xproto.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <XimProto.h>
#include <IMdkit.h>
#include <Xi18n.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <langinfo.h>
#include <locale.h>
#include <iconv.h>
#define _GNU_SOURCES
#include <getopt.h>
#define LOG(level, fmt, args...) \
if (g_debug_level >= (level)) { \
fprintf (stderr, fmt, args); \
}
#include <ibusimclient.h>
#include "gdk-private.h"
struct _X11ICONN {
GList *clients;
};
typedef struct _X11ICONN X11ICONN;
struct _X11IC {
GtkIMContext *context;
GdkWindow *client_window;
GdkWindow *focus_window;
gint32 input_style;
X11ICONN *conn;
gint icid;
gint connect_id;
gchar *lang;
GdkRectangle preedit_area;
};
typedef struct _X11IC X11IC;
static void _xim_commit_cb (GtkIMContext *context, gchar *arg, gpointer data);
static GHashTable *g_clients = NULL;
static GHashTable *g_connections = NULL;
static XIMS g_xims = NULL;
static gchar g_server_name[128] = "ibus";
static gchar g_locale[1024] =
"aa,af,am,an,ar,as,az,be,bg,bn,br,bs,"
"ca,cs,cy,da,de,dz,el,en,es,et,eu,"
"fa,fi,fo,fr,fy,ga,gd,gl,gu,gv,"
"he,hi,hr,hu,hy,id,is,it,iw,ja,"
"ka,kk,kl,km,kn,ko,ku,kw,ky,lg,lo,lt,lv,"
"mg,mi,mk,ml,mn,mr,ms,mt,nb,ne,nl,nn,no,nr,"
"oc,om,or,pa,pl,pt,ro,ru,rw,"
"se,si,sk,sl,so,sq,sr,ss,st,sv,"
"ta,te,tg,th,ti,tl,tn,tr,ts,tt,"
"uk,ur,uz,ve,vi,wa,xh,yi,zh,zu";
static gint g_debug_level = 0;
IBusIMClient *_client = NULL;
static void
_xim_preedit_start (XIMS xims, int icid, int connect_id)
{
IMPreeditStateStruct ips;
ips.major_code = 0;
ips.minor_code = 0;
ips.icid = icid;
ips.connect_id = connect_id;
IMPreeditStart (xims, (XPointer)&ips);
}
static void
_xim_preedit_end (XIMS xims, int icid, int connect_id)
{
IMPreeditStateStruct ips;
ips.major_code = 0;
ips.minor_code = 0;
ips.icid = icid;
ips.connect_id = connect_id;
IMPreeditEnd (xims, (XPointer)&ips);
}
int
_xim_store_ic_values (X11IC *ic, IMChangeICStruct *call_data)
{
XICAttribute *ic_attr = call_data->ic_attr;
XICAttribute *pre_attr = call_data->preedit_attr;
XICAttribute *sts_attr = call_data->status_attr;
gint i;
guint32 attrs = 1;
if (ic == NULL) {
return 0;
}
#define _is_attr(a, b) (strcmp(a, b->name) == 0)
for (i=0; i< (int) call_data->ic_attr_num; ++i, ++ic_attr) {
if (_is_attr (XNInputStyle, ic_attr)) {
ic->input_style = *(gint32 *) ic_attr->value;
}
else if (_is_attr (XNClientWindow, ic_attr)) {
Window w;
if (ic->client_window != NULL) {
g_object_unref (ic->client_window);
}
w = *(Window *) call_data->ic_attr[i].value;
ic->client_window = gdk_window_foreign_new (w);
}
else if (_is_attr (XNFocusWindow, ic_attr)) {
Window w;
if (ic->focus_window != NULL) {
g_object_unref (ic->focus_window);
}
w = *(Window *) call_data->ic_attr[i].value;
ic->focus_window = gdk_window_foreign_new (w);
}
else {
// fprintf (stderr, "Unknown attr: %s\n", ic_attr->name);
}
}
for (i=0; i< (int) call_data->preedit_attr_num; ++i, ++pre_attr) {
if (_is_attr (XNSpotLocation, pre_attr)) {
ic->preedit_area.x = ((XPoint *)pre_attr->value)->x;
ic->preedit_area.y = ((XPoint *)pre_attr->value)->y;
}
else {
// fprintf (stderr, "Unknown attr: %s\n", pre_attr->name);
}
}
for (i=0; i< (int) call_data->status_attr_num; ++i, ++sts_attr) {
// printf ("set status: %s\n", sts_attr->name);
}
#undef _is_attr
return attrs;
}
static void
_xim_commit_cb (GtkIMContext *context, gchar *arg, gpointer data)
{
char *clist[1];
XTextProperty tp;
IMCommitStruct cms;
X11IC *ic = (X11IC *)data;
clist[0] = arg;
Xutf8TextListToTextProperty (GDK_DISPLAY (), clist, 1, XCompoundTextStyle, &tp);
memset (&cms, 0, sizeof (cms));
cms.major_code = XIM_COMMIT;
cms.icid = ic->icid;
cms.connect_id = ic->connect_id;
cms.flag = XimLookupChars;
cms.commit_string = (char *)tp.value;
IMCommitString (g_xims, (XPointer) & cms);
XFree (tp.value);
}
int
xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
{
static int base_icid = 1;
X11IC *ic;
int i;
LOG (1, "XIM_CREATE_IC ic=%d, connect_id=%d\n", call_data->icid, call_data->connect_id);
call_data->icid = base_icid ++;
ic = g_malloc0 (sizeof (X11IC));
ic->icid = call_data->icid;
ic->connect_id = call_data->connect_id;
ic->conn = (X11ICONN *)g_hash_table_lookup (g_connections,
(gconstpointer)(unsigned long)call_data->connect_id);
i = _xim_store_ic_values (ic, call_data);
ic->context = (GtkIMContext *)ibus_im_client_create_im_context (_client);
gtk_im_context_set_client_window (ic->context, ic->client_window);
gtk_im_context_set_use_preedit (ic->context, FALSE);
g_signal_connect (ic->context,
"commit",
G_CALLBACK (_xim_commit_cb),
(gpointer)ic);
g_hash_table_insert (g_clients, (gpointer)ic->icid, (gpointer) ic);
ic->conn->clients = g_list_append (ic->conn->clients, (gpointer) ic);
return 1;
}
int
xim_destroy_ic (XIMS xims, IMChangeICStruct *call_data)
{
X11IC *ic;
LOG (1, "XIM_DESTROY_IC ic=%d, connect_id=%d\n", call_data->icid, call_data->connect_id);
ic = (X11IC *)g_hash_table_lookup (g_clients,
(gconstpointer)(unsigned long)call_data->icid);
g_object_unref (ic->context);
ic->conn->clients = g_list_remove (ic->conn->clients, (gconstpointer)ic);
g_hash_table_remove (g_clients,
(gconstpointer)(unsigned long)call_data->icid);
g_free (ic);
return 1;
}
int
xim_set_ic_focus (XIMS xims, IMChangeFocusStruct *call_data)
{
X11IC *ic;
LOG (1, "XIM_SET_IC_FOCUS ic=%d, connect_id=%d\n", call_data->icid, call_data->connect_id);
ic = (X11IC *)g_hash_table_lookup (g_clients,
(gconstpointer)(unsigned long)call_data->icid);
gtk_im_context_focus_in (ic->context);
return 1;
}
int
xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data)
{
X11IC *ic;
LOG (1, "XIM_UNSET_IC_FOCUS ic=%d, connect_id=%d\n", call_data->icid, call_data->connect_id);
ic = (X11IC *)g_hash_table_lookup (g_clients,
(gconstpointer)(unsigned long)call_data->icid);
gtk_im_context_focus_out (ic->context);
return 1;
}
int
xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
{
X11IC *ic;
XKeyEvent *xevent;
GdkEventKey event;
GdkWindow *window;
ic = (X11IC *)g_hash_table_lookup (g_clients,
(gconstpointer)(unsigned long)call_data->icid);
g_return_val_if_fail (ic != NULL, 1);
window = ic->focus_window != NULL ? ic->focus_window : ic->client_window;
xevent = (XKeyEvent*) &(call_data->event);
translate_key_event (gdk_drawable_get_display (window),
(GdkEvent *)&event, (XEvent *)xevent);
event.send_event = xevent->send_event;
event.window = window;
if (gtk_im_context_filter_keypress (ic->context, &event)) {
return 1;
}
else {
IMForwardEventStruct fe;
XEvent xkp;
XKeyEvent *event = (XKeyEvent*) (&xkp);
memset (&fe, 0, sizeof (fe));
fe.major_code = XIM_FORWARD_EVENT;
fe.icid = ic->icid;
fe.connect_id = ic->connect_id;
fe.sync_bit = 0;
fe.serial_number = 0L;
fe.event = call_data->event;
IMForwardEvent (g_xims, (XPointer) & fe);
return 1;
}
}
int
xim_open (XIMS xims, IMOpenStruct *call_data)
{
X11ICONN *conn;
gchar *last;
LOG (1, "XIM_OPEN connect_id=%d\n", call_data->connect_id);
conn = (X11ICONN *)g_hash_table_lookup (g_connections,
(gconstpointer)(unsigned long)call_data->connect_id);
g_return_val_if_fail (conn == NULL, 1);
conn = (X11ICONN *) g_malloc0(sizeof (X11ICONN));
// conn->context = GTK_IM_CONTEXT (gtk_im_multicontext_new ());
g_hash_table_insert (g_connections,
(gpointer)(unsigned long)call_data->connect_id,
(gpointer) conn);
// g_signal_connect_after (conn->context,
// "commit",
// G_CALLBACK (_xim_commit_cb),
// (gpointer)(unsigned long)call_data->connect_id);
return 1;
}
static void
_free_ic (gpointer data, gpointer user_data)
{
X11IC *ic = (X11IC *) data;
g_return_if_fail (ic != NULL);
g_object_unref (ic->context);
/* Remove the IC from g_client dictionary */
g_hash_table_remove (g_clients,
(gconstpointer)(unsigned long)ic->icid);
g_free (ic);
}
int
xim_close (XIMS ims, IMCloseStruct *call_data)
{
X11ICONN *conn;
LOG (1, "XIM_CLOSE connect_id=%d\n", call_data->connect_id);
conn = (X11ICONN *)g_hash_table_lookup (g_connections,
(gconstpointer)(unsigned long)call_data->connect_id);
g_return_val_if_fail (conn != NULL, 1);
g_list_foreach (conn->clients, _free_ic, NULL);
g_list_free (conn->clients);
// g_object_unref (conn->context);
g_hash_table_remove (g_connections, (gconstpointer)(unsigned long)call_data->connect_id);
g_free (conn);
return 1;
}
int
xim_set_ic_values (XIMS xims, IMChangeICStruct *call_data)
{
X11IC *ic;
gint i;
LOG (1, "XIM_SET_IC_VALUES ic=%d connect_id=%d\n", call_data->icid, call_data->connect_id);
ic = (X11IC *)g_hash_table_lookup (g_clients,
(gconstpointer)(unsigned long)call_data->icid);
g_return_val_if_fail (ic != NULL, 1);
i = _xim_store_ic_values (ic, call_data);
if (i) {
gtk_im_context_set_cursor_location (ic->context, &ic->preedit_area);
}
return i;
}
int
xim_reset_ic (XIMS xims, IMResetICStruct *call_data)
{
X11IC *ic;
LOG (1, "XIM_RESET_IC ic=%d connect_id=%d\n", call_data->icid, call_data->connect_id);
ic = (X11IC *)g_hash_table_lookup (g_clients,
(gconstpointer)(unsigned long)call_data->icid);
g_return_val_if_fail (ic != NULL, 1);
gtk_im_context_reset (ic->context);
return 1;
}
int
ims_protocol_handler (XIMS xims, IMProtocol *call_data)
{
g_return_val_if_fail (xims != NULL, 1);
g_return_val_if_fail (call_data != NULL, 1);
switch (call_data->major_code) {
case XIM_OPEN:
return xim_open (xims, (IMOpenStruct *)call_data);
case XIM_CLOSE:
return xim_close (xims, (IMCloseStruct *)call_data);
case XIM_CREATE_IC:
return xim_create_ic (xims, (IMChangeICStruct *)call_data);
case XIM_DESTROY_IC:
return xim_destroy_ic (xims, (IMChangeICStruct *)call_data);
case XIM_SET_IC_VALUES:
return xim_set_ic_values (xims, (IMChangeICStruct *)call_data);
case XIM_GET_IC_VALUES:
return 1;
case XIM_FORWARD_EVENT:
return xim_forward_event (xims, (IMForwardEventStruct *)call_data);
case XIM_SET_IC_FOCUS:
return xim_set_ic_focus (xims, (IMChangeFocusStruct *)call_data);
case XIM_UNSET_IC_FOCUS:
return xim_unset_ic_focus (xims, (IMChangeFocusStruct *)call_data);
case XIM_RESET_IC:
return xim_reset_ic (xims, (IMResetICStruct *)call_data);
case XIM_TRIGGER_NOTIFY:
case XIM_PREEDIT_START_REPLY:
case XIM_PREEDIT_CARET_REPLY:
case XIM_SYNC_REPLY:
return 1;
default:
break;
}
return 1;
}
#if 0
static void
_xim_forward_gdk_event (GdkEventKey *event)
{
IMForwardEventStruct fe;
XEvent xkp;
memset (&xkp, 0, sizeof (xkp));
memset (&fe, 0, sizeof (fe));
xkp.xkey.type = (event->type == GDK_KEY_PRESS) ? KeyPress : KeyRelease;
xkp.xkey.serial = 0L;
xkp.xkey.send_event = False;
xkp.xkey.same_screen = False;
xkp.xkey.display = GDK_WINDOW_XDISPLAY (event->window);
xkp.xkey.window = GDK_WINDOW_XWINDOW (event->window);
xkp.xkey.subwindow = None;
xkp.xkey.root = DefaultRootWindow (GDK_WINDOW_XDISPLAY (event->window));
xkp.xkey.time = event->time;
xkp.xkey.state = event->state;
xkp.xkey.keycode = event->hardware_keycode;
fe.major_code = XIM_FORWARD_EVENT;
fe.icid = g_focus_ic->icid;
fe.connect_id = g_focus_ic->connect_id;
fe.sync_bit = 0;
fe.serial_number = 0L;
fe.event = xkp;
IMForwardEvent (g_xims, (XPointer) & fe);
}
#endif
static void
_xim_event_cb (GdkEvent *event, gpointer data)
{
switch (event->type) {
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
//_xim_forward_gdk_event ((GdkEventKey *)event);
break;
default:
gtk_main_do_event (event);
break;
}
}
static void
_xim_event_destroy_cb (gpointer data)
{
}
static void
_xim_init_IMdkit ()
{
XIMStyle ims_styles_overspot [] = {
XIMPreeditPosition | XIMStatusNothing,
XIMPreeditNothing | XIMStatusNothing,
XIMPreeditPosition | XIMStatusCallbacks,
XIMPreeditNothing | XIMStatusCallbacks,
0
};
XIMStyle ims_styles_onspot [] = {
XIMPreeditPosition | XIMStatusNothing,
XIMPreeditCallbacks | XIMStatusNothing,
XIMPreeditNothing | XIMStatusNothing,
XIMPreeditPosition | XIMStatusCallbacks,
XIMPreeditCallbacks | XIMStatusCallbacks,
XIMPreeditNothing | XIMStatusCallbacks,
0
};
XIMEncoding ims_encodings[] = {
"COMPOUND_TEXT",
0
};
GdkWindowAttr window_attr = {
title : "xim2gtkim",
event_mask : GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
wclass: GDK_INPUT_OUTPUT,
window_type: GDK_WINDOW_TOPLEVEL,
override_redirect: 1,
};
XIMStyles styles;
XIMEncodings encodings;
GdkWindow *win;
win = gdk_window_new (NULL, &window_attr, GDK_WA_TITLE);
styles.count_styles =
sizeof (ims_styles_onspot)/sizeof (XIMStyle) - 1;
styles.supported_styles = ims_styles_onspot;
encodings.count_encodings =
sizeof (ims_encodings)/sizeof (XIMEncoding) - 1;
encodings.supported_encodings = ims_encodings;
g_xims = IMOpenIM(GDK_DISPLAY(),
IMModifiers, "Xi18n",
IMServerWindow, GDK_WINDOW_XWINDOW(win),
IMServerName, g_server_name,
IMLocale, g_locale,
IMServerTransport, "X/",
IMInputStyles, &styles,
IMEncodingList, &encodings,
IMProtocolHandler, ims_protocol_handler,
IMFilterEventMask, KeyPressMask | KeyReleaseMask,
NULL);
gdk_event_handler_set (_xim_event_cb, NULL,
_xim_event_destroy_cb);
ibus_im_client_register_type (NULL);
ibus_im_context_register_type (NULL);
_client = ibus_im_client_new ();
}
static void
print_usage (FILE *fp, gchar *name)
{
fprintf (fp,
"Usage:\n"
" %s --help Show this message\n"
" --server-name= -n Setup xim sevrer name\n"
" --locale= -l Setup support locale\n"
" --debug= -v Setup debug level\n",
name);
}
int main (int argc, char **argv)
{
GMainLoop *loop;
gint option_index = 0;
gint c;
gdk_init (&argc, &argv);
while (1) {
static struct option long_options [] = {
{"debug", 1, 0, 0},
{"server-name", 1, 0, 0},
{"locale", 1, 0, 0},
{"help", 0, 0, 0},
{0, 0, 0, 0},
};
c = getopt_long (argc, argv, "v:n:l:",
long_options, &option_index);
if (c == -1) break;
switch (c) {
case 0:
if (strcmp (long_options[option_index].name, "debug") == 0) {
g_debug_level = atoi (optarg);
}
else if (strcmp (long_options[option_index].name, "server-name") == 0) {
strncpy (g_server_name, optarg, sizeof (g_server_name));
}
else if (strcmp (long_options[option_index].name, "locale") == 0) {
strncpy (g_locale, optarg, sizeof (g_locale));
}
else if (strcmp (long_options[option_index].name, "help") == 0) {
print_usage (stdout, argv[0]);
exit (EXIT_SUCCESS);
}
break;
case 'v':
g_debug_level = atoi (optarg);
break;
case 'n':
strncpy (g_server_name, optarg, sizeof (g_server_name));
break;
case 'l':
strncpy (g_locale, optarg, sizeof (g_locale));
break;
case '?':
default:
print_usage (stderr, argv[0]);
exit (EXIT_FAILURE);
}
}
g_clients = g_hash_table_new (g_direct_hash, g_direct_equal);
g_connections = g_hash_table_new (g_direct_hash, g_direct_equal);
printf ("server-name = %s\n", g_server_name);
printf ("locale = %s\n", g_locale);
_xim_init_IMdkit ();
loop = g_main_loop_new (NULL, TRUE);
if (g_main_loop_is_running (loop)) {
GDK_THREADS_LEAVE ();
g_main_loop_run (loop);
GDK_THREADS_ENTER ();
gdk_flush ();
}
return 0;
}