summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Peng <shawn.p.huang@gmail.com>2009-02-05 10:39:56 +0800
committerHuang Peng <shawn.p.huang@gmail.com>2009-02-05 10:39:56 +0800
commitaedad1ea0a7fef604aa27f4b58433fd8f2ece29e (patch)
treeffcb531d8474bde18b90341bcd4eb639edd74525
parent41ad46305a88637dd99f00a2d2a3f455505d357b (diff)
downloadibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.tar.gz
ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.tar.xz
ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.zip
re-implement ibus in c language.
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am32
-rwxr-xr-xautogen.sh1
-rw-r--r--bindings/Makefile.am (renamed from lib/Makefile.am)2
-rw-r--r--bindings/python/Makefile.am80
-rw-r--r--bindings/python/common.h7
-rwxr-xr-xbindings/python/gendefs.sh3
-rw-r--r--bindings/python/ibus-types.defs27
-rw-r--r--bindings/python/ibus-virtual-methods.defs23
-rw-r--r--bindings/python/ibus.defs5
-rw-r--r--bindings/python/ibus.override11
-rw-r--r--bindings/python/ibusmodule.c29
-rw-r--r--bus/.gitignore2
-rw-r--r--bus/Makefile.am99
-rw-r--r--bus/connection.c261
-rw-r--r--bus/connection.h71
-rw-r--r--bus/dbusimpl.c1174
-rw-r--r--bus/dbusimpl.h87
-rw-r--r--bus/engineproxy.c716
-rw-r--r--bus/engineproxy.h95
-rw-r--r--bus/factoryproxy.c220
-rw-r--r--bus/factoryproxy.h84
-rw-r--r--bus/ibusimpl.c935
-rw-r--r--bus/ibusimpl.h102
-rw-r--r--bus/inputcontext.c1559
-rw-r--r--bus/inputcontext.h82
-rw-r--r--bus/main.c148
-rw-r--r--bus/matchrule.c672
-rw-r--r--bus/matchrule.h124
-rw-r--r--bus/panelproxy.c757
-rw-r--r--bus/panelproxy.h112
-rw-r--r--bus/registry.c447
-rw-r--r--bus/registry.h88
-rw-r--r--bus/server.c152
-rw-r--r--bus/server.h72
-rw-r--r--bus/test-matchrule.c40
-rw-r--r--bus/test-registry.c9
-rw-r--r--client/Makefile.am2
-rw-r--r--client/gtk2/Makefile.am12
-rw-r--r--client/gtk2/ibusim.c25
-rw-r--r--client/gtk2/ibusimcontext.c508
-rw-r--r--client/x11/.gitignore1
-rw-r--r--client/x11/Makefile.am14
-rw-r--r--client/x11/main.c254
-rw-r--r--configure.ac86
-rw-r--r--daemon/.gitignore1
-rw-r--r--daemon/Makefile.am55
-rw-r--r--daemon/_dbus.py319
-rw-r--r--daemon/bus.py714
-rw-r--r--daemon/config.py101
-rw-r--r--daemon/connection.py98
-rw-r--r--daemon/contextmanager.py45
-rw-r--r--daemon/engine.py221
-rw-r--r--daemon/enginefactory.py83
-rw-r--r--daemon/factorymanager.py123
-rw-r--r--daemon/ibusdaemon.py112
-rw-r--r--daemon/inputcontext.py449
-rw-r--r--daemon/lookuptable.py95
-rw-r--r--daemon/notifications.py92
-rw-r--r--daemon/panel.py262
-rw-r--r--daemon/register.py205
-rw-r--r--docs/Makefile.am (renamed from gconf/ibus-gconf.in)8
-rw-r--r--docs/reference/Makefile.am (renamed from daemon/ibus-daemon.in)9
-rw-r--r--docs/reference/ibus/.gitignore24
-rw-r--r--docs/reference/ibus/Makefile.am101
-rw-r--r--docs/reference/ibus/ibus.types29
-rw-r--r--gconf/.gitignore2
-rw-r--r--gconf/Makefile.am48
-rw-r--r--gconf/config.c312
-rw-r--r--gconf/config.py151
-rw-r--r--gconf/gconf.xml.in12
-rw-r--r--gconf/main.c65
-rw-r--r--gconf/main.py84
-rw-r--r--ibus-1.0.pc.in11
-rw-r--r--ibus.spec.in50
-rw-r--r--ibus/.gitignore1
-rw-r--r--ibus/Makefile.am8
-rw-r--r--ibus/__init__.py6
-rw-r--r--ibus/_gtk.py (renamed from ibus/gtk.py)4
-rw-r--r--ibus/attribute.py99
-rw-r--r--ibus/bus.py358
-rw-r--r--ibus/common.py34
-rw-r--r--ibus/component.py131
-rw-r--r--ibus/config.py96
-rw-r--r--ibus/engine.py63
-rw-r--r--ibus/enginedesc.py106
-rw-r--r--ibus/factory.py102
-rw-r--r--ibus/inputcontext.py301
-rw-r--r--ibus/interface/Makefile.am1
-rw-r--r--ibus/interface/__init__.py1
-rw-r--r--ibus/interface/iconfig.py8
-rw-r--r--ibus/interface/iengine.py33
-rw-r--r--ibus/interface/ienginefactory.py10
-rw-r--r--ibus/interface/iibus.py81
-rw-r--r--ibus/interface/iinputcontext.py133
-rw-r--r--ibus/interface/inotifications.py8
-rw-r--r--ibus/interface/ipanel.py36
-rw-r--r--ibus/lookuptable.py133
-rw-r--r--ibus/notifications.py10
-rw-r--r--ibus/object.py19
-rw-r--r--ibus/observedpath.py64
-rw-r--r--ibus/panel.py124
-rw-r--r--ibus/property.py131
-rw-r--r--ibus/serializable.py81
-rw-r--r--ibus/text.py68
-rw-r--r--launcher/Makefile.am33
-rw-r--r--launcher/ibus.desktop.in11
-rw-r--r--launcher/ibus.in152
-rw-r--r--lib/gtk2/Makefile.am71
-rw-r--r--lib/gtk2/ibusattribute.c276
-rw-r--r--lib/gtk2/ibusattribute.h100
-rw-r--r--lib/gtk2/ibusimclient.c1536
-rw-r--r--lib/gtk2/ibusimclient.h133
-rw-r--r--lib/gtk2/ibusmarshalers.list5
-rw-r--r--po/.gitignore5
-rw-r--r--po/POTFILES.in16
-rw-r--r--po/ja.po88
-rw-r--r--po/pa.po109
-rw-r--r--po/zh_CN.po106
-rw-r--r--setup/.gitignore1
-rw-r--r--setup/Makefile.am3
-rw-r--r--setup/enginecombobox.py92
-rw-r--r--setup/enginetreeview.py157
-rw-r--r--setup/icon.py60
-rw-r--r--setup/keyboardshortcut.py4
-rw-r--r--setup/main.py233
-rw-r--r--setup/setup.glade114
-rw-r--r--src/.gitignore12
-rw-r--r--src/Makefile.am209
-rw-r--r--src/ibus.h51
-rw-r--r--src/ibusattribute.c433
-rw-r--r--src/ibusattribute.h126
-rw-r--r--src/ibusbus.c773
-rw-r--r--src/ibusbus.h97
-rw-r--r--src/ibuscomponent.c743
-rw-r--r--src/ibuscomponent.h115
-rw-r--r--src/ibusconfig.c357
-rw-r--r--src/ibusconfig.h70
-rw-r--r--src/ibusconfigprivate.h221
-rw-r--r--src/ibusconfigservice.c314
-rw-r--r--src/ibusconfigservice.h85
-rw-r--r--src/ibusconnection.c697
-rw-r--r--src/ibusconnection.h147
-rw-r--r--src/ibusdebug.h27
-rw-r--r--src/ibusengine.c957
-rw-r--r--src/ibusengine.h152
-rw-r--r--src/ibusenginedesc.c356
-rw-r--r--src/ibusenginedesc.h86
-rw-r--r--src/ibusenumtypes.c146
-rw-r--r--src/ibusenumtypes.c.template34
-rw-r--r--src/ibusenumtypes.h37
-rw-r--r--src/ibusenumtypes.h.template24
-rw-r--r--src/ibuserror.c87
-rw-r--r--src/ibuserror.h41
-rw-r--r--src/ibusfactory.c483
-rw-r--r--src/ibusfactory.h120
-rw-r--r--src/ibushotkey.c479
-rw-r--r--src/ibushotkey.h87
-rw-r--r--src/ibusinputcontext.c695
-rw-r--r--src/ibusinputcontext.h87
-rw-r--r--src/ibusinternal.c667
-rw-r--r--src/ibusinternal.h36
-rw-r--r--src/ibuskeynames.c199
-rwxr-xr-xsrc/ibuskeysyms-update.pl105
-rw-r--r--src/ibuskeysyms.h2014
-rw-r--r--src/ibuslookuptable.c283
-rw-r--r--src/ibuslookuptable.h82
-rw-r--r--src/ibusmarshalers.list18
-rw-r--r--src/ibusmessage.c872
-rw-r--r--src/ibusmessage.h146
-rw-r--r--src/ibusobject.c189
-rw-r--r--src/ibusobject.h92
-rw-r--r--src/ibusobservedpath.c335
-rw-r--r--src/ibusobservedpath.h79
-rw-r--r--src/ibuspendingcall.c103
-rw-r--r--src/ibuspendingcall.h56
-rw-r--r--src/ibusproperty.c531
-rw-r--r--src/ibusproperty.h140
-rw-r--r--src/ibusproxy.c638
-rw-r--r--src/ibusproxy.h107
-rw-r--r--src/ibusserializable.c578
-rw-r--r--src/ibusserializable.h108
-rw-r--r--src/ibusserver.c327
-rw-r--r--src/ibusserver.h79
-rw-r--r--src/ibusservice.c406
-rw-r--r--src/ibusservice.h99
-rw-r--r--src/ibusshare.c164
-rw-r--r--src/ibusshare.h68
-rw-r--r--src/ibustext.c283
-rw-r--r--src/ibustext.h77
-rw-r--r--src/ibustypes.h74
-rw-r--r--src/ibusxml.c317
-rw-r--r--src/ibusxml.h37
-rw-r--r--src/keyname-table.h3978
-rw-r--r--src/test-attribute.c44
-rw-r--r--src/test-bus.c22
-rw-r--r--src/test-engine.c16
-rw-r--r--src/test-keynames.c8
-rw-r--r--src/test-lookuptable.c39
-rw-r--r--src/test-proxy.c18
-rw-r--r--src/test-server.c30
-rw-r--r--src/test-text.c42
-rw-r--r--ui/gtk/.gitignore1
-rw-r--r--ui/gtk/Makefile.am12
-rw-r--r--ui/gtk/candidatepanel.py47
-rw-r--r--ui/gtk/gtkpanel.xml.in12
-rw-r--r--ui/gtk/icon.py3
-rw-r--r--ui/gtk/languagebar.py4
-rw-r--r--ui/gtk/main.py11
-rw-r--r--ui/gtk/menu.py8
-rw-r--r--ui/gtk/notifications.py14
-rw-r--r--ui/gtk/panel.py116
-rw-r--r--ui/gtk/propitem.py2
-rw-r--r--ui/gtk/toolitem.py14
-rw-r--r--util/Makefile.am1
-rw-r--r--util/gconf/Makefile.am51
-rw-r--r--util/gconf/gconf-arg-types.py30
-rw-r--r--util/gconf/gconf-fixes.c57
-rw-r--r--util/gconf/gconf-fixes.h14
-rw-r--r--util/gconf/gconf-types.c157
-rw-r--r--util/gconf/gconf-types.h35
-rw-r--r--util/gconf/gconf.defs1978
-rw-r--r--util/gconf/gconf.override920
-rw-r--r--util/gconf/gconfmodule.c33
-rw-r--r--util/gconf/wscript47
-rw-r--r--xinput-ibus6
226 files changed, 33580 insertions, 10515 deletions
diff --git a/.gitignore b/.gitignore
index 1664ac7..7d7f11b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
*.so
*~
tags
+TAGS
Makefile.qmake
Makefile
Makefile.in
@@ -34,3 +35,4 @@ stamp-h1
py-compile
ibus-*.tar.*
ibus.spec
+ibus-1.0.pc
diff --git a/Makefile.am b/Makefile.am
index 7f99b46..47a21d0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,25 +19,30 @@
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307 USA
-SUBDIRS = \
- daemon \
- gconf \
- ibus \
- launcher \
- ui \
- lib \
- util \
- client \
- setup \
- icons \
- m4 \
- po \
+SUBDIRS = \
+ src \
+ bindings \
+ gconf \
+ ibus \
+ ui \
+ util \
+ client \
+ setup \
+ bus \
+ icons \
+ m4 \
+ po \
+ docs \
$(NULL)
ACLOCAL_AMFLAGS = -I m4
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = ibus-1.0.pc
+
EXTRA_DIST = \
autogen.sh \
+ ibus-1.0.pc.in \
ibus.spec.in \
python-config.py \
$(NULL)
@@ -55,6 +60,7 @@ install-data-hook:
DISTCHECK_CONFIGURE_FLAGS = \
--enable-pygconf \
+ --enable-gtk-doc \
$(NULL)
rpm: dist @PACKAGE_NAME@.spec
diff --git a/autogen.sh b/autogen.sh
index 1cd17a7..d9a7a56 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -4,6 +4,7 @@ set -x
autopoint --force
libtoolize --automake --copy --force
+gtkdocize #--flavour=no-tmpl
aclocal -I m4 --force
autoheader --force
automake --add-missing --copy --force
diff --git a/lib/Makefile.am b/bindings/Makefile.am
index 19d7bc3..59fb9f4 100644
--- a/lib/Makefile.am
+++ b/bindings/Makefile.am
@@ -20,5 +20,5 @@
# Boston, MA 02111-1307 USA
SUBDIRS = \
- gtk2 \
+ python \
$(NULL)
diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am
new file mode 100644
index 0000000..75a2e49
--- /dev/null
+++ b/bindings/python/Makefile.am
@@ -0,0 +1,80 @@
+# 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
+
+# pyexec_PYTHON =
+# pyexec_LTLIBRARIES = ibus.la
+#
+# INCLUDES = \
+# -I$(top_srcdir)/src \
+# -I$(top_builddir)/src \
+# $(NULL)
+#
+# ibus_la_SOURCES = ibus.c ibusmodule.c
+# ibus_la_CFLAGS = \
+# @PYTHON_CFLAGS@ \
+# @GLIB2_CFLAGS@ \
+# @GOBJECT2_CFLAGS@ \
+# @PYGOBJECT2_CFLAGS@ \
+# @DBUS_CFLAGS@ \
+# $(NULL)
+# ibus_la_LDFLAGS = \
+# @PYTHON_LIBS@ \
+# @GLIB2_LIBS@ \
+# @GOBJECT2_LIBS@ \
+# @DBUS_LIBS@ \
+# $(top_builddir)/src/libibus.la \
+# -avoid-version \
+# -module \
+# -export-symbols-regex "initibus" \
+# $(NULL)
+#
+# ibus-codegen.defs:
+# (cd $(srcdir); \
+# ./gendefs.sh; ) > ibus-codegen.defs
+#
+# IBUS_DEFS = \
+# ibus.defs \
+# ibus-types.defs \
+# ibus-func.defs \
+# ibus-virtual-methods.defs \
+# ibus.override \
+# $(NULL)
+#
+# ibus.c: $(IBUS_DEFS) ibus.override ibus-codegen.defs
+#
+# CLEANFILES = ibus.c ibus-codegen.defs
+# EXTRA_DIST = \
+# gendefs.sh \
+# common.h \
+# $(GIK_DEFS) \
+# $(NULL)
+#
+# PYGOBJECT_CODEGEN = pygobject-codegen-2.0
+#
+# .defs.c:
+# (cd $(srcdir)\
+# && $(PYGOBJECT_CODEGEN) \
+# -o $*.override \
+# -I $(abs_builddir) \
+# -p py$* $*.defs) > gen-$*.c \
+# && cp gen-$*.c $*.c \
+# && rm -f gen-$*.c
+#
diff --git a/bindings/python/common.h b/bindings/python/common.h
new file mode 100644
index 0000000..f3267ee
--- /dev/null
+++ b/bindings/python/common.h
@@ -0,0 +1,7 @@
+#ifndef __PY_COMMON_H_
+#define __PY_COMMON_H_
+
+#include <pygobject.h>
+#include <ibus.h>
+
+#endif //__PY_COMMON_H_
diff --git a/bindings/python/gendefs.sh b/bindings/python/gendefs.sh
new file mode 100755
index 0000000..bc92257
--- /dev/null
+++ b/bindings/python/gendefs.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+codegendir=`pkg-config pygobject-2.0 --variable=codegendir`
+python $codegendir/h2def.py -m ibus ../../src/*.h
diff --git a/bindings/python/ibus-types.defs b/bindings/python/ibus-types.defs
new file mode 100644
index 0000000..a077851
--- /dev/null
+++ b/bindings/python/ibus-types.defs
@@ -0,0 +1,27 @@
+;; (define-boxed EventKey
+;; (in-module "Gik")
+;; (c-name "GikEventKey")
+;; (gtype-id "GIK_TYPE_EVENT_KEY")
+;; (copy-func "gik_event_copy")
+;; (release-func "gik_event_free")
+;; (fields
+;; '("gint" "type")
+;; '("guint" "state")
+;; '("guint" "keyval")
+;; '("guint16" "hardware_keycode")
+;; '("guint" "is_modifier")
+;; )
+;; )
+;;
+;; (define-boxed Event
+;; (in-module "Gik")
+;; (c-name "GikEvent")
+;; (gtype-id "GIK_TYPE_EVENT")
+;; (copy-func "gik_event_copy")
+;; (release-func "gik_event_free")
+;; (fields
+;; '("gint" "type")
+;; '("GikEventKey" "key")
+;; )
+;; )
+;;
diff --git a/bindings/python/ibus-virtual-methods.defs b/bindings/python/ibus-virtual-methods.defs
new file mode 100644
index 0000000..542f0b4
--- /dev/null
+++ b/bindings/python/ibus-virtual-methods.defs
@@ -0,0 +1,23 @@
+;; For GikEngine class
+;; (define-virtual filter_keypress
+;; (of-object "GikEngine")
+;; (return-type "gboolean")
+;; (parameters
+;; '("GikEventKey*" "key")
+;; )
+;; )
+;;
+;; (define-virtual focus_in
+;; (of-object "GikEngine")
+;; (return-type "none")
+;; )
+;;
+;; (define-virtual focus_out
+;; (of-object "GikEngine")
+;; (return-type "none")
+;; )
+;;
+;; (define-virtual reset
+;; (of-object "GikEngine")
+;; (return-type "none")
+;; )
diff --git a/bindings/python/ibus.defs b/bindings/python/ibus.defs
new file mode 100644
index 0000000..eada9c8
--- /dev/null
+++ b/bindings/python/ibus.defs
@@ -0,0 +1,5 @@
+(include "ibus-types.defs")
+(include "ibus-func.defs")
+(include "ibus-virtual-methods.defs")
+(include "ibus-codegen.defs")
+
diff --git a/bindings/python/ibus.override b/bindings/python/ibus.override
new file mode 100644
index 0000000..a00771c
--- /dev/null
+++ b/bindings/python/ibus.override
@@ -0,0 +1,11 @@
+%%
+headers
+#include "common.h"
+%%
+modulename ibus
+%%
+import gobject.GObject as PyGObject_Type
+%%
+ignore-glob
+ *_get_type
+%%
diff --git a/bindings/python/ibusmodule.c b/bindings/python/ibusmodule.c
new file mode 100644
index 0000000..875ff88
--- /dev/null
+++ b/bindings/python/ibusmodule.c
@@ -0,0 +1,29 @@
+#include <Python.h>
+#include <pygobject.h>
+
+void pyibus_register_classes (PyObject *d);
+void pyibus_add_constants (PyObject *module, const gchar *strip_prefix);
+extern PyMethodDef pyibus_functions[];
+
+
+DL_EXPORT(void)
+initibus (void)
+{
+ PyObject *m, *d;
+
+ init_pygobject ();
+
+ m = Py_InitModule ("ibus", pyibus_functions);
+ d = PyModule_GetDict (m);
+
+ pyibus_register_classes (d);
+
+ if (PyErr_Occurred ()) {
+ Py_FatalError ("unable to initialise ibus module");
+ }
+ pyibus_add_constants (m, "GIK_");
+ if (PyErr_Occurred ()) {
+ Py_FatalError ("unable to initialise ibus module");
+ }
+}
+
diff --git a/bus/.gitignore b/bus/.gitignore
new file mode 100644
index 0000000..847558d
--- /dev/null
+++ b/bus/.gitignore
@@ -0,0 +1,2 @@
+ibus-daemon
+test-matchrule
diff --git a/bus/Makefile.am b/bus/Makefile.am
new file mode 100644
index 0000000..d0f883a
--- /dev/null
+++ b/bus/Makefile.am
@@ -0,0 +1,99 @@
+# 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
+
+libibus = $(top_builddir)/src/libibus.la
+
+INCLUDES = \
+ -I$(top_srcdir)/src \
+ $(NULL)
+
+AM_CFLAGS = \
+ @GLIB2_CFLAGS@ \
+ @DBUS_CFLAGS@ \
+ -DG_LOG_DOMAIN=\"IBUS\" \
+ -DPKGDATADIR=\"$(pkgdatadir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ $(INCLUDES) \
+ $(NULL)
+AM_LDFLAGS = \
+ @GLIB2_LIBS@ \
+ @DBUS_LIBS@ \
+ $(libibus) \
+ $(NULL)
+
+TESTS = \
+ test-matchrule \
+ $(NULL)
+
+noinst_PROGRAMS = $(TESTS)
+bin_PROGRAMS = ibus-daemon
+ibus_daemon_DEPENDENCIES = \
+ $(libibus) \
+ $(NULL)
+ibus_daemon_SOURCES = \
+ main.c \
+ dbusimpl.c \
+ dbusimpl.h \
+ ibusimpl.c \
+ ibusimpl.h \
+ inputcontext.c \
+ inputcontext.h \
+ engineproxy.c \
+ engineproxy.h \
+ panelproxy.c \
+ panelproxy.h \
+ factoryproxy.c \
+ factoryproxy.h \
+ server.c \
+ server.h \
+ connection.c \
+ connection.h \
+ matchrule.c \
+ matchrule.h \
+ registry.c \
+ registry.h \
+ $(NULL)
+ibus_daemon_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(NULL)
+ibus_daemon_LDADD = \
+ $(AM_LDFLAGS) \
+ $(NULL)
+
+test_registry_SOURCES = \
+ registry.c \
+ registry.h \
+ factoryproxy.c \
+ factoryproxy.h \
+ test-registry.c \
+ $(NULL)
+
+test_matchrule_SOURCES = \
+ connection.c \
+ matchrule.c \
+ test-matchrule.c \
+ $(NULL)
+
+$(libibus):
+ $(MAKE) -C $(top_builddir)/src
+
+test: ibus-daemon
+ $(builddir)/ibus-daemon
diff --git a/bus/connection.c b/bus/connection.c
new file mode 100644
index 0000000..fd05ab1
--- /dev/null
+++ b/bus/connection.c
@@ -0,0 +1,261 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "connection.h"
+#include "matchrule.h"
+
+#define BUS_CONNECTION_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_CONNECTION, BusConnectionPrivate))
+
+/* BusConnectionPriv */
+struct _BusConnectionPrivate {
+ gchar *unique_name;
+ /* list for well known names */
+ GList *names;
+ GList *rules;
+};
+typedef struct _BusConnectionPrivate BusConnectionPrivate;
+
+// static guint _signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void bus_connection_class_init (BusConnectionClass *klass);
+static void bus_connection_init (BusConnection *connection);
+static void bus_connection_destroy (BusConnection *connection);
+static gboolean bus_connection_ibus_message (BusConnection *connection,
+ IBusMessage *message);
+#if 0
+static gboolean bus_connection_dbus_signal (BusConnection *connection,
+ DBusMessage *message);
+#endif
+
+static IBusObjectClass *parent_class = NULL;
+
+GType
+bus_connection_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusConnectionClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_connection_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusConnection),
+ 0,
+ (GInstanceInitFunc) bus_connection_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_CONNECTION,
+ "BusConnection",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+BusConnection *
+bus_connection_new (void)
+{
+ BusConnection *connection = BUS_CONNECTION (g_object_new (BUS_TYPE_CONNECTION, NULL));
+ return connection;
+}
+
+static void
+bus_connection_class_init (BusConnectionClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+ IBusConnectionClass *ibus_connection_class = IBUS_CONNECTION_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (BusConnectionPrivate));
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_connection_destroy;
+
+ ibus_connection_class->ibus_message =
+ (IBusIBusMessageFunc) bus_connection_ibus_message;
+
+}
+
+static void
+bus_connection_init (BusConnection *connection)
+{
+ BusConnectionPrivate *priv;
+
+ priv = BUS_CONNECTION_GET_PRIVATE (connection);
+
+ priv->unique_name = NULL;
+ priv->names = NULL;
+}
+
+static void
+bus_connection_destroy (BusConnection *connection)
+{
+ GList *name;
+ BusConnectionPrivate *priv;
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (connection));
+
+ priv = BUS_CONNECTION_GET_PRIVATE (connection);
+
+ if (priv->unique_name) {
+ g_free (priv->unique_name);
+ priv->unique_name = NULL;
+ }
+
+ for (name = priv->names; name != NULL; name = name->next) {
+ g_free (name->data);
+ }
+ g_list_free (priv->names);
+ priv->names = NULL;
+}
+
+static gboolean
+bus_connection_ibus_message (BusConnection *connection,
+ IBusMessage *message)
+{
+ gboolean retval;
+
+#if 0
+ gchar *str = ibus_message_to_string (message);
+ g_debug ("%s", str);
+ g_free(str);
+#endif
+
+ retval = IBUS_CONNECTION_CLASS (parent_class)->ibus_message (
+ (IBusConnection *)connection,
+ message);
+ return retval;
+}
+
+#if 0
+static gboolean
+bus_connection_dbus_signal (BusConnection *connection,
+ DBusMessage *message)
+{
+ gboolean retval;
+ retval = IBUS_CONNECTION_CLASS (parent_class)->dbus_signal (
+ IBUS_CONNECTION (connection), message);
+ return retval;
+}
+#endif
+
+const gchar *
+bus_connection_get_unique_name (BusConnection *connection)
+{
+ BusConnectionPrivate *priv;
+
+ priv = BUS_CONNECTION_GET_PRIVATE (connection);
+ return priv->unique_name;
+}
+
+void
+bus_connection_set_unique_name (BusConnection *connection,
+ const gchar *name)
+{
+ BusConnectionPrivate *priv;
+ priv = BUS_CONNECTION_GET_PRIVATE (connection);
+ g_assert (priv->unique_name == NULL);
+ priv->unique_name = g_strdup (name);
+}
+
+const GList *
+bus_connection_get_names (BusConnection *connection)
+{
+ BusConnectionPrivate *priv;
+
+ priv = BUS_CONNECTION_GET_PRIVATE (connection);
+ return priv->names;
+}
+
+const gchar *
+bus_connection_add_name (BusConnection *connection,
+ const gchar *name)
+{
+ gchar *new_name;
+ BusConnectionPrivate *priv;
+
+ priv = BUS_CONNECTION_GET_PRIVATE (connection);
+ new_name = g_strdup (name);
+ priv->names = g_list_append (priv->names, new_name);
+
+ return new_name;
+}
+
+gboolean
+bus_connection_remove_name (BusConnection *connection,
+ const gchar *name)
+{
+ BusConnectionPrivate *priv;
+ GList *link;
+
+ priv = BUS_CONNECTION_GET_PRIVATE (connection);
+
+ link = g_list_find_custom (priv->names, name, (GCompareFunc) g_strcmp0);
+
+ if (link) {
+ g_free (link->data);
+ priv->names = g_list_delete_link (priv->names, link);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+bus_connection_add_match (BusConnection *connection,
+ const gchar *rule)
+{
+ g_assert (BUS_IS_CONNECTION (connection));
+ g_assert (rule != NULL);
+
+ BusMatchRule *p;
+ GList *link;
+ BusConnectionPrivate *priv;
+
+ priv = BUS_CONNECTION_GET_PRIVATE (connection);
+
+ p = bus_match_rule_new (rule);
+ if (p == NULL)
+ return FALSE;
+
+ for (link = priv->rules; link != NULL; link = link->next) {
+ if (bus_match_rule_is_equal (p, (BusMatchRule *)link->data)) {
+ g_object_unref (p);
+ return TRUE;
+ }
+ }
+
+ priv->rules = g_list_append (priv->rules, p);
+ return TRUE;
+
+}
+
+gboolean
+bus_connection_remove_match (BusConnection *connection,
+ const gchar *rule)
+{
+ return FALSE;
+}
+
diff --git a/bus/connection.h b/bus/connection.h
new file mode 100644
index 0000000..1c0624d
--- /dev/null
+++ b/bus/connection.h
@@ -0,0 +1,71 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __CONNECTION_H_
+#define __CONNECTION_H_
+
+#include <ibus.h>
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_CONNECTION \
+ (bus_connection_get_type ())
+#define BUS_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_CONNECTION, BusConnection))
+#define BUS_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_CONNECTION, BusConnectionClass))
+#define BUS_IS_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_CONNECTION))
+#define BUS_IS_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_CONNECTION))
+#define BUS_CONNECTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_CONNECTION, BusConnectionClass))
+
+G_BEGIN_DECLS
+
+typedef struct _BusConnection BusConnection;
+typedef struct _BusConnectionClass BusConnectionClass;
+
+struct _BusConnection {
+ IBusConnection parent;
+ /* instance members */
+};
+
+struct _BusConnectionClass {
+ IBusConnectionClass parent;
+
+ /* class members */
+};
+
+GType bus_connection_get_type (void);
+BusConnection *bus_connection_new (void);
+const gchar *bus_connection_get_unique_name (BusConnection *connection);
+void bus_connection_set_unique_name (BusConnection *connection,
+ const gchar *name);
+const GList *bus_connection_get_names (BusConnection *connection);
+const gchar *bus_connection_add_name (BusConnection *connection,
+ const gchar *name);
+gboolean bus_connection_remove_name (BusConnection *connection,
+ const gchar *name);
+G_END_DECLS
+#endif
+
diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c
new file mode 100644
index 0000000..6a70f89
--- /dev/null
+++ b/bus/dbusimpl.c
@@ -0,0 +1,1174 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <ibusinternal.h>
+#include <ibusmarshalers.h>
+#include "dbusimpl.h"
+#include "connection.h"
+#include "matchrule.h"
+
+#define BUS_DBUS_IMPL_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_DBUS_IMPL, BusDBusImplPrivate))
+
+enum {
+ NAME_ACQUIRED,
+ NAME_LOST,
+ NAME_OWNER_CHANGED,
+ LAST_SIGNAL,
+};
+
+enum {
+ PROP_0,
+};
+
+
+/* IBusDBusImplPriv */
+struct _BusDBusImplPrivate {
+ GHashTable *unique_names;
+ GHashTable *names;
+ GHashTable *objects;
+ GList *connections;
+ GList *rules;
+ gint id;
+};
+
+typedef struct _BusDBusImplPrivate BusDBusImplPrivate;
+
+static guint dbus_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void bus_dbus_impl_class_init (BusDBusImplClass *klass);
+static void bus_dbus_impl_init (BusDBusImpl *dbus);
+static void bus_dbus_impl_dispose (BusDBusImpl *dbus);
+static gboolean bus_dbus_impl_ibus_message (BusDBusImpl *dbus,
+ BusConnection *connection,
+ IBusMessage *message);
+static void bus_dbus_impl_name_owner_changed
+ (BusDBusImpl *dbus,
+ gchar *name,
+ gchar *old_name,
+ gchar *new_name);
+
+static IBusServiceClass *parent_class = NULL;
+
+GType
+bus_dbus_impl_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusDBusImplClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_dbus_impl_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusDBusImpl),
+ 0,
+ (GInstanceInitFunc) bus_dbus_impl_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERVICE,
+ "BusDBusImpl",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+ return type;
+}
+
+BusDBusImpl *
+bus_dbus_impl_get_default (void)
+{
+ // BusDBusImplPrivate *priv;
+ static BusDBusImpl *dbus = NULL;
+
+ if (dbus == NULL) {
+ dbus = (BusDBusImpl *) g_object_new (BUS_TYPE_DBUS_IMPL,
+ "path", DBUS_PATH_DBUS,
+ NULL);
+ }
+
+ return dbus;
+}
+
+static void
+bus_dbus_impl_class_init (BusDBusImplClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ IBusServiceClass *service_class = IBUS_SERVICE_CLASS (klass);
+
+ parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (BusDBusImplPrivate));
+
+ gobject_class->dispose = (GObjectFinalizeFunc) bus_dbus_impl_dispose;
+
+ service_class->ibus_message = (ServiceIBusMessageFunc) bus_dbus_impl_ibus_message;
+
+ klass->name_owner_changed = bus_dbus_impl_name_owner_changed;
+
+ /* install signals */
+ dbus_signals[NAME_OWNER_CHANGED] =
+ g_signal_new (I_("name-owner-changed"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (BusDBusImplClass, name_owner_changed),
+ NULL, NULL,
+ ibus_marshal_VOID__STRING_STRING_STRING,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+}
+
+static void
+bus_dbus_impl_init (BusDBusImpl *dbus)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ priv->unique_names = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->names = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->objects = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->connections = NULL;
+ priv->rules = NULL;
+ priv->id = 1;
+
+ g_object_ref (dbus);
+ g_hash_table_insert (priv->objects, DBUS_PATH_DBUS, dbus);
+}
+
+static void
+bus_dbus_impl_dispose (BusDBusImpl *dbus)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ G_OBJECT_CLASS(parent_class)->dispose (G_OBJECT (dbus));
+}
+
+
+/* introspectable interface */
+static IBusMessage *
+_dbus_introspect (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ static const gchar *introspect =
+ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+ "<node>\n"
+ " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+ " <method name=\"Introspect\">\n"
+ " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " </interface>\n"
+ " <interface name=\"org.freedesktop.DBus\">\n"
+ " <method name=\"Hello\">\n"
+ " <arg direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"RequestName\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"in\" type=\"u\"/>\n"
+ " <arg direction=\"out\" type=\"u\"/>\n"
+ " </method>\n"
+ " <method name=\"ReleaseName\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"out\" type=\"u\"/>\n"
+ " </method>\n"
+ " <method name=\"StartServiceByName\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"in\" type=\"u\"/>\n"
+ " <arg direction=\"out\" type=\"u\"/>\n"
+ " </method>\n"
+ " <method name=\"UpdateActivationEnvironment\">\n"
+ " <arg direction=\"in\" type=\"a{ss}\"/>\n"
+ " </method>\n"
+ " <method name=\"NameHasOwner\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"ListNames\">\n"
+ " <arg direction=\"out\" type=\"as\"/>\n"
+ " </method>\n"
+ " <method name=\"ListActivatableNames\">\n"
+ " <arg direction=\"out\" type=\"as\"/>\n"
+ " </method>\n"
+ " <method name=\"AddMatch\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"RemoveMatch\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"GetNameOwner\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"ListQueuedOwners\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"out\" type=\"as\"/>\n"
+ " </method>\n"
+ " <method name=\"GetConnectionUnixUser\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"out\" type=\"u\"/>\n"
+ " </method>\n"
+ " <method name=\"GetConnectionUnixProcessID\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"out\" type=\"u\"/>\n"
+ " </method>\n"
+ " <method name=\"GetAdtAuditSessionData\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"out\" type=\"ay\"/>\n"
+ " </method>\n"
+ " <method name=\"GetConnectionSELinuxSecurityContext\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"out\" type=\"ay\"/>\n"
+ " </method>\n"
+ " <method name=\"ReloadConfig\">\n"
+ " </method>\n"
+ " <method name=\"GetId\">\n"
+ " <arg direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " <signal name=\"NameOwnerChanged\">\n"
+ " <arg type=\"s\"/>\n"
+ " <arg type=\"s\"/>\n"
+ " <arg type=\"s\"/>\n"
+ " </signal>\n"
+ " <signal name=\"NameLost\">\n"
+ " <arg type=\"s\"/>\n"
+ " </signal>\n"
+ " <signal name=\"NameAcquired\">\n"
+ " <arg type=\"s\"/>\n"
+ " </signal>\n"
+ " </interface>\n"
+ "</node>\n";
+
+ IBusMessage *reply_message;
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ G_TYPE_STRING, &introspect,
+ G_TYPE_INVALID);
+
+ return reply_message;
+}
+
+
+/* dbus interface */
+static IBusMessage *
+_dbus_no_implement (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ IBusMessage *reply_message;
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_UNKNOWN_METHOD,
+ "IBus does not support %s.",
+ ibus_message_get_member (message));
+ return reply_message;
+}
+
+
+static IBusMessage *
+_dbus_hello (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ IBusMessage *reply_message;
+
+ if (bus_connection_get_unique_name (connection) != NULL) {
+ reply_message = ibus_message_new_error (message,
+ DBUS_ERROR_FAILED,
+ "Already handled an Hello message");
+ }
+ else {
+ gchar *name;
+
+ name = g_strdup_printf (":1.%d", priv->id ++);
+ bus_connection_set_unique_name (connection, name);
+ g_free (name);
+
+ name = (gchar *) bus_connection_get_unique_name (connection);
+ g_hash_table_insert (priv->unique_names, name, connection);
+
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID);
+
+ ibus_connection_send ((IBusConnection *) connection, reply_message);
+ ibus_message_unref (reply_message);
+ ibus_connection_flush ((IBusConnection *) connection);
+ reply_message = NULL;
+
+ g_signal_emit (dbus,
+ dbus_signals[NAME_OWNER_CHANGED],
+ 0,
+ name,
+ "",
+ name);
+
+ }
+
+ return reply_message;
+}
+
+static IBusMessage *
+_dbus_list_names (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ IBusMessage *reply_message;
+ IBusMessageIter iter, sub_iter;
+ GList *name, *names;
+
+ reply_message = ibus_message_new_method_return (message);
+
+ ibus_message_iter_init_append (message, &iter);
+ ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "s", &sub_iter);
+
+ // append unique names
+ names = g_hash_table_get_keys (priv->unique_names);
+
+ names = g_list_sort (names, (GCompareFunc) g_strcmp0);
+ for (name = names; name != NULL; name = name->next) {
+ ibus_message_iter_append (&sub_iter, G_TYPE_STRING, &(name->data));
+ }
+ g_list_free (names);
+
+ // append well-known names
+ names = g_hash_table_get_keys (priv->names);
+ names = g_list_sort (names, (GCompareFunc) g_strcmp0);
+ for (name = names; name != NULL; name = name->next) {
+ ibus_message_iter_append (&sub_iter, G_TYPE_STRING, &(name->data));
+ }
+ g_list_free (names);
+
+ ibus_message_iter_close_container (&iter, &sub_iter);
+
+ return reply_message;
+}
+
+static IBusMessage *
+_dbus_name_has_owner (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ gchar *name;
+ gboolean retval;
+ gboolean has_owner;
+ IBusMessage *reply_message;
+ IBusError *error;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID);
+
+ if (! retval) {
+ reply_message = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply_message;
+ }
+
+ if (name[0] == ':') {
+ has_owner = g_hash_table_lookup (priv->unique_names, name) != NULL;
+ }
+ else {
+ has_owner = g_hash_table_lookup (priv->names, name) != NULL;
+ }
+
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ G_TYPE_BOOLEAN, &has_owner,
+ G_TYPE_INVALID);
+
+ return reply_message;
+}
+
+
+static IBusMessage *
+_dbus_get_name_owner (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ gchar *name;
+ BusConnection *owner;
+ gboolean retval;
+ const gchar *owner_name = NULL;
+ IBusMessage *reply_message;
+ IBusError *error;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID);
+
+ if (! retval) {
+ reply_message = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply_message;
+ }
+
+ if (g_strcmp0 (name, DBUS_SERVICE_DBUS) == 0 ||
+ g_strcmp0 (name, IBUS_SERVICE_IBUS) == 0) {
+ owner_name = name;
+ }
+ else {
+ owner = bus_dbus_impl_get_connection_by_name (dbus, name);
+ if (owner != NULL) {
+ owner_name = bus_connection_get_unique_name (owner);
+ }
+ }
+
+ if (owner_name != NULL) {
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ G_TYPE_STRING, &owner_name,
+ G_TYPE_INVALID);
+ }
+ else {
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_NAME_HAS_NO_OWNER,
+ "Name '%s' does have owner",
+ name);
+ }
+
+ return reply_message;
+}
+
+static IBusMessage *
+_dbus_get_id (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ IBusMessage *reply_message;
+ const gchar *name;
+
+ name = bus_connection_get_unique_name (connection);
+
+ if (name == NULL) {
+ reply_message = ibus_message_new_error (message,
+ DBUS_ERROR_FAILED,
+ "Can not GetId before Hello");
+ return reply_message;
+ }
+
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID);
+ return reply_message;
+}
+
+static void
+_rule_destroy_cb (BusMatchRule *rule,
+ BusDBusImpl *dbus)
+{
+ g_assert (BUS_IS_MATCH_RULE (rule));
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ priv->rules = g_list_remove (priv->rules, rule);
+ g_object_unref (rule);
+}
+
+static IBusMessage *
+_dbus_add_match (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ IBusMessage *reply_message;
+ IBusError *error;
+ gboolean retval;
+ gchar *rule_text;
+ BusMatchRule *rule;
+ GList *link;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &rule_text,
+ G_TYPE_INVALID);
+
+ if (!retval) {
+ reply_message = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply_message;
+ }
+
+ rule = bus_match_rule_new (rule_text);
+
+ if (rule == NULL) {
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_MATCH_RULE_INVALID,
+ "Parse rule [%s] failed",
+ rule_text);
+ return reply_message;
+ }
+
+ for (link = priv->rules; link != NULL; link = link->next) {
+ if (bus_match_rule_is_equal (rule, BUS_MATCH_RULE (link->data))) {
+ bus_match_rule_add_recipient (BUS_MATCH_RULE (link->data), connection);
+ g_object_unref (rule);
+ rule = NULL;
+ break;
+ }
+ }
+
+ if (rule) {
+ bus_match_rule_add_recipient (rule, connection);
+ priv->rules = g_list_append (priv->rules, rule);
+ g_signal_connect (rule, "destroy", G_CALLBACK (_rule_destroy_cb), dbus);
+ }
+
+ reply_message = ibus_message_new_method_return (message);
+ return reply_message;
+}
+
+static IBusMessage *
+_dbus_remove_match (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ IBusMessage *reply_message;
+ IBusError *error;
+ gchar *rule_text;
+ BusMatchRule *rule;
+ GList *link;
+
+ if (!ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &rule_text,
+ G_TYPE_INVALID)) {
+ reply_message = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply_message;
+ }
+
+ rule = bus_match_rule_new (rule_text);
+
+ if (rule == NULL ) {
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_MATCH_RULE_INVALID,
+ "Parse rule [%s] failed",
+ rule_text);
+ return reply_message;
+ }
+
+ for (link = priv->rules; link != NULL; link = link->next) {
+ if (bus_match_rule_is_equal (rule, BUS_MATCH_RULE (link->data))) {
+ bus_match_rule_remove_recipient (BUS_MATCH_RULE (link->data), connection);
+ break;
+ }
+ }
+
+ g_object_unref (rule);
+
+ reply_message = ibus_message_new_method_return (message);
+ return reply_message;
+}
+
+static IBusMessage *
+_dbus_request_name (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ IBusMessage *reply_message;
+ IBusError *error;
+ gchar *name;
+ guint flags;
+ guint retval;
+
+ if (!ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &name,
+ G_TYPE_UINT, &flags,
+ G_TYPE_INVALID)) {
+ reply_message = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply_message;
+ }
+
+ if (g_hash_table_lookup (priv->names, name) != NULL) {
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_FAILED,
+ "Name %s has owner",
+ name);
+ return reply_message;
+ }
+
+ retval = 1;
+ g_hash_table_insert (priv->names,
+ (gpointer )bus_connection_add_name (connection, name),
+ connection);
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ G_TYPE_UINT, &retval,
+ G_TYPE_INVALID);
+
+ ibus_connection_send ((IBusConnection *) connection, reply_message);
+ ibus_message_unref (reply_message);
+ ibus_connection_flush ((IBusConnection *) connection);
+
+ g_signal_emit (dbus,
+ dbus_signals[NAME_OWNER_CHANGED],
+ 0,
+ name,
+ "",
+ bus_connection_get_unique_name (connection));
+
+ return NULL;
+}
+
+static IBusMessage *
+_dbus_release_name (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ IBusMessage *reply_message;
+ IBusError *error;
+ gchar *name;
+ guint retval;
+
+ if (!ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID)) {
+ reply_message = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply_message;
+ }
+
+ reply_message = ibus_message_new_method_return (message);
+ if (bus_connection_remove_name (connection, name)) {
+ retval = 1;
+ }
+ else {
+ retval = 2;
+ }
+
+ ibus_message_append_args (message,
+ G_TYPE_UINT, &retval,
+ G_TYPE_INVALID);
+
+ return reply_message;
+}
+
+
+static gboolean
+bus_dbus_impl_ibus_message (BusDBusImpl *dbus,
+ BusConnection *connection,
+ IBusMessage *message)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (BUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+
+ gint i;
+ IBusMessage *reply_message = NULL;
+
+ static const struct {
+ const gchar *interface;
+ const gchar *name;
+ IBusMessage *(* handler) (BusDBusImpl *, IBusMessage *, BusConnection *);
+ } handlers[] = {
+ /* Introspectable interface */
+ { DBUS_INTERFACE_INTROSPECTABLE,
+ "Introspect", _dbus_introspect },
+ /* DBus interface */
+ { DBUS_INTERFACE_DBUS, "Hello", _dbus_hello },
+ { DBUS_INTERFACE_DBUS, "ListNames", _dbus_list_names },
+ { DBUS_INTERFACE_DBUS, "ListActivatableNames",
+ _dbus_no_implement },
+ { DBUS_INTERFACE_DBUS, "NameHasOwner",
+ _dbus_name_has_owner },
+ { DBUS_INTERFACE_DBUS, "StartServiceByName",
+ _dbus_no_implement },
+ { DBUS_INTERFACE_DBUS, "GetNameOwner",
+ _dbus_get_name_owner },
+ { DBUS_INTERFACE_DBUS, "GetConnectionUnixUser",
+ _dbus_no_implement },
+ { DBUS_INTERFACE_DBUS, "AddMatch", _dbus_add_match },
+ { DBUS_INTERFACE_DBUS, "RemoveMatch",
+ _dbus_remove_match },
+ { DBUS_INTERFACE_DBUS, "GetId", _dbus_get_id },
+ { DBUS_INTERFACE_DBUS, "RequestName", _dbus_request_name },
+ { DBUS_INTERFACE_DBUS, "ReleaseName", _dbus_release_name },
+ { NULL, NULL, NULL }
+ };
+
+ ibus_message_set_destination (message, DBUS_SERVICE_DBUS);
+
+ for (i = 0; handlers[i].interface != NULL; i++) {
+ if (ibus_message_is_method_call (message,
+ handlers[i].interface,
+ handlers[i].name)) {
+
+ reply_message = handlers[i].handler (dbus, message, connection);
+ if (reply_message) {
+
+ ibus_message_set_sender (reply_message, DBUS_SERVICE_DBUS);
+ ibus_message_set_destination (reply_message,
+ bus_connection_get_unique_name (connection));
+ ibus_message_set_no_reply (reply_message, TRUE);
+
+ ibus_connection_send (IBUS_CONNECTION (connection), reply_message);
+ ibus_message_unref (reply_message);
+ }
+
+ g_signal_stop_emission_by_name (dbus, "ibus-message");
+ return TRUE;
+ }
+ }
+
+ return parent_class->ibus_message ((IBusService *) dbus,
+ (IBusConnection *) connection,
+ message);
+}
+
+static void
+bus_dbus_impl_name_owner_changed (BusDBusImpl *dbus,
+ gchar *name,
+ gchar *old_name,
+ gchar *new_name)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (name != NULL);
+ g_assert (old_name != NULL);
+ g_assert (new_name != NULL);
+
+ IBusMessage *message;
+
+ message = ibus_message_new_signal (DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "NameOwnerChanged");
+ ibus_message_append_args (message,
+ G_TYPE_STRING, &name,
+ G_TYPE_STRING, &old_name,
+ G_TYPE_STRING, &new_name,
+ G_TYPE_INVALID);
+ ibus_message_set_sender (message, DBUS_SERVICE_DBUS);
+
+ bus_dbus_impl_dispatch_message_by_rule (dbus, message, NULL);
+
+ ibus_message_unref (message);
+
+}
+
+static gboolean
+_connection_ibus_message_cb (BusConnection *connection,
+ IBusMessage *message,
+ BusDBusImpl *dbus)
+{
+ g_assert (BUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+
+ const gchar *dest;
+
+ if (ibus_message_is_signal (message,
+ DBUS_INTERFACE_LOCAL,
+ "Disconnected")) {
+ /* ignore signal from local interface */
+ return FALSE;
+ }
+
+ ibus_message_set_sender (message, bus_connection_get_unique_name (connection));
+
+ switch (ibus_message_get_type (message)) {
+ case DBUS_MESSAGE_TYPE_ERROR:
+ g_debug ("From :%s to %s, Error: %s : %s",
+ ibus_message_get_sender (message),
+ ibus_message_get_destination (message),
+ ibus_message_get_error_name (message),
+ ibus_message_get_error_message (message));
+ break;
+#if 0
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ g_debug("From %s to %s, Method %s on %s",
+ ibus_message_get_sender (message),
+ ibus_message_get_destination (message),
+ ibus_message_get_path (message),
+ ibus_message_get_member (message));
+ break;
+#endif
+ }
+
+ dest = ibus_message_get_destination (message);
+
+ if (dest == NULL ||
+ strcmp ((gchar *)dest, IBUS_SERVICE_IBUS) == 0 ||
+ strcmp ((gchar *)dest, DBUS_SERVICE_DBUS) == 0) {
+ /* this message is sent to ibus-daemon */
+
+ switch (ibus_message_get_type (message)) {
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ case DBUS_MESSAGE_TYPE_ERROR:
+ bus_dbus_impl_dispatch_message_by_rule (dbus, message, NULL);
+ return FALSE;
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ {
+ const gchar *path;
+ IBusService *object;
+
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ path = ibus_message_get_path (message);
+
+ object = g_hash_table_lookup (priv->objects, path);
+
+ if (object == NULL ||
+ ibus_service_handle_message (object,
+ (IBusConnection *) connection,
+ message) == FALSE) {
+ IBusMessage *error;
+ error = ibus_message_new_error_printf (message,
+ DBUS_ERROR_UNKNOWN_METHOD,
+ "Unknown method %s on %s",
+ ibus_message_get_member (message),
+ path);
+ ibus_connection_send ((IBusConnection *) connection, error);
+ ibus_message_unref (error);
+ }
+
+ /* dispatch message */
+ bus_dbus_impl_dispatch_message_by_rule (dbus, message, NULL);
+ }
+ break;
+ default:
+ g_assert (FALSE);
+ }
+ }
+ else {
+ /* If the destination is not IBus or DBus, the message will be forwanded. */
+ bus_dbus_impl_dispatch_message (dbus, message);
+ }
+
+ g_signal_stop_emission_by_name (connection, "ibus-message");
+ return TRUE;
+}
+
+static void
+_connection_ibus_message_sent_cb (BusConnection *connection,
+ IBusMessage *message,
+ BusDBusImpl *dbus)
+{
+ g_assert (BUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+
+ bus_dbus_impl_dispatch_message_by_rule (dbus, message, connection);
+}
+
+static void
+_connection_destroy_cb (BusConnection *connection,
+ BusDBusImpl *dbus)
+{
+ g_assert (BUS_IS_CONNECTION (connection));
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ /*
+ ibus_service_remove_from_connection (
+ IBUS_SERVICE (dbus),
+ IBUS_CONNECTION (connection));
+ */
+
+ const gchar *unique_name = bus_connection_get_unique_name (connection);
+ if (unique_name != NULL) {
+ g_hash_table_remove (priv->unique_names, unique_name);
+ g_signal_emit (dbus,
+ dbus_signals[NAME_OWNER_CHANGED],
+ 0,
+ unique_name,
+ unique_name,
+ "");
+ }
+
+ const GList *name = bus_connection_get_names (connection);
+
+ while (name != NULL) {
+ g_hash_table_remove (priv->names, name->data);
+ g_signal_emit (dbus,
+ dbus_signals[NAME_OWNER_CHANGED],
+ 0,
+ name->data,
+ unique_name,
+ "");
+ name = name->next;
+ }
+
+ priv->connections = g_list_remove (priv->connections, connection);
+ g_object_unref (connection);
+}
+
+
+gboolean
+bus_dbus_impl_new_connection (BusDBusImpl *dbus,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ g_assert (g_list_find (priv->connections, connection) == NULL);
+
+ g_object_ref (connection);
+ priv->connections = g_list_append (priv->connections, connection);
+
+ g_signal_connect (connection,
+ "ibus-message",
+ G_CALLBACK (_connection_ibus_message_cb),
+ dbus);
+
+ g_signal_connect (connection,
+ "ibus-message-sent",
+ G_CALLBACK (_connection_ibus_message_sent_cb),
+ dbus);
+
+
+ g_signal_connect (connection,
+ "destroy",
+ G_CALLBACK (_connection_destroy_cb),
+ dbus);
+ return TRUE;
+}
+
+
+BusConnection *
+bus_dbus_impl_get_connection_by_name (BusDBusImpl *dbus,
+ const gchar *name)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (name != NULL);
+
+ BusConnection *connection = NULL;
+
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ if (name[0] == ':') {
+ connection = BUS_CONNECTION (g_hash_table_lookup (
+ priv->unique_names,
+ name));
+ }
+ else {
+ connection = BUS_CONNECTION (g_hash_table_lookup (
+ priv->names,
+ name));
+ }
+
+ return connection;
+}
+
+
+void
+bus_dbus_impl_dispatch_message (BusDBusImpl *dbus,
+ IBusMessage *message)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (message != NULL);
+
+ const gchar *destination;
+ BusConnection *dest_connection = NULL;
+
+ destination = ibus_message_get_destination (message);
+
+ if (destination != NULL) {
+ dest_connection = bus_dbus_impl_get_connection_by_name (dbus, destination);
+
+ if (dest_connection != NULL) {
+ ibus_connection_send (IBUS_CONNECTION (dest_connection), message);
+ }
+ else {
+ IBusMessage *reply_message;
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_SERVICE_UNKNOWN,
+ "Can not find service %s",
+ destination);
+ bus_dbus_impl_dispatch_message (dbus, reply_message);
+ ibus_message_unref (reply_message);
+ }
+ }
+
+ bus_dbus_impl_dispatch_message_by_rule (dbus, message, dest_connection);
+}
+
+void
+bus_dbus_impl_dispatch_message_by_rule (BusDBusImpl *dbus,
+ IBusMessage *message,
+ BusConnection *skip_connection)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (skip_connection) || skip_connection == NULL);
+
+ GList *recipients = NULL;
+ GList *link = NULL;
+
+ static gint32 data_slot = -1;
+
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ if (data_slot == -1) {
+ dbus_message_allocate_data_slot (&data_slot);
+ }
+
+ /* If this message has been dispatched by rule, it will be ignored. */
+ if (dbus_message_get_data (message, data_slot) != NULL)
+ return;
+
+ dbus_message_set_data (message, data_slot, (gpointer) TRUE, NULL);
+
+#if 0
+ if (g_strcmp0 (ibus_message_get_member (message), "ValueChanged") == 0) {
+ g_debug ("Dispatch ValueChanged");
+ }
+#endif
+
+ for (link = priv->rules; link != NULL; link = link->next) {
+ if (bus_match_rule_get_recipients (BUS_MATCH_RULE (link->data),
+ message,
+ &recipients)) {
+ break;
+ }
+ }
+
+ for (link = recipients; link != NULL; link = link->next) {
+ BusConnection *connection = BUS_CONNECTION (link->data);
+ if (connection != skip_connection) {
+ ibus_connection_send (IBUS_CONNECTION (connection), message);
+ }
+ g_object_unref (link->data);
+ }
+ g_list_free (recipients);
+}
+
+
+static void
+_object_destroy_cb (IBusService *object,
+ BusDBusImpl *dbus)
+{
+ gboolean retval;
+
+ retval = bus_dbus_impl_unregister_object (dbus, object);
+
+ g_assert (retval);
+}
+
+gboolean
+bus_dbus_impl_register_object (BusDBusImpl *dbus,
+ IBusService *object)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (IBUS_IS_SERVICE (object));
+
+ const gchar *path;
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ path = ibus_service_get_path (object);
+
+ g_return_val_if_fail (path, FALSE);
+
+ g_return_val_if_fail (g_hash_table_lookup (priv->objects, path) == NULL, FALSE);
+
+ g_object_ref (object);
+ g_hash_table_insert (priv->objects, (gpointer)path, object);
+
+ g_signal_connect (object, "destroy", G_CALLBACK (_object_destroy_cb), dbus);
+
+ return TRUE;
+}
+
+gboolean
+bus_dbus_impl_unregister_object (BusDBusImpl *dbus,
+ IBusService *object)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (IBUS_IS_SERVICE (object));
+
+ const gchar *path;
+ BusDBusImplPrivate *priv;
+ priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+
+ path = ibus_service_get_path (object);
+ g_return_val_if_fail (path, FALSE);
+
+ g_return_val_if_fail (g_hash_table_lookup (priv->objects, path) == object, FALSE);
+
+ g_signal_handlers_disconnect_by_func (object, G_CALLBACK (_object_destroy_cb), dbus);
+
+ g_hash_table_remove (priv->objects, path);
+ g_object_unref (object);
+
+ return TRUE;
+}
+
diff --git a/bus/dbusimpl.h b/bus/dbusimpl.h
new file mode 100644
index 0000000..d04326e
--- /dev/null
+++ b/bus/dbusimpl.h
@@ -0,0 +1,87 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __DBUS_IMPL_H_
+#define __DBUS_IMPL_H_
+
+#include <ibus.h>
+#include "connection.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_DBUS_IMPL \
+ (bus_dbus_impl_get_type ())
+#define BUS_DBUS_IMPL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_DBUS_IMPL, BusDBusImpl))
+#define BUS_DBUS_IMPL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_DBUS_IMPL, BusDBusImplClass))
+#define BUS_IS_DBUS_IMPL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_DBUS_IMPL))
+#define BUS_IS_DBUS_IMPL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_DBUS_IMPL))
+#define BUS_DBUS_IMPL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_DBUS_IMPL, BusDBusImplClass))
+
+#define BUS_DEFAULT_DBUS \
+ (bus_dbus_impl_get_default ())
+
+G_BEGIN_DECLS
+
+typedef struct _BusDBusImpl BusDBusImpl;
+typedef struct _BusDBusImplClass BusDBusImplClass;
+
+struct _BusDBusImpl {
+ IBusService parent;
+ /* instance members */
+};
+
+struct _BusDBusImplClass {
+ IBusServiceClass parent;
+
+ /* class members */
+ void (* name_owner_changed) (BusDBusImpl *dbus,
+ gchar *name,
+ gchar *old_name,
+ gchar *new_name);
+};
+
+GType bus_dbus_impl_get_type (void);
+BusDBusImpl *bus_dbus_impl_get_default (void);
+gboolean bus_dbus_impl_new_connection (BusDBusImpl *dbus,
+ BusConnection *connection);
+BusConnection *bus_dbus_impl_get_connection_by_name
+ (BusDBusImpl *dbus,
+ const gchar *name);
+void bus_dbus_impl_dispatch_message (BusDBusImpl *dbus,
+ DBusMessage *message);
+void bus_dbus_impl_dispatch_message_by_rule
+ (BusDBusImpl *dbus,
+ DBusMessage *message,
+ BusConnection *skip_connection);
+gboolean bus_dbus_impl_register_object (BusDBusImpl *dbus,
+ IBusService *object);
+gboolean bus_dbus_impl_unregister_object(BusDBusImpl *dbus,
+ IBusService *object);
+
+G_END_DECLS
+#endif
+
diff --git a/bus/engineproxy.c b/bus/engineproxy.c
new file mode 100644
index 0000000..963dfe2
--- /dev/null
+++ b/bus/engineproxy.c
@@ -0,0 +1,716 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ibusinternal.h>
+#include <ibusmarshalers.h>
+#include "engineproxy.h"
+
+#define BUS_ENGINE_PROXY_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_ENGINE_PROXY, BusEngineProxyPrivate))
+
+enum {
+ COMMIT_TEXT,
+ FORWARD_KEY_EVENT,
+ UPDATE_PREEDIT_TEXT,
+ SHOW_PREEDIT_TEXT,
+ HIDE_PREEDIT_TEXT,
+ UPDATE_AUXILIARY_TEXT,
+ SHOW_AUXILIARY_TEXT,
+ HIDE_AUXILIARY_TEXT,
+ UPDATE_LOOKUP_TABLE,
+ SHOW_LOOKUP_TABLE,
+ HIDE_LOOKUP_TABLE,
+ PAGE_UP_LOOKUP_TABLE,
+ PAGE_DOWN_LOOKUP_TABLE,
+ CURSOR_UP_LOOKUP_TABLE,
+ CURSOR_DOWN_LOOKUP_TABLE,
+ REGISTER_PROPERTIES,
+ UPDATE_PROPERTY,
+ LAST_SIGNAL,
+};
+
+
+/* BusEngineProxyPriv */
+struct _BusEngineProxyPrivate {
+ gboolean enabled;
+ IBusEngineDesc *desc;
+
+ IBusPropList *prop_list;
+};
+typedef struct _BusEngineProxyPrivate BusEngineProxyPrivate;
+
+static guint engine_signals[LAST_SIGNAL] = { 0 };
+// static guint engine_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void bus_engine_proxy_class_init (BusEngineProxyClass *klass);
+static void bus_engine_proxy_init (BusEngineProxy *engine);
+static void bus_engine_proxy_real_destroy (BusEngineProxy *engine);
+
+static gboolean bus_engine_proxy_ibus_signal (IBusProxy *proxy,
+ IBusMessage *message);
+
+static IBusProxyClass *parent_class = NULL;
+
+GType
+bus_engine_proxy_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusEngineProxyClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_engine_proxy_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusEngineProxy),
+ 0,
+ (GInstanceInitFunc) bus_engine_proxy_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_PROXY,
+ "BusEngineProxy",
+ &type_info,
+ (GTypeFlags)0);
+ }
+ return type;
+}
+
+BusEngineProxy *
+bus_engine_proxy_new (const gchar *path,
+ IBusEngineDesc *desc,
+ BusConnection *connection)
+{
+ g_assert (path);
+ g_assert (IBUS_IS_ENGINE_DESC (desc));
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ BusEngineProxy *engine;
+
+ engine = (BusEngineProxy *) g_object_new (BUS_TYPE_ENGINE_PROXY,
+ "name", NULL,
+ "path", path,
+ "connection", connection,
+ NULL);
+
+ BusEngineProxyPrivate *priv;
+ priv = BUS_ENGINE_PROXY_GET_PRIVATE (engine);
+ priv->desc = desc;
+ g_object_ref (desc);
+
+ return engine;
+}
+
+static void
+bus_engine_proxy_class_init (BusEngineProxyClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+ IBusProxyClass *proxy_class = IBUS_PROXY_CLASS (klass);
+
+
+ parent_class = (IBusProxyClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (BusEngineProxyPrivate));
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_engine_proxy_real_destroy;
+
+ proxy_class->ibus_signal = bus_engine_proxy_ibus_signal;
+
+ /* install signals */
+ engine_signals[COMMIT_TEXT] =
+ g_signal_new (I_("commit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IBUS_TYPE_TEXT);
+
+ engine_signals[FORWARD_KEY_EVENT] =
+ g_signal_new (I_("forward-key-event"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_UINT,
+ G_TYPE_UINT);
+
+ engine_signals[UPDATE_PREEDIT_TEXT] =
+ g_signal_new (I_("update-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT_UINT_BOOLEAN,
+ G_TYPE_NONE,
+ 3,
+ IBUS_TYPE_TEXT,
+ G_TYPE_UINT,
+ G_TYPE_BOOLEAN);
+
+ engine_signals[SHOW_PREEDIT_TEXT] =
+ g_signal_new (I_("show-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[HIDE_PREEDIT_TEXT] =
+ g_signal_new (I_("hide-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[UPDATE_AUXILIARY_TEXT] =
+ g_signal_new (I_("update-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE,
+ 2,
+ IBUS_TYPE_TEXT,
+ G_TYPE_BOOLEAN);
+
+ engine_signals[SHOW_AUXILIARY_TEXT] =
+ g_signal_new (I_("show-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[HIDE_AUXILIARY_TEXT] =
+ g_signal_new (I_("hide-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[UPDATE_LOOKUP_TABLE] =
+ g_signal_new (I_("update-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__BOXED_BOOLEAN,
+ G_TYPE_NONE,
+ 2,
+ IBUS_TYPE_LOOKUP_TABLE,
+ G_TYPE_BOOLEAN);
+
+ engine_signals[SHOW_LOOKUP_TABLE] =
+ g_signal_new (I_("show-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[HIDE_LOOKUP_TABLE] =
+ g_signal_new (I_("hide-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[PAGE_UP_LOOKUP_TABLE] =
+ g_signal_new (I_("page-up-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[PAGE_DOWN_LOOKUP_TABLE] =
+ g_signal_new (I_("page-down-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[CURSOR_UP_LOOKUP_TABLE] =
+ g_signal_new (I_("cursor-up-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[CURSOR_DOWN_LOOKUP_TABLE] =
+ g_signal_new (I_("cursor-down-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ engine_signals[REGISTER_PROPERTIES] =
+ g_signal_new (I_("register-properties"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IBUS_TYPE_PROP_LIST);
+
+ engine_signals[UPDATE_PROPERTY] =
+ g_signal_new (I_("update-property"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IBUS_TYPE_PROPERTY);
+
+}
+
+static void
+bus_engine_proxy_init (BusEngineProxy *engine)
+{
+ BusEngineProxyPrivate *priv;
+ priv = BUS_ENGINE_PROXY_GET_PRIVATE (engine);
+
+ priv->enabled = FALSE;
+ priv->prop_list = NULL;
+ priv->desc = NULL;
+}
+
+static void
+bus_engine_proxy_real_destroy (BusEngineProxy *engine)
+{
+ BusEngineProxyPrivate *priv;
+ priv = BUS_ENGINE_PROXY_GET_PRIVATE (engine);
+
+ if (priv->prop_list) {
+ g_object_unref (priv->prop_list);
+ priv->prop_list = NULL;
+ }
+
+ if (ibus_proxy_get_connection ((IBusProxy *) engine)) {
+ ibus_proxy_call ((IBusProxy *) engine,
+ "Destroy",
+ DBUS_TYPE_INVALID);
+ }
+
+ if (priv->desc) {
+ g_object_unref (priv->desc);
+ priv->desc = NULL;
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (engine));
+}
+
+static gboolean
+bus_engine_proxy_ibus_signal (IBusProxy *proxy,
+ IBusMessage *message)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (proxy));
+ g_assert (message != NULL);
+
+ BusEngineProxy *engine;
+ BusEngineProxyPrivate *priv;
+ IBusError *error;
+ gint i;
+
+ static const struct {
+ const gchar *member;
+ const guint signal_id;
+ } signals [] = {
+ { "ShowPreeditText", SHOW_PREEDIT_TEXT },
+ { "HidePreeditText", HIDE_PREEDIT_TEXT },
+ { "ShowAuxiliaryText", SHOW_AUXILIARY_TEXT },
+ { "HideAuxiliaryText", HIDE_AUXILIARY_TEXT },
+ { "ShowLookupTable", SHOW_LOOKUP_TABLE },
+ { "HideLookupTable", HIDE_LOOKUP_TABLE },
+ { "PageUpLookupTable", PAGE_UP_LOOKUP_TABLE },
+ { "PageDownLookupTable", PAGE_DOWN_LOOKUP_TABLE },
+ { "CursorUpLookupTable", CURSOR_UP_LOOKUP_TABLE },
+ { "CursorDownLookupTable", CURSOR_DOWN_LOOKUP_TABLE },
+ { NULL, 0},
+ };
+
+ engine = BUS_ENGINE_PROXY (proxy);
+ priv = BUS_ENGINE_PROXY_GET_PRIVATE (engine);
+
+ for (i = 0; ; i++) {
+ if (signals[i].member == NULL)
+ break;
+ if (ibus_message_is_signal (message, IBUS_INTERFACE_ENGINE, signals[i].member)) {
+ g_signal_emit (engine, engine_signals[signals[i].signal_id], 0);
+ goto handled;
+ }
+ }
+
+ if (ibus_message_is_signal (message, IBUS_INTERFACE_ENGINE, "CommitText")) {
+ IBusText *text;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_INVALID);
+ if (!retval)
+ goto failed;
+ g_signal_emit (engine, engine_signals[COMMIT_TEXT], 0, text);
+ g_object_unref (text);
+ }
+ else if (ibus_message_is_signal (message, IBUS_INTERFACE_ENGINE, "ForwardKeyEvent")) {
+ guint keyval;
+ guint states;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_UINT, &keyval,
+ G_TYPE_UINT, &states,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+ g_signal_emit (engine, engine_signals[FORWARD_KEY_EVENT], keyval, states);
+ }
+ else if (ibus_message_is_signal (message, IBUS_INTERFACE_ENGINE, "UpdatePreeditText")) {
+ IBusText *text;
+ gint cursor_pos;
+ gboolean visible;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_UINT, &cursor_pos,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (engine, engine_signals[UPDATE_PREEDIT_TEXT], 0,
+ text, cursor_pos, visible);
+ g_object_unref (text);
+ }
+ else if (ibus_message_is_signal (message, IBUS_INTERFACE_ENGINE, "UpdateAuxiliaryText")) {
+ IBusText *text;
+ gboolean visible;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (engine, engine_signals[UPDATE_AUXILIARY_TEXT], 0, text, visible);
+ g_object_unref (text);
+ }
+ else if (ibus_message_is_signal (message, IBUS_INTERFACE_ENGINE, "UpdateLookupTable")) {
+ IBusLookupTable *table;
+ gboolean visible;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_LOOKUP_TABLE, &table,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (engine, engine_signals[UPDATE_LOOKUP_TABLE], 0, table, visible);
+ g_object_unref (table);
+ }
+ else if (ibus_message_is_signal (message, IBUS_INTERFACE_ENGINE, "RegisterProperties")) {
+ gboolean retval;
+
+ if (priv->prop_list) {
+ g_object_unref (priv->prop_list);
+ priv->prop_list = NULL;
+ }
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_PROP_LIST, &priv->prop_list,
+ G_TYPE_INVALID);
+ if (!retval) {
+ priv->prop_list = NULL;
+ goto failed;
+ }
+ g_signal_emit (engine, engine_signals[REGISTER_PROPERTIES], 0, priv->prop_list);
+ }
+ else if (ibus_message_is_signal (message, IBUS_INTERFACE_ENGINE, "UpdateProperty")) {
+ IBusProperty *prop;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_PROPERTY, &prop,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (engine, engine_signals[UPDATE_PROPERTY], 0, prop);
+ g_object_unref (prop);
+ }
+ else {
+ return FALSE;
+ }
+
+handled:
+ g_signal_stop_emission_by_name (engine, "ibus-signal");
+ return TRUE;
+
+failed:
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ return FALSE;
+}
+
+typedef struct {
+ GFunc func;
+ gpointer user_data;
+}CallData;
+
+static void
+bus_engine_proxy_process_key_event_reply_cb (IBusPendingCall *pending,
+ CallData *call_data)
+{
+ IBusMessage *reply_message;
+ IBusError *error;
+ gboolean retval;
+
+ reply_message = dbus_pending_call_steal_reply (pending);
+
+ if ((error = ibus_error_new_from_message (reply_message)) != NULL) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_message_unref (reply_message);
+ ibus_error_free (error);
+ call_data->func(FALSE, call_data->user_data);
+ return;
+ }
+
+ if (!ibus_message_get_args (reply_message,
+ &error,
+ G_TYPE_BOOLEAN, &retval,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_message_unref (reply_message);
+ ibus_error_free (error);
+ call_data->func(FALSE, call_data->user_data);
+ return;
+ }
+
+ call_data->func((gpointer *)retval, call_data->user_data);
+ g_slice_free (CallData, call_data);
+}
+
+void
+bus_engine_proxy_process_key_event (BusEngineProxy *engine,
+ guint keyval,
+ guint state,
+ GFunc return_cb,
+ gpointer user_data)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (return_cb);
+
+ IBusPendingCall *pending = NULL;
+ CallData *call_data;
+ IBusError *error;
+ gboolean retval;
+
+ retval = ibus_proxy_call_with_reply ((IBusProxy *) engine,
+ "ProcessKeyEvent",
+ &pending,
+ -1,
+ &error,
+ G_TYPE_UINT, &keyval,
+ G_TYPE_UINT, &state,
+ G_TYPE_INVALID);
+ if (!retval) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ return_cb (FALSE, user_data);
+ return;
+ }
+
+ call_data = g_slice_new0 (CallData);
+ call_data->func = return_cb;
+ call_data->user_data = user_data;
+
+ retval = ibus_pending_call_set_notify (pending,
+ (IBusPendingCallNotifyFunction) bus_engine_proxy_process_key_event_reply_cb,
+ call_data,
+ NULL);
+ ibus_pending_call_unref (pending);
+
+ if (!retval) {
+ g_warning ("%s : ProcessKeyEvent", DBUS_ERROR_NO_MEMORY);
+ return_cb (FALSE, user_data);
+ return;
+ }
+}
+
+void
+bus_engine_proxy_set_cursor_location (BusEngineProxy *engine,
+ gint x,
+ gint y,
+ gint w,
+ gint h)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+
+ ibus_proxy_call ((IBusProxy *) engine,
+ "SetCursorLocation",
+ G_TYPE_INT, &x,
+ G_TYPE_INT, &y,
+ G_TYPE_INT, &w,
+ G_TYPE_INT, &h,
+ G_TYPE_INVALID);
+}
+
+void
+bus_engine_proxy_set_capabilities (BusEngineProxy *engine,
+ guint caps)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+
+ ibus_proxy_call ((IBusProxy *) engine,
+ "SetCapabilites",
+ G_TYPE_UINT, &caps,
+ G_TYPE_INVALID);
+
+}
+
+void
+bus_engine_proxy_property_activate (BusEngineProxy *engine,
+ const gchar *prop_name,
+ guint prop_state)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (prop_name != NULL);
+
+ ibus_proxy_call ((IBusProxy *) engine,
+ "PropertyActivate",
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_UINT, &prop_state,
+ G_TYPE_INVALID);
+}
+
+void
+bus_engine_proxy_property_show (BusEngineProxy *engine,
+ const gchar *prop_name)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (prop_name != NULL);
+
+ ibus_proxy_call ((IBusProxy *) engine,
+ "PropertyShow",
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_INVALID);
+}
+
+void bus_engine_proxy_property_hide (BusEngineProxy *engine,
+ const gchar *prop_name)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (prop_name != NULL);
+
+ ibus_proxy_call ((IBusProxy *) engine,
+ "PropertyHide",
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_INVALID);
+}
+
+#define DEFINE_FUNCTION(Name, name) \
+ void bus_engine_proxy_##name (BusEngineProxy *engine) \
+ { \
+ g_assert (BUS_IS_ENGINE_PROXY (engine)); \
+ ibus_proxy_call ((IBusProxy *) engine, \
+ #Name, \
+ DBUS_TYPE_INVALID); \
+ }
+
+DEFINE_FUNCTION (FocusIn, focus_in)
+DEFINE_FUNCTION (FocusOut, focus_out)
+DEFINE_FUNCTION (Reset, reset)
+DEFINE_FUNCTION (PageUp, page_up)
+DEFINE_FUNCTION (PageDown, page_down)
+DEFINE_FUNCTION (CursorUp, cursor_up)
+DEFINE_FUNCTION (CursorDown, cursor_down)
+DEFINE_FUNCTION (Enable, enable)
+DEFINE_FUNCTION (Disable, disable)
+
+#undef DEFINE_FUNCTION
+
+
+IBusEngineDesc *
+bus_engine_proxy_get_desc (BusEngineProxy *engine)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+
+ BusEngineProxyPrivate *priv;
+ priv = BUS_ENGINE_PROXY_GET_PRIVATE (engine);
+
+ return priv->desc;
+}
diff --git a/bus/engineproxy.h b/bus/engineproxy.h
new file mode 100644
index 0000000..2206c9a
--- /dev/null
+++ b/bus/engineproxy.h
@@ -0,0 +1,95 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __ENGINE_PROXY_H_
+#define __ENGINE_PROXY_H_
+
+#include <ibus.h>
+#include "connection.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_ENGINE_PROXY \
+ (bus_engine_proxy_get_type ())
+#define BUS_ENGINE_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_ENGINE_PROXY, BusEngineProxy))
+#define BUS_ENGINE_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_ENGINE_PROXY, BusEngineProxyClass))
+#define BUS_IS_ENGINE_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_ENGINE_PROXY))
+#define BUS_IS_ENGINE_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_ENGINE_PROXY))
+#define BUS_ENGINE_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_ENGINE_PROXY, BusEngineProxyClass))
+
+G_BEGIN_DECLS
+
+typedef struct _BusEngineProxy BusEngineProxy;
+typedef struct _BusEngineProxyClass BusEngineProxyClass;
+
+struct _BusEngineProxy {
+ IBusProxy parent;
+ /* instance members */
+};
+
+struct _BusEngineProxyClass {
+ IBusProxyClass parent;
+ /* class members */
+};
+
+GType bus_engine_proxy_get_type (void);
+BusEngineProxy *bus_engine_proxy_new (const gchar *path,
+ IBusEngineDesc *desc,
+ BusConnection *connection);
+IBusEngineDesc *bus_engine_proxy_get_desc (BusEngineProxy *engine);
+void bus_engine_proxy_process_key_event (BusEngineProxy *engine,
+ guint keyval,
+ guint state,
+ GFunc return_cn,
+ gpointer user_data);
+void bus_engine_proxy_set_cursor_location
+ (BusEngineProxy *engine,
+ gint x,
+ gint y,
+ gint w,
+ gint h);
+void bus_engine_proxy_focus_in (BusEngineProxy *engine);
+void bus_engine_proxy_focus_out (BusEngineProxy *engine);
+void bus_engine_proxy_reset (BusEngineProxy *engine);
+void bus_engine_proxy_set_capabilities (BusEngineProxy *engine,
+ guint caps);
+void bus_engine_proxy_page_up (BusEngineProxy *engine);
+void bus_engine_proxy_page_down (BusEngineProxy *engine);
+void bus_engine_proxy_cursor_up (BusEngineProxy *engine);
+void bus_engine_proxy_cursor_down (BusEngineProxy *engine);
+void bus_engine_proxy_enable (BusEngineProxy *engine);
+void bus_engine_proxy_disable (BusEngineProxy *engine);
+void bus_engine_proxy_property_activate (BusEngineProxy *engine,
+ const gchar *prop_name,
+ guint state);
+void bus_engine_proxy_property_show (BusEngineProxy *engine,
+ const gchar *prop_name);
+void bus_engine_proxy_property_hide (BusEngineProxy *engine,
+ const gchar *prop_name);
+G_END_DECLS
+#endif
+
diff --git a/bus/factoryproxy.c b/bus/factoryproxy.c
new file mode 100644
index 0000000..38357b4
--- /dev/null
+++ b/bus/factoryproxy.c
@@ -0,0 +1,220 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ibusinternal.h>
+#include <ibusmarshalers.h>
+#include "dbusimpl.h"
+#include "factoryproxy.h"
+
+/* functions prototype */
+static void bus_factory_proxy_class_init (BusFactoryProxyClass *klass);
+static void bus_factory_proxy_init (BusFactoryProxy *factory);
+static void bus_factory_proxy_destroy (BusFactoryProxy *factory);
+
+
+static IBusProxyClass *parent_class = NULL;
+
+GType
+bus_factory_proxy_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusFactoryProxyClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_factory_proxy_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusFactoryProxy),
+ 0,
+ (GInstanceInitFunc) bus_factory_proxy_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_PROXY,
+ "BusFactoryProxy",
+ &type_info,
+ (GTypeFlags)0);
+ }
+ return type;
+}
+
+BusFactoryProxy *
+bus_factory_proxy_new (IBusComponent *component,
+ BusConnection *connection)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+
+ BusFactoryProxy *factory;
+ GList *p;
+
+ if (connection == NULL) {
+ connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, component->name);
+ }
+
+ if (connection == NULL) {
+ return NULL;
+ }
+
+ factory = g_object_new (BUS_TYPE_FACTORY_PROXY,
+ "name", NULL,
+ "path", "/org/freedesktop/IBus/Factory",
+ "connection", connection,
+ NULL);
+
+ g_object_ref (component);
+ factory->component = component;
+ g_object_set_data ((GObject *)factory->component, "factory", factory);
+
+ factory->engine_list = ibus_component_get_engines (factory->component);
+
+ for (p = factory->engine_list; p != NULL; p = p->next) {
+ IBusEngineDesc *desc = (IBusEngineDesc *)p->data;
+ g_object_ref (desc);
+ g_object_set_data ((GObject *)desc, "factory", factory);
+ }
+
+ return factory;
+}
+
+static void
+bus_factory_proxy_class_init (BusFactoryProxyClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusProxyClass *) g_type_class_peek_parent (klass);
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_factory_proxy_destroy;
+
+}
+
+static void
+bus_factory_proxy_init (BusFactoryProxy *factory)
+{
+ factory->component = NULL;
+}
+
+static void
+bus_factory_proxy_destroy (BusFactoryProxy *factory)
+{
+ GList *p;
+
+ for (p = factory->engine_list; p != NULL ; p = p->next) {
+ IBusEngineDesc *desc = (IBusEngineDesc *)p->data;
+ g_object_steal_data ((GObject *)desc, "factory");
+ g_object_unref (desc);
+ }
+ g_list_free (factory->engine_list);
+ factory->engine_list = NULL;
+
+ if (factory->component) {
+ g_object_steal_data ((GObject *)factory->component, "factory");
+ g_object_unref (factory->component);
+ factory->component = NULL;
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (factory));
+}
+
+IBusComponent *
+bus_factory_proxy_get_component (BusFactoryProxy *factory)
+{
+ return factory->component;
+}
+
+BusFactoryProxy *
+bus_factory_proxy_get_from_component (IBusComponent *component)
+{
+ IBUS_IS_COMPONENT (component);
+
+ BusFactoryProxy *factory;
+
+ factory = (BusFactoryProxy *) g_object_get_data ((GObject *)component, "factory");
+
+ return factory;
+}
+
+BusFactoryProxy *
+bus_factory_proxy_get_from_engine (IBusEngineDesc *desc)
+{
+
+ IBUS_IS_ENGINE_DESC (desc);
+
+ BusFactoryProxy *factory;
+
+ factory = (BusFactoryProxy *) g_object_get_data ((GObject *)desc, "factory");
+
+ return factory;
+}
+
+BusEngineProxy *
+bus_factory_proxy_create_engine (BusFactoryProxy *factory,
+ IBusEngineDesc *desc)
+{
+ g_assert (BUS_IS_FACTORY_PROXY (factory));
+ g_assert (IBUS_IS_ENGINE_DESC (desc));
+
+ IBusMessage *reply_message;
+ IBusError *error;
+ BusEngineProxy *engine;
+ gchar *object_path;
+
+ if (g_list_find (factory->component->engines, desc) == NULL) {
+ return NULL;
+ }
+
+ reply_message = ibus_proxy_call_with_reply_and_block ((IBusProxy *) factory,
+ "CreateEngine",
+ -1,
+ &error,
+ G_TYPE_STRING, &(desc->name),
+ DBUS_TYPE_INVALID);
+ if (reply_message == NULL) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ return NULL;
+ }
+
+ if ((error = ibus_error_new_from_message (reply_message)) != NULL) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ ibus_message_unref (reply_message);
+ return NULL;
+ }
+
+ if (!ibus_message_get_args (reply_message,
+ &error,
+ IBUS_TYPE_OBJECT_PATH, &object_path,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ ibus_message_unref (reply_message);
+
+ return NULL;
+ }
+
+ IBusConnection *connection = ibus_proxy_get_connection ((IBusProxy *) factory);
+ engine = bus_engine_proxy_new (object_path, desc, (BusConnection *) connection);
+ ibus_message_unref (reply_message);
+
+ return engine;
+}
+
diff --git a/bus/factoryproxy.h b/bus/factoryproxy.h
new file mode 100644
index 0000000..198b458
--- /dev/null
+++ b/bus/factoryproxy.h
@@ -0,0 +1,84 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __FACTORY_PROXY_H_
+#define __FACTORY_PROXY_H_
+
+#include <ibus.h>
+#include "connection.h"
+#include "engineproxy.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_FACTORY_PROXY \
+ (bus_factory_proxy_get_type ())
+#define BUS_FACTORY_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_FACTORY_PROXY, BusFactoryProxy))
+#define BUS_FACTORY_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_FACTORY_PROXY, BusFactoryProxyClass))
+#define BUS_IS_FACTORY_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_FACTORY_PROXY))
+#define BUS_IS_FACTORY_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_FACTORY_PROXY))
+#define BUS_FACTORY_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_FACTORY_PROXY, BusFactoryProxyClass))
+
+G_BEGIN_DECLS
+
+typedef struct _BusFactoryProxy BusFactoryProxy;
+typedef struct _BusFactoryProxyClass BusFactoryProxyClass;
+
+struct _BusFactoryProxy {
+ IBusProxy parent;
+ /* instance members */
+
+ IBusComponent *component;
+ GList *engine_list;
+};
+
+struct _BusFactoryProxyClass {
+ IBusProxyClass parent;
+ /* class members */
+};
+
+GType bus_factory_proxy_get_type (void);
+BusFactoryProxy *bus_factory_proxy_new (IBusComponent *component,
+ BusConnection *connection);
+IBusComponent *bus_factory_proxy_get_component(BusFactoryProxy *factory);
+BusEngineProxy *bus_factory_proxy_create_engine(BusFactoryProxy *factory,
+ IBusEngineDesc *desc);
+BusFactoryProxy *bus_factory_proxy_get_from_component
+ (IBusComponent *component);
+BusFactoryProxy *bus_factory_proxy_get_from_engine
+ (IBusEngineDesc *desc);
+
+#if 0
+const gchar *bus_factory_proxy_get_name (BusFactoryProxy *factory);
+const gchar *bus_factory_proxy_get_lang (BusFactoryProxy *factory);
+const gchar *bus_factory_proxy_get_icon (BusFactoryProxy *factory);
+const gchar *bus_factory_proxy_get_authors (BusFactoryProxy *factory);
+const gchar *bus_factory_proxy_get_credits (BusFactoryProxy *factory);
+#endif
+
+G_END_DECLS
+#endif
+
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
new file mode 100644
index 0000000..31799d6
--- /dev/null
+++ b/bus/ibusimpl.c
@@ -0,0 +1,935 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusimpl.h"
+#include "dbusimpl.h"
+#include "server.h"
+#include "connection.h"
+#include "registry.h"
+#include "factoryproxy.h"
+#include "panelproxy.h"
+#include "inputcontext.h"
+
+
+enum {
+ LAST_SIGNAL,
+};
+
+enum {
+ PROP_0,
+};
+
+// static guint _signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void bus_ibus_impl_class_init (BusIBusImplClass *klass);
+static void bus_ibus_impl_init (BusIBusImpl *ibus);
+static void bus_ibus_impl_destroy (BusIBusImpl *ibus);
+static gboolean bus_ibus_impl_ibus_message (BusIBusImpl *ibus,
+ BusConnection *connection,
+ IBusMessage *message);
+static void bus_ibus_impl_add_factory (BusIBusImpl *ibus,
+ BusFactoryProxy *factory);
+static void bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
+ GValue *value);
+static void bus_ibus_impl_set_preload_engines
+ (BusIBusImpl *ibus,
+ GValue *value);
+static void _factory_destroy_cb (BusFactoryProxy *factory,
+ BusIBusImpl *ibus);
+
+static IBusServiceClass *parent_class = NULL;
+
+GType
+bus_ibus_impl_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusIBusImplClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_ibus_impl_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusIBusImpl),
+ 0,
+ (GInstanceInitFunc) bus_ibus_impl_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERVICE,
+ "BusIBusImpl",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+ return type;
+}
+
+BusIBusImpl *
+bus_ibus_impl_get_default (void)
+{
+ static BusIBusImpl *ibus = NULL;
+
+ if (ibus == NULL) {
+ ibus = (BusIBusImpl *) g_object_new (BUS_TYPE_IBUS_IMPL,
+ "path", IBUS_PATH_IBUS,
+ NULL);
+ bus_dbus_impl_register_object (BUS_DEFAULT_DBUS,
+ (IBusService *)ibus);
+ }
+ return ibus;
+}
+
+static void
+bus_ibus_impl_class_init (BusIBusImplClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_ibus_impl_destroy;
+
+ IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) bus_ibus_impl_ibus_message;
+
+}
+
+static void
+_panel_destroy_cb (BusPanelProxy *panel,
+ BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ g_return_if_fail (ibus->panel == panel);
+
+ ibus->panel = NULL;
+ g_object_unref (panel);
+}
+
+static void
+bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
+ GValue *value)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ GValueArray *array;
+ gint i;
+
+ ibus_hotkey_profile_remove_hotkey_by_event (ibus->hotkey_profile,
+ g_quark_from_static_string ("trigger"));
+
+ if (value == NULL) {
+ ibus_hotkey_profile_add_hotkey (ibus->hotkey_profile,
+ IBUS_space,
+ IBUS_CONTROL_MASK,
+ g_quark_from_static_string ("trigger"));
+ return;
+ }
+
+ g_return_if_fail (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY);
+ array = g_value_get_boxed (value);
+
+ for (i = 0; i < array->n_values; i++) {
+ GValue *str;
+
+ str = g_value_array_get_nth (array, i);
+ g_return_if_fail (G_VALUE_TYPE (str) == G_TYPE_STRING);
+
+ ibus_hotkey_profile_add_hotkey_from_string (ibus->hotkey_profile,
+ g_value_get_string (str),
+ g_quark_from_static_string ("trigger"));
+ }
+}
+
+static void
+bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus,
+ GValue *value)
+{
+ GList *engine_list = NULL;
+
+ g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL);
+ g_list_free (ibus->engine_list);
+
+ if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY) {
+ GValueArray *array;
+ gint i;
+
+ array = (GValueArray *) g_value_get_boxed (value);
+ for (i = 0; array && i < array->n_values; i++) {
+ const gchar *engine_name;
+ IBusEngineDesc *engine;
+
+ if (G_VALUE_TYPE (&array->values[i]) != G_TYPE_STRING)
+ continue;
+
+ engine_name = g_value_get_string (&array->values[i]);
+
+ engine = bus_registry_find_engine_by_name (ibus->registry, engine_name);
+
+ if (engine == NULL || g_list_find (engine_list, engine) != NULL)
+ continue;
+
+ engine_list = g_list_append (engine_list, engine);
+ }
+ }
+
+ g_list_foreach (engine_list, (GFunc) g_object_ref, NULL);
+ ibus->engine_list = engine_list;
+}
+
+static void
+bus_ibus_impl_reload_config (BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ gint i;
+ GValue value = { 0 };
+
+ const static struct {
+ gchar *section;
+ gchar *key;
+ void ( *func) (BusIBusImpl *, GValue *);
+ } entries [] = {
+ { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
+ { "general", "preload_engines", bus_ibus_impl_set_preload_engines },
+ { NULL, NULL, NULL },
+ };
+
+ for (i = 0; entries[i].section != NULL; i++) {
+ if (ibus->config != NULL &&
+ ibus_config_get_value (ibus->config,
+ entries[i].section,
+ entries[i].key,
+ &value)) {
+ entries[i].func (ibus, &value);
+ g_value_unset (&value);
+ }
+ else {
+ entries[i].func (ibus, NULL);
+ }
+ }
+}
+
+static void
+_config_value_changed_cb (IBusConfig *config,
+ gchar *section,
+ gchar *key,
+ GValue *value,
+ BusIBusImpl *ibus)
+{
+ g_assert (IBUS_IS_CONFIG (config));
+ g_assert (section);
+ g_assert (key);
+ g_assert (value);
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ gint i;
+
+ const static struct {
+ gchar *section;
+ gchar *key;
+ void ( *func) (BusIBusImpl *, GValue *);
+ } entries [] = {
+ { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
+ { "general", "preload_engines", bus_ibus_impl_set_preload_engines },
+ { NULL, NULL, NULL },
+ };
+
+ for (i = 0; entries[i].section != NULL; i++) {
+ if (g_strcmp0 (entries[i].section, section) == 0 &&
+ g_strcmp0 (entries[i].key, key) == 0) {
+ entries[i].func (ibus, value);
+ break;
+ }
+ }
+}
+
+static void
+_config_destroy_cb (IBusConfig *config,
+ BusIBusImpl *ibus)
+{
+ g_assert (IBUS_IS_CONFIG (config));
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ g_assert (ibus->config == config);
+
+ ibus->config = NULL;
+ g_object_unref (config);
+}
+
+static void
+_dbus_name_owner_changed_cb (BusDBusImpl *dbus,
+ const gchar *name,
+ const gchar *old_name,
+ const gchar *new_name,
+ BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_DBUS_IMPL (dbus));
+ g_assert (name != NULL);
+ g_assert (old_name != NULL);
+ g_assert (new_name != NULL);
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ BusFactoryProxy *factory;
+
+ if (g_strcmp0 (name, IBUS_SERVICE_PANEL) == 0) {
+ if (g_strcmp0 (new_name, "") != 0) {
+ BusConnection *connection;
+
+ if (ibus->panel != NULL) {
+ ibus_object_destroy (IBUS_OBJECT (ibus->panel));
+ ibus->panel = NULL;
+ }
+
+ connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
+ g_return_if_fail (connection != NULL);
+
+ ibus->panel = bus_panel_proxy_new (connection);
+
+ g_signal_connect (ibus->panel,
+ "destroy",
+ G_CALLBACK (_panel_destroy_cb),
+ ibus);
+
+ if (ibus->focused_context != NULL) {
+ bus_panel_proxy_focus_in (ibus->panel, ibus->focused_context);
+ }
+ }
+ }
+ else if (g_strcmp0 (name, IBUS_SERVICE_CONFIG) == 0) {
+ if (g_strcmp0 (new_name, "") != 0) {
+ BusConnection *connection;
+
+ if (ibus->config != NULL) {
+ ibus_object_destroy (IBUS_OBJECT (ibus->config));
+ ibus->config = NULL;
+ }
+
+ connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
+ g_return_if_fail (connection != NULL);
+
+ ibus->config = g_object_new (IBUS_TYPE_CONFIG,
+ "name", NULL,
+ "path", IBUS_PATH_CONFIG,
+ "connection", connection,
+ NULL);
+
+ g_signal_connect (ibus->config,
+ "value-changed",
+ G_CALLBACK (_config_value_changed_cb),
+ ibus);
+
+ g_signal_connect (ibus->config,
+ "destroy",
+ G_CALLBACK (_config_destroy_cb),
+ ibus);
+
+ bus_ibus_impl_reload_config (ibus);
+ }
+ }
+
+ factory = bus_registry_name_owner_changed (ibus->registry, name, old_name, new_name);
+
+ if (factory) {
+ bus_ibus_impl_add_factory (ibus, factory);
+ g_object_unref (factory);
+ }
+}
+
+static void
+bus_ibus_impl_init (BusIBusImpl *ibus)
+{
+ ibus->factory_dict = g_hash_table_new_full (
+ g_str_hash,
+ g_str_equal,
+ NULL,
+ (GDestroyNotify) g_object_unref);
+
+ ibus->registry = bus_registry_new ();
+ ibus->engine_list = NULL;
+ ibus->register_engine_list = NULL;
+ ibus->contexts = NULL;
+ ibus->focused_context = NULL;
+ ibus->panel = NULL;
+ ibus->config = NULL;
+
+ ibus->hotkey_profile = ibus_hotkey_profile_new ();
+
+ bus_ibus_impl_reload_config (ibus);
+
+ g_signal_connect (BUS_DEFAULT_DBUS,
+ "name-owner-changed",
+ G_CALLBACK (_dbus_name_owner_changed_cb),
+ ibus);
+}
+
+static void
+bus_ibus_impl_destroy (BusIBusImpl *ibus)
+{
+ g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL);
+ g_list_free (ibus->engine_list);
+ ibus->engine_list = NULL;
+
+ g_list_foreach (ibus->register_engine_list, (GFunc) g_object_unref, NULL);
+ g_list_free (ibus->register_engine_list);
+ ibus->register_engine_list = NULL;
+
+ if (ibus->factory_dict != NULL) {
+ g_hash_table_destroy (ibus->factory_dict);
+ ibus->factory_dict = NULL;
+ }
+
+ if (ibus->hotkey_profile != NULL) {
+ g_object_unref (ibus->hotkey_profile);
+ ibus->hotkey_profile = NULL;
+ }
+
+ bus_server_quit (BUS_DEFAULT_SERVER);
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (ibus));
+}
+
+/* introspectable interface */
+static IBusMessage *
+_ibus_introspect (BusIBusImpl *ibus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ static const gchar *introspect =
+ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+ "<node>\n"
+ " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+ " <method name=\"Introspect\">\n"
+ " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " </interface>\n"
+ " <interface name=\"org.freedesktop.DBus\">\n"
+ " <method name=\"RequestName\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"in\" type=\"u\"/>\n"
+ " <arg direction=\"out\" type=\"u\"/>\n"
+ " </method>\n"
+ " <signal name=\"NameOwnerChanged\">\n"
+ " <arg type=\"s\"/>\n"
+ " <arg type=\"s\"/>\n"
+ " <arg type=\"s\"/>\n"
+ " </signal>\n"
+ " </interface>\n"
+ "</node>\n";
+
+ IBusMessage *reply_message;
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ G_TYPE_STRING, &introspect,
+ G_TYPE_INVALID);
+
+ return reply_message;
+}
+
+
+
+static IBusMessage *
+_ibus_get_address (BusIBusImpl *ibus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ const gchar *address;
+ IBusMessage *reply;
+
+ address = ibus_server_get_address (IBUS_SERVER (BUS_DEFAULT_SERVER));
+
+ reply = ibus_message_new_method_return (message);
+ ibus_message_append_args (message,
+ G_TYPE_STRING, &address,
+ G_TYPE_INVALID);
+
+ return reply;
+}
+
+static void
+_context_request_engine_cb (BusInputContext *context,
+ gchar *engine_name,
+ BusIBusImpl *ibus)
+{
+ IBusEngineDesc *engine_desc = NULL;
+ IBusComponent *comp;
+ BusFactoryProxy *factory;
+ BusEngineProxy *engine;
+
+ if (engine_name == NULL || engine_name[0] == '\0') {
+ /* request default engine */
+ if (ibus->register_engine_list) {
+ engine_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
+ }
+ else if (ibus->engine_list) {
+ engine_desc = (IBusEngineDesc *)ibus->engine_list->data;
+ }
+ }
+ else {
+ /* request engine by name */
+ GList *p;
+ gboolean found = FALSE;
+
+ /* find engine in registered engine list */
+ for (p = ibus->register_engine_list; p != NULL; p = p->next) {
+ engine_desc = (IBusEngineDesc *)p->data;
+ if (g_strcmp0 (engine_desc->name, engine_name) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found) {
+ /* find engine in preload engine list */
+ for (p = ibus->engine_list; p != NULL; p = p->next) {
+ engine_desc = (IBusEngineDesc *)p->data;
+ if (g_strcmp0 (engine_desc->name, engine_name) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ engine_desc = NULL;
+ }
+ }
+
+ if (engine_desc == NULL)
+ return;
+
+ factory = bus_factory_proxy_get_from_engine (engine_desc);
+
+ if (factory == NULL) {
+ /* try to execute the engine */
+ comp = ibus_component_get_from_engine (engine_desc);
+ g_assert (comp);
+
+ if (!ibus_component_is_running (comp)) {
+ ibus_component_start (comp);
+
+ gint time = 0;
+ while (time < G_USEC_PER_SEC * 3) {
+ if (g_main_context_pending (NULL)) {
+ g_main_context_iteration (NULL, FALSE);
+ }
+ else {
+ g_usleep (50 * 1000);
+ time += 50 * 1000;
+ }
+ factory = bus_factory_proxy_get_from_engine (engine_desc);
+ if (factory != NULL) {
+ break;
+ }
+ }
+ }
+ factory = bus_factory_proxy_get_from_engine (engine_desc);
+ }
+
+ if (factory == NULL)
+ return;
+
+ engine = bus_factory_proxy_create_engine (factory, engine_desc);
+
+ if (engine == NULL)
+ return;
+
+ bus_input_context_set_engine (context, engine);
+}
+
+static void
+_context_request_next_engine_cb (BusInputContext *context,
+ BusIBusImpl *ibus)
+{
+
+}
+
+static void
+_context_request_prev_engine_cb (BusInputContext *context,
+ BusIBusImpl *ibus)
+{
+
+}
+
+static void
+_context_focus_out_cb (BusInputContext *context,
+ BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ if (ibus->focused_context != context)
+ return;
+
+ if (ibus->panel != NULL) {
+ bus_panel_proxy_focus_out (ibus->panel, context);
+ }
+
+ if (context) {
+ g_object_unref (context);
+ ibus->focused_context = NULL;
+ }
+}
+
+static void
+_context_focus_in_cb (BusInputContext *context,
+ BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ if (ibus->focused_context) {
+ /* focus out context */
+ bus_input_context_focus_out (ibus->focused_context);
+ g_assert (ibus->focused_context == NULL);
+ }
+
+ g_object_ref (context);
+ ibus->focused_context = context;
+
+ if (ibus->panel != NULL) {
+ bus_panel_proxy_focus_in (ibus->panel, ibus->focused_context);
+ }
+
+}
+
+static void
+_context_destroy_cb (BusInputContext *context,
+ BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ if (context == ibus->focused_context) {
+ /* focus out context */
+ bus_input_context_focus_out (ibus->focused_context);
+ g_assert (ibus->focused_context == NULL);
+ }
+
+ ibus->contexts = g_list_remove (ibus->contexts, context);
+ g_object_unref (context);
+}
+
+static IBusMessage *
+_ibus_create_input_context (BusIBusImpl *ibus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ gint i;
+ gchar *client;
+ IBusError *error;
+ IBusMessage *reply;
+ BusInputContext *context;
+ const gchar *path;
+
+ if (!ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &client,
+ G_TYPE_INVALID)) {
+ reply = ibus_message_new_error (message,
+ DBUS_ERROR_INVALID_ARGS,
+ "Argument 1 of CreateInputContext should be an string");
+ ibus_error_free (error);
+ return reply;
+ }
+
+ context = bus_input_context_new (connection, client);
+ ibus->contexts = g_list_append (ibus->contexts, context);
+
+ static const struct {
+ gchar *name;
+ GCallback callback;
+ } signals [] = {
+ { "request-engine", G_CALLBACK (_context_request_engine_cb) },
+ { "request-next-engine", G_CALLBACK (_context_request_next_engine_cb) },
+ { "request-prev-engine", G_CALLBACK (_context_request_prev_engine_cb) },
+ { "focus-in", G_CALLBACK (_context_focus_in_cb) },
+ { "focus-out", G_CALLBACK (_context_focus_out_cb) },
+ { "destroy", G_CALLBACK (_context_destroy_cb) },
+ { NULL, NULL }
+ };
+
+ for (i = 0; signals[i].name != NULL; i++) {
+ g_signal_connect (context,
+ signals[i].name,
+ signals[i].callback,
+ ibus);
+ }
+
+ path = ibus_service_get_path ((IBusService *) context);
+ reply = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply,
+ IBUS_TYPE_OBJECT_PATH, &path,
+ G_TYPE_INVALID);
+
+ bus_dbus_impl_register_object (BUS_DEFAULT_DBUS,
+ (IBusService *)context);
+ return reply;
+}
+
+static void
+_factory_destroy_cb (BusFactoryProxy *factory,
+ BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+ g_assert (BUS_IS_FACTORY_PROXY (factory));
+
+ IBusComponent *component;
+ GList *engines, *p;
+
+ ibus->factory_list = g_list_remove (ibus->factory_list, factory);
+
+ component = bus_factory_proxy_get_component (factory);
+
+ if (component != NULL) {
+ p = engines = ibus_component_get_engines (component);
+ for (; p != NULL; p = p->next) {
+ if (g_list_find (ibus->register_engine_list, p->data)) {
+ ibus->register_engine_list = g_list_remove (ibus->register_engine_list, p->data);
+ g_object_unref (p->data);
+ }
+ }
+ g_list_free (engines);
+ }
+
+ g_object_unref (factory);
+}
+
+static void
+bus_ibus_impl_add_factory (BusIBusImpl *ibus,
+ BusFactoryProxy *factory)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+ g_assert (BUS_IS_FACTORY_PROXY (factory));
+
+ g_object_ref (factory);
+ ibus->factory_list = g_list_append (ibus->factory_list, factory);
+
+ g_signal_connect (factory, "destroy", G_CALLBACK (_factory_destroy_cb), ibus);
+}
+
+
+static IBusMessage *
+_ibus_register_component (BusIBusImpl *ibus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ IBusMessage *reply;
+ IBusError *error;
+ gboolean retval;
+ GList *engines;
+ IBusComponent *component;
+ BusFactoryProxy *factory;
+
+ retval = ibus_message_get_args (message, &error,
+ IBUS_TYPE_COMPONENT, &component,
+ G_TYPE_INVALID);
+
+ if (!retval) {
+ reply = ibus_message_new_error_printf (message,
+ DBUS_ERROR_INVALID_ARGS,
+ "1st Argument must be IBusComponent: %s",
+ error->message);
+ ibus_error_free (error);
+ return reply;
+ }
+
+ factory = bus_factory_proxy_new (component, connection);
+
+ if (factory == NULL) {
+ reply = ibus_message_new_error (message,
+ DBUS_ERROR_FAILED,
+ "Can not create factory");
+ return reply;
+ }
+
+ bus_ibus_impl_add_factory (ibus, factory);
+ g_object_unref (factory);
+
+ engines = ibus_component_get_engines (component);
+
+ g_list_foreach (engines, (GFunc) g_object_ref, NULL);
+ ibus->register_engine_list = g_list_concat (ibus->register_engine_list, engines);
+ g_object_unref (component);
+
+ reply = ibus_message_new_method_return (message);
+ return reply;
+}
+
+static IBusMessage *
+_ibus_list_engines (BusIBusImpl *ibus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ IBusMessage *reply;
+ IBusMessageIter iter, sub_iter;
+ GList *engines, *p;
+
+ reply = ibus_message_new_method_return (message);
+
+ ibus_message_iter_init_append (reply, &iter);
+ ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "v", &sub_iter);
+
+ engines = bus_registry_get_engines (ibus->registry);
+ for (p = engines; p != NULL; p = p->next) {
+ ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
+ }
+ g_list_free (engines);
+ ibus_message_iter_close_container (&iter, &sub_iter);
+
+ return reply;
+}
+
+static IBusMessage *
+_ibus_list_active_engines (BusIBusImpl *ibus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ IBusMessage *reply;
+ IBusMessageIter iter, sub_iter;
+ GList *p;
+
+ reply = ibus_message_new_method_return (message);
+
+ ibus_message_iter_init_append (reply, &iter);
+ ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "v", &sub_iter);
+
+ for (p = ibus->engine_list; p != NULL; p = p->next) {
+ ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
+ }
+
+ for (p = ibus->register_engine_list; p != NULL; p = p->next) {
+ ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
+ }
+ ibus_message_iter_close_container (&iter, &sub_iter);
+
+ return reply;
+}
+
+static IBusMessage *
+_ibus_kill (BusIBusImpl *ibus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ IBusMessage *reply;
+
+ reply = ibus_message_new_method_return (message);
+ ibus_connection_send ((IBusConnection *) connection, reply);
+ ibus_connection_flush ((IBusConnection *) connection);
+ ibus_message_unref (reply);
+
+ ibus_object_destroy (IBUS_OBJECT (ibus));
+ return NULL;
+}
+
+static gboolean
+bus_ibus_impl_ibus_message (BusIBusImpl *ibus,
+ BusConnection *connection,
+ IBusMessage *message)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+ g_assert (BUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+
+ gint i;
+ IBusMessage *reply_message = NULL;
+
+ static const struct {
+ const gchar *interface;
+ const gchar *name;
+ IBusMessage *(* handler) (BusIBusImpl *, IBusMessage *, BusConnection *);
+ } handlers[] = {
+ /* Introspectable interface */
+ { DBUS_INTERFACE_INTROSPECTABLE,
+ "Introspect", _ibus_introspect },
+ /* IBus interface */
+ { IBUS_INTERFACE_IBUS, "GetAddress", _ibus_get_address },
+ { IBUS_INTERFACE_IBUS, "CreateInputContext", _ibus_create_input_context },
+ { IBUS_INTERFACE_IBUS, "RegisterComponent", _ibus_register_component },
+ { IBUS_INTERFACE_IBUS, "ListEngines", _ibus_list_engines },
+ { IBUS_INTERFACE_IBUS, "ListActiveEngines", _ibus_list_active_engines },
+ { IBUS_INTERFACE_IBUS, "Kill", _ibus_kill },
+ { NULL, NULL, NULL }
+ };
+
+ ibus_message_set_sender (message, bus_connection_get_unique_name (connection));
+ ibus_message_set_destination (message, DBUS_SERVICE_DBUS);
+
+ for (i = 0; handlers[i].interface != NULL; i++) {
+ if (ibus_message_is_method_call (message,
+ handlers[i].interface,
+ handlers[i].name)) {
+
+ reply_message = handlers[i].handler (ibus, message, connection);
+ if (reply_message) {
+
+ ibus_message_set_sender (reply_message, DBUS_SERVICE_DBUS);
+ ibus_message_set_destination (reply_message, bus_connection_get_unique_name (connection));
+ ibus_message_set_no_reply (reply_message, TRUE);
+
+ ibus_connection_send ((IBusConnection *) connection, reply_message);
+ ibus_message_unref (reply_message);
+ }
+
+ g_signal_stop_emission_by_name (ibus, "ibus-message");
+ return TRUE;
+ }
+ }
+
+ return parent_class->ibus_message ((IBusService *) ibus,
+ (IBusConnection *) connection,
+ message);
+}
+
+BusFactoryProxy *
+bus_ibus_impl_lookup_factory (BusIBusImpl *ibus,
+ const gchar *path)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ BusFactoryProxy *factory;
+
+ factory = (BusFactoryProxy *) g_hash_table_lookup (ibus->factory_dict, path);
+
+ return factory;
+}
+
+IBusHotkeyProfile *
+bus_ibus_impl_get_hotkey_profile (BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ return ibus->hotkey_profile;
+}
+
+BusRegistry *
+bus_ibus_impl_get_registry (BusIBusImpl *ibus)
+{
+
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ return ibus->registry;
+}
+
diff --git a/bus/ibusimpl.h b/bus/ibusimpl.h
new file mode 100644
index 0000000..fd85138
--- /dev/null
+++ b/bus/ibusimpl.h
@@ -0,0 +1,102 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_IMPL_H_
+#define __IBUS_IMPL_H_
+
+#include <ibus.h>
+#include "connection.h"
+#include "inputcontext.h"
+#include "registry.h"
+#include "factoryproxy.h"
+#include "panelproxy.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_IBUS_IMPL \
+ (bus_ibus_impl_get_type ())
+#define BUS_IBUS_IMPL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_IBUS_IMPL, BusIBusImpl))
+#define BUS_IBUS_IMPL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_IBUS_IMPL, BusIBusImplClass))
+#define BUS_IS_IBUS_IMPL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_IBUS_IMPL))
+#define BUS_IS_IBUS_IMPL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_IBUS_IMPL))
+#define BUS_IBUS_IMPL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_IBUS_IMPL, BusIBusImplClass))
+
+#define BUS_DEFAULT_IBUS \
+ (bus_ibus_impl_get_default ())
+#define BUS_DEFAULT_HOTKEY_PROFILE \
+ (bus_ibus_impl_get_hotkey_profile (BUS_DEFAULT_IBUS))
+#define BUS_DEFAULT_REGISTRY \
+ (bus_ibus_impl_get_registry (BUS_DEFAULT_IBUS))
+
+G_BEGIN_DECLS
+
+typedef struct _BusIBusImpl BusIBusImpl;
+typedef struct _BusIBusImplClass BusIBusImplClass;
+
+struct _BusIBusImpl {
+ IBusService parent;
+ /* instance members */
+
+ GHashTable *factory_dict;
+ GList *factory_list;
+ GList *contexts;
+
+ GList *engine_list;
+ GList *register_engine_list;
+ GList *component_list;
+
+ BusRegistry *registry;
+
+ BusInputContext *focused_context;
+ BusPanelProxy *panel;
+ IBusConfig *config;
+ IBusHotkeyProfile *hotkey_profile;
+
+};
+
+struct _BusIBusImplClass {
+ IBusServiceClass parent;
+
+ /* class members */
+};
+
+GType bus_ibus_impl_get_type (void);
+BusIBusImpl *bus_ibus_impl_get_default (void);
+BusFactoryProxy *bus_ibus_impl_get_default_factory (BusIBusImpl *ibus);
+BusFactoryProxy *bus_ibus_impl_get_next_factory (BusIBusImpl *ibus,
+ BusFactoryProxy *factory);
+BusFactoryProxy *bus_ibus_impl_get_previous_factory (BusIBusImpl *ibus,
+ BusFactoryProxy *factory);
+BusFactoryProxy *bus_ibus_impl_lookup_factory (BusIBusImpl *ibus,
+ const gchar *path);
+IBusHotkeyProfile
+ *bus_ibus_impl_get_hotkey_profile (BusIBusImpl *ibus);
+BusRegistry *bus_ibus_impl_get_registry (BusIBusImpl *ibus);
+
+G_END_DECLS
+#endif
+
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
new file mode 100644
index 0000000..a4e3359
--- /dev/null
+++ b/bus/inputcontext.c
@@ -0,0 +1,1559 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ibusinternal.h>
+#include <ibusmarshalers.h>
+#include "ibusimpl.h"
+#include "inputcontext.h"
+#include "engineproxy.h"
+#include "factoryproxy.h"
+
+#define BUS_INPUT_CONTEXT_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_INPUT_CONTEXT, BusInputContextPrivate))
+
+enum {
+ PROCESS_KEY_EVENT,
+ SET_CURSOR_LOCATION,
+ FOCUS_IN,
+ FOCUS_OUT,
+ UPDATE_PREEDIT_TEXT,
+ SHOW_PREEDIT_TEXT,
+ HIDE_PREEDIT_TEXT,
+ UPDATE_AUXILIARY_TEXT,
+ SHOW_AUXILIARY_TEXT,
+ HIDE_AUXILIARY_TEXT,
+ UPDATE_LOOKUP_TABLE,
+ SHOW_LOOKUP_TABLE,
+ HIDE_LOOKUP_TABLE,
+ PAGE_UP_LOOKUP_TABLE,
+ PAGE_DOWN_LOOKUP_TABLE,
+ CURSOR_UP_LOOKUP_TABLE,
+ CURSOR_DOWN_LOOKUP_TABLE,
+ REGISTER_PROPERTIES,
+ UPDATE_PROPERTY,
+ ENABLED,
+ DISABLED,
+ ENGINE_CHANGED,
+ REQUEST_ENGINE,
+ REQUEST_NEXT_ENGINE,
+ REQUEST_PREV_ENGINE,
+ LAST_SIGNAL,
+};
+
+enum {
+ PROP_0,
+};
+
+
+/* IBusInputContextPriv */
+struct _BusInputContextPrivate {
+ BusConnection *connection;
+ BusEngineProxy *engine;
+ gchar *client;
+
+ gboolean has_focus;
+ gboolean enabled;
+
+ /* capabilities */
+ guint capabilities;
+
+ /* cursor location */
+ gint x;
+ gint y;
+ gint w;
+ gint h;
+};
+
+typedef struct _BusInputContextPrivate BusInputContextPrivate;
+
+static guint context_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void bus_input_context_class_init (BusInputContextClass *klass);
+static void bus_input_context_init (BusInputContext *context);
+static void bus_input_context_destroy (BusInputContext *context);
+static gboolean bus_input_context_ibus_message (BusInputContext *context,
+ BusConnection *connection,
+ IBusMessage *message);
+static gboolean bus_input_context_filter_keyboard_shortcuts
+ (BusInputContext *context,
+ guint keyval,
+ guint modifiers);
+static gboolean bus_input_context_send_signal (BusInputContext *context,
+ const gchar *signal_name,
+ GType first_arg_type,
+ ...);
+static void _engine_destroy_cb (BusEngineProxy *factory,
+ BusInputContext *context);
+
+static IBusServiceClass *parent_class = NULL;
+static guint id = 0;
+
+GType
+bus_input_context_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusInputContextClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_input_context_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusInputContext),
+ 0,
+ (GInstanceInitFunc) bus_input_context_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERVICE,
+ "BusInputContext",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+ return type;
+}
+
+static void
+_connection_destroy_cb (BusConnection *connection,
+ BusInputContext *context)
+{
+ BUS_IS_CONNECTION (connection);
+ BUS_IS_INPUT_CONTEXT (context);
+
+ ibus_object_destroy (IBUS_OBJECT (context));
+}
+
+
+BusInputContext *
+bus_input_context_new (BusConnection *connection,
+ const gchar *client)
+{
+ g_assert (BUS_IS_CONNECTION (connection));
+ g_assert (client != NULL);
+
+ BusInputContext *context;
+ gchar *path;
+ BusInputContextPrivate *priv;
+
+ path = g_strdup_printf (IBUS_PATH_INPUT_CONTEXT, ++id);
+
+ context = (BusInputContext *) g_object_new (BUS_TYPE_INPUT_CONTEXT,
+ "path", path,
+ NULL);
+ g_free (path);
+
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+#if 0
+ ibus_service_add_to_connection (IBUS_SERVICE (context),
+ IBUS_CONNECTION (connection));
+#endif
+
+ g_object_ref (connection);
+ priv->connection = connection;
+ priv->client = g_strdup (client);
+
+ g_signal_connect (priv->connection,
+ "destroy",
+ (GCallback) _connection_destroy_cb,
+ context);
+
+ return context;
+}
+
+static void
+bus_input_context_class_init (BusInputContextClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (BusInputContextPrivate));
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_input_context_destroy;
+
+ IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) bus_input_context_ibus_message;
+
+ /* install signals */
+ context_signals[PROCESS_KEY_EVENT] =
+ g_signal_new (I_("process-key-event"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_BOOL__UINT_UINT,
+ G_TYPE_BOOLEAN,
+ 2,
+ G_TYPE_UINT,
+ G_TYPE_UINT);
+
+ context_signals[SET_CURSOR_LOCATION] =
+ g_signal_new (I_("set-cursor-location"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__INT_INT_INT_INT,
+ G_TYPE_NONE,
+ 4,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+ context_signals[FOCUS_IN] =
+ g_signal_new (I_("focus-in"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[FOCUS_OUT] =
+ g_signal_new (I_("focus-out"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[UPDATE_PREEDIT_TEXT] =
+ g_signal_new (I_("update-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT_UINT_BOOLEAN,
+ G_TYPE_NONE,
+ 3,
+ IBUS_TYPE_TEXT,
+ G_TYPE_UINT,
+ G_TYPE_BOOLEAN);
+
+ context_signals[SHOW_PREEDIT_TEXT] =
+ g_signal_new (I_("show-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[HIDE_PREEDIT_TEXT] =
+ g_signal_new (I_("hide-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[UPDATE_AUXILIARY_TEXT] =
+ g_signal_new (I_("update-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE,
+ 2,
+ IBUS_TYPE_TEXT,
+ G_TYPE_BOOLEAN);
+
+ context_signals[SHOW_AUXILIARY_TEXT] =
+ g_signal_new (I_("show-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[HIDE_AUXILIARY_TEXT] =
+ g_signal_new (I_("hide-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[UPDATE_LOOKUP_TABLE] =
+ g_signal_new (I_("update-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE,
+ 2,
+ IBUS_TYPE_LOOKUP_TABLE,
+ G_TYPE_BOOLEAN);
+
+ context_signals[SHOW_LOOKUP_TABLE] =
+ g_signal_new (I_("show-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[HIDE_LOOKUP_TABLE] =
+ g_signal_new (I_("hide-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[PAGE_UP_LOOKUP_TABLE] =
+ g_signal_new (I_("page-up-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[PAGE_DOWN_LOOKUP_TABLE] =
+ g_signal_new (I_("page-down-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[CURSOR_UP_LOOKUP_TABLE] =
+ g_signal_new (I_("cursor-up-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[CURSOR_DOWN_LOOKUP_TABLE] =
+ g_signal_new (I_("cursor-down-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[REGISTER_PROPERTIES] =
+ g_signal_new (I_("register-properties"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IBUS_TYPE_PROP_LIST);
+
+ context_signals[UPDATE_PROPERTY] =
+ g_signal_new (I_("update-property"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IBUS_TYPE_PROPERTY);
+
+ context_signals[ENABLED] =
+ g_signal_new (I_("enabled"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[DISABLED] =
+ g_signal_new (I_("disabled"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[ENGINE_CHANGED] =
+ g_signal_new (I_("factory-changed"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[REQUEST_ENGINE] =
+ g_signal_new (I_("request-engine"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ context_signals[REQUEST_NEXT_ENGINE] =
+ g_signal_new (I_("request-next-engine"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[REQUEST_PREV_ENGINE] =
+ g_signal_new (I_("request-prev-engine"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+}
+
+static void
+bus_input_context_init (BusInputContext *context)
+{
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ priv->connection = NULL;
+ priv->client = NULL;
+ priv->engine = NULL;
+ priv->has_focus = FALSE;
+ priv->enabled = FALSE;
+
+ priv->capabilities = 0;
+
+ priv->x = 0;
+ priv->y = 0;
+ priv->w = 0;
+ priv->h = 0;
+
+}
+
+static void
+bus_input_context_destroy (BusInputContext *context)
+{
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->has_focus) {
+ bus_input_context_focus_out (context);
+ priv->has_focus = FALSE;
+ }
+
+ if (priv->engine) {
+ g_signal_handlers_disconnect_by_func (priv->engine,
+ G_CALLBACK (_engine_destroy_cb),
+ context);
+ g_object_unref (priv->engine);
+ priv->engine = NULL;
+ }
+
+ if (priv->connection) {
+ g_signal_handlers_disconnect_by_func (priv->connection,
+ (GCallback) _connection_destroy_cb,
+ context);
+ g_object_unref (priv->connection);
+ priv->connection = NULL;
+ }
+
+ if (priv->client) {
+ g_free (priv->client);
+ priv->client = NULL;
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (context));
+}
+
+/* introspectable interface */
+static IBusMessage *
+_ibus_introspect (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ static const gchar *introspect =
+ "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
+ "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
+ "<node>\n"
+ " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+ " <method name=\"Introspect\">\n"
+ " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " </interface>\n"
+ " <interface name=\"org.freedesktop.IBus\">\n"
+ " <method name=\"RequestName\">\n"
+ " <arg direction=\"in\" type=\"s\"/>\n"
+ " <arg direction=\"in\" type=\"u\"/>\n"
+ " <arg direction=\"out\" type=\"u\"/>\n"
+ " </method>\n"
+ " <signal name=\"NameOwnerChanged\">\n"
+ " <arg type=\"s\"/>\n"
+ " <arg type=\"s\"/>\n"
+ " <arg type=\"s\"/>\n"
+ " </signal>\n"
+ " </interface>\n"
+ "</node>\n";
+
+ IBusMessage *reply_message;
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ G_TYPE_STRING, &introspect,
+ G_TYPE_INVALID);
+
+ return reply_message;
+}
+
+typedef struct {
+ BusInputContext *context;
+ IBusMessage *message;
+}CallData;
+
+static void
+_ic_process_key_event_reply_cb (gboolean retval,
+ CallData *call_data)
+{
+ IBusMessage *reply;
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (call_data->context);
+
+ reply = ibus_message_new_method_return (call_data->message);
+ ibus_message_append_args (reply,
+ G_TYPE_BOOLEAN, &retval,
+ G_TYPE_INVALID);
+ ibus_connection_send ((IBusConnection *)priv->connection, reply);
+
+ g_object_unref (call_data->context);
+ ibus_message_unref (call_data->message);
+ ibus_message_unref (reply);
+ g_slice_free (CallData, call_data);
+}
+
+static IBusMessage *
+_ic_process_key_event (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply = NULL;
+ guint keyval, modifiers;
+ gboolean retval;
+ IBusError *error;
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+
+ error = ibus_error_new ();
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_UINT, &keyval,
+ G_TYPE_UINT, &modifiers,
+ G_TYPE_INVALID);
+
+ if (!retval) {
+ reply = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply;
+ }
+
+ ibus_error_free (error);
+
+ retval = bus_input_context_filter_keyboard_shortcuts (context, keyval, modifiers);
+
+ if (retval) {
+ reply = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply,
+ G_TYPE_BOOLEAN, &retval,
+ G_TYPE_INVALID);
+ }
+ else if (priv->enabled && priv->engine) {
+ CallData *call_data = g_slice_new (CallData);
+ call_data->context = context;
+ call_data->message = message;
+ g_object_ref (context);
+ ibus_message_ref (message);
+
+ bus_engine_proxy_process_key_event (priv->engine,
+ keyval,
+ modifiers,
+ (GFunc) _ic_process_key_event_reply_cb,
+ call_data);
+ }
+ else {
+ reply = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply,
+ G_TYPE_BOOLEAN, &retval,
+ G_TYPE_INVALID);
+ }
+ return reply;
+}
+
+static IBusMessage *
+_ic_set_cursor_location (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply;
+ guint x, y, w, h;
+ gboolean retval;
+ IBusError *error;
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ retval = ibus_message_get_args (message, &error,
+ G_TYPE_INT, &x,
+ G_TYPE_INT, &y,
+ G_TYPE_INT, &w,
+ G_TYPE_INT, &h,
+ G_TYPE_INVALID);
+
+ if (!retval) {
+ reply = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply;
+ }
+
+ priv->x = x;
+ priv->y = y;
+ priv->h = h;
+ priv->w = w;
+
+ if (priv->engine) {
+ bus_engine_proxy_set_cursor_location (priv->engine, x, y, w, h);
+ }
+
+ if (priv->capabilities & IBUS_CAP_FOCUS) {
+ g_signal_emit (context,
+ context_signals[SET_CURSOR_LOCATION],
+ 0,
+ x,
+ y,
+ w,
+ h);
+ }
+
+ reply = ibus_message_new_method_return (message);
+ return reply;
+}
+
+static IBusMessage *
+_ic_focus_in (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply;
+
+ bus_input_context_focus_in (context);
+
+ reply = ibus_message_new_method_return (message);
+
+ return reply;
+}
+
+static IBusMessage *
+_ic_focus_out (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply;
+
+ bus_input_context_focus_out (context);
+
+ reply = ibus_message_new_method_return (message);
+
+ return reply;
+}
+
+static IBusMessage *
+_ic_reset (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply;
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+
+ if (priv->engine) {
+ bus_engine_proxy_reset (priv->engine);
+ }
+
+ reply = ibus_message_new_method_return (message);
+ return reply;
+}
+
+static IBusMessage *
+_ic_set_capabilities (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply;
+ guint caps;
+ gboolean retval;
+ IBusError *error;
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_UINT, &caps,
+ G_TYPE_INVALID);
+
+ if (!retval) {
+ reply = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply;
+ }
+
+ if (priv->capabilities != caps) {
+ priv->capabilities = caps;
+
+ if (priv->engine) {
+ bus_engine_proxy_set_capabilities (priv->engine, caps);
+ }
+ }
+
+ reply = ibus_message_new_method_return (message);
+ return reply;
+}
+
+static IBusMessage *
+_ic_is_enabled (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply;
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ reply = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply,
+ G_TYPE_BOOLEAN, &priv->enabled,
+ G_TYPE_INVALID);
+
+ return reply;
+}
+
+static IBusMessage *
+_ic_set_engine (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ gboolean retval;
+ IBusMessage *reply;
+ IBusError *error;
+ gchar *engine_name;
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &engine_name,
+ G_TYPE_INVALID);
+ if (!retval) {
+ reply = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ return reply;
+ }
+
+ g_signal_emit (context, context_signals[REQUEST_ENGINE], 0, engine_name);
+
+ if (priv->engine == NULL) {
+ reply = ibus_message_new_error_printf (message,
+ "org.freedesktop.IBus.NoEngine",
+ "can not find engine with name %s",
+ engine_name);
+ return reply;
+ }
+
+ bus_input_context_enable (context);
+
+ reply = ibus_message_new_method_return (message);
+ return reply;
+}
+
+static IBusMessage *
+_ic_get_engine (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply;
+ IBusEngineDesc *desc;
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->engine) {
+ desc = bus_engine_proxy_get_desc (priv->engine);
+ if (desc != NULL) {
+ reply = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply,
+ IBUS_TYPE_ENGINE_DESC, &desc,
+ G_TYPE_INVALID);
+ return reply;
+ }
+ }
+
+ reply = ibus_message_new_error (message,
+ DBUS_ERROR_FAILED,
+ "InputContext does not have factory.");
+ return reply;
+}
+
+static IBusMessage *
+_ic_destroy (BusInputContext *context,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (message != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ IBusMessage *reply;
+ reply = ibus_message_new_method_return (message);
+
+ ibus_connection_send ((IBusConnection *) connection, reply);
+ ibus_connection_flush ((IBusConnection *) connection);
+ ibus_message_unref (reply);
+
+ ibus_object_destroy ((IBusObject *) context);
+
+ return NULL;
+}
+
+static gboolean
+bus_input_context_ibus_message (BusInputContext *context,
+ BusConnection *connection,
+ IBusMessage *message)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (BUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+
+ gint i;
+ IBusMessage *reply_message = NULL;
+
+ static const struct {
+ const gchar *interface;
+ const gchar *name;
+ IBusMessage *(* handler) (BusInputContext *, IBusMessage *, BusConnection *);
+ } handlers[] = {
+ /* Introspectable interface */
+ { DBUS_INTERFACE_INTROSPECTABLE,
+ "Introspect", _ibus_introspect },
+ /* IBus interface */
+ { IBUS_INTERFACE_INPUT_CONTEXT, "ProcessKeyEvent", _ic_process_key_event },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "SetCursorLocation", _ic_set_cursor_location },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "FocusIn", _ic_focus_in },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "FocusOut", _ic_focus_out },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "Reset", _ic_reset },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "SetCapabilities", _ic_set_capabilities },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "IsEnabled", _ic_is_enabled },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "SetEngine", _ic_set_engine },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "GetEngine", _ic_get_engine },
+ { IBUS_INTERFACE_INPUT_CONTEXT, "Destroy", _ic_destroy },
+
+ { NULL, NULL, NULL }
+ };
+
+ ibus_message_set_sender (message, bus_connection_get_unique_name (connection));
+ ibus_message_set_destination (message, DBUS_SERVICE_DBUS);
+
+ for (i = 0; handlers[i].interface != NULL; i++) {
+ if (ibus_message_is_method_call (message,
+ handlers[i].interface,
+ handlers[i].name)) {
+
+ reply_message = handlers[i].handler (context, message, connection);
+ if (reply_message) {
+
+ ibus_message_set_sender (reply_message,
+ DBUS_SERVICE_DBUS);
+ ibus_message_set_destination (reply_message,
+ bus_connection_get_unique_name (connection));
+ ibus_message_set_no_reply (reply_message, TRUE);
+
+ ibus_connection_send (IBUS_CONNECTION (connection), reply_message);
+ ibus_message_unref (reply_message);
+ }
+
+ g_signal_stop_emission_by_name (context, "ibus-message");
+ return TRUE;
+ }
+ }
+
+ return parent_class->ibus_message ((IBusService *)context,
+ (IBusConnection *)connection,
+ message);
+}
+
+
+gboolean
+bus_input_context_is_focus (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ return priv->has_focus;
+}
+
+void
+bus_input_context_focus_in (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->has_focus)
+ return;
+
+ priv->has_focus = TRUE;
+
+ if (priv->engine) {
+ bus_engine_proxy_focus_in (priv->engine);
+ }
+
+ if (priv->capabilities & IBUS_CAP_FOCUS) {
+ g_signal_emit (context, context_signals[FOCUS_IN], 0);
+ }
+}
+
+void
+bus_input_context_focus_out (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (!priv->has_focus)
+ return;
+
+ priv->has_focus = FALSE;
+
+ if (priv->engine) {
+ bus_engine_proxy_focus_out (priv->engine);
+ }
+
+ if (priv->capabilities & IBUS_CAP_FOCUS) {
+ g_signal_emit (context, context_signals[FOCUS_OUT], 0);
+ }
+}
+
+void
+bus_input_context_page_up (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->engine) {
+ bus_engine_proxy_page_up (priv->engine);
+ }
+}
+
+void
+bus_input_context_page_down (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->engine) {
+ bus_engine_proxy_page_down (priv->engine);
+ }
+}
+
+void
+bus_input_context_cursor_up (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->engine) {
+ bus_engine_proxy_cursor_up (priv->engine);
+ }
+}
+
+void
+bus_input_context_cursor_down (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->engine) {
+ bus_engine_proxy_cursor_down (priv->engine);
+ }
+}
+
+void
+bus_input_context_property_activate (BusInputContext *context,
+ const gchar *prop_name,
+ gint prop_state)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->engine) {
+ bus_engine_proxy_property_activate (priv->engine, prop_name, prop_state);
+ }
+}
+
+static void
+_engine_destroy_cb (BusEngineProxy *engine,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->engine == engine);
+
+ bus_input_context_set_engine (context, NULL);
+}
+
+static void
+_engine_commit_text_cb (BusEngineProxy *engine,
+ IBusText *text,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (text != NULL);
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->engine == engine);
+
+ bus_input_context_send_signal (context,
+ "CommitText",
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_INVALID);
+
+}
+
+static void
+_engine_forward_key_event_cb (BusEngineProxy *engine,
+ guint keyval,
+ guint state,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->engine == engine);
+
+ bus_input_context_send_signal (context,
+ "ForwardKeyEvent",
+ G_TYPE_UINT, &keyval,
+ G_TYPE_UINT, &state,
+ G_TYPE_INVALID);
+
+}
+
+static void
+_engine_update_preedit_text_cb (BusEngineProxy *engine,
+ IBusText *text,
+ guint cursor_pos,
+ gboolean visible,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (IBUS_IS_TEXT (text));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->engine == engine);
+
+ if (priv->capabilities & IBUS_CAP_PREEDIT_TEXT) {
+ bus_input_context_send_signal (context,
+ "UpdatePreeditText",
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_UINT, &cursor_pos,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+ }
+ else {
+ g_signal_emit (context,
+ context_signals[UPDATE_PREEDIT_TEXT],
+ 0,
+ text,
+ cursor_pos,
+ visible);
+ }
+}
+
+static void
+_engine_update_auxiliary_text_cb (BusEngineProxy *engine,
+ IBusText *text,
+ gboolean visible,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (IBUS_IS_TEXT (text));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->engine == engine);
+
+ if (priv->capabilities & IBUS_CAP_AUXILIARY_TEXT) {
+ bus_input_context_send_signal (context,
+ "UpdateAuxiliaryText",
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+ }
+ else {
+ g_signal_emit (context,
+ context_signals[UPDATE_AUXILIARY_TEXT],
+ 0,
+ text,
+ visible);
+ }
+}
+
+static void
+_engine_update_lookup_table_cb (BusEngineProxy *engine,
+ IBusLookupTable *table,
+ gboolean visible,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (IBUS_IS_LOOKUP_TABLE (table));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->engine == engine);
+
+ if (priv->capabilities & IBUS_CAP_LOOKUP_TABLE) {
+ bus_input_context_send_signal (context,
+ "UpdateLookupTable",
+ IBUS_TYPE_LOOKUP_TABLE, &table,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+ }
+ else {
+ g_signal_emit (context,
+ context_signals[UPDATE_LOOKUP_TABLE],
+ 0,
+ table,
+ visible);
+ }
+}
+
+static void
+_engine_register_properties_cb (BusEngineProxy *engine,
+ IBusPropList *prop_list,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (IBUS_IS_PROP_LIST (prop_list));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->engine == engine);
+
+ if (priv->capabilities & IBUS_CAP_PROPERTY) {
+ bus_input_context_send_signal (context,
+ "RegisterProperties",
+ IBUS_TYPE_PROP_LIST, &prop_list,
+ G_TYPE_INVALID);
+ }
+ else {
+ g_signal_emit (context,
+ context_signals[REGISTER_PROPERTIES],
+ 0,
+ prop_list);
+ }
+}
+
+static void
+_engine_update_property_cb (BusEngineProxy *engine,
+ IBusProperty *prop,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+ g_assert (IBUS_IS_PROPERTY (prop));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->engine == engine);
+
+ if (priv->capabilities & IBUS_CAP_PROPERTY) {
+ bus_input_context_send_signal (context,
+ "UpdateProperty",
+ IBUS_TYPE_PROPERTY, &prop,
+ G_TYPE_INVALID);
+ }
+ else {
+ g_signal_emit (context,
+ context_signals[UPDATE_PROPERTY],
+ 0,
+ prop);
+ }
+}
+
+#define DEFINE_FUNCTION(name, Name, signal_name, cap) \
+ static void \
+ _engine_##name##_cb (BusEngineProxy *engine, \
+ BusInputContext *context) \
+ { \
+ g_assert (BUS_IS_ENGINE_PROXY (engine)); \
+ g_assert (BUS_IS_INPUT_CONTEXT (context)); \
+ \
+ BusInputContextPrivate *priv; \
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context); \
+ \
+ g_assert (priv->engine == engine); \
+ \
+ if ((priv->capabilities & (cap)) == (cap)) { \
+ bus_input_context_send_signal (context, \
+ #Name, \
+ G_TYPE_INVALID); \
+ } \
+ else { \
+ g_signal_emit (context, \
+ context_signals[signal_name], \
+ 0); \
+ } \
+}
+
+DEFINE_FUNCTION (show_preedit_text, ShowPreeditText, SHOW_PREEDIT_TEXT, IBUS_CAP_PREEDIT_TEXT)
+DEFINE_FUNCTION (hide_preedit_text, HidePreeditText, HIDE_PREEDIT_TEXT, IBUS_CAP_PREEDIT_TEXT)
+DEFINE_FUNCTION (show_auxiliary_text, ShowAuxiliaryText, SHOW_AUXILIARY_TEXT, IBUS_CAP_AUXILIARY_TEXT)
+DEFINE_FUNCTION (hide_auxiliary_text, HideAuxiliaryText, HIDE_AUXILIARY_TEXT, IBUS_CAP_AUXILIARY_TEXT)
+DEFINE_FUNCTION (show_lookup_table, ShowLookupTable, SHOW_LOOKUP_TABLE, IBUS_CAP_LOOKUP_TABLE)
+DEFINE_FUNCTION (hide_lookup_table, HideLookupTable, HIDE_LOOKUP_TABLE, IBUS_CAP_LOOKUP_TABLE)
+DEFINE_FUNCTION (page_up_lookup_table, PageUpLookupTable, PAGE_UP_LOOKUP_TABLE, IBUS_CAP_LOOKUP_TABLE)
+DEFINE_FUNCTION (page_down_lookup_table, PageDownLookupTable, PAGE_DOWN_LOOKUP_TABLE, IBUS_CAP_LOOKUP_TABLE)
+DEFINE_FUNCTION (cursor_up_lookup_table, CursorUpLookupTable, CURSOR_UP_LOOKUP_TABLE, IBUS_CAP_LOOKUP_TABLE)
+DEFINE_FUNCTION (cursor_down_lookup_table, CursorDownLookupTable, CURSOR_DOWN_LOOKUP_TABLE, IBUS_CAP_LOOKUP_TABLE)
+
+#undef DEFINE_FUNCTION
+
+void
+bus_input_context_enable (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->engine == NULL)
+ return;
+
+ priv->enabled = TRUE;
+
+ bus_engine_proxy_enable (priv->engine);
+ bus_input_context_send_signal (context,
+ "Enabled",
+ G_TYPE_INVALID);
+ g_signal_emit (context,
+ context_signals[ENABLED],
+ 0);
+ if (priv->has_focus) {
+ bus_engine_proxy_focus_in (priv->engine);
+ }
+}
+
+void
+bus_input_context_disable (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ priv->enabled = FALSE;
+
+ if (priv->engine) {
+ if (priv->has_focus) {
+ bus_engine_proxy_focus_out (priv->engine);
+ }
+ bus_engine_proxy_disable (priv->engine);
+ }
+
+ bus_input_context_send_signal (context,
+ "Disabled",
+ G_TYPE_INVALID);
+ g_signal_emit (context,
+ context_signals[DISABLED],
+ 0);
+}
+
+
+void
+bus_input_context_set_engine (BusInputContext *context,
+ BusEngineProxy *engine)
+{
+
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ if (priv->engine != NULL) {
+ g_signal_handlers_disconnect_by_func (priv->engine, _engine_destroy_cb, context);
+ ibus_object_destroy ((IBusObject *) priv->engine);
+ g_object_unref (priv->engine);
+ priv->engine = NULL;
+ }
+
+ if (engine == NULL) {
+ bus_input_context_disable (context);
+ g_signal_emit (context,
+ context_signals[ENGINE_CHANGED],
+ 0);
+ return;
+ }
+
+ priv->engine = engine;
+ g_object_ref (priv->engine);
+
+ gint i;
+ const static struct {
+ const gchar *name;
+ GCallback callback;
+ } signals [] = {
+ { "commit-text", G_CALLBACK (_engine_commit_text_cb) },
+ { "forward-key-event", G_CALLBACK (_engine_forward_key_event_cb) },
+ { "update-preedit-text", G_CALLBACK (_engine_update_preedit_text_cb) },
+ { "show-preedit-text", G_CALLBACK (_engine_show_preedit_text_cb) },
+ { "hide-preedit-text", G_CALLBACK (_engine_hide_preedit_text_cb) },
+ { "update-auxiliary-text", G_CALLBACK (_engine_update_auxiliary_text_cb) },
+ { "show-auxiliary-text", G_CALLBACK (_engine_show_auxiliary_text_cb) },
+ { "hide-auxiliary-text", G_CALLBACK (_engine_hide_auxiliary_text_cb) },
+ { "update-lookup-table", G_CALLBACK (_engine_update_lookup_table_cb) },
+ { "show-lookup-table", G_CALLBACK (_engine_show_lookup_table_cb) },
+ { "hide-lookup-table", G_CALLBACK (_engine_hide_lookup_table_cb) },
+ { "page-up-lookup-table", G_CALLBACK (_engine_page_up_lookup_table_cb) },
+ { "page-down-lookup-table", G_CALLBACK (_engine_page_down_lookup_table_cb) },
+ { "cursor-up-lookup-table", G_CALLBACK (_engine_cursor_up_lookup_table_cb) },
+ { "cursor-down-lookup-table", G_CALLBACK (_engine_cursor_down_lookup_table_cb) },
+ { "register-properties", G_CALLBACK (_engine_register_properties_cb) },
+ { "update-property", G_CALLBACK (_engine_update_property_cb) },
+ { "destroy", G_CALLBACK (_engine_destroy_cb) },
+ { NULL, 0 }
+ };
+
+ for (i = 0; signals[i].name != NULL; i++) {
+ g_signal_connect (priv->engine,
+ signals[i].name,
+ signals[i].callback,
+ context);
+ }
+
+ g_signal_emit (context,
+ context_signals[ENGINE_CHANGED],
+ 0);
+}
+
+static gboolean
+bus_input_context_filter_keyboard_shortcuts (BusInputContext *context,
+ guint keyval,
+ guint modifiers)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ static GQuark trigger;
+ static GQuark next_factory;
+ static GQuark prev_factory;
+
+ GQuark event;
+
+ if (trigger == 0) {
+ trigger = g_quark_from_static_string ("trigger");
+ next_factory = g_quark_from_static_string ("next-engine");
+ prev_factory = g_quark_from_static_string ("prev-engine");
+ }
+
+ event = ibus_hotkey_profile_filter_key_event (BUS_DEFAULT_HOTKEY_PROFILE,
+ keyval,
+ modifiers,
+ 0);
+
+ if (event == trigger) {
+ if (priv->engine == NULL) {
+ g_signal_emit (context, context_signals[REQUEST_ENGINE], 0, NULL);
+ }
+
+ if (priv->engine == NULL) {
+ return FALSE;
+ }
+
+ if (priv->enabled) {
+ bus_input_context_disable (context);
+ }
+ else {
+ bus_input_context_enable (context);
+ }
+
+ return TRUE;
+ }
+ else if (event == next_factory) {
+ return TRUE;
+ }
+ else if (event == prev_factory) {
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+static gboolean
+bus_input_context_send_signal (BusInputContext *context,
+ const gchar *signal_name,
+ GType first_arg_type,
+ ...)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (signal_name != NULL);
+
+ va_list args;
+ gboolean retval;
+ IBusMessage *message;
+ BusInputContextPrivate *priv;
+
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ g_assert (priv->connection != NULL);
+
+ message = ibus_message_new_signal (ibus_service_get_path ((IBusService *)context),
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ signal_name);
+
+ ibus_message_set_sender (message, IBUS_SERVICE_IBUS);
+
+ va_start (args, first_arg_type);
+ ibus_message_append_args_valist (message, first_arg_type, args);
+ va_end (args);
+
+ retval = ibus_connection_send ((IBusConnection *)priv->connection, message);
+ ibus_message_unref (message);
+
+ return retval;
+}
diff --git a/bus/inputcontext.h b/bus/inputcontext.h
new file mode 100644
index 0000000..edebdc0
--- /dev/null
+++ b/bus/inputcontext.h
@@ -0,0 +1,82 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __INPUT_CONTEXT_H_
+#define __INPUT_CONTEXT_H_
+
+#include <ibus.h>
+#include "connection.h"
+#include "factoryproxy.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_INPUT_CONTEXT \
+ (bus_input_context_get_type ())
+#define BUS_INPUT_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_INPUT_CONTEXT, BusInputContext))
+#define BUS_INPUT_CONTEXT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_INPUT_CONTEXT, BusInputContextClass))
+#define BUS_IS_INPUT_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_INPUT_CONTEXT))
+#define BUS_IS_INPUT_CONTEXT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_INPUT_CONTEXT))
+#define BUS_INPUT_CONTEXT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_INPUT_CONTEXT, BusInputContextClass))
+
+G_BEGIN_DECLS
+
+typedef struct _BusInputContext BusInputContext;
+typedef struct _BusInputContextClass BusInputContextClass;
+
+struct _BusInputContext {
+ IBusService parent;
+ /* instance members */
+};
+
+struct _BusInputContextClass {
+ IBusServiceClass parent;
+
+ /* class members */
+};
+
+GType bus_input_context_get_type (void);
+BusInputContext *bus_input_context_new (BusConnection *connection,
+ const gchar *client);
+gboolean bus_input_context_is_focus (BusInputContext *context);
+void bus_input_context_focus_in (BusInputContext *context);
+void bus_input_context_focus_out (BusInputContext *context);
+void bus_input_context_enable_or_disable(BusInputContext *context);
+void bus_input_context_enable (BusInputContext *context);
+void bus_input_context_disable (BusInputContext *context);
+void bus_input_context_page_up (BusInputContext *context);
+void bus_input_context_page_down (BusInputContext *context);
+void bus_input_context_cursor_up (BusInputContext *context);
+void bus_input_context_cursor_down (BusInputContext *context);
+void bus_input_context_set_engine (BusInputContext *context,
+ BusEngineProxy *factory);
+void bus_input_context_property_activate(BusInputContext *context,
+ const gchar *prop_name,
+ gint prop_state);
+
+G_END_DECLS
+#endif
+
diff --git a/bus/main.c b/bus/main.c
new file mode 100644
index 0000000..74e05d8
--- /dev/null
+++ b/bus/main.c
@@ -0,0 +1,148 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <locale.h>
+#include "server.h"
+#include "ibusimpl.h"
+
+static gboolean daemonize = FALSE;
+static gboolean single = FALSE;
+static gboolean xim = FALSE;
+static gchar *panel = "default";
+static gchar *config = "default";
+static gchar *desktop = "gnome";
+static gboolean verbose = FALSE;
+
+static const GOptionEntry entries[] =
+{
+ { "daemonize", 'd', 0, G_OPTION_ARG_NONE, &daemonize, "run ibus as background process.", NULL },
+ { "single", 's', 0, G_OPTION_ARG_NONE, &single, "do not execute panel and config module.", NULL },
+ { "xim", 'x', 0, G_OPTION_ARG_NONE, &xim, "execute ibus XIM server.", NULL },
+ { "desktop", 'n', 0, G_OPTION_ARG_STRING, &desktop, "specify the name of desktop session. [default=gnome]", "name" },
+ { "panel", 'p', 0, G_OPTION_ARG_STRING, &panel, "specify the cmdline of panel program.", "cmdline" },
+ { "config", 'c', 0, G_OPTION_ARG_STRING, &config, "specify the cmdline of config program.", "cmdline" },
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "verbose.", NULL },
+ { NULL },
+};
+
+static gboolean
+execute_cmdline (const gchar *cmdline)
+{
+ g_assert (cmdline);
+
+ gint argc;
+ gchar **argv;
+ gboolean retval;
+ GError *error;
+
+ error = NULL;
+ if (!g_shell_parse_argv (cmdline, &argc, &argv, &error)) {
+ g_warning ("Can not parse cmdline `%s` exec: %s", cmdline, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ error = NULL;
+ retval = g_spawn_async (NULL, argv, NULL,
+ G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL,
+ NULL, &error);
+ g_strfreev (argv);
+
+ if (!retval) {
+ g_warning ("Can not execute cmdline `%s`: %s", cmdline, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+ GOptionContext *context;
+ BusServer *server;
+
+ GError *error = NULL;
+
+ setlocale (LC_ALL, "");
+
+ context = g_option_context_new ("- ibus daemon");
+
+ g_option_context_add_main_entries (context, entries, "ibus-daemon");
+
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_printerr ("Option parsing failed: %s\n", error->message);
+ exit (-1);
+ }
+
+ if (daemonize) {
+ if (daemon (1, 0) != 0) {
+ g_printerr ("Can not daemonize ibus.\n");
+ exit (-1);
+ }
+ }
+
+ g_type_init ();
+
+ server = bus_server_get_default ();
+ bus_server_listen (server);
+
+ if (!single) {
+ /* execute config component */
+ if (g_strcmp0 (config, "default") == 0) {
+ IBusComponent *component;
+ component = bus_registry_lookup_component_by_name (BUS_DEFAULT_REGISTRY, IBUS_SERVICE_CONFIG);
+ if (component == NULL || !ibus_component_start (component)) {
+ g_printerr ("Can not execute default config program\n");
+ exit (-1);
+ }
+ } else if (g_strcmp0 (config, "disable") != 0 && g_strcmp0 (config, "") != 0) {
+ if (!execute_cmdline (config))
+ exit (-1);
+ }
+
+ /* execut panel component */
+ if (g_strcmp0 (panel, "default") == 0) {
+ IBusComponent *component;
+ component = bus_registry_lookup_component_by_name (BUS_DEFAULT_REGISTRY, IBUS_SERVICE_PANEL);
+ if (component == NULL || !ibus_component_start (component)) {
+ g_printerr ("Can not execute default panel program\n");
+ exit (-1);
+ }
+ } else if (g_strcmp0 (panel, "disable") != 0 && g_strcmp0 (panel, "") != 0) {
+ if (!execute_cmdline (panel))
+ exit (-1);
+ }
+ }
+
+ /* execute ibus xim server */
+ if (xim) {
+ if (!execute_cmdline (LIBEXECDIR"/ibus-x11 --kill-daemon"))
+ exit (-1);
+ }
+
+ bus_server_run (server);
+
+ return 0;
+}
diff --git a/bus/matchrule.c b/bus/matchrule.c
new file mode 100644
index 0000000..6884fd6
--- /dev/null
+++ b/bus/matchrule.c
@@ -0,0 +1,672 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <string.h>
+#include "matchrule.h"
+
+#define BUS_CONFIG_PROXY_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_CONFIG_PROXY, BusMatchRulePrivate))
+
+
+static void bus_match_rule_class_init (BusMatchRuleClass *klass);
+static void bus_match_rule_init (BusMatchRule *rule);
+static void bus_match_rule_destroy (BusMatchRule *rule);
+
+static IBusObjectClass *parent_class = NULL;
+
+GType
+bus_match_rule_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusMatchRuleClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_match_rule_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusMatchRule),
+ 0,
+ (GInstanceInitFunc) bus_match_rule_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_OBJECT,
+ "BusMatchRule",
+ &type_info,
+ (GTypeFlags)0);
+ }
+ return type;
+}
+
+static void
+bus_match_rule_class_init (BusMatchRuleClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_match_rule_destroy;
+}
+
+static void
+bus_match_rule_init (BusMatchRule *rule)
+{
+ rule->flags = 0;
+ rule->message_type = DBUS_MESSAGE_TYPE_INVALID;
+ rule->interface = NULL;
+ rule->member = NULL;
+ rule->sender = NULL;
+ rule->destination = NULL;
+ rule->path = NULL;
+ rule->args = g_array_new (TRUE, TRUE, sizeof (gchar *));
+}
+
+static void
+bus_match_rule_destroy (BusMatchRule *rule)
+{
+ g_free (rule->interface);
+ g_free (rule->member);
+ g_free (rule->sender);
+ g_free (rule->destination);
+ g_free (rule->path);
+
+ gint i;
+ GList *link;
+
+ for (i = 0; i < rule->args->len; i++) {
+ g_free (g_array_index (rule->args, gchar *, i));
+ }
+ g_array_free (rule->args, TRUE);
+
+ for (link = rule->recipients; link != NULL; link = link->next) {
+ BusRecipient *recipient = (BusRecipient *) link->data;
+ g_object_unref (recipient->connection);
+ g_slice_free (BusRecipient, recipient);
+ }
+ g_list_free (rule->recipients);
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (rule));
+}
+
+
+typedef struct _Token {
+ gchar *key;
+ gchar *value;
+} Token;
+
+#define SKIP_WHITE(a) \
+ while (*(a) == ' ' || *(a) == '\t') { (a)++; }
+#define IS_ALPHA(a) \
+ ((*(a) >= 'a' && *(a) <= 'z') || (*(a) >= 'A' && *(a) <= 'Z'))
+#define IS_NUMBER(a) \
+ (*(a) >= '0' && *(a) <= '9')
+
+static gchar *
+find_key (const gchar **p)
+{
+ GString *text;
+
+ text = g_string_new ("");
+
+ SKIP_WHITE(*p)
+ if (!IS_ALPHA (*p))
+ goto failed;
+
+ g_string_append_c (text, **p);
+ (*p) ++;
+
+ while (IS_ALPHA (*p) || IS_NUMBER (*p)) {
+ g_string_append_c (text, **p);
+ (*p) ++;
+ }
+
+ return g_string_free (text, FALSE);
+
+failed:
+ g_string_free (text, TRUE);
+ return NULL;
+
+}
+
+static gchar *
+find_value (const gchar **p)
+{
+ GString *text;
+
+ text = g_string_new ("");
+
+ SKIP_WHITE (*p);
+
+ if (**p != '\'')
+ goto failed;
+ (*p) ++;
+
+ while (**p != '\'') {
+ if (**p == '\0')
+ goto failed;
+ if (**p == '\\')
+ (*p) ++;
+ g_string_append_c (text, **p);
+ (*p) ++;
+ }
+ (*p) ++;
+
+ return g_string_free (text, FALSE);
+
+failed:
+ g_string_free (text, TRUE);
+ return NULL;
+}
+
+static Token *
+tokenize_rule (const gchar *text)
+{
+ GArray *tokens;
+ Token token;
+ const gchar *p;
+ gint i;
+
+ tokens = g_array_new (TRUE, TRUE, sizeof (Token));
+
+ p = text;
+
+ while (*p != '\0') {
+ gchar *key;
+ gchar *value;
+
+ SKIP_WHITE (p);
+ key = find_key (&p);
+ if (key == NULL)
+ goto failed;
+ SKIP_WHITE (p);
+ if (*p != '=')
+ goto failed;
+ p ++;
+ SKIP_WHITE (p);
+ value = find_value (&p);
+ if (value == NULL) {
+ g_free (key);
+ goto failed;
+ }
+ SKIP_WHITE (p);
+ if (*p != ',' && *p != '\0') {
+ g_free (key);
+ g_free (value);
+ goto failed;
+ }
+
+ if (*p == ',')
+ p ++;
+ token.key = key;
+ token.value = value;
+ g_array_append_val (tokens, token);
+ }
+
+ return (Token *)g_array_free (tokens, FALSE);
+
+failed:
+
+ for (i = 0; i < tokens->len; i++) {
+ Token *p = &g_array_index (tokens, Token, i);
+ g_free (p->key);
+ g_free (p->value);
+ }
+
+ g_array_free (tokens, TRUE);
+ return NULL;
+}
+
+static void
+tokens_free (Token *tokens)
+{
+ Token *p;
+ p = tokens;
+
+ while (p != NULL && p->key != NULL) {
+ g_free (p->key);
+ g_free (p->value);
+ p ++;
+ }
+ g_free (tokens);
+}
+
+static gboolean
+_atoi (const gchar *text, gint *i)
+{
+ const gchar *p = text;
+ *i = 0;
+ while (*p != '\0') {
+ if (!IS_NUMBER(p))
+ return FALSE;
+ *i = (*i) * 10 - '0' + *p;
+ p ++;
+ }
+ return TRUE;
+}
+
+BusMatchRule *
+bus_match_rule_new (const gchar *text)
+{
+ g_assert (text != NULL);
+
+ Token *tokens, *p;
+ BusMatchRule *rule;
+
+ rule = BUS_MATCH_RULE (g_object_new (BUS_TYPE_MATCH_RULE, NULL));
+
+ /* parse rule */
+ tokens = tokenize_rule (text);
+
+ for (p = tokens; p != NULL && p->key != 0; p++) {
+ if (g_strcmp0 (p->key, "type") == 0) {
+ if (g_strcmp0 (p->value, "signal") == 0) {
+ bus_match_rule_set_message_type (rule, DBUS_MESSAGE_TYPE_SIGNAL);
+ }
+ else if (g_strcmp0 (p->value, "method_call") == 0) {
+ bus_match_rule_set_message_type (rule, DBUS_MESSAGE_TYPE_METHOD_CALL);
+ }
+ else if (g_strcmp0 (p->value, "method_return") == 0) {
+ bus_match_rule_set_message_type (rule, DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ }
+ else if (g_strcmp0 (p->value, "error") == 0) {
+ bus_match_rule_set_message_type (rule, DBUS_MESSAGE_TYPE_ERROR);
+ }
+ else
+ goto failed;
+ }
+ else if (g_strcmp0 (p->key, "sender") == 0) {
+ bus_match_rule_set_sender (rule, p->value);
+ }
+ else if (g_strcmp0 (p->key, "interface") == 0) {
+ bus_match_rule_set_interface (rule, p->value);
+ }
+ else if (g_strcmp0 (p->key, "member") == 0) {
+ bus_match_rule_set_member (rule, p->value);
+ }
+ else if (g_strcmp0 (p->key, "path") == 0) {
+ bus_match_rule_set_path (rule, p->value);
+ }
+ else if (g_strcmp0 (p->key, "destination") == 0) {
+ bus_match_rule_set_destination (rule, p->value);
+ }
+ else if (strncmp (p->key, "arg", 3) == 0) {
+ gint i;
+ if (! _atoi (p->key + 3, &i))
+ goto failed;
+ bus_match_rule_set_arg (rule, i, p->value);
+ }
+ else
+ goto failed;
+ }
+
+ tokens_free (tokens);
+ return rule;
+
+failed:
+ tokens_free (tokens);
+ g_object_unref (rule);
+ return NULL;
+}
+
+gboolean
+bus_match_rule_set_message_type (BusMatchRule *rule,
+ gint type)
+{
+ g_assert (rule != NULL);
+ g_assert (type == DBUS_MESSAGE_TYPE_SIGNAL ||
+ type == DBUS_MESSAGE_TYPE_METHOD_CALL ||
+ type == DBUS_MESSAGE_TYPE_METHOD_RETURN ||
+ type == DBUS_MESSAGE_TYPE_ERROR);
+
+ rule->flags |= MATCH_TYPE;
+ rule->message_type = type;
+
+ return TRUE;
+}
+
+gboolean
+bus_match_rule_set_sender (BusMatchRule *rule,
+ const gchar *sender)
+{
+ g_assert (rule != NULL);
+ g_assert (sender != NULL);
+
+ rule->flags |= MATCH_SENDER;
+
+ g_free (rule->sender);
+ rule->sender = g_strdup (sender);
+
+ return TRUE;
+}
+
+gboolean
+bus_match_rule_set_interface (BusMatchRule *rule,
+ const gchar *interface)
+{
+ g_assert (rule != NULL);
+ g_assert (interface != NULL);
+
+ rule->flags |= MATCH_INTERFACE;
+
+ g_free (rule->interface);
+ rule->interface = g_strdup (interface);
+ return TRUE;
+}
+
+gboolean
+bus_match_rule_set_member (BusMatchRule *rule,
+ const gchar *member)
+{
+ g_assert (rule != NULL);
+ g_assert (member != NULL);
+
+ rule->flags |= MATCH_MEMBER;
+
+ g_free (rule->member);
+ rule->member = g_strdup (member);
+
+ return TRUE;
+}
+
+gboolean
+bus_match_rule_set_path (BusMatchRule *rule,
+ const gchar *path)
+{
+ g_assert (rule != NULL);
+ g_assert (path != NULL);
+
+ rule->flags |= MATCH_PATH;
+
+ g_free (rule->path);
+ rule->path = g_strdup (path);
+
+ return TRUE;
+}
+
+gboolean
+bus_match_rule_set_destination (BusMatchRule *rule,
+ const gchar *dest)
+{
+ g_assert (rule != NULL);
+ g_assert (dest != NULL);
+
+ rule->flags |= MATCH_DESTINATION;
+
+ g_free (rule->destination);
+ rule->destination = g_strdup (dest);
+
+ return TRUE;
+}
+
+gboolean
+bus_match_rule_set_arg (BusMatchRule *rule,
+ guint arg_i,
+ const gchar *arg)
+{
+ g_assert (rule != NULL);
+ g_assert (arg != NULL);
+
+ rule->flags |= MATCH_ARGS;
+
+ if (arg_i >= rule->args->len) {
+ g_array_set_size (rule->args, arg_i + 1);
+ }
+
+ g_free (g_array_index (rule->args, gchar *, arg_i));
+ g_array_index (rule->args, gchar *, arg_i) = g_strdup (arg);
+ return TRUE;
+}
+
+gboolean
+bus_match_rule_match (BusMatchRule *rule,
+ DBusMessage *message)
+{
+ g_assert (rule != NULL);
+ g_assert (message != NULL);
+
+ if (rule->flags & MATCH_TYPE) {
+ if (ibus_message_get_type (message) != rule->message_type)
+ return FALSE;
+ }
+
+ if (rule->flags & MATCH_INTERFACE) {
+ if (g_strcmp0 (ibus_message_get_interface (message), rule->interface) != 0)
+ return FALSE;
+ }
+
+ if (rule->flags & MATCH_MEMBER) {
+ if (g_strcmp0 (ibus_message_get_member (message), rule->member) != 0)
+ return FALSE;
+ }
+
+ if (rule->flags & MATCH_SENDER) {
+ if (g_strcmp0 (ibus_message_get_sender (message), rule->sender) != 0)
+ return FALSE;
+ }
+
+ if (rule->flags & MATCH_DESTINATION) {
+ if (g_strcmp0 (ibus_message_get_destination (message), rule->destination) != 0)
+ return FALSE;
+ }
+
+ if (rule->flags & MATCH_PATH) {
+ if (g_strcmp0 (ibus_message_get_path (message), rule->path) != 0)
+ return FALSE;
+ }
+
+ if (rule->flags & MATCH_ARGS) {
+ guint i;
+ DBusMessageIter iter;
+
+ ibus_message_iter_init (message, &iter);
+
+ for (i = 0; i < rule->args->len; i++) {
+ gchar *arg = g_array_index (rule->args, gchar *, i);
+ if (arg != NULL) {
+ gint type;
+ gchar *value;
+
+ type = ibus_message_iter_get_arg_type (&iter);
+ if (type != G_TYPE_STRING && type != IBUS_TYPE_OBJECT_PATH)
+ return FALSE;
+
+ ibus_message_iter_get_basic (&iter, &value);
+
+ if (g_strcmp0 (arg, value) != 0)
+ return FALSE;
+ }
+ ibus_message_iter_next (&iter);
+ }
+ }
+ return TRUE;
+}
+
+gboolean
+bus_match_rule_is_equal (BusMatchRule *a,
+ BusMatchRule *b)
+{
+ g_assert (a != NULL);
+ g_assert (b != NULL);
+
+ if (a->flags != b->flags)
+ return FALSE;
+
+ if (a->flags & MATCH_TYPE) {
+ if (a->message_type != b->message_type)
+ return FALSE;
+ }
+
+ if (a->flags & MATCH_INTERFACE) {
+ if (g_strcmp0 (a->interface, b->interface) != 0)
+ return FALSE;
+ }
+
+ if (a->flags & MATCH_MEMBER) {
+ if (g_strcmp0 (a->member, b->member) != 0)
+ return FALSE;
+ }
+
+ if (a->flags & MATCH_SENDER) {
+ if (g_strcmp0 (a->sender, b->sender) != 0)
+ return FALSE;
+ }
+
+ if (a->flags & MATCH_DESTINATION) {
+ if (g_strcmp0 (a->destination, b->destination) != 0)
+ return FALSE;
+ }
+
+ if (a->flags & MATCH_PATH) {
+ if (g_strcmp0 (a->path, b->path) != 0)
+ return FALSE;
+ }
+
+ if (a->flags & MATCH_ARGS) {
+ if (a->args->len != b->args->len)
+ return FALSE;
+
+ gint i;
+
+ for (i = 0; i < a->args->len; i++) {
+ if (g_strcmp0 (g_array_index (a->args, gchar *, i),
+ g_array_index (b->args, gchar *, i)) != 0)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+_connection_destroy_cb (BusConnection *connection,
+ BusMatchRule *rule)
+{
+ g_assert (BUS_IS_MATCH_RULE (rule));
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ GList *link;
+ BusRecipient *recipient;
+
+ for (link = rule->recipients; link != NULL; link = link->next) {
+ recipient = (BusRecipient *)link->data;
+
+ if (recipient->connection == connection) {
+ rule->recipients = g_list_remove_link (rule->recipients, link);
+ g_object_unref (connection);
+ g_slice_free (BusRecipient, recipient);
+ return;
+ }
+
+ if (rule->recipients == NULL) {
+ ibus_object_destroy (IBUS_OBJECT (rule));
+ }
+ }
+ g_assert_not_reached ();
+}
+
+void
+bus_match_rule_add_recipient (BusMatchRule *rule,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_MATCH_RULE (rule));
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ GList *link;
+ BusRecipient *recipient;
+
+ for (link = rule->recipients; link != NULL; link = link->next) {
+ recipient = (BusRecipient *) link->data;
+ if (connection == recipient->connection) {
+ recipient->refcount ++;
+ return;
+ }
+ }
+
+ recipient = g_slice_new (BusRecipient);
+
+ g_object_ref (connection);
+ recipient->connection = connection;
+ recipient->refcount = 1;
+
+ rule->recipients = g_list_append (rule->recipients, recipient);
+ g_signal_connect (connection,
+ "destroy",
+ G_CALLBACK (_connection_destroy_cb),
+ rule);
+}
+
+void
+bus_match_rule_remove_recipient (BusMatchRule *rule,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_MATCH_RULE (rule));
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ GList *link;
+ BusRecipient *recipient;
+
+ for (link = rule->recipients; link != NULL; link = link->next) {
+ recipient = (BusRecipient *) link->data;
+ if (connection == recipient->connection) {
+ recipient->refcount --;
+ if (recipient->refcount == 0) {
+ rule->recipients = g_list_remove_link (rule->recipients, link);
+ g_slice_free (BusRecipient, recipient);
+ g_signal_handlers_disconnect_by_func (connection,
+ G_CALLBACK (_connection_destroy_cb),
+ rule);
+ g_object_unref (connection);
+ }
+
+ if (rule->recipients == NULL ) {
+ ibus_object_destroy (IBUS_OBJECT(rule));
+ }
+ return;
+ }
+ }
+
+ g_warning ("Remove recipient failed");
+}
+
+gboolean
+bus_match_rule_get_recipients (BusMatchRule *rule,
+ DBusMessage *message,
+ GList **recipients)
+{
+ g_assert (BUS_IS_MATCH_RULE (rule));
+ g_assert (message != NULL);
+ g_assert (recipients != NULL);
+
+ GList *link;
+
+ if (!bus_match_rule_match (rule, message))
+ return FALSE;
+
+ for (link = rule->recipients; link != NULL; link = link->next) {
+ BusRecipient *recipient = (BusRecipient *) link->data;
+
+ g_object_ref (recipient->connection);
+ *recipients = g_list_append (*recipients, recipient->connection);
+ }
+
+ return TRUE;
+}
+
diff --git a/bus/matchrule.h b/bus/matchrule.h
new file mode 100644
index 0000000..e8aaf39
--- /dev/null
+++ b/bus/matchrule.h
@@ -0,0 +1,124 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __MATCH_RULE_H_
+#define __MATCH_RULE_H_
+
+#include <ibus.h>
+#include "connection.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_MATCH_RULE \
+ (bus_match_rule_get_type ())
+#define BUS_MATCH_RULE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_MATCH_RULE, BusMatchRule))
+#define BUS_MATCH_RULE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_MATCH_RULE, BusMatchRuleClass))
+#define BUS_IS_MATCH_RULE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_MATCH_RULE))
+#define BUS_IS_MATCH_RULE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_MATCH_RULE))
+#define BUS_MATCH_RULE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_MATCH_RULE, BusMatchRuleClass))
+
+G_BEGIN_DECLS
+
+typedef struct _BusMatchRule BusMatchRule;
+typedef struct _BusMatchRuleClass BusMatchRuleClass;
+
+typedef enum {
+ MATCH_TYPE = 1 << 0,
+ MATCH_INTERFACE = 1 << 1,
+ MATCH_MEMBER = 1 << 2,
+ MATCH_SENDER = 1 << 3,
+ MATCH_DESTINATION = 1 << 4,
+ MATCH_PATH = 1 << 5,
+ MATCH_ARGS = 1 << 6,
+} BusMatchFlags;
+
+typedef struct _BusRecipient BusRecipient;
+struct _BusRecipient {
+ BusConnection *connection;
+ gint refcount;
+};
+
+struct _BusMatchRule {
+ IBusProxy parent;
+ /* instance members */
+ gint flags;
+ gint message_type;
+ gchar *interface;
+ gchar *member;
+ gchar *sender;
+ gchar *destination;
+ gchar *path;
+ GArray *args;
+ GList *recipients;
+};
+
+struct _BusMatchRuleClass {
+ IBusProxyClass parent;
+ /* class members */
+};
+
+GType bus_match_rule_get_type (void);
+BusMatchRule *bus_match_rule_new (const gchar *text);
+BusMatchRule *bus_match_rule_ref (BusMatchRule *rule);
+void bus_match_rule_unref (BusMatchRule *rule);
+void bus_match_rule_free (BusMatchRule *rule);
+gboolean bus_match_rule_set_message_type
+ (BusMatchRule *rule,
+ gint type);
+gboolean bus_match_rule_set_sender (BusMatchRule *rule,
+ const gchar *sender);
+gboolean bus_match_rule_set_interface
+ (BusMatchRule *rule,
+ const gchar *interface);
+gboolean bus_match_rule_set_member (BusMatchRule *rule,
+ const gchar *member);
+gboolean bus_match_rule_set_path (BusMatchRule *rule,
+ const gchar *path);
+gboolean bus_match_rule_set_destination
+ (BusMatchRule *rule,
+ const gchar *dest);
+gboolean bus_match_rule_set_arg (BusMatchRule *rule,
+ guint arg_i,
+ const gchar *arg);
+gboolean bus_match_rule_match (BusMatchRule *rule,
+ DBusMessage *message);
+gboolean bus_match_rule_is_equal (BusMatchRule *a,
+ BusMatchRule *b);
+void bus_match_rule_add_recipient
+ (BusMatchRule *rule,
+ BusConnection *connection);
+void bus_match_rule_remove_recipient
+ (BusMatchRule *rule,
+ BusConnection *connection);
+gboolean bus_match_rule_get_recipients
+ (BusMatchRule *rule,
+ DBusMessage *message,
+ GList **recipients);
+
+G_END_DECLS
+#endif
+
diff --git a/bus/panelproxy.c b/bus/panelproxy.c
new file mode 100644
index 0000000..7d99f67
--- /dev/null
+++ b/bus/panelproxy.c
@@ -0,0 +1,757 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ibusinternal.h>
+#include <ibusmarshalers.h>
+#include "panelproxy.h"
+
+#define BUS_PANEL_PROXY_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_PANEL_PROXY, BusPanelProxyPrivate))
+
+enum {
+ PAGE_UP,
+ PAGE_DOWN,
+ CURSOR_UP,
+ CURSOR_DOWN,
+ PROPERTY_ACTIVATE,
+ PROPERTY_SHOW,
+ PROPERTY_HIDE,
+ LAST_SIGNAL,
+};
+
+
+/* BusPanelProxyPriv */
+struct _BusPanelProxyPrivate {
+ BusInputContext *focused_context;
+};
+typedef struct _BusPanelProxyPrivate BusPanelProxyPrivate;
+
+static guint panel_signals[LAST_SIGNAL] = { 0 };
+// static guint engine_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void bus_panel_proxy_class_init (BusPanelProxyClass *klass);
+static void bus_panel_proxy_init (BusPanelProxy *panel);
+static void bus_panel_proxy_real_destroy (BusPanelProxy *panel);
+
+static gboolean bus_panel_proxy_ibus_signal (IBusProxy *proxy,
+ IBusMessage *message);
+static void bus_panel_proxy_page_up (BusPanelProxy *panel);
+static void bus_panel_proxy_page_down (BusPanelProxy *panel);
+static void bus_panel_proxy_cursor_up (BusPanelProxy *panel);
+static void bus_panel_proxy_cursor_down (BusPanelProxy *panel);
+static void bus_panel_proxy_property_activate
+ (BusPanelProxy *panel,
+ const gchar *prop_name,
+ gint prop_state);
+
+static IBusProxyClass *parent_class = NULL;
+
+struct _SignalCallbackTable {
+ gchar *name;
+ GCallback callback;
+} ;
+
+static const struct _SignalCallbackTable __signals[];
+
+GType
+bus_panel_proxy_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusPanelProxyClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_panel_proxy_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusPanelProxy),
+ 0,
+ (GInstanceInitFunc) bus_panel_proxy_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_PROXY,
+ "BusPanelProxy",
+ &type_info,
+ (GTypeFlags)0);
+ }
+ return type;
+}
+
+BusPanelProxy *
+bus_panel_proxy_new (BusConnection *connection)
+{
+ g_assert (BUS_IS_CONNECTION (connection));
+
+ GObject *obj;
+ obj = g_object_new (BUS_TYPE_PANEL_PROXY,
+ "name", NULL,
+ "path", IBUS_PATH_PANEL,
+ "connection", connection,
+ NULL);
+
+ return BUS_PANEL_PROXY (obj);
+}
+
+static void
+bus_panel_proxy_class_init (BusPanelProxyClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+ IBusProxyClass *proxy_class = IBUS_PROXY_CLASS (klass);
+
+
+ parent_class = (IBusProxyClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (BusPanelProxyPrivate));
+
+ klass->page_up = bus_panel_proxy_page_up;
+ klass->page_down = bus_panel_proxy_page_down;
+ klass->cursor_up = bus_panel_proxy_cursor_up;
+ klass->cursor_down = bus_panel_proxy_cursor_down;
+
+ klass->property_activate = bus_panel_proxy_property_activate;
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_panel_proxy_real_destroy;
+
+ proxy_class->ibus_signal = bus_panel_proxy_ibus_signal;
+
+ /* install signals */
+ panel_signals[PAGE_UP] =
+ g_signal_new (I_("page-up"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(BusPanelProxyClass, page_up),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ panel_signals[PAGE_DOWN] =
+ g_signal_new (I_("page-down"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(BusPanelProxyClass, page_down),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ panel_signals[CURSOR_UP] =
+ g_signal_new (I_("cursor-up"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(BusPanelProxyClass, cursor_up),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ panel_signals[CURSOR_DOWN] =
+ g_signal_new (I_("cursor-down"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(BusPanelProxyClass, cursor_down),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ panel_signals[PROPERTY_ACTIVATE] =
+ g_signal_new (I_("property-activate"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(BusPanelProxyClass, property_activate),
+ NULL, NULL,
+ ibus_marshal_VOID__STRING_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_INT);
+
+ panel_signals[PROPERTY_SHOW] =
+ g_signal_new (I_("property-show"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ panel_signals[PROPERTY_HIDE] =
+ g_signal_new (I_("property-hide"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+}
+
+static void
+bus_panel_proxy_init (BusPanelProxy *panel)
+{
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ priv->focused_context = NULL;
+}
+
+static void
+bus_panel_proxy_real_destroy (BusPanelProxy *panel)
+{
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ if (ibus_proxy_get_connection ((IBusProxy *)panel) != NULL) {
+ ibus_proxy_call ((IBusProxy *) panel,
+ "Destroy",
+ DBUS_TYPE_INVALID);
+ }
+
+ if (priv->focused_context) {
+ bus_panel_proxy_focus_out (panel, priv->focused_context);
+ priv->focused_context = NULL;
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (panel));
+}
+
+static gboolean
+bus_panel_proxy_ibus_signal (IBusProxy *proxy,
+ IBusMessage *message)
+{
+ g_assert (BUS_IS_PANEL_PROXY (proxy));
+ g_assert (message != NULL);
+
+ BusPanelProxy *panel;
+ IBusError *error;
+ gint i;
+
+ static const struct {
+ const gchar *member;
+ const guint signal_id;
+ } signals [] = {
+ { "PageUp", PAGE_UP },
+ { "PageDown", PAGE_DOWN },
+ { "CursorUp", CURSOR_UP },
+ { "CursorDown", CURSOR_DOWN },
+ { NULL, 0},
+ };
+
+ panel = BUS_PANEL_PROXY (proxy);
+
+ for (i = 0; ; i++) {
+ if (signals[i].member == NULL)
+ break;
+ if (ibus_message_is_signal (message, IBUS_INTERFACE_PANEL, signals[i].member)) {
+ g_signal_emit (panel, panel_signals[signals[i].signal_id], 0);
+ goto handled;
+ }
+ }
+
+ if (ibus_message_is_signal (message, IBUS_INTERFACE_PANEL, "PropertyActivate")) {
+ gchar *prop_name;
+ gint prop_state;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_INT, &prop_state,
+ G_TYPE_INVALID);
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (panel, panel_signals[PROPERTY_ACTIVATE], 0, prop_name, prop_state);
+ }
+ else if (ibus_message_is_signal (message, IBUS_INTERFACE_PANEL, "PropertyShow")) {
+ gchar *prop_name;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_INVALID);
+ if (!retval)
+ goto failed;
+ g_signal_emit (panel, panel_signals[PROPERTY_SHOW], 0, prop_name);
+ }
+ else if (ibus_message_is_signal (message, IBUS_INTERFACE_PANEL, "PropertyHide")) {
+ gchar *prop_name;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_INVALID);
+ if (!retval)
+ goto failed;
+ g_signal_emit (panel, panel_signals[PROPERTY_HIDE], 0, prop_name);
+ }
+
+handled:
+ g_signal_stop_emission_by_name (panel, "ibus-signal");
+ return TRUE;
+
+failed:
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ return FALSE;
+}
+
+
+void
+bus_panel_proxy_focus_in (BusPanelProxy *panel,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ if (priv->focused_context == context)
+ return;
+
+ if (priv->focused_context != NULL)
+ bus_panel_proxy_focus_out (panel, priv->focused_context);
+
+ g_object_ref (context);
+ priv->focused_context = context;
+
+ const gchar *path = ibus_service_get_path ((IBusService *)context);
+
+ ibus_proxy_call ((IBusProxy *) panel,
+ "FocusIn",
+ IBUS_TYPE_OBJECT_PATH, &path,
+ G_TYPE_INVALID);
+
+ /* install signal handlers */
+ gint i;
+ for (i = 0; __signals[i].name != NULL; i++) {
+ g_signal_connect (context,
+ __signals[i].name,
+ __signals[i].callback,
+ panel);
+ }
+}
+
+void
+bus_panel_proxy_focus_out (BusPanelProxy *panel,
+ BusInputContext *context)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ g_assert (priv->focused_context == context);
+
+ /* uninstall signal handlers */
+ gint i;
+ for (i = 0; __signals[i].name != NULL; i++) {
+ g_signal_handlers_disconnect_by_func (context,
+ __signals[i].callback,
+ panel);
+ }
+
+ const gchar *path = ibus_service_get_path ((IBusService *)context);
+
+ ibus_proxy_call ((IBusProxy *) panel,
+ "FocusOut",
+ IBUS_TYPE_OBJECT_PATH, &path,
+ G_TYPE_INVALID);
+
+ g_object_unref (priv->focused_context);
+ priv->focused_context = NULL;
+}
+
+void
+bus_panel_proxy_set_cursor_location (BusPanelProxy *panel,
+ gint x,
+ gint y,
+ gint w,
+ gint h)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ ibus_proxy_call ((IBusProxy *) panel,
+ "SetCursorLocation",
+ G_TYPE_INT, &x,
+ G_TYPE_INT, &y,
+ G_TYPE_INT, &w,
+ G_TYPE_INT, &h,
+ G_TYPE_INVALID);
+}
+
+void
+bus_panel_proxy_update_preedit_text (BusPanelProxy *panel,
+ IBusText *text,
+ guint cursor_pos,
+ gboolean visible)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+ g_assert (text != NULL);
+
+ ibus_proxy_call ((IBusProxy *) panel,
+ "UpdatePreeditText",
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_UINT, &cursor_pos,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+}
+
+void
+bus_panel_proxy_update_auxiliary_text (BusPanelProxy *panel,
+ IBusText *text,
+ gboolean visible)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+ g_assert (text != NULL);
+
+ ibus_proxy_call ((IBusProxy *) panel,
+ "UpdateAuxiliaryText",
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+}
+
+void
+bus_panel_proxy_update_lookup_table (BusPanelProxy *panel,
+ IBusLookupTable *table,
+ gboolean visible)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+ g_assert (table != NULL);
+
+ ibus_proxy_call ((IBusProxy *) panel,
+ "UpdateLookupTable",
+ IBUS_TYPE_LOOKUP_TABLE, &table,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+}
+
+void
+bus_panel_proxy_register_properties (BusPanelProxy *panel,
+ IBusPropList *prop_list)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+ g_assert (prop_list != NULL);
+
+ ibus_proxy_call ((IBusProxy *) panel,
+ "RegisterProperties",
+ IBUS_TYPE_PROP_LIST, &prop_list,
+ G_TYPE_INVALID);
+ ibus_connection_flush (ibus_proxy_get_connection((IBusProxy *)panel));
+}
+
+void
+bus_panel_proxy_update_property (BusPanelProxy *panel,
+ IBusProperty *prop)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+ g_assert (prop != NULL);
+
+ ibus_proxy_call ((IBusProxy *) panel,
+ "UpdateProperty",
+ IBUS_TYPE_PROPERTY, &prop,
+ G_TYPE_INVALID);
+}
+
+static void
+bus_panel_proxy_page_up (BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ if (priv->focused_context) {
+ bus_input_context_page_up (priv->focused_context);
+ }
+}
+
+static void
+bus_panel_proxy_page_down (BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ if (priv->focused_context) {
+ bus_input_context_page_down (priv->focused_context);
+ }
+}
+static void
+bus_panel_proxy_cursor_up (BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ if (priv->focused_context) {
+ bus_input_context_cursor_up (priv->focused_context);
+ }
+}
+
+static void
+bus_panel_proxy_cursor_down (BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ if (priv->focused_context) {
+ bus_input_context_cursor_down (priv->focused_context);
+ }
+}
+
+static void
+bus_panel_proxy_property_activate (BusPanelProxy *panel,
+ const gchar *prop_name,
+ gint prop_state)
+{
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ if (priv->focused_context) {
+ bus_input_context_property_activate (priv->focused_context, prop_name, prop_state);
+ }
+}
+
+#define DEFINE_FUNCTION(Name, name) \
+ void bus_panel_proxy_##name (BusPanelProxy *panel) \
+ { \
+ g_assert (BUS_IS_PANEL_PROXY (panel)); \
+ ibus_proxy_call ((IBusProxy *) panel, \
+ #Name, \
+ G_TYPE_INVALID); \
+ }
+
+DEFINE_FUNCTION (ShowPreeditText, show_preedit_text)
+DEFINE_FUNCTION (HidePreeditText, hide_preedit_text)
+DEFINE_FUNCTION (ShowAuxiliaryText, show_auxiliary_text)
+DEFINE_FUNCTION (HideAuxiliaryText, hide_auxiliary_text)
+DEFINE_FUNCTION (ShowLookupTable, show_lookup_table)
+DEFINE_FUNCTION (HideLookupTable, hide_lookup_table)
+DEFINE_FUNCTION (PageUpLookupTable, page_up_lookup_table)
+DEFINE_FUNCTION (PageDownLookupTable, page_down_lookup_table)
+DEFINE_FUNCTION (CursorUpLookupTable, cursor_up_lookup_table)
+DEFINE_FUNCTION (CursorDownLookupTable, cursor_down_lookup_table)
+DEFINE_FUNCTION (StateChanged, state_changed)
+
+#undef DEFINE_FUNCTION
+
+static void
+_context_set_cursor_location_cb (BusInputContext *context,
+ gint x,
+ gint y,
+ gint w,
+ gint h,
+ BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ g_return_if_fail (priv->focused_context == context);
+
+ bus_panel_proxy_set_cursor_location (panel, x, y, w, h);
+}
+
+static void
+_context_update_preedit_text_cb (BusInputContext *context,
+ IBusText *text,
+ guint cursor_pos,
+ gboolean visible,
+ BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (text != NULL);
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ g_return_if_fail (priv->focused_context == context);
+
+ bus_panel_proxy_update_preedit_text (panel,
+ text,
+ cursor_pos,
+ visible);
+}
+
+static void
+_context_update_auxiliary_text_cb (BusInputContext *context,
+ IBusText *text,
+ gboolean visible,
+ BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ g_return_if_fail (priv->focused_context == context);
+
+ bus_panel_proxy_update_auxiliary_text (panel,
+ text,
+ visible);
+}
+
+static void
+_context_update_lookup_table_cb (BusInputContext *context,
+ IBusLookupTable *table,
+ gboolean visible,
+ BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ g_return_if_fail (priv->focused_context == context);
+
+ bus_panel_proxy_update_lookup_table (panel,
+ table,
+ visible);
+}
+
+static void
+_context_register_properties_cb (BusInputContext *context,
+ IBusPropList *prop_list,
+ BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ g_return_if_fail (priv->focused_context == context);
+
+ bus_panel_proxy_register_properties (panel,
+ prop_list);
+}
+
+static void
+_context_update_property_cb (BusInputContext *context,
+ IBusProperty *prop,
+ BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ g_return_if_fail (priv->focused_context == context);
+
+ bus_panel_proxy_update_property (panel,
+ prop);
+}
+
+#if 0
+static void
+_context_destroy_cb (BusInputContext *context,
+ BusPanelProxy *panel)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+ g_assert (BUS_IS_PANEL_PROXY (panel));
+
+ BusPanelProxyPrivate *priv;
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel);
+
+ g_assert (context == priv->focused_context);
+
+ bus_panel_proxy_focus_out (panel, context);
+}
+#endif
+
+#define DEFINE_FUNCTION(name) \
+ static void _context_##name##_cb (BusInputContext *context, \
+ BusPanelProxy *panel) \
+ { \
+ g_assert (BUS_IS_INPUT_CONTEXT (context)); \
+ g_assert (BUS_IS_PANEL_PROXY (panel)); \
+ \
+ BusPanelProxyPrivate *priv; \
+ priv = BUS_PANEL_PROXY_GET_PRIVATE (panel); \
+ \
+ g_return_if_fail (priv->focused_context == context); \
+ \
+ bus_panel_proxy_##name (panel); \
+ }
+
+DEFINE_FUNCTION (show_preedit_text)
+DEFINE_FUNCTION (hide_preedit_text)
+DEFINE_FUNCTION (show_auxiliary_text)
+DEFINE_FUNCTION (hide_auxiliary_text)
+DEFINE_FUNCTION (show_lookup_table)
+DEFINE_FUNCTION (hide_lookup_table)
+DEFINE_FUNCTION (page_up_lookup_table)
+DEFINE_FUNCTION (page_down_lookup_table)
+DEFINE_FUNCTION (cursor_up_lookup_table)
+DEFINE_FUNCTION (cursor_down_lookup_table)
+DEFINE_FUNCTION (state_changed)
+
+#undef DEFINE_FUNCTION
+
+static const struct _SignalCallbackTable
+__signals[] = {
+ { "set-cursor-location", G_CALLBACK (_context_set_cursor_location_cb) },
+
+ { "update-preedit-text", G_CALLBACK (_context_update_preedit_text_cb) },
+ { "show-preedit-text", G_CALLBACK (_context_show_preedit_text_cb) },
+ { "hide-preedit-text", G_CALLBACK (_context_hide_preedit_text_cb) },
+
+ { "update-auxiliary-text", G_CALLBACK (_context_update_auxiliary_text_cb) },
+ { "show-auxiliary-text", G_CALLBACK (_context_show_auxiliary_text_cb) },
+ { "hide-auxiliary-text", G_CALLBACK (_context_hide_auxiliary_text_cb) },
+
+ { "update-lookup-table", G_CALLBACK (_context_update_lookup_table_cb) },
+ { "show-lookup-table", G_CALLBACK (_context_show_lookup_table_cb) },
+ { "hide-lookup-table", G_CALLBACK (_context_hide_lookup_table_cb) },
+ { "page-up-lookup-table", G_CALLBACK (_context_page_up_lookup_table_cb) },
+ { "page-down-lookup-table", G_CALLBACK (_context_page_down_lookup_table_cb) },
+ { "cursor-up-lookup-table", G_CALLBACK (_context_cursor_up_lookup_table_cb) },
+ { "cursor-down-lookup-table", G_CALLBACK (_context_cursor_down_lookup_table_cb) },
+
+ { "register-properties", G_CALLBACK (_context_register_properties_cb) },
+ { "update-property", G_CALLBACK (_context_update_property_cb) },
+
+ { "enabled", G_CALLBACK (_context_state_changed_cb) },
+ { "disabled", G_CALLBACK (_context_state_changed_cb) },
+ { "factory-changed", G_CALLBACK (_context_state_changed_cb) },
+
+ // { "destroy", G_CALLBACK (_context_destroy_cb) },
+ { NULL, NULL}
+};
+
diff --git a/bus/panelproxy.h b/bus/panelproxy.h
new file mode 100644
index 0000000..0ecc4a7
--- /dev/null
+++ b/bus/panelproxy.h
@@ -0,0 +1,112 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __PANEL_PROXY_H_
+#define __PANEL_PROXY_H_
+
+#include <ibus.h>
+#include "connection.h"
+#include "inputcontext.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_PANEL_PROXY \
+ (bus_panel_proxy_get_type ())
+#define BUS_PANEL_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_PANEL_PROXY, BusPanelProxy))
+#define BUS_PANEL_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_PANEL_PROXY, BusPanelProxyClass))
+#define BUS_IS_PANEL_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_PANEL_PROXY))
+#define BUS_IS_PANEL_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_PANEL_PROXY))
+#define BUS_PANEL_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_PANEL_PROXY, BusPanelProxyClass))
+
+G_BEGIN_DECLS
+
+typedef struct _BusPanelProxy BusPanelProxy;
+typedef struct _BusPanelProxyClass BusPanelProxyClass;
+
+struct _BusPanelProxy {
+ IBusProxy parent;
+ /* instance members */
+};
+
+struct _BusPanelProxyClass {
+ IBusProxyClass parent;
+ /* class members */
+
+ void (* page_up) (BusPanelProxy *panel);
+ void (* page_down) (BusPanelProxy *panel);
+ void (* cursor_up) (BusPanelProxy *panel);
+ void (* cursor_down) (BusPanelProxy *panel);
+
+ void (* property_activate) (BusPanelProxy *panel,
+ const gchar *prop_name,
+ gint prop_state);
+};
+
+GType bus_panel_proxy_get_type (void);
+BusPanelProxy *bus_panel_proxy_new (BusConnection *connection);
+void bus_panel_proxy_focus_in (BusPanelProxy *panel,
+ BusInputContext *context);
+void bus_panel_proxy_focus_out (BusPanelProxy *panel,
+ BusInputContext *context);
+void bus_panel_proxy_set_cursor_location
+ (BusPanelProxy *panel,
+ gint32 x,
+ gint32 y,
+ gint32 w,
+ gint32 h);
+void bus_panel_proxy_update_preedit_text(BusPanelProxy *panel,
+ IBusText *text,
+ guint cursor_pos,
+ gboolean visible);
+void bus_panel_proxy_show_preedit_text (BusPanelProxy *panel);
+void bus_panel_proxy_hide_preedit_text (BusPanelProxy *panel);
+void bus_panel_proxy_update_auxiliary_text
+ (BusPanelProxy *panel,
+ IBusText *text,
+ gboolean visible);
+void bus_panel_proxy_show_auxiliary_text(BusPanelProxy *panel);
+void bus_panel_proxy_hide_auxiliary_text(BusPanelProxy *panel);
+void bus_panel_proxy_update_lookup_table(BusPanelProxy *panel,
+ IBusLookupTable *table,
+ gboolean visible);
+void bus_panel_proxy_show_lookup_table (BusPanelProxy *panel);
+void bus_panel_proxy_hide_lookup_table (BusPanelProxy *panel);
+void bus_panel_proxy_page_up_lookup_table
+ (BusPanelProxy *panel);
+void bus_panel_proxy_page_down_lookup_table
+ (BusPanelProxy *panel);
+void bus_panel_proxy_cursor_up_lookup_table
+ (BusPanelProxy *panel);
+void bus_panel_proxy_cursor_down_lookup_table
+ (BusPanelProxy *panel);
+void bus_panel_proxy_register_properties(BusPanelProxy *panel,
+ IBusPropList *prop_list);
+void bus_panel_proxy_update_property (BusPanelProxy *panel,
+ IBusProperty *prop);
+G_END_DECLS
+#endif
+
diff --git a/bus/registry.c b/bus/registry.c
new file mode 100644
index 0000000..cdc1aa7
--- /dev/null
+++ b/bus/registry.c
@@ -0,0 +1,447 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+#include <stdlib.h>
+#include "registry.h"
+
+enum {
+ LAST_SIGNAL,
+};
+
+// static guint _signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void bus_registry_class_init (BusRegistryClass *klass);
+static void bus_registry_init (BusRegistry *registry);
+static void bus_registry_destroy (BusRegistry *registry);
+static void bus_registry_load (BusRegistry *registry);
+static void bus_registry_load_in_dir (BusRegistry *registry,
+ const gchar *dirname);
+static gboolean bus_registry_save_cache (BusRegistry *registry);
+static gboolean bus_registry_load_cache (BusRegistry *registry);
+static gboolean bus_registry_check_modification(BusRegistry *registry);
+static void bus_registry_remove_all (BusRegistry *registry);
+
+static IBusObjectClass *parent_class = NULL;
+
+GType
+bus_registry_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusRegistryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_registry_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusRegistry),
+ 0,
+ (GInstanceInitFunc) bus_registry_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_OBJECT,
+ "BusRegistry",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+
+static void
+bus_registry_class_init (BusRegistryClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_registry_destroy;
+}
+
+static void
+bus_registry_init (BusRegistry *registry)
+{
+ GList *p;
+ registry->observed_paths = NULL;
+ registry->components = NULL;
+ registry->engine_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if (bus_registry_load_cache (registry) == FALSE || bus_registry_check_modification (registry)) {
+ bus_registry_remove_all (registry);
+ bus_registry_load (registry);
+ bus_registry_save_cache (registry);
+ }
+
+ for (p = registry->components; p != NULL; p = p->next) {
+ IBusComponent *comp = (IBusComponent *)p->data;
+ GList *p1;
+
+ for (p1 = comp->engines; p1 != NULL; p1 = p1->next) {
+ IBusEngineDesc *desc = (IBusEngineDesc *)p1->data;
+ g_hash_table_insert (registry->engine_table, desc->name, desc);
+ g_object_set_data ((GObject *)desc, "component", comp);
+ }
+ }
+}
+
+static void
+bus_registry_remove_all (BusRegistry *registry)
+{
+ g_list_foreach (registry->observed_paths, (GFunc) g_object_unref, NULL);
+ g_list_free (registry->observed_paths);
+ registry->observed_paths = NULL;
+
+ g_list_foreach (registry->components, (GFunc) g_object_unref, NULL);
+ g_list_free (registry->components);
+ registry->components = NULL;
+
+ g_hash_table_remove_all (registry->engine_table);
+}
+
+static void
+bus_registry_destroy (BusRegistry *registry)
+{
+ bus_registry_remove_all (registry);
+
+ g_hash_table_destroy (registry->engine_table);
+ registry->engine_table = NULL;
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy (IBUS_OBJECT (registry));
+}
+
+
+static void
+bus_registry_load (BusRegistry *registry)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+
+ gchar *dirname;
+ gchar *homedir;
+ IBusObservedPath *path;
+
+ dirname = g_build_filename (PKGDATADIR, "component", NULL);
+
+ path = ibus_observed_path_new (dirname, TRUE);
+ registry->observed_paths = g_list_append (registry->observed_paths, path);
+
+ bus_registry_load_in_dir (registry, dirname);
+
+ g_free (dirname);
+
+ homedir = (gchar *) g_getenv ("HOME");
+ if (!homedir)
+ homedir = (gchar *) g_get_home_dir ();
+ dirname = g_build_filename (homedir, ".ibus", "component", NULL);
+
+ path = ibus_observed_path_new (dirname, TRUE);
+ registry->observed_paths = g_list_append (registry->observed_paths, path);
+
+ if (g_file_test(dirname, G_FILE_TEST_EXISTS)) {
+ bus_registry_load_in_dir (registry, dirname);
+ }
+
+ g_free (dirname);
+}
+
+
+#define g_string_append_indent(string, indent) \
+ { \
+ gint i; \
+ for (i = 0; i < (indent); i++) { \
+ g_string_append (string, " "); \
+ } \
+ }
+
+static gboolean
+bus_registry_load_cache (BusRegistry *registry)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+
+ gchar *filename;
+ XMLNode *node;
+ GList *p;
+
+ filename = g_build_filename (g_get_user_cache_dir (), "ibus", "registry.xml", NULL);
+ node = ibus_xml_parse_file (filename);
+ g_free (filename);
+
+ if (node == NULL) {
+ return FALSE;
+ }
+
+ if (g_strcmp0 (node->name, "ibus-registry") != 0) {
+ ibus_xml_free (node);
+ return FALSE;
+ }
+
+ for (p = node->sub_nodes; p != NULL; p = p->next) {
+ XMLNode *sub_node = (XMLNode *) p->data;
+
+ if (g_strcmp0 (sub_node->name, "observed-paths") == 0) {
+ GList *pp;
+ for (pp = sub_node->sub_nodes; pp != NULL; pp = pp->next) {
+ IBusObservedPath *path;
+ path = ibus_observed_path_new_from_xml_node (pp->data, FALSE);
+ if (path) {
+ registry->observed_paths = g_list_append (registry->observed_paths, path);
+ }
+ }
+ continue;
+ }
+ if (g_strcmp0 (sub_node->name, "components") == 0) {
+ GList *pp;
+ for (pp = sub_node->sub_nodes; pp != NULL; pp = pp->next) {
+ IBusComponent *component;
+ component = ibus_component_new_from_xml_node (pp->data);
+ if (component) {
+ registry->components = g_list_append (registry->components, component);
+ }
+ }
+
+ continue;
+ }
+ g_warning ("Unknown element <%s>", sub_node->name);
+ }
+
+ ibus_xml_free (node);
+ return TRUE;
+}
+
+static gboolean
+bus_registry_check_modification (BusRegistry *registry)
+{
+ GList *p;
+
+ for (p = registry->observed_paths; p != NULL; p = p->next) {
+ if (ibus_observed_path_check_modification ((IBusObservedPath *)p->data))
+ return TRUE;
+ }
+
+ for (p = registry->components; p != NULL; p = p->next) {
+ if (ibus_component_check_modification ((IBusComponent *)p->data))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+bus_registry_save_cache (BusRegistry *registry)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+
+ gchar *cachedir;
+ gchar *filename;
+ GString *output;
+ GList *p;
+ FILE *pf;
+
+ cachedir = g_build_filename (g_get_user_cache_dir (), "ibus", NULL);
+ filename = g_build_filename (cachedir, "registry.xml", NULL);
+ g_mkdir_with_parents (cachedir, 0775);
+ pf = g_fopen (filename, "w");
+ g_free (filename);
+ g_free (cachedir);
+
+ if (pf == NULL) {
+ g_warning ("create registry.xml failed");
+ return FALSE;
+ }
+
+ output = g_string_new ("");
+ g_string_append (output, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+ g_string_append (output, "<!-- \n"
+ " This file was generated by ibus-daemon. Please don't modify it.\n"
+ " -->\n");
+ g_string_append (output, "<ibus-registry>\n");
+
+ if (registry->observed_paths) {
+ g_string_append_indent (output, 1);
+ g_string_append (output, "<observed-paths>\n");
+ for (p = registry->observed_paths; p != NULL; p = p->next) {
+ ibus_observed_path_output ((IBusObservedPath *)p->data,
+ output, 2);
+ }
+ g_string_append_indent (output, 1);
+ g_string_append (output, "</observed-paths>\n");
+ }
+
+ if (registry->components) {
+ g_string_append_indent (output, 1);
+ g_string_append (output, "<components>\n");
+ for (p = registry->components; p != NULL; p = p->next) {
+ ibus_component_output ((IBusComponent *)p->data,
+ output, 2);
+ }
+ g_string_append_indent (output, 1);
+ g_string_append (output, "</components>\n");
+ }
+
+ g_string_append (output, "</ibus-registry>\n");
+ fwrite (output->str, output->len, 1, pf);
+ g_string_free (output, TRUE);
+ fclose (pf);
+ return TRUE;
+}
+
+static void
+bus_registry_load_in_dir (BusRegistry *registry,
+ const gchar *dirname)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+ g_assert (dirname);
+
+ GError *error = NULL;
+ GDir *dir;
+ const gchar *filename;
+
+ dir = g_dir_open (dirname, 0, &error);
+
+ if (dir == NULL) {
+ g_warning ("Unable open directory %s : %s", dirname, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ while ((filename = g_dir_read_name (dir)) != NULL) {
+ glong size;
+ gchar *path;
+ IBusComponent *component;
+
+ size = g_utf8_strlen (filename, -1);
+ if (g_strcmp0 (MAX (filename, filename + size -4), ".xml" ) != 0)
+ continue;
+
+ path = g_build_filename (dirname, filename, NULL);
+ component = ibus_component_new_from_file (path);
+ registry->components = g_list_append (registry->components, component);
+
+ g_free (path);
+ }
+
+ g_dir_close (dir);
+}
+
+
+BusRegistry *
+bus_registry_new (void)
+{
+ BusRegistry *registry;
+ registry = (BusRegistry *)g_object_new (BUS_TYPE_REGISTRY, NULL);
+ return registry;
+}
+
+static gint
+_component_is_name (IBusComponent *component,
+ const gchar *name)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+ g_assert (name);
+
+ return g_strcmp0 (component->name, name);
+}
+
+IBusComponent *
+bus_registry_lookup_component_by_name (BusRegistry *registry,
+ const gchar *name)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+ g_assert (name);
+
+ GList *p;
+ p = g_list_find_custom (registry->components,
+ name,
+ (GCompareFunc)_component_is_name);
+ if (p) {
+ return (IBusComponent *)p->data;
+ }
+ else {
+ return NULL;
+ }
+}
+
+GList *
+bus_registry_get_components (BusRegistry *registry)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+
+ return g_list_copy (registry->components);
+}
+
+GList *
+bus_registry_get_engines (BusRegistry *registry)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+
+ return g_hash_table_get_values (registry->engine_table);
+}
+
+
+IBusEngineDesc *
+bus_registry_find_engine_by_name (BusRegistry *registry,
+ const gchar *name)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+ g_assert (name);
+
+ return (IBusEngineDesc *) g_hash_table_lookup (registry->engine_table, name);
+}
+
+
+BusFactoryProxy *
+bus_registry_name_owner_changed (BusRegistry *registry,
+ const gchar *name,
+ const gchar *old_name,
+ const gchar *new_name)
+{
+ g_assert (BUS_IS_REGISTRY (registry));
+ g_assert (name);
+ g_assert (old_name);
+ g_assert (new_name);
+
+ IBusComponent *component;
+ BusFactoryProxy *factory;
+
+ component = bus_registry_lookup_component_by_name (registry, name);
+
+ if (component == NULL) {
+ return NULL;
+ }
+
+ if (g_strcmp0 (old_name, "") != 0) {
+ factory = bus_factory_proxy_get_from_component (component);
+
+ if (factory != NULL) {
+ ibus_object_destroy ((IBusObject *)factory);
+ }
+ }
+
+ if (g_strcmp0 (new_name, "") != 0) {
+ factory = bus_factory_proxy_new (component, NULL);
+ return factory;
+ }
+
+ return NULL;
+}
diff --git a/bus/registry.h b/bus/registry.h
new file mode 100644
index 0000000..9dadda6
--- /dev/null
+++ b/bus/registry.h
@@ -0,0 +1,88 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __REGISTRY_H_
+#define __REGISTRY_H_
+
+#include <ibus.h>
+#include "factoryproxy.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_REGISTRY \
+ (bus_registry_get_type ())
+#define BUS_REGISTRY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_REGISTRY, BusRegistry))
+#define BUS_REGISTRY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_REGISTRY, BusRegistryClass))
+#define BUS_IS_REGISTRY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_REGISTRY))
+#define BUS_IS_REGISTRY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_REGISTRY))
+#define BUS_REGISTRY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_REGISTRY, BusRegistryClass))
+
+G_BEGIN_DECLS
+
+typedef struct _BusRegistry BusRegistry;
+typedef struct _BusRegistryClass BusRegistryClass;
+
+struct _BusRegistry {
+ IBusObject parent;
+
+ /* instance members */
+ GList *observed_paths;
+ GList *components;
+
+ GHashTable *engine_table;
+ GList *active_engines;
+};
+
+struct _BusRegistryClass {
+ IBusObjectClass parent;
+
+ /* class members */
+};
+
+GType bus_registry_get_type (void);
+BusRegistry *bus_registry_new (void);
+GList *bus_registry_get_components (BusRegistry *registry);
+GList *bus_registry_get_engines (BusRegistry *registry);
+gboolean bus_registry_exec_component (BusRegistry *registry,
+ const gchar *name);
+gboolean bus_registry_kill_component (BusRegistry *registry,
+ const gchar *name);
+
+IBusComponent *bus_registry_lookup_component_by_name
+ (BusRegistry *registry,
+ const gchar *name);
+IBusEngineDesc *bus_registry_find_engine_by_name
+ (BusRegistry *registry,
+ const gchar *name);
+BusFactoryProxy *bus_registry_name_owner_changed(BusRegistry *registry,
+ const gchar *name,
+ const gchar *old_name,
+ const gchar *new_name);
+
+G_END_DECLS
+#endif
+
diff --git a/bus/server.c b/bus/server.c
new file mode 100644
index 0000000..2ae36bf
--- /dev/null
+++ b/bus/server.c
@@ -0,0 +1,152 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <libgen.h>
+
+#include "server.h"
+#include "connection.h"
+#include "dbusimpl.h"
+#include "ibusimpl.h"
+
+/* functions prototype */
+static void bus_server_class_init (BusServerClass *klass);
+static void bus_server_init (BusServer *server);
+static void bus_server_destroy (BusServer *server);
+static void bus_server_new_connection
+ (BusServer *server,
+ BusConnection *connection);
+
+static IBusObjectClass *parent_class = NULL;
+
+GType
+bus_server_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (BusServerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) bus_server_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (BusServer),
+ 0,
+ (GInstanceInitFunc) bus_server_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERVER,
+ "BusServer",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+BusServer *
+bus_server_get_default (void)
+{
+ static BusServer *server = NULL;
+
+ if (server == NULL) {
+ server = (BusServer *) g_object_new (BUS_TYPE_SERVER,
+ "connection-type", BUS_TYPE_CONNECTION,
+ NULL);
+ bus_dbus_impl_get_default ();
+ bus_ibus_impl_get_default ();
+ }
+ return server;
+}
+
+gboolean
+bus_server_listen (BusServer *server)
+{
+ g_assert (BUS_IS_SERVER (server));
+
+ // const gchar *address = "unix:abstract=/tmp/ibus-c"
+ const gchar *address;
+ gchar *path;
+
+ path = g_strdup_printf("/tmp/ibus-%s", ibus_get_user_name ());
+ mkdir (path, 0775);
+ g_free(path);
+ address = ibus_get_address ();
+
+ return ibus_server_listen (IBUS_SERVER (server), address);
+}
+
+void
+bus_server_run (BusServer *server)
+{
+ g_assert (BUS_IS_SERVER (server));
+
+ g_main_loop_run (server->loop);
+}
+
+void
+bus_server_quit (BusServer *server)
+{
+ g_assert (BUS_IS_SERVER (server));
+
+ g_main_loop_quit (server->loop);
+}
+
+static void
+bus_server_class_init (BusServerClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_server_destroy;
+
+ IBUS_SERVER_CLASS (klass)->new_connection = (IBusNewConnectionFunc) bus_server_new_connection;
+}
+
+static void
+bus_server_init (BusServer *server)
+{
+ server->loop = g_main_loop_new (NULL, FALSE);
+}
+
+static void
+bus_server_new_connection (BusServer *server,
+ BusConnection *connection)
+{
+ g_assert (BUS_IS_SERVER (server));
+ bus_dbus_impl_new_connection (BUS_DEFAULT_DBUS, connection);
+}
+
+static void
+bus_server_destroy (BusServer *server)
+{
+ g_assert (BUS_IS_SERVER (server));
+
+ while (g_main_loop_is_running (server->loop)) {
+ g_main_loop_quit (server->loop);
+ }
+ g_main_loop_unref (server->loop);
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy (IBUS_OBJECT (server));
+}
diff --git a/bus/server.h b/bus/server.h
new file mode 100644
index 0000000..9ea5794
--- /dev/null
+++ b/bus/server.h
@@ -0,0 +1,72 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __SERVER_H_
+#define __SERVER_H_
+
+#include <ibus.h>
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define BUS_TYPE_SERVER \
+ (bus_server_get_type ())
+#define BUS_SERVER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_SERVER, BusServer))
+#define BUS_SERVER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_SERVER, BusServerClass))
+#define BUS_IS_SERVER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_SERVER))
+#define BUS_IS_SERVER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_SERVER))
+#define BUS_SERVER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_SERVER, BusServerClass))
+#define BUS_DEFAULT_SERVER \
+ (bus_server_get_default ())
+
+G_BEGIN_DECLS
+
+typedef struct _BusServer BusServer;
+typedef struct _BusServerClass BusServerClass;
+
+struct _BusServer {
+ IBusServer parent;
+
+ /* instance members */
+ GMainLoop *loop;
+
+};
+
+struct _BusServerClass {
+ IBusServerClass parent;
+
+ /* class members */
+};
+
+GType bus_server_get_type (void);
+BusServer *bus_server_get_default (void);
+gboolean bus_server_listen (BusServer *server);
+void bus_server_run (BusServer *server);
+void bus_server_quit (BusServer *server);
+
+G_END_DECLS
+#endif
+
diff --git a/bus/test-matchrule.c b/bus/test-matchrule.c
new file mode 100644
index 0000000..63110fd
--- /dev/null
+++ b/bus/test-matchrule.c
@@ -0,0 +1,40 @@
+#include "matchrule.h"
+
+int
+main(gint argc, gchar **argv)
+{
+ BusMatchRule *rule, *rule1;
+ g_type_init ();
+
+ rule = bus_match_rule_new (" type='signal' , interface = 'org.freedesktop.IBus' ");
+ g_assert (rule->message_type == DBUS_MESSAGE_TYPE_SIGNAL);
+ g_assert (g_strcmp0 (rule->interface, "org.freedesktop.IBus") == 0 );
+ g_object_unref (rule);
+
+ rule = bus_match_rule_new ("type='method_call', interface='org.freedesktop.IBus' ");
+ g_assert (rule->message_type == DBUS_MESSAGE_TYPE_METHOD_CALL);
+ g_assert (g_strcmp0 (rule->interface, "org.freedesktop.IBus") == 0 );
+ g_object_unref (rule);
+
+ rule = bus_match_rule_new ("type='signal',"
+ "interface='org.freedesktop.DBus',"
+ "member='NameOwnerChanged',"
+ "arg0='ibus.freedesktop.IBus.config',"
+ "arg0='ibus.freedesktop.IBus.config',"
+ "arg2='ibus.freedesktop.IBus.config'");
+ g_assert (rule->message_type == DBUS_MESSAGE_TYPE_SIGNAL);
+ g_assert (g_strcmp0 (rule->interface, "org.freedesktop.DBus") == 0 );
+ rule1 = bus_match_rule_new ("type='signal',"
+ "interface='org.freedesktop.DBus',"
+ "member='NameOwnerChanged',"
+ "arg0='ibus.freedesktop.IBus.config',"
+ "arg0='ibus.freedesktop.IBus.config',"
+ "arg2='ibus.freedesktop.IBus.config'");
+
+ g_assert (bus_match_rule_is_equal (rule, rule1));
+
+ g_object_unref (rule);
+ g_object_unref (rule1);
+
+ return 0;
+}
diff --git a/bus/test-registry.c b/bus/test-registry.c
new file mode 100644
index 0000000..fdcbba8
--- /dev/null
+++ b/bus/test-registry.c
@@ -0,0 +1,9 @@
+#include "registry.h"
+
+int main()
+{
+ g_type_init ();
+ BusRegistry *registry = bus_registry_new ();
+ g_object_unref (registry);
+ return 0;
+}
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);
diff --git a/configure.ac b/configure.ac
index d978fb2..a2087a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,9 +21,9 @@
# if not 1, append datestamp to the version number.
m4_define([ibus_released], [0])
-m4_define([ibus_major_version], [0])
+m4_define([ibus_major_version], [1])
m4_define([ibus_minor_version], [1])
-m4_define([ibus_micro_version], [1])
+m4_define([ibus_micro_version], [0])
m4_define(ibus_maybe_datestamp,
m4_esyscmd([if test x]ibus_released[ != x1; then date +.%Y%m%d | tr -d '\n\r'; fi]))
@@ -49,20 +49,34 @@ AC_ISC_POSIX
AC_HEADER_STDC
AM_PROG_LIBTOOL
+# If only source code changed, lt_revision + 1
+# If any interface added, lt_age + 1
+# If any interfaces changed or removed, lt_current + 1
+m4_define([lt_current], [0])
+m4_define([lt_revision], [0])
+m4_define([lt_age], [0])
+LT_VERSION_INFO="lt_current:lt_revision:lt_age"
+AC_SUBST(LT_VERSION_INFO)
+
# check inotify
AC_CHECK_HEADERS([sys/inotify.h])
# check glib2
AM_PATH_GLIB_2_0
PKG_CHECK_MODULES(GLIB2, [
- glib-2.0 >= 2.16
+ glib-2.0 >= 2.18
])
PKG_CHECK_MODULES(GOBJECT2, [
- gobject-2.0
+ gobject-2.0 >= 2.18
+])
+PKG_CHECK_MODULES(GIO2, [
+ gio-2.0 >= 2.18
+])
+PKG_CHECK_MODULES(PYGOBJECT2, [
+ pygobject-2.0 >= 2.15
])
-
-# check gtk, gdk & pygtk
+# check for gtk, gdk & pygtk
PKG_CHECK_MODULES(GTK2, [
gtk+-2.0
])
@@ -74,9 +88,11 @@ PKG_CHECK_MODULES(GDK2, [
gdk-2.0
])
-# check dbus-glib
+# check for gtk-doc
+GTK_DOC_CHECK(1.9)
+# check for dbus-glib
PKG_CHECK_MODULES(DBUS, [
- dbus-glib-1
+ dbus-1
])
# Check for Qt4
@@ -131,6 +147,9 @@ AC_SUBST(PYTHON_CFLAGS)
AC_SUBST(PYTHON_INCLUDES)
AC_SUBST(PYTHON_LIBS)
+#
+REBUILD = #
+AC_SUBST(REBUILD)
# define GETTEXT_* variables
GETTEXT_PACKAGE=ibus
@@ -158,32 +177,9 @@ AC_ARG_ENABLE(qt4-immodule,
if test x"$IBUS_HAS_QT4" != x"yes"; then
enable_qt4=no
fi
+enable_qt=no
AM_CONDITIONAL(IBUS_BUILD_QT4, [test x"$enable_qt4" = x"yes" ])
-# check pygtk gconf for pygconf
-AC_ARG_ENABLE(pygconf,
- AS_HELP_STRING([--enable-pygconf],
- [Build python gconf binding, with it ibus will not depend on gnome-python]),
- [enable_pygconf=$enableval],
- [enable_pygconf=no],
-)
-
-PKG_CHECK_MODULES(PYGTK,
- pygtk-2.0 >= 2.10.3,
- [IBUS_HAS_PYGTK=yes],
- [IBUS_HAS_PYGTK=no]
-)
-AC_SUBST(PYGTK_CFLAGS)
-AC_SUBST(PYGTK_LIBS)
-if test x"$IBUS_HAS_PYGTK" != x"yes" -a x"$enable_pygconf" = x"yes"; then
- AC_MSG_ERROR(can not build python gconf binding without pygtk-2.0)
-fi
-
-AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no)
-if test x"$PYGTK_CODEGEN" = x"no" -a x"$enable_pygconf" = x"yes"; then
- AC_MSG_ERROR(can not build python gconf binding without pygtk-codegen-2.0)
-fi
-
PKG_CHECK_MODULES(GCONF,
[gconf-2.0 >= 2.11.1],
[IBUS_HAS_GCONF=yes],
@@ -191,11 +187,6 @@ PKG_CHECK_MODULES(GCONF,
)
AC_SUBST(GCONF_CFLAGS)
AC_SUBST(GCONF_LIBS)
-if test x"$IBUS_HAS_GCONF" != x"yes" -a x"$enable_pygconf" = x"yes"; then
- AC_MSG_ERROR(can not build python gconf binding without gconf-2.0)
-fi
-
-AM_CONDITIONAL(IBUS_BUILD_PYGCONF, [test x"$enable_pygconf" = x"yes" ])
# check iso-codes
AC_ARG_ENABLE(iso-codes-check,
@@ -220,22 +211,17 @@ fi
# OUTPUT files
AC_CONFIG_FILES([ po/Makefile.in
Makefile
+ibus-1.0.pc
ibus.spec
ibus/_config.py
ibus/Makefile
ibus/interface/Makefile
-daemon/Makefile
-daemon/ibus-daemon
-launcher/ibus
-launcher/ibus.desktop
-launcher/Makefile
ui/Makefile
ui/gtk/Makefile
ui/gtk/ibus-ui-gtk
+ui/gtk/gtkpanel.xml
gconf/Makefile
-gconf/ibus-gconf
-lib/Makefile
-lib/gtk2/Makefile
+gconf/gconf.xml
client/Makefile
client/gtk2/Makefile
client/qt4/Makefile
@@ -243,10 +229,16 @@ client/x11/Makefile
setup/Makefile
setup/ibus-setup
setup/ibus-setup.desktop
+src/Makefile
+bus/Makefile
+bindings/Makefile
+bindings/python/Makefile
util/Makefile
util/IMdkit/Makefile
-util/gconf/Makefile
icons/Makefile
+docs/Makefile
+docs/reference/Makefile
+docs/reference/ibus/Makefile
m4/Makefile
])
@@ -259,6 +251,6 @@ Build options:
Build static libs $enable_static
Gtk immodule dir $GTK_IM_MODULEDIR
Enable Qt4 IM module $enable_qt4
- Build pygconf $enable_pygconf
+ Build document $enable_gtk_doc
])
diff --git a/daemon/.gitignore b/daemon/.gitignore
deleted file mode 100644
index 76a720d..0000000
--- a/daemon/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-ibus-daemon
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
deleted file mode 100644
index 0d32443..0000000
--- a/daemon/Makefile.am
+++ /dev/null
@@ -1,55 +0,0 @@
-# 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
-ibusdaemon_PYTHON = \
- bus.py \
- _dbus.py \
- config.py \
- connection.py \
- contextmanager.py \
- enginefactory.py \
- engine.py \
- factorymanager.py \
- ibusdaemon.py \
- inputcontext.py \
- lookuptable.py \
- panel.py \
- notifications.py \
- register.py \
- $(NULL)
-
-bin_SCRIPTS = ibus-daemon
-
-ibusdaemondir = $(pkgdatadir)/daemon
-
-CLEANFILES = \
- *.pyc \
- $(NULL)
-
-EXTRA_DIST = \
- ibus-daemon.in \
- $(NULL)
-
-test:
- $(ENV) \
- DBUS_DEBUG=true \
- PYTHONPATH=$${PYTHONPATH}:$(top_srcdir) \
- IBUS_DATAROOTDIR=${datarootdir} \
- $(PYTHON) $(srcdir)/ibusdaemon.py
diff --git a/daemon/_dbus.py b/daemon/_dbus.py
deleted file mode 100644
index 1b007a0..0000000
--- a/daemon/_dbus.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import gobject
-import dbus
-import dbus.service
-import ibus
-
-class MatchRule:
- def __init__(self, rule):
- m = self.__eval_rule(rule)
- self.__type = m.get('type', None)
- self.__sender = m.get('sender', None)
- self.__interface = m.get('interface', None)
- self.__member = m.get('member', None)
- self.__path = m.get('path', None)
- self.__destination = m.get('destination', None)
- self.__args = []
- for i in range(64):
- arg = m.get('arg%d'%i, None)
- if arg == None:
- continue
- self.__args.append((i, arg))
-
- def __eval_rule(self, rule):
- _fn = lambda **kargs: kargs
- try:
- return eval("_fn(%s)" % rule)
- except:
- raise ibus.IBusException("Parse match rule failed\n%s" % rule)
-
- def __cmp_bus_name(self, dbusobj, a, b):
- if a == None or b == None:
- return a == b
- a_is_unique = a.startswith(":")
- b_is_unique = b.startswith(":")
- if a_is_unique == b_is_unique:
- return a == b
- else:
- try:
- if not a_is_unique:
- a = dbusobj.get_name_owner(a).get_unique_name()
- if not b_is_unique:
- b = dbusobj.get_name_owner(b).get_unique_name()
- return a == b
- except:
- return False
-
- def match_message(self, dbusobj, message):
- if self.__type == 'signal' and message.get_type() != 4:
- return False
-
- if self.__sender:
- if not self.__cmp_bus_name(dbusobj, self.__sender, message.get_sender()):
- return False
-
- if self.__interface and self.__interface != message.get_interface():
- return False
-
- if self.__member and self.__member != message.get_member():
- return False
-
- if self.__path and self.__path != message.get_path():
- return False
-
- if self.__destination:
- if not self.__cmp_bus_name(dbusobj, self.__destination, message.get_destination()):
- return False
- args = message.get_args_list()
- for i, arg in self.__args:
- if i >= len(args):
- return False
- if arg != args[i]:
- return False
- return True
-
-class DBusReal(ibus.Object):
- __gsignals__ = {
- "name-owner-changed" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)),
- }
-
- def __init__(self):
- super(DBusReal, self).__init__()
- self.__connections = dict()
- self.__unique_name_dict = dict()
- self.__name_dict = dict()
- self.__id = 0
-
- def add_connection(self, ibusconn):
- self.__connections[ibusconn] = list()
- ibusconn.connect("dbus-message", self.__dbus_message_cb)
- ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
-
- def register_connection(self, ibusconn):
- name = ibusconn.get_unique_name()
- if name:
- raise ibus.IBusException("Already handled an Hello message")
- self.__id += 1
- name = ":1.%d" % self.__id
- self.__unique_name_dict[name] = ibusconn
- ibusconn.set_unique_name(name)
- return name
-
- def list_names(self):
- return self.__name_dict.keys() + self.__unique_name_dict.keys()
-
- def list_activatable_names(self):
- return self.__name_dict.keys() + self.__unique_name_dict.keys()
-
- def name_has_owner(self, name):
- if name.startswith(":"):
- return name in self.__unique_name_dict
- return name in self.__name_dict
-
- def get_name_owner(self, name):
- if name == dbus.BUS_DAEMON_NAME or \
- name == ibus.IBUS_NAME:
- return name
- if name.startswith(":"):
- if name in self.__unique_name_dict:
- return name
- elif name in self.__name_dict:
- ibusconn = self.__name_dict[name]
- return ibusconn.get_unique_name()
-
- raise ibus.IBusException(
- "org.freedesktop.DBus.Error.NameHasNoOwner:\n"
- "\tCould not get owner of name '%s': no such name" % name)
-
- def start_service_by_name(self, name, flags):
- return 0
-
- def get_connection_unix_user(self, connection_name):
- return 0
-
- def add_match(self, ibusconn, rule):
- self.__connections[ibusconn].append(MatchRule(rule))
-
- def remove_match(self, ibusconn, rule):
- pass
-
- def request_name(self, ibusconn, name, flags):
- if name.startswith(":"):
- raise ibus.IBusException("Only unique name can start with ':'")
- if not ibusconn.get_unique_name():
- raise ibus.IBusException("Can not call any method before Hello.")
- if name in ibusconn.get_names():
- return 0
- if name in self.__name_dict:
- raise ibus.IBusException("Name has been registered")
- self.__name_dict[name] = ibusconn
- self.emit("name-owner-changed", name, "", ibusconn.get_unique_name())
- ibusconn.add_name(name)
- return 1
-
- def release_name(self, ibusconn, name):
- if name.startswith(":"):
- raise ibus.IBusException("Only unique name can start with ':'")
- if name not in ibusconn.get_names():
- return 2
- del self.__name_dict[name]
- self.emit("name-owner-changed", name, ibusconn.get_unique_name(), "")
- ibusconn.remove_name(name)
- return 1
-
- def dispatch_dbus_signal(self, message):
- for conn, rules in self.__connections.items():
- for rule in rules:
- if rule.match_message(self, message):
- conn.send_message(message)
- break
- def get_connection_by_name(self, name):
- if not name.startswith(":"):
- return None
- return self.__unique_name_dict.get(name, None)
-
- def do_name_owner_changed(self, name, old_name, new_name):
- message = dbus.lowlevel.SignalMessage(dbus.BUS_DAEMON_PATH,
- dbus.BUS_DAEMON_IFACE, "NameOwnerChanged")
- # message.set_sender(dbus.BUS_DAEMON_NAME)
- message.append(name)
- message.append(old_name)
- message.append(new_name)
- self.dispatch_dbus_signal(message)
-
- def __dbus_message_cb(self, ibusconn, message):
- dest = message.get_destination()
- message.set_sender(ibusconn.get_unique_name())
- if (not dest):
- if message.get_type() != 4: # Is not signal
- raise ibus.IBusException("Message without destination")
- self.dispatch_dbus_signal(message)
- return True
-
- if not dest.startswith(":"):
- raise ibus.IBusException("Destination of message must be an unique name")
-
- destconn = self.__unique_name_dict.get(dest, None)
- if destconn == None:
- raise ibus.IBusException("Can not find the destination(%s)" % dest)
-
- destconn.send_message(message)
- return True
-
- def __ibusconn_destroy_cb(self, ibusconn):
- name = ibusconn.get_unique_name()
- for name in ibusconn.get_names():
- del self.__name_dict[name]
- self.emit("name-owner-changed", name, ibusconn.get_unique_name(), "")
- if name:
- del self.__unique_name_dict[name]
- self.emit("name-owner-changed", name, name, "")
-
- del self.__connections[ibusconn]
-
-bus = DBusReal()
-
-class DBus(dbus.service.Object):
-
- method = lambda **args: \
- dbus.service.method(dbus_interface = dbus.BUS_DAEMON_IFACE, \
- **args)
-
- signal = lambda **args: \
- dbus.service.signal(dbus_interface = dbus.BUS_DAEMON_IFACE, \
- **args)
-
- __bus = bus
-
- def __init__(self, ibusconn):
- super(DBus, self).__init__(ibusconn.get_dbusconn(), dbus.BUS_DAEMON_PATH)
- self.__ibusconn = ibusconn
- self.__name = DBus.__bus.register_connection(self.__ibusconn)
- self.__active = False
- self.__bus.add_connection(ibusconn)
-
- @method(out_signature="s")
- def Hello(self):
- if not self.__active:
- self.__active = True
- return self.__name
- raise ibus.IBusException("Already handled an Hello message")
-
- @method(out_signature="as")
- def ListNames(self):
- return DBus.__bus.list_names()
-
- @method(out_signature="as")
- def ListActivatableNames(self):
- return DBus.__bus.list_activatable_names()
-
- @method(in_signature="s", out_signature="as")
- def NameHasOwner(self, name):
- return DBus.__bus.name_has_owner(name)
-
- @method(in_signature="si", out_signature="i")
- def StartServiceByName(self, name, flags):
- return DBus.__bus.start_service_by_name(name, flags)
-
- @method(in_signature="s", out_signature="s")
- def GetNameOwner(self, name):
- return DBus.__bus.get_name_owner(name)
-
- @method(in_signature="s", out_signature="i")
- def GetConnectionUnixUser(self, connection_name):
- return DBus.__bus.get_connection_unix_user(connection_name)
-
- @method(in_signature="s")
- def AddMatch(self, rule):
- return DBus.__bus.add_match(self.__ibusconn, rule)
-
- @method(in_signature="s")
- def RemoveMatch(self, rule):
- return DBus.__bus.remove_match(self.__ibusconn, rule)
-
- @method(out_signature="s")
- def GetId(self):
- return self.__name
-
- @method(in_signature="su", out_signature="u")
- def RequestName(self, name, flags):
- return self.__bus.request_name(self.__ibusconn, name, flags)
-
- @method(in_signature="s", out_signature="u")
- def ReleaseName(self, name):
- return self.__bus.release_name(self.__ibusconn, name)
-
- @signal(signature="sss")
- def NameOwnerChanged(self, name, old_owner, new_owner):
- pass
-
- @signal(signature="s")
- def NameLost(self, name):
- pass
-
- @signal(signature="s")
- def NameAcquired(self, name):
- pass
diff --git a/daemon/bus.py b/daemon/bus.py
deleted file mode 100644
index 5c5cb3a..0000000
--- a/daemon/bus.py
+++ /dev/null
@@ -1,714 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import sys
-import ibus
-import gobject
-from ibus import keysyms
-from ibus import modifier
-from contextmanager import ContextManager
-from factorymanager import FactoryManager
-from panel import Panel, DummyPanel
-from notifications import Notifications, DummyNotifications
-from config import Config, DummyConfig
-from register import Register
-import _dbus
-
-from gettext import dgettext
-_ = lambda a : dgettext("ibus", a)
-N_ = lambda a : a
-
-class IBus(ibus.Object):
- def __init__(self):
- super(IBus, self).__init__()
- _dbus.bus.connect("name-owner-changed", self.__dbus_name_owner_changed_cb)
- self.__context_manager = ContextManager()
- self.__factory_manager = FactoryManager()
- self.__factory_manager.connect("default-factory-changed",
- self.__factory_manager_default_factory_changed_cb)
-
- self.__panel = DummyPanel()
- self.__panel_handlers = list()
- self.__install_panel_handlers()
-
- self.__notifications = DummyNotifications()
- self.__notifications_handlers = list()
- self.__install_notifications_handlers()
-
- self.__no_engine_notification_id = 0
- self.__no_engine_notification_show = True
-
- self.__config = DummyConfig()
- self.__config_handlers = list()
- self.__install_config_handlers()
-
- self.__register = Register()
-
- self.__focused_context = None
- self.__last_focused_context = None
- self.__context_handlers = list()
-
- self.__connections = list()
-
- self.__prev_key = None
- self.__config_load_settings ()
-
- def __config_load_settings (self):
- self.__shortcut_trigger = self.__load_config_shortcut(
- "general", "keyboard_shortcut_trigger",
- ibus.CONFIG_GENERAL_SHORTCUT_TRIGGER_DEFAULT)
- self.__shortcut_next_engine = self.__load_config_shortcut(
- "general", "keyboard_shortcut_next_engine",
- ibus.CONFIG_GENERAL_SHORTCUT_NEXT_ENGINE_DEFAULT)
- self.__shortcut_prev_engine = self.__load_config_shortcut(
- "general", "keyboard_shortcut_next_engine",
- ibus.CONFIG_GENERAL_SHORTCUT_NEXT_ENGINE_DEFAULT)
- self.__default_factory = None
-
- def __dbus_name_owner_changed_cb(self, bus, name, old_name, new_name):
- if name == ibus.IBUS_PANEL_NAME:
- self.__panel_changed(new_name)
- elif name == ibus.IBUS_CONFIG_NAME:
- self.__config_changed(new_name)
- elif name == ibus.IBUS_NOTIFICATIONS_NAME:
- self.__notifications_changed(new_name)
-
- def __factory_manager_default_factory_changed_cb(self, manager, factory):
- if self.__default_factory != factory:
- self.__default_factory = factory
- if factory == None:
- return
- self.__config.set_value("general", "default_factory", factory.get_object_path())
-
- def __load_config_shortcut(self, section, name, default_value):
-
- # load trigger
- shortcut_strings = default_value
- try:
- shortcut_strings = self.__config.get_value(section, name)
- except:
- pass
- shortcuts = []
- for s in shortcut_strings:
- keyval, keymask = self.__parse_shortcut_string(s)
- if keyval != 0:
- shortcuts.append((keyval, keymask))
- return shortcuts
-
- def new_connection(self, conn):
- IBusProxy(self, conn)
- conn.connect("destroy", self.__conn_destroy_cb)
- self.__connections.append(conn)
-
- def __conn_destroy_cb(self, conn):
- self.__connections.remove(conn)
-
- ##########################################################
- # methods for im context
- ##########################################################
- def __load_default_factory(self):
- if self.__default_factory != None:
- return
- try:
- factory_path = self.__config.get_value("general", "default_factory")
- self.__default_factory = self.__factory_manager.get_factory(factory_path)
- except:
- pass
- if self.__default_factory != None:
- self.__factory_manager.set_default_factory(self.__default_factory)
- return
-
- def create_input_context(self, name, conn):
- context = self.__context_manager.create_input_context(name, conn)
- self.__load_default_factory()
- if self.__default_factory != None:
- engine = self.__default_factory.create_engine()
- context.set_engine(engine)
- return context.get_id()
-
- def release_input_context(self, ic, conn):
- self.__context_manager.release_input_context(ic, conn)
-
- def focus_in(self, ic, conn):
- context = self.__lookup_context(ic, conn)
- if not context.get_support_focus():
- return
- if self.__focused_context != context and self.__focused_context != None:
- self.__remove_focused_context_handlers()
- self.__focused_context.focus_out()
-
- self.__focused_context = context
- self.__install_focused_context_handlers()
-
- self.__panel.focus_in(context.get_id())
- self.__last_focused_context = context
- context.focus_in()
- self.__prev_key = None
-
- def focus_out(self, ic, conn):
- context = self.__lookup_context(ic, conn)
-
- if context == self.__focused_context:
- self.__remove_focused_context_handlers()
- self.__focused_context = None
- self.__panel.focus_out(context.get_id())
-
- context.focus_out()
-
- def reset(self, ic, conn):
- context = self.__lookup_context(ic, conn)
- context.reset()
-
- def is_enabled(self, ic, conn):
- context = self.__lookup_context(ic, conn)
- return context.is_enabled()
-
- def set_capabilities(self, ic, caps, conn):
- context = self.__lookup_context(ic, conn)
- return context.set_capabilities(caps)
-
- def process_key_event(self, ic, keyval, is_press, state,
- conn, reply_cb, error_cb):
- context = self.__lookup_context(ic, conn)
-
- # focus in the context, if context supports focus
- if context != self.__focused_context and context.get_support_focus():
- self.focus_in(ic, conn)
-
- if self.__filter_keyboard_shortcuts(context, keyval, is_press, state):
- reply_cb(True)
- return
- else:
- context.process_key_event(keyval, is_press, state, reply_cb, error_cb)
-
- def set_cursor_location(self, ic, x, y, w, h, conn):
- context = self.__lookup_context(ic, conn)
- context.set_cursor_location(x, y, w, h)
- if context == self.__focused_context:
- self.__panel.set_cursor_location(x, y, w, h)
-
- def __context_enable(self, context):
- if context.get_engine() == None:
- self.__load_default_factory()
- if self.__default_factory == None:
- self.__default_factory = self.__factory_manager.get_default_factory()
- if self.__default_factory:
- engine = self.__default_factory.create_engine()
- engine.focus_in()
- context.set_engine(engine)
- else:
- if self.__no_engine_notification_show:
- self.__no_engine_notification_id = self.__notifications.notify(
- self.__no_engine_notification_id,
- "ibus", _("Cannot enable input engine"),
- _("IBus can not enable input engine, because IBus does not load any input engines!\n"
- "Please use ibus-setup program to load some input engines."),
- ["Setup", _("Setup"), "NoAgain", _("Don't show this again")],
- 15000)
-
- if context.get_engine() != None:
- context.set_enable(True)
- self.__panel.states_changed()
-
- def __context_disable(self, context):
- context.set_enable(False)
- self.__panel.reset()
- self.__panel.states_changed()
-
- def __context_next_factory(self, context):
- old_factory = context.get_factory()
- new_factory = self.__factory_manager.get_next_factory(old_factory)
- self.__factory_manager.set_default_factory(new_factory)
- engine = new_factory.create_engine()
- self.__panel.reset()
- engine.focus_in()
- context.set_engine(engine)
- self.__panel.states_changed()
-
- def __match_keyboard_shortcuts(self, keyval, is_press, state, shortcuts):
- for sc in shortcuts:
- if state == sc[1] and keyval == sc[0]:
- if state & modifier.RELEASE_MASK == 0:
- return True
- if self.__prev_key[0] == keyval and \
- self.__prev_key[1] == True:
- return True
- return False
-
- def __filter_keyboard_shortcuts(self, context, keyval, is_press, state):
- state = state & (modifier.CONTROL_MASK | \
- modifier.SHIFT_MASK | \
- modifier.MOD1_MASK | \
- modifier.SUPER_MASK | \
- modifier.HYPER_MASK | \
- modifier.META_MASK)
- if not is_press:
- state = state | modifier.RELEASE_MASK
-
- retval = True
- if self.__match_keyboard_shortcuts(keyval,
- is_press, state, self.__shortcut_trigger):
- if context.is_enabled():
- self.__context_disable(context)
- else:
- self.__context_enable(context)
- retval = True
- elif self.__match_keyboard_shortcuts(keyval,
- is_press, state, self.__shortcut_next_engine):
- if not context.is_enabled():
- self.__context_enable(context)
- else:
- self.__context_next_factory(context)
- else:
- retval = False
-
- self.__prev_key = (keyval, is_press, state)
- return retval
-
- def __lookup_context(self, ic, conn):
- return self.__context_manager.lookup_context(ic, conn)
-
- def __install_focused_context_handlers(self):
- # Install all callback functions
- if self.__focused_context == None:
- return
- signals = (
- ("update-preedit", self.__update_preedit_cb),
- ("show-preedit", self.__show_preedit_cb),
- ("hide-preedit", self.__hide_preedit_cb),
- ("update-aux-string", self.__update_aux_string_cb),
- ("show-aux-string", self.__show_aux_string_cb),
- ("hide-aux-string", self.__hide_aux_string_cb),
- ("update-lookup-table", self.__update_lookup_table_cb),
- ("show-lookup-table", self.__show_lookup_table_cb),
- ("hide-lookup-table", self.__hide_lookup_table_cb),
- ("page-up-lookup-table", self.__page_up_lookup_table_cb),
- ("page-down-lookup-table", self.__page_down_lookup_table_cb),
- ("cursor-up-lookup-table", self.__cursor_up_lookup_table_cb),
- ("cursor-down-lookup-table", self.__cursor_down_lookup_table_cb),
- ("register-properties", self.__register_properties_cb),
- ("update-property", self.__update_property_cb),
- ("engine-lost", self.__engine_lost_cb),
- ("destroy", self.__context_destroy_cb)
- )
- for name, handler in signals:
- id = self.__focused_context.connect(name, handler)
- self.__context_handlers.append(id)
-
- def __remove_focused_context_handlers(self):
- if self.__focused_context == None:
- return
- map(self.__focused_context.disconnect, self.__context_handlers)
- self.__context_handlers = []
-
- def __update_preedit_cb(self, context, text, attrs, cursor_pos, visible):
- assert self.__focused_context == context
- self.__panel.update_preedit(text, attrs, cursor_pos, visible)
-
- def __show_preedit_cb(self, context):
- assert self.__focused_context == context
- self.__panel.show_preedit()
-
- def __hide_preedit_cb(self, context):
- assert self.__focused_context == context
- self.__panel.hide_preedit()
-
- def __update_aux_string_cb(self, context, text, attrs, visible):
- assert self.__focused_context == context
- self.__panel.update_aux_string(text, attrs, visible)
-
- def __show_aux_string_cb(self, context):
- assert self.__focused_context == context
- self.__panel.show_aux_string()
-
- def __hide_aux_string_cb(self, context):
- assert self.__focused_context == context
- self.__panel.hide_aux_string()
-
- def __update_lookup_table_cb(self, context, lookup_table, visible):
- assert self.__focused_context == context
- self.__panel.update_lookup_table(lookup_table, visible)
-
- def __show_lookup_table_cb(self, context):
- assert self.__focused_context == context
- self.__panel.show_lookup_table()
-
- def __hide_lookup_table_cb(self, context):
- assert self.__focused_context == context
- self.__panel.hide_lookup_table()
-
- def __page_up_lookup_table_cb(self, context):
- assert self.__focused_context == context
- self.__panel.page_up_lookup_table()
-
- def __page_down_lookup_table_cb(self, context):
- assert self.__focused_context == context
- self.__panel.page_down_lookup_table()
-
- def __cursor_up_lookup_table_cb(self, context):
- assert self.__focused_context == context
- self.__panel.cursor_up_lookup_table()
-
- def __cursor_down_lookup_table_cb(self, context):
- assert self.__focused_context == context
- self.__panel.cursor_down_lookup_table()
-
- def __register_properties_cb(self, context, props):
- assert self.__focused_context == context
- self.__panel.register_properties(props)
-
-
- def __update_property_cb(self, context, prop):
- assert self.__focused_context == context
- self.__panel.update_property(prop)
-
- def __engine_lost_cb(self, context):
- assert self.__focused_context == context
- self.__panel.reset()
-
- def __context_destroy_cb(self, context):
- assert context == self.__focused_context
- self.__remove_focused_context_handlers()
- self.__panel.focus_out(context.get_id())
- self.__focused_context = None
-
- ##########################################################
- # methods for im engines
- ##########################################################
- def register_factories(self, object_paths, conn):
- self.__factory_manager.register_factories(object_paths, conn)
-
-
- ##########################################################
- # methods for panel
- ##########################################################
- def __panel_changed(self, bus_name):
- if not isinstance(self.__panel, DummyPanel):
- self.__uninstall_panel_handlers()
- self.__panel.destroy()
- ibusconn = _dbus.bus.get_connection_by_name(bus_name)
- if ibusconn == None:
- self.__panel = DummyPanel()
- else:
- self.__panel = Panel(ibusconn)
- self.__install_panel_handlers()
- if self.__focused_context:
- self.__panel.focus_in(self.__focused_context.get_id())
-
- def __install_panel_handlers(self):
- signals = (
- ("page-up", self.__panel_page_up_cb),
- ("page-down", self.__panel_page_down_cb),
- ("cursor-up", self.__panel_cursor_up_cb),
- ("cursor-down", self.__panel_cursor_down_cb),
- ("property-activate", self.__panel_property_active_cb),
- ("property-show", self.__panel_property_show_cb),
- ("property-hide", self.__panel_property_hide_cb),
- ("destroy", self.__panel_destroy_cb)
- )
-
- for signal, handler in signals:
- id = self.__panel.connect(signal, handler)
- self.__panel_handlers.append(id)
-
- def __uninstall_panel_handlers(self):
- map(lambda id:self.__panel.disconnect(id), self.__panel_handlers)
- self.__panel_handlers = list()
-
-
- def __panel_page_up_cb(self, panel):
- assert panel == self.__panel
- if self.__focused_context:
- self.__focused_context.page_up()
-
- def __panel_page_down_cb(self, panel):
- assert panel == self.__panel
- if self.__focused_context:
- self.__focused_context.page_down()
-
- def __panel_cursor_up_cb(self, panel):
- assert panel == self.__panel
- if self.__focused_context:
- self.__focused_context.cursor_up()
-
- def __panel_cursor_down_cb(self, panel):
- assert panel == self.__panel
- if self.__focused_context:
- self.__focused_context.cursor_down()
-
- def __panel_property_active_cb(self, panel, prop_name, prop_state):
- assert panel == self.__panel
- if self.__focused_context:
- self.__focused_context.property_activate(prop_name, prop_state)
-
- def __panel_property_show_cb(self, panel, prop_name):
- assert panel == self.__panel
- if self.__focused_context:
- self.__focused_context.property_show(prop_name)
-
- def __panel_property_hide_cb(self, panel, prop_name):
- assert panel == self.__panel
- if self.__focused_context:
- self.__focused_context.property_hide(prop_name)
-
- def __panel_destroy_cb(self, panel):
- if panel == self.__panel:
- self.__uninstall_panel_handlers()
- self.__panel = DummyPanel()
-
- ##########################################################
- # methods for notifications
- ##########################################################
- def __notifications_changed(self, bus_name):
- if not isinstance(self.__notifications, DummyNotifications):
- self.__uninstall_notifications_handlers()
- self.__notifications.destroy()
- ibusconn = _dbus.bus.get_connection_by_name(bus_name)
- if ibusconn == None:
- self.__notifications = DummyNotifications()
- else:
- self.__notifications = Notifications(ibusconn)
- self.__install_notifications_handlers()
-
- def __install_notifications_handlers(self):
- signals = (
- ("notification-closed", self.__notifications_notification_closed_cb),
- ("action-invoked", self.__notifications_action_invoked_cb),
- ("destroy", self.__notifications_destroy_cb)
- )
-
- for signal, handler in signals:
- id = self.__notifications.connect(signal, handler)
- self.__notifications_handlers.append(id)
-
- def __uninstall_notifications_handlers(self):
- map(lambda id:self.__notifications.disconnect(id), self.__notifications_handlers)
- self.__notifications_handlers = list()
-
- def __notifications_notification_closed_cb(self, notifications, id, reason):
- pass
-
- def __notifications_action_invoked_cb(self, notifications, id, action_key):
- if id == self.__no_engine_notification_id:
- if action_key == "NoAgain":
- self.__no_engine_notification_show = False
- elif action_key == "Setup":
- self.__panel.start_setup()
-
-
- def __notifications_destroy_cb(self, notifications):
- if notifications == self.__notifications:
- self.__uninstall_notifications_handlers()
- self.__notifications = DummyNotifications()
-
-
- ##########################################################
- # methods for config
- ##########################################################
- def __config_changed(self, bus_name):
- ibusconn = _dbus.bus.get_connection_by_name(bus_name)
- self.__uninstall_config_handlers()
- self.__config.destroy()
- self.__config = Config(ibusconn)
- self.__install_config_handlers()
- gobject.idle_add (self.__config_load_settings)
-
- def __install_config_handlers(self):
- signals = (
- ("value-changed", self.__config_value_changed_cb),
- ("destroy", self.__config_destroy_cb),
- )
- for signal, handler in signals:
- id = self.__config.connect(signal, handler)
- self.__config_handlers.append(id)
-
- def __uninstall_config_handlers(self):
- map(lambda id:self.__config.disconnect(id), self.__config_handlers)
- self.__config_handlers = list()
-
- def __parse_shortcut_string(self, string):
- keys = string.split("+")
- keymask = 0
- for name, mask in modifier.MODIFIER_NAME_TABLE:
- if name in keys[:-1]:
- keymask |= mask
- keyname = keys[-1]
- keyval = keysyms.name_to_keycode(keyname)
- if keyval == None:
- keyval = 0
-
- return keyval, keymask
-
- def __config_value_changed_cb (self, config, section, name, value):
- if section == "general":
- if name == "keyboard_shortcut_trigger":
- self.__shortcut_trigger = self.__load_config_shortcut(
- "general", "keyboard_shortcut_trigger",
- ibus.CONFIG_GENERAL_SHORTCUT_TRIGGER_DEFAULT)
- elif name =="keyboard_shortcut_next_engine":
- self.__shortcut_next_engine = self.__load_config_shortcut(
- "general", "keyboard_shortcut_next_engine",
- ibus.CONFIG_GENERAL_SHORTCUT_NEXT_ENGINE_DEFAULT)
-
- def __config_destroy_cb(self, config):
- if config == self.__config:
- self.__config = DefaultConfig()
-
- ##########################################################
- # engine register methods
- ##########################################################
- def register_list_engines(self, conn):
- return self.__register.list_engines()
-
- def register_reload_engines(self, conn):
- return self.__register.reload_engines()
-
- def register_start_engine(self, lang, name, conn):
- return self.__register.start_engine(lang, name)
-
- def register_restart_engine(self, lang, name, conn):
- return self.__register.restart_engine(lang, name)
-
- def register_stop_engine(self, lang, name, conn):
- return self.__register.stop_engine(lang, name)
-
- ##########################################################
- # general methods
- ##########################################################
- def get_factories(self):
- return self.__factory_manager.get_factories()
-
- def get_factory_info(self, factory_path):
- return self.__factory_manager.get_factory_info(factory_path)
-
- def set_factory(self, factory_path):
- if self.__focused_context == None:
- return
- self.__panel.reset()
- factory = self.__factory_manager.get_factory(factory_path)
- self.__factory_manager.set_default_factory(factory)
- engine = factory.create_engine()
- self.__focused_context.set_engine(engine)
- self.__focused_context.set_enable(True)
- engine.focus_in()
- self.__panel.states_changed()
-
- def get_input_context_states(self, ic, conn):
- factory_path = ""
- context = self.__lookup_context(ic, conn)
- if context.get_factory() != None:
- factory_path = context.get_factory().get_object_path()
- return factory_path, context.is_enabled()
-
- def kill(self, conn):
- print "be killed"
- sys.exit(0)
-
-
-class IBusProxy(ibus.IIBus):
- def __init__(self, bus, conn):
- super(IBusProxy, self).__init__(conn.get_dbusconn(), ibus.IBUS_PATH)
- self.__ibus = bus
- self.__conn = conn
- self.__conn.connect("destroy", self.__conn_destroy_cb)
-
- def __conn_destroy_cb(self, conn):
- self.__conn = None
- self.__ibus = None
-
- def GetIBusAddress(self, dbusconn):
- return self.__ibus_addr
-
- def CreateInputContext(self, context_name, dbusconn):
- return self.__ibus.create_input_context(context_name, self.__conn)
-
- def ReleaseInputContext(self, ic, dbusconn):
- self.__ibus.release_input_context(ic, self.__conn)
-
- def RegisterFactories(self, object_paths, dbusconn):
- self.__ibus.register_factories(object_paths, self.__conn)
-
- def UnregisterEngines(self, object_paths, dbusconn):
- self.__ibus.unregister_engines(object_paths, self.__conn)
-
- def RegisterPanel(self, object_path, replace, dbusconn):
- self.__ibus.register_panel(object_path, replace, self.__conn)
-
- def RegisterConfig(self, object_path, replace, dbusconn):
- self.__ibus.register_config(object_path, replace, self.__conn)
-
- def ProcessKeyEvent(self, ic, keyval, is_press, state, \
- dbusconn, reply_cb, error_cb):
- try:
- self.__ibus.process_key_event(ic, keyval, is_press, state,
- self.__conn, reply_cb, error_cb)
- except Exception, e:
- error_cb(e)
-
- def SetCursorLocation(self, ic, x, y, w, h, dbusconn):
- self.__ibus.set_cursor_location(ic, x, y, w, h, self.__conn)
-
- def FocusIn(self, ic, dbusconn):
- self.__ibus.focus_in(ic, self.__conn)
-
- def FocusOut(self, ic, dbusconn):
- self.__ibus.focus_out(ic, self.__conn)
-
- def Reset(self, ic, dbusconn):
- self.__ibus.reset(ic, self.__conn)
-
- def IsEnabled(self, ic, dbusconn):
- return self.__ibus.is_enabled(ic, self.__conn)
-
- def SetCapabilities(self, ic, caps, dbusconn):
- return self.__ibus.set_capabilities(ic, caps, self.__conn)
-
- def GetFactories(self, dbusconn):
- return self.__ibus.get_factories()
-
- def GetFactoryInfo(self, factory_path, dbusconn):
- return self.__ibus.get_factory_info(factory_path)
-
- def SetFactory(self, factory_path, dbusconn):
- return self.__ibus.set_factory(factory_path)
-
- def GetInputContextStates(self, ic, dbusconn):
- return self.__ibus.get_input_context_states(ic, self.__conn)
-
- def RegisterListEngines(self, dbusconn):
- return self.__ibus.register_list_engines(self.__conn)
-
- def RegisterReloadEngines(self, dbusconn):
- return self.__ibus.register_reload_engines(self.__conn)
-
- def RegisterStartEngine(self, lang, name, dbusconn):
- return self.__ibus.register_start_engine(lang, name, self.__conn)
-
- def RegisterRestartEngine(self, lang, name, dbusconn):
- return self.__ibus.register_restart_engine(lang, name, self.__conn)
-
- def RegisterStopEngine(self, lang, name, dbusconn):
- return self.__ibus.register_stop_engine(lang, name, self.__conn)
-
- def Kill(self, dbusconn, reply_cb, error_cb):
- reply_cb()
- self.__ibus.kill(self.__conn)
-
diff --git a/daemon/config.py b/daemon/config.py
deleted file mode 100644
index 3a41c9c..0000000
--- a/daemon/config.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# vim:set et sts=4 sw=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
-
-__all__ = (
- "Config",
- "DefaultConfig"
-)
-
-import gobject
-import ibus
-
-class Config(ibus.Object):
- __gsignals__ = {
- "value-changed" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)),
- }
-
- def __init__(self, ibusconn):
- super(Config, self).__init__()
- self.__ibusconn = ibusconn
- self.__config = self.__ibusconn.get_object(ibus.IBUS_CONFIG_PATH)
-
- self.__ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
- self.__ibusconn.connect("dbus-signal", self.__dbus_signal_cb)
-
- def get_value(self, section, name, **kargs):
- return self.__config.GetValue(section, name, **kargs)
-
- def set_value(self, section, name, value, **kargs):
- return self.__config.SetValue(section, name, value, **kargs)
-
- def destroy(self):
- if self.__ibusconn != None:
- self.__config.Destroy(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- self.__ibusconn = None
- self.__config = None
- ibus.Object.destroy(self)
-
- # signal callbacks
- def __ibusconn_destroy_cb(self, ibusconn):
- self.__ibusconn = None
- self.destroy()
-
- def __dbus_signal_cb(self, ibusconn, message):
- if message.is_signal(ibus.IBUS_CONFIG_IFACE, "ValueChanged"):
- args = message.get_args_list()
- self.emit("value-changed", args[0], args[1], args[2])
- return False
-
-gobject.type_register(Config)
-
-class DummyConfig(ibus.Object):
- __gsignals__ = {
- "value-changed" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)),
- }
-
- def __init__(self):
- super(DummyConfig, self).__init__()
- self.__values = dict()
-
- def get_value(self, section, name, **kargs):
- value = self.__values.get((section, name), None)
- if value == None:
- raise ibus.IBusException("Can not get config section=%s name=%s" % (section, name))
- return value
-
- def set_value(self, section, name, value, **kargs):
- old_value = self.__values.get((section, name), None)
- if value == old_value:
- return
- if value == None:
- del self.__values[(section, name)]
- else:
- self.__values[(section, name)] = value
- self.emit("value-changed", section, name, value)
-
-gobject.type_register(DummyConfig)
diff --git a/daemon/connection.py b/daemon/connection.py
deleted file mode 100644
index f897e08..0000000
--- a/daemon/connection.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import dbus.lowlevel
-import ibus
-import gobject
-
-class Connection(ibus.Object):
- __gsignals__ = {
- "dbus-signal" : (
- gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_BOOLEAN,
- (gobject.TYPE_PYOBJECT, )
- ),
- "dbus-message" : (
- gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_BOOLEAN,
- (gobject.TYPE_PYOBJECT, )
- )
- }
- def __init__(self, dbusconn):
- super(Connection, self).__init__()
- self.__dbusconn = dbusconn
- self.__unique_name = ""
- self.__names = set()
- dbusconn.add_message_filter(self.message_filter_cb)
-
- def message_filter_cb(self, dbusconn, message):
- if message.is_signal(dbus.LOCAL_IFACE, "Disconnected"):
- self.destroy()
- return dbus.lowlevel.HANDLER_RESULT_HANDLED
-
- if message.get_destination() in set(["org.freedesktop.IBus", "org.freedesktop.DBus"]):
- return dbus.lowlevel.HANDLER_RESULT_NOT_YET_HANDLED
-
- if message.get_type() == 4: # is signal
- if self.emit("dbus-signal", message):
- return dbus.lowlevel.HANDLER_RESULT_HANDLED
- if self.emit("dbus-message", message):
- return dbus.lowlevel.HANDLER_RESULT_HANDLED
- return dbus.lowlevel.HANDLER_RESULT_NOT_YET_HANDLED
-
- def get_object(self, path):
- return self.__dbusconn.get_object("no.name", path)
-
- def emit_dbus_signal(self, name, *args):
- message = dbus.lowlevel.SignalMessage(ibus.IBUS_PATH, ibus.IBUS_IFACE, name)
- message.append(*args)
- self.send_message(message)
-
- def send_message(self, message):
- self.__dbusconn.send_message(message)
- self.__dbusconn.flush()
-
- def do_destroy(self):
- self.__dbusconn = None
-
- def get_dbusconn(self):
- return self.__dbusconn
-
- def get_unique_name(self):
- return self.__unique_name
-
- def set_unique_name(self, name):
- assert name
- assert not self.__unique_name
- self.__unique_name = name
-
- def get_names(self):
- return self.__names
-
- def add_name(self, name):
- if name not in self.__names:
- self.__names.add(name)
-
- def remove_name(self, name):
- if name in self.__names:
- self.__names.remove(name)
-
-gobject.type_register(Connection)
diff --git a/daemon/contextmanager.py b/daemon/contextmanager.py
deleted file mode 100644
index 44b4bdb..0000000
--- a/daemon/contextmanager.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import ibus
-from inputcontext import InputContext
-
-class ContextManager(ibus.Object):
- def __init__(self):
- super(ContextManager, self).__init__()
- self._contexts = {}
-
- def create_input_context(self, name, ibusconn):
- context = InputContext(name, ibusconn)
- self._contexts[context.get_id()] = context
- context.connect("destroy", self._context_destroy_cb)
- return context
-
- def release_input_context(self, ic, ibusconn):
- context = self._contexts[ic]
- context.destroy()
-
- def lookup_context(self, ic, ibusconn):
- return self._contexts[ic]
-
- def _context_destroy_cb(self, context):
- del self._contexts[context.get_id()]
-
diff --git a/daemon/engine.py b/daemon/engine.py
deleted file mode 100644
index e4bc048..0000000
--- a/daemon/engine.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import gobject
-import ibus
-
-class Engine(ibus.Object):
- __gsignals__ = {
- "commit-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, )),
- "forward-key-event" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_UINT, gobject.TYPE_BOOLEAN, gobject.TYPE_UINT )),
- "update-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_INT, gobject.TYPE_BOOLEAN)),
- "show-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "hide-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "update-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)),
- "show-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "hide-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "update-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)),
- "show-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "hide-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "page-up-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "page-down-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "cursor-up-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "cursor-down-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "register-properties" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, )),
- "update-property" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, )),
- }
-
- def __init__(self, factory, ibusconn, object_path):
- super(Engine, self).__init__()
- self.__factory = factory
- self.__ibusconn = ibusconn
- self.__object_path = object_path
- self.__engine = ibusconn.get_object(self.__object_path)
- self.__lookup_table = ibus.LookupTable()
- self.__ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
-
- def get_factory(self):
- return self.__factory
-
- def get_object_path(self):
- return self.__object_path
-
- def handle_dbus_signal(self, message):
- if message.is_signal(ibus.IBUS_ENGINE_IFACE, "CommitString"):
- args = message.get_args_list()
- self.emit("commit-string", args[0])
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "ForwardKeyEvent"):
- args = message.get_args_list()
- self.emit("forward-key-event", args[0], bool(arg[1]), arg[2])
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "UpdatePreedit"):
- args = message.get_args_list()
- self.emit("update-preedit", args[0], args[1], args[2], args[3])
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "ShowPreedit"):
- self.emit("show-preedit")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "HidePreedit"):
- self.emit("hide-preedit")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "UpdateAuxString"):
- args = message.get_args_list()
- self.emit("update-aux-string", args[0], args[1], args[2])
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "ShowAuxString"):
- self.emit("show-aux-string")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "HideAuxString"):
- self.emit("hide-aux-string")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "UpdateLookupTable"):
- args = message.get_args_list()
- self.emit("update-lookup-table", args[0], args[1])
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "ShowLookupTable"):
- self.emit("show-lookup-table")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "HideLookupTable"):
- self.emit("hide-lookup-table")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "PageUpLookupTable"):
- self.emit("page-up-lookup-table")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "PageDownLookupTable"):
- self.emit("page-down-lookup-table")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "CursorUpLookupTable"):
- self.emit("cursor-up-lookup-table")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "CursorDownLookupTable"):
- self.emit("cursor-down-lookup-table")
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "RegisterProperties"):
- args = message.get_args_list()
- self.emit("register-properties", args[0])
- elif message.is_signal(ibus.IBUS_ENGINE_IFACE, "UpdateProperty"):
- args = message.get_args_list()
- self.emit("update-property", args[0])
- else:
- return False
-
- return True
-
- def focus_in(self):
- self.__engine.FocusIn(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def focus_out(self):
- self.__engine.FocusOut(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def reset(self):
- self.__engine.Reset(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def process_key_event(self, keyval, is_press, state, reply_cb, error_cb):
- self.__engine.ProcessKeyEvent(keyval, is_press, state,
- reply_handler = reply_cb,
- error_handler = error_cb)
-
- def set_cursor_location(self, x, y, w, h):
- self.__engine.SetCursorLocation(x, y, w, h,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def enable(self):
- self.__engine.Enable(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def disable(self):
- self.__engine.Disable(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- # cursor for lookup table
-
- def page_up(self):
- self.__engine.PageUp(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def page_down(self):
- self.__engine.PageDown(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def cursor_up(self):
- self.__engine.CursorUp(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def cursor_down(self):
- self.__engine.CursorDown(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def property_activate(self, prop_name, prop_state):
- self.__engine.PropertyActivate(prop_name, prop_state,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def property_show(self, prop_name):
- self.__engine.PropertyShow(prop_name,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def property_hide(self, prop_name):
- self.__engine.PropertyHide(prop_name,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def destroy(self):
- ibus.Object.destroy(self)
- if self.__engine:
- self.__engine.Destroy(**ibus.DEFAULT_ASYNC_HANDLERS)
- self.__engine = None
- self.__ibusconn = None
-
- def __ibusconn_destroy_cb(self, ibusconn):
- self.__engine = None
- self.destroy()
-
-gobject.type_register(Engine)
-
diff --git a/daemon/enginefactory.py b/daemon/enginefactory.py
deleted file mode 100644
index 5ef6cc6..0000000
--- a/daemon/enginefactory.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import weakref
-import gobject
-import ibus
-from engine import Engine
-
-class EngineFactory(ibus.Object):
- def __init__(self, ibusconn, object_path):
- super(EngineFactory, self).__init__()
- self._ibusconn = ibusconn
- self._object_path = object_path
- self._factory = self._ibusconn.get_object(self._object_path)
-
- self._ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
-
- self._ibusconn.connect("dbus-signal", self.__dbus_signal_cb)
- self._engines = weakref.WeakValueDictionary()
-
- self._info = None
-
- def get_object_path(self):
- return self._object_path
-
- def get_info(self):
- if self._info == None:
- self._info = self._factory.GetInfo()
- return self._info
-
- def create_engine(self):
- object_path = self._factory.CreateEngine()
- engine = Engine(self, self._ibusconn, object_path)
- self._engines[object_path] = engine
- return engine
-
- def destroy(self):
- ibus.Object.destroy(self)
- self._ibusconn = None
- self._factory = None
-
- def __ibusconn_destroy_cb(self, ibusconn):
- self.destroy()
-
- def __dbus_signal_cb(self, ibusconn, message):
- object_path = message.get_path()
- if object_path in self._engines:
- if self._engines[object_path].handle_dbus_signal(message):
- ibusconn.stop_emission("dbus-signal")
- return True
- return False
-
- # methods for cmp
- def __lt__(self, other):
- x = self.get_info()
- y = other.get_info()
- if x[1] < y[1]: return True
- if x[1] == y[1]: return x[0] < y[0]
-
- def __gt__(self, other):
- x = self.get_info()
- y = other.get_info()
- if x[1] > y[1]: return True
- if x[1] == y[1]: return x[0] > y[0]
-
diff --git a/daemon/factorymanager.py b/daemon/factorymanager.py
deleted file mode 100644
index 351f40c..0000000
--- a/daemon/factorymanager.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import gobject
-import ibus
-from enginefactory import EngineFactory
-
-class FactoryManager(ibus.Object):
- __gsignals__ = {
- 'new-factories-added' : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, )
- ),
- 'default-factory-changed' : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, )
- )
- }
-
- def __init__(self):
- super(FactoryManager, self).__init__()
- self.__factories = {}
- self.__ibusconn_factory_dict = {}
- self.__default_factory = None
- self.__sorted_factories = None
-
- def register_factories(self, object_paths, ibusconn):
- if ibusconn in self.__factories:
- raise ibus.IBusException("this conn has registered factories!")
-
- self.__ibusconn_factory_dict[ibusconn] = []
-
- for object_path in object_paths:
- if object_path in self.__factories:
- raise ibus.IBusException(
- "Factory [%s] has been registered!" % object_path)
-
- factory = EngineFactory(ibusconn, object_path)
- self.__factories[object_path] = factory
- self.__ibusconn_factory_dict[ibusconn].append(object_path)
- self.__sorted_factories = None
-
- ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
-
- self.emit("new-factories-added",
- self.__ibusconn_factory_dict[ibusconn][:])
-
- def get_default_factory(self):
- if self.__default_factory == None:
- factories = self.__get_sorted_factories()
- if factories:
- self.set_default_factory(factories[0])
-
- return self.__default_factory
-
- def set_default_factory(self, factory):
- if factory in self.__get_sorted_factories() or factory == None:
- if self.__default_factory != factory:
- self.__default_factory = factory
- self.emit("default-factory-changed", self.__default_factory)
- else:
- print "unknown factory"
-
- def get_next_factory(self, factory):
- factories = self.__get_sorted_factories()
- i = factories.index(factory) + 1
- if i >= len(factories):
- i = 0
-
- return factories[i]
-
- def get_factories(self):
- return self.__factories.keys()
-
- def get_factory_info(self, factory_path):
- factory = self.__factories[factory_path]
- return factory.get_info()
-
- def get_factory(self, factory_path):
- factory = self.__factories.get(factory_path, None)
- return factory
-
- def __get_sorted_factories(self, resort = False):
- if not self.__sorted_factories or resort:
- factories = self.__factories.values()
- factories.sort()
- self.__sorted_factories = factories
- return self.__sorted_factories
-
- def __ibusconn_destroy_cb(self, ibusconn):
- assert ibusconn in self.__ibusconn_factory_dict
-
- for object_path in self.__ibusconn_factory_dict[ibusconn]:
- factory = self.__factories[object_path]
- if factory == self.__default_factory:
- self.set_default_factory(None)
- del self.__factories[object_path]
-
- del self.__ibusconn_factory_dict[ibusconn]
- self.__sorted_factories = None
-
-gobject.type_register(FactoryManager)
-
diff --git a/daemon/ibusdaemon.py b/daemon/ibusdaemon.py
deleted file mode 100644
index b2f44c8..0000000
--- a/daemon/ibusdaemon.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import os
-import sys
-import getopt
-import getpass
-import gobject
-import dbus.server
-import dbus.mainloop.glib
-import ibus
-from _dbus import DBus
-from bus import IBus
-from connection import Connection
-
-
-class IBusServer(dbus.server.Server):
- def __init__(self, *args, **kargs):
- super(IBusServer, self).__init__()
-
- self.__ibus = IBus()
- # self.__launch_auto_load_engines()
-
- # def __launch_auto_load_engines(self):
- # engines = []
- # try:
- # engines = self.__ibus.config_get_value("general", "preload_engines", None)
- # if not engines:
- # engines = []
- # except:
- # pass
- # for e in engines:
- # try:
- # lang, name = e.split(":")
- # self.__ibus.register_start_engine(lang, name, None)
- # except:
- # pass
-
- def connection_added(self, dbusconn):
- conn = Connection(dbusconn)
- self.__ibus.new_connection(conn)
- DBus(conn)
-
- def connection_removed(self, dbusconn):
- # do nothing.
- pass
-
-def launch_ibus():
- dbus.mainloop.glib.DBusGMainLoop(set_as_default = True)
- loop = gobject.MainLoop()
- try:
- os.mkdir("/tmp/ibus-%s" % getpass.getuser())
- except:
- pass
- bus = IBusServer(ibus.IBUS_ADDR)
- try:
- loop.run()
- except KeyboardInterrupt, e:
- print "daemon exits"
- sys.exit()
-
-
-def print_help(out, v = 0):
- print >> out, "-h, --help show this message."
- print >> out, "-d, --daemonize daemonize ibus"
- sys.exit(v)
-
-def main():
- daemonize = False
- shortopt = "hd"
- longopt = ["help", "daemonize"]
- try:
- opts, args = getopt.getopt(sys.argv[1:], shortopt, longopt)
- except getopt.GetoptError, err:
- print_help(sys.stderr, 1)
-
- for o, a in opts:
- if o in ("-h", "--help"):
- print_help(sys.stdout)
- elif o in ("-d", "--daemonize"):
- daemonize = True
- else:
- print >> sys.stderr, "Unknown argument: %s" % o
- print_help(sys.stderr, 1)
-
- if daemonize:
- if os.fork():
- sys.exit()
-
- launch_ibus()
-
-
-if __name__ == "__main__":
- main()
diff --git a/daemon/inputcontext.py b/daemon/inputcontext.py
deleted file mode 100644
index 8e433a2..0000000
--- a/daemon/inputcontext.py
+++ /dev/null
@@ -1,449 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import gobject
-import ibus
-
-IBUS_CAP_PREEDIT = 1
-IBUS_CAP_AUX_STRING = 1 << 1
-IBUS_CAP_LOOKUP_TABLE = 1 << 2
-IBUS_CAP_FOCUS = 1 << 3
-
-class InputContext(ibus.Object):
- id = 1
- __gsignals__ = {
- "update-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_INT, gobject.TYPE_BOOLEAN)),
- "show-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "hide-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "update-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)),
- "show-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "hide-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "update-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)),
- "show-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "hide-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "page-up-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "page-down-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "cursor-up-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "cursor-down-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "register-properties" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, )),
- "update-property" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, )),
- "engine-lost" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- }
-
- def __init__(self, name, ibusconn):
- super(InputContext, self).__init__()
- self.__id = "%d" % InputContext.id
- InputContext.id += 1
- self.__ibusconn = ibusconn
- self.__ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
-
- # init default values
- self.__enable = False
- self.__engine = None
- self.__engine_handlers = []
-
- # client state
- self.__aux_string = None
- self.__aux_attrs = None
- self.__aux_visible = False
-
- # capabitlies
- self.__support_preedit = True
- self.__support_aux_string = False
- self.__support_lookup_table = False
- self.__support_focus = True
-
- self.__preedit_string = None
- self.__preedit_attrs = None
- self.__cursor_pos = 0
- self.__preedit_visible = False
-
- self.__lookup_table = None
- self.__lookup_table_visible = False
-
- def get_id(self):
- return self.__id;
-
- def get_preedit_string(self):
- return self.__preedit_string, self.__preedit_attrs, self.__cursor_pos
-
- def get_aux_string(self):
- return self.__aux_string, self.__aux_attrs
-
- def process_key_event(self, keyval, is_press, state,
- reply_cb, error_cb):
- if self.__engine != None and self.__enable:
- self.__engine.process_key_event(keyval, is_press, state,
- reply_cb, error_cb)
- else:
- reply_cb(False)
-
- def set_cursor_location(self, x, y, w, h):
- if self.__engine:
- self.__engine.set_cursor_location(x, y, w, h)
-
- def focus_in(self):
- if self.__engine and self.__enable:
- self.__engine.focus_in()
-
- def focus_out(self):
- if self.__engine and self.__enable:
- self.__engine.focus_out()
-
- def reset(self):
- if self.__engine and self.__enable:
- self.__engine.reset()
-
- def page_up(self):
- if self.__engine and self.__enable:
- self.__engine.page_up()
-
- def page_down(self):
- if self.__engine and self.__enable:
- self.__engine.page_down()
-
- def cursor_up(self):
- if self.__engine and self.__enable:
- self.__engine.cursor_up()
-
- def cursor_down(self):
- if self.__engine and self.__enable:
- self.__engine.cursor_down()
-
- def property_activate(self, prop_name, prop_state):
- if self.__engine and self.__enable:
- self.__engine.property_activate(prop_name, prop_state)
-
- def property_show(self, prop_name):
- if self.__engine and self.__enable:
- self.__engine.property_show(prop_name)
-
- def property_hide(self, prop_name):
- if self.__engine and self.__enable:
- self.__engine.property_hide(prop_name)
-
- def is_enabled(self):
- return self.__enable
-
- def set_capabilities(self, caps):
- self.__support_preedit = bool(caps & IBUS_CAP_PREEDIT)
- self.__support_aux_string = bool(caps & IBUS_CAP_AUX_STRING)
- self.__support_lookup_table = bool(caps & IBUS_CAP_LOOKUP_TABLE)
- self.__support_focus = bool(caps & IBUS_CAP_FOCUS)
-
- def get_support_focus(self):
- return self.__support_focus
-
- def set_enable(self, enable):
- if self.__enable != enable:
- self.__enable = enable
- if self.__enable:
- self.__ibusconn.emit_dbus_signal("Enabled", self.__id)
- if self.__engine:
- self.__engine.enable()
- self.__engine.focus_in()
- else:
- self.hide_preedit()
- self.__ibusconn.emit_dbus_signal("Disabled", self.__id)
- if self.__engine:
- self.__engine.disable()
-
- def commit_string(self, text):
- self.__ibusconn.emit_dbus_signal("CommitString", self.__id, text)
-
- def update_preedit(self, text, attrs, cursor_pos, visible):
- self.__preedit_string = text
- self.__preedit_attrs = attrs
- self.__cursor_pos = cursor_pos
- self.__preedit_visible = visible
- if self.__support_preedit:
- self.__ibusconn.emit_dbus_signal("UpdatePreedit", self.__id, text, attrs, cursor_pos, visible)
- else:
- # show preedit on panel
- self.emit("update-preedit", text, attrs, cursor_pos, visible)
-
- def show_preedit(self):
- self.__preedit_visible = True
- if self.__support_preedit:
- self.__ibusconn.emit_dbus_signal("ShowPreedit", self.__id)
- else:
- # show preedit on panel
- self.emit("show-preedit")
-
- def hide_preedit(self):
- self.__preedit_visible = False
- if self.__support_preedit:
- self.__ibusconn.emit_dbus_signal("HidePreedit", self.__id)
- else:
- # show preedit on panel
- self.emit("hide-preedit")
-
- def set_engine(self, engine):
- if self.__engine == engine:
- return
-
- if self.__engine != None:
- self.__remove_engine_handlers()
- self.__engine.destroy()
- self.__engine = None
-
- self.__engine = engine
- self.__install_engine_handlers()
-
- def get_engine(self):
- return self.__engine
-
- def get_factory(self):
- if self.__engine:
- return self.__engine.get_factory()
- return None
-
- def __engine_destroy_cb(self, engine):
- if self.__engine == engine:
- self.__remove_engine_handlers()
- self.__engine = None
- self.__enable = False
- if self.__support_preedit:
- self.__ibusconn.emit_dbus_signal("UpdatePreedit",
- self.__id,
- u"",
- ibus.AttrList().to_dbus_value(),
- 0,
- False)
- self.__ibusconn.emit_dbus_signal("Disabled", self.__id)
- self.emit("engine-lost")
-
- def __ibusconn_destroy_cb(self, ibusconn):
- if self.__engine != None:
- self.__remove_engine_handlers()
- self.__engine.destroy()
- self.__engine = None
- self.destroy()
-
- def __commit_string_cb(self, engine, text):
- if not self.__enable:
- return
- self.commit_string(text)
-
- def __update_preedit_cb(self, engine, text, attrs, cursor_pos, visible):
- if not self.__enable:
- return
- self.update_preedit(text, attrs, cursor_pos, visible)
-
- def __show_preedit_cb(self, engine):
- if not self.__enable:
- return
- self.show_preedit()
-
- def __hide_preedit_cb(self, engine):
- if not self.__enable:
- return
- self.hide_preedit()
-
- def __update_aux_string_cb(self, engine, text, attrs, visible):
- if not self.__enable:
- return
- self.__aux_string = text
- self.__aux_attrs = attrs
- self.__aux_visible = visible
-
- if self.__support_aux_string:
- self.__ibusconn.emit_dbus_signal("UpdateAuxString", self.__id, text, attrs, visible)
- else:
- self.emit("update-aux-string", text, attrs, visible)
-
- def __show_aux_string_cb(self, engine):
- if not self.__enable:
- return
- self.__aux_visible = True
-
- if self.__support_aux_string:
- self.__ibusconn.emit_dbus_signal("ShowAuxString", self.__id)
- else:
- self.emit("show-aux-string")
-
- def __hide_aux_string_cb(self, engine):
- if not self.__enable:
- return
- self.__aux_visible = False
-
- if self.__support_aux_string:
- self.__ibusconn.emit_dbus_signal("HideAuxString", self.__id)
- else:
- self.emit("hide-aux-string")
-
- def __update_lookup_table_cb(self, engine, lookup_table, visible):
- if not self.__enable:
- return
- self.__lookup_table = lookup_table
- self.__lookup_table_visible = visible
-
- if self.__support_lookup_table:
- self.__ibusconn.emit_dbus_signal("UpdateLookupTable", self.__id, lookup_table, visible)
- else:
- self.emit("update-lookup-table", lookup_table, visible)
-
- def __show_lookup_table_cb(self, engine):
- if not self.__enable:
- return
- self.__lookup_table_visible = True
-
- if self.__support_lookup_table:
- self.__ibusconn.emit_dbus_signal("ShowLookupTable", self.__id)
- else:
- self.emit("show-lookup-table")
-
- def __hide_lookup_table_cb(self, engine):
- if not self.__enable:
- return
- self.__lookup_table_visible = False
-
- if self.__support_lookup_table:
- self.__ibusconn.emit_dbus_signal("HideLookupTable", self.__id)
- else:
- self.emit("hide-lookup-table")
-
- def __page_up_lookup_table_cb(self, engine):
- if not self.__enable:
- return
-
- if self.__support_lookup_table:
- self.__ibusconn.emit_dbus_signal("PageUpLookupTable", self.__id)
- else:
- self.emit("page-up-lookup-table")
-
- def __page_down_lookup_table_cb(self, engine):
- if not self.__enable:
- return
-
- if self.__support_lookup_table:
- self.__ibusconn.emit_dbus_signal("PageDownLookupTable", self.__id)
- else:
- self.emit("page-down-lookup-table")
-
- def __cursor_up_lookup_table_cb(self, engine):
- if not self.__enable:
- return
-
- if self.__support_lookup_table:
- self.__ibusconn.emit_dbus_signal("CursorUpLookupTable", self.__id)
- else:
- self.emit("cursor-up-lookup-table")
-
- def __cursor_down_lookup_table_cb(self, engine):
- if not self.__enable:
- return
-
- if self.__support_lookup_table:
- self.__ibusconn.emit_dbus_signal("CursorDownLookupTable", self.__id)
- else:
- self.emit("cursor-down-lookup-table")
-
- def __register_properties_cb(self, engine, props):
- if not self.__enable:
- return
- self.emit("register-properties", props)
-
- def __update_property_cb(self, engine, prop):
- if not self.__enable:
- return
- self.emit("update-property", prop)
-
- def __remove_engine_handlers(self):
- assert self.__engine != None
-
- map(self.__engine.disconnect, self.__engine_handlers)
- del self.__engine_handlers[:]
-
- def __install_engine_handlers(self):
- signals = (
- ("destroy", self.__engine_destroy_cb),
- ("commit-string", self.__commit_string_cb),
- ("update-preedit", self.__update_preedit_cb),
- ("show-preedit", self.__show_preedit_cb),
- ("hide-preedit", self.__hide_preedit_cb),
- ("update-aux-string", self.__update_aux_string_cb),
- ("show-aux-string", self.__show_aux_string_cb),
- ("hide-aux-string", self.__hide_aux_string_cb),
- ("update-lookup-table", self.__update_lookup_table_cb),
- ("show-lookup-table", self.__show_lookup_table_cb),
- ("hide-lookup-table", self.__hide_lookup_table_cb),
- ("page-up-lookup-table", self.__page_up_lookup_table_cb),
- ("page-down-lookup-table", self.__page_down_lookup_table_cb),
- ("cursor-up-lookup-table", self.__cursor_up_lookup_table_cb),
- ("cursor-down-lookup-table", self.__cursor_down_lookup_table_cb),
- ("register-properties", self.__register_properties_cb),
- ("update-property", self.__update_property_cb)
- )
-
- for signal, handler in signals:
- id = self.__engine.connect(signal, handler)
- self.__engine_handlers.append(id)
-
-gobject.type_register(InputContext)
diff --git a/daemon/lookuptable.py b/daemon/lookuptable.py
deleted file mode 100644
index 02d2cbc..0000000
--- a/daemon/lookuptable.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import dbus
-
-class Candidates(list):
- SIGNATURE = "a(saau)"
- def to_dbus_value(self):
- value = dbus.Array(signature = "(saau)")
- for text, attrs in self:
- value.append((text, attrs.to_dbus_value()), "(s%s)" % attrs.SIGNATURE)
-
- def from_dbus_value(self):
- pass
-
-class LookupTable(object):
- SIGNATURE = "(ibia(saau))"
-
- def __init__(self, page_size = 5):
- self._page_size = page_size
- self._cursor_visible = False
- self._cursor_pos = 0
- self._candidates = []
-
- def set_page_size(self, page_size):
- self._page_size = page_size
-
- def get_page_size(self):
- return self._page_size
-
- def show_cursor(self):
- self._cursor_visible = True
-
- def hide_cursor(self):
- self._cursor_visible = False
-
- def is_cursor_visible(self):
- return self._cursor_visible
-
- def get_current_page_start(self):
- return(self._cursor_pos / self._page_size) * self._page_size
-
- def set_cursor_pos(self, pos):
- self._current_pos = pos
-
- def get_cursor_pos(self):
- return self._current_pos
-
- def get_cursor_pos_in_current_page(self):
- return self._current_pos % self._page_size
-
- def page_up(self):
- pass
-
- def page_down(self):
- pass
-
- def cursor_up(self):
- pass
-
- def cursor_down(self):
- pass
-
- def clear(self):
- self._candidates = []
-
- def append_candidate(self, candidate, attrs = None):
- self._candidates.append((candidates, attrs))
-
- def get_candidate(self, index):
- return self._candidates[index]
-
- def to_dbus_struct(self):
- pass
-
- def from_dbus_struct(self, value):
- pass
diff --git a/daemon/notifications.py b/daemon/notifications.py
deleted file mode 100644
index 370bdac..0000000
--- a/daemon/notifications.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import gobject
-import ibus
-
-class Notifications(ibus.Object):
- __gsignals__ = {
- "notification-closed" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_UINT, gobject.TYPE_UINT)),
- "action-invoked" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_UINT, gobject.TYPE_STRING)),
- }
-
- def __init__(self, ibusconn):
- super(Notifications, self).__init__()
- self.__ibusconn = ibusconn
- self.__notifications = self.__ibusconn.get_object(ibus.IBUS_NOTIFICATIONS_PATH)
-
- self.__ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
- self.__ibusconn.connect("dbus-signal", self.__dbus_signal_cb)
-
- def notify(self, replaces_id, app_icon, summary, body, actions, expire_timeout):
- id = self.__notifications.Notify(
- replaces_id, app_icon, summary, body, actions, expire_timeout)
- return id
-
- def close_notification(self, id):
- return self.__notifications.CloseNotifications(id)
-
- def __dbus_signal_cb(self, ibusconn, message):
- if message.is_signal(ibus.IBUS_NOTIFICATIONS_IFACE, "NotificationsClosed"):
- args = message.get_args_list()
- self.emit("notifications-closed", args[0], args[1])
- elif message.is_signal(ibus.IBUS_NOTIFICATIONS_IFACE, "ActionInvoked"):
- args = message.get_args_list()
- self.emit("action-invoked", args[0], args[1])
- else:
- return False
- ibusconn.stop_emission("dbus-signal")
- return False
-
- def __ibusconn_destroy_cb(self, ibusconn):
- self.__ibusconn = None
- self.destroy()
-
-gobject.type_register(Notifications)
-
-
-class DummyNotifications(ibus.Object):
- __gsignals__ = {
- "notification-closed" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_UINT, gobject.TYPE_UINT)),
- "action-invoked" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_UINT, gobject.TYPE_STRING)),
- }
-
- def notify(self, replaces_id, app_icon, summary, body, actions, expire_timeout):
- return 0
-
- def close_notification(self, id):
- pass
-
-gobject.type_register(DummyNotifications)
-
-
diff --git a/daemon/panel.py b/daemon/panel.py
deleted file mode 100644
index aee1185..0000000
--- a/daemon/panel.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import gobject
-import ibus
-
-class Panel(ibus.Object):
- __gsignals__ = {
- "page-up" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "page-down" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "cursor-up" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "cursor-down" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "property-activate" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_INT)),
- "property-show" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )),
- "property-hide" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )),
- }
-
- def __init__(self, ibusconn):
- super(Panel, self).__init__()
- self.__ibusconn = ibusconn
- self.__panel = self.__ibusconn.get_object(ibus.IBUS_PANEL_PATH)
-
- self.__ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
- self.__ibusconn.connect("dbus-signal", self.__dbus_signal_cb)
-
- def set_cursor_location(self, x, y, w, h):
- self.__panel.SetCursorLocation(x, y, w, h,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def update_preedit(self, text, attrs, cursor_pos, visible):
- self.__panel.UpdatePreedit(text, attrs, cursor_pos, visible,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def show_preedit(self):
- self.__panel.ShowPreedit(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def hide_preedit(self):
- self.__panel.HidePreedit(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def update_aux_string(self, text, attrs, visible):
- self.__panel.UpdateAuxString(text, attrs, visible,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def show_aux_string(self):
- self.__panel.ShowAuxString(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def hide_aux_string(self):
- self.__panel.HideAuxString(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def update_lookup_table(self, lookup_table, visible):
- self.__panel.UpdateLookupTable(lookup_table, visible,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def show_lookup_table(self):
- self.__panel.ShowLookupTable(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def hide_lookup_table(self):
- self.__panel.HideLookupTable(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def page_up_lookup_table(self):
- self.__panel.PageUpLookupTable(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def page_down_lookup_table(self):
- self.__panel.PageDownLookupTable(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def cursor_up_lookup_table(self):
- self.__panel.CursorUpLookupTable(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def cursor_down_lookup_table(self):
- self.__panel.CursorDownLookupTable(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def register_properties(self, props):
- self.__panel.RegisterProperties(props,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def update_property(self, prop):
- self.__panel.UpdateProperty(prop,
- **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def show_language_bar(self):
- self.__panel.ShowLanguageBar(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def hide_language_bar(self):
- self.__panel.HideLanguageBar(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def focus_in(self, ic):
- self.__panel.FocusIn(ic, **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def focus_out(self, ic):
- self.__panel.FocusOut(ic, **ibus.DEFAULT_ASYNC_HANDLERS)
-
- def states_changed(self):
- self.__panel.StatesChanged(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def reset(self):
- self.__panel.Reset(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def start_setup(self):
- self.__panel.StartSetup(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- def destroy(self):
- if self.__ibusconn != None:
- self.__panel.Destroy(**ibus.DEFAULT_ASYNC_HANDLERS)
-
- self.__ibusconn = None
- self.__panel = None
- ibus.Object.destroy(self)
-
- # signal callbacks
- def __ibusconn_destroy_cb(self, ibusconn):
- self.__ibusconn = None
- self.destroy()
-
- def __dbus_signal_cb(self, ibusconn, message):
- if message.is_signal(ibus.IBUS_PANEL_IFACE, "PageUp"):
- self.emit("page-up")
- elif message.is_signal(ibus.IBUS_PANEL_IFACE, "PageDown"):
- self.emit("page-down")
- elif message.is_signal(ibus.IBUS_PANEL_IFACE, "CursorUp"):
- self.emit("cursor-up")
- elif message.is_signal(ibus.IBUS_PANEL_IFACE, "CursorDown"):
- self.emit("cursor-down")
- elif message.is_signal(ibus.IBUS_PANEL_IFACE, "PropertyActivate"):
- args = message.get_args_list()
- self.emit("property-activate", args[0], args[1])
- elif message.is_signal(ibus.IBUS_PANEL_IFACE, "PropertyShow"):
- args = message.get_args_list()
- self.emit("property-show", args[0])
- elif message.is_signal(ibus.IBUS_PANEL_IFACE, "PropertyHide"):
- args = message.get_args_list()
- self.emit("property-hide", args[0])
- else:
- return False
- ibusconn.stop_emission("dbus-signal")
- return True
-
- # methods for cmp
- # def __lt__(self, other):
- # x = self.get_info()
- # y = other.get_info()
- # if x[1] < y[1]: return True
- # if x[1] == y[1]: return x[0] < y[0]
- #
- # def __gt__(self, other):
- # x = self.get_info()
- # y = other.get_info()
- # if x[1] > y[1]: return True
- # if x[1] == y[1]: return x[0] > y[0]
-
-gobject.type_register(Panel)
-
-class DummyPanel(ibus.Object):
- __gsignals__ = {
- "page-up" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "page-down" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "cursor-up" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "cursor-down" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
- "property-activate" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )),
- "property-show" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )),
- "property-hide" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )),
- }
-
- def set_cursor_location(self, x, y, w, h):
- pass
-
- def update_preedit(self, text, attrs, cursor_pos, visible):
- pass
-
- def update_aux_string(self, text, attrs, visible):
- pass
-
- def update_lookup_table(self, lookup_table, visible):
- pass
-
- def register_properties(self, props):
- pass
-
- def update_property(self, prop):
- pass
-
- def show_language_bar(self):
- pass
-
- def hide_language_bar(self):
- pass
-
- def focus_in(self, ic):
- pass
-
- def focus_out(self, ic):
- pass
-
- def states_changed(self):
- pass
-
- def reset(self):
- pass
-
- def start_setup(self):
- pass
-
-gobject.type_register(DummyPanel)
diff --git a/daemon/register.py b/daemon/register.py
deleted file mode 100644
index bfef2b3..0000000
--- a/daemon/register.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import os
-from os import path
-import signal
-import glob
-import ibus
-import locale
-
-locale.setlocale(locale.LC_ALL, "")
-
-LANG = tuple()
-try:
- LANG = locale.getlocale()[0], locale.getlocale()[0].split("_")[0]
-except:
- pass
-
-IBUS_DATAROOTDIR = os.getenv("IBUS_DATAROOTDIR")
-
-class Engine(ibus.Object):
- def __init__(self, name, local_name, lang = "other", icon = "", author = "", credits = "", _exec = "", pid = 0):
- super(Engine, self).__init__()
- self.name = name
- self.local_name = local_name
- self.lang = lang
- self.icon = icon
- self.author = author
- self.credits = credits
- self._exec = _exec
- self.pid = pid
-
- def start(self):
- if self.pid != 0:
- return
- pid = os.fork()
- if pid > 0: # parent
- self.pid = pid
- elif pid == 0: # child
- os.setpgrp()
- args = self._exec.split()
- os.execv(args[0], args)
- sys.exit(1)
-
- def stop(self, force = False):
- if self.pid == 0:
- return
- try:
- if force:
- os.kill(-self.pid, signal.SIGKILL)
- else:
- os.kill(-self.pid, signal.SIGTERM)
- except:
- pass
-
- def engine_exit(self, pid):
- if self.pid == pid:
- self.pid = 0
- return True
- return False
-
- def __eq__(self, o):
- # We don't test icon author & credits
- return self.name == o.name and \
- self.lang == o.lang and \
- self._exec == o._exec
-
- def __str__(self):
- return "Engine('%s', '%s', '%s', '%s', '%s', '%s', '%s', %d" % (self.name, self.local_name, self.lang, \
- self.icon, self.author, \
- self.credits, self._exec, \
- self.pid)
-
-class Register(ibus.Object):
- def __init__(self):
- super(Register, self).__init__()
- self.__engines = dict()
- self.__load()
- signal.signal(signal.SIGCHLD, self.__sigchld_cb)
-
- def start_engine(self, lang, name):
- key = (lang, name)
- if key not in self.__engines:
- raise ibus.IBusException("Can not find engine(%s, %s)" % (lang, name))
-
- engine = self.__engines[(lang, name)]
- engine.start()
-
- def stop_engine(self, lang, name):
- key = (lang, name)
- if key not in self.__engines:
- raise ibus.IBusException("Can not find engine(%s, %s)" % (lang, name))
-
- engine = self.__engines[(lang, name)]
- engine.stop()
-
- def restart_engine(self, lang, name):
- key = (lang, name)
- if key not in self.__engines:
- raise ibus.IBusException("Can not find engine (%s, %s)" % (lang, name))
-
- engine = self.__engines[(lang, name)]
- engine.stop()
- engine.start()
-
- def list_engines(self):
- engines = []
- for key, e in self.__engines.items():
- engines.append((e.name, e.local_name, e.lang, e.icon, e.author, e.credits, e._exec, e.pid != 0))
- return engines
-
- def reload_engines(self):
- self.__load()
-
- def __sigchld_cb(self, sig, f):
- pid, state = os.wait()
- for key, engine in self.__engines.items():
- if engine.engine_exit(pid):
- break
-
- def __load(self):
- _dir = path.join(IBUS_DATAROOTDIR, "ibus/engine")
- for _file in glob.glob(_dir + "/*.engine"):
- engine = self.__load_engine(_file)
- if (engine.lang, engine.name) in self.__engines:
- old_engine = self.__engines[(engine.lang, engine.name)]
- if old_engine == engine:
- engine.pid = old_engine.pid
- self.__engines[(engine.lang, engine.name)] = engine
- else:
- self.__engines[(engine.lang, engine.name + " (old)")] = old_engine
- self.__engines[(engine.lang, engine.name)] = engine
- else:
- self.__engines[(engine.lang, engine.name)] = engine
-
-
-
- def __load_engine(self, _file):
- f = file(_file)
- name = None
- local_name = None
- lang = "other"
- icon = ""
- author = ""
- credits = ""
- _exec = None
- line = 0
- for l in f:
- line += 1
- l = l.strip()
- if l.startswith("#"):
- continue
- n, v = l.split("=")
- if n == "Name":
- name = v
- if local_name == None:
- local_name = name
- elif n.startswith("Name."):
- if n[5:] in LANG:
- local_name = v
- elif n == "Lang":
- lang = v
- elif n == "Icon":
- icon = v
- elif n == "Author":
- author = v
- elif n == "Credits":
- credits = v
- elif n == "Exec":
- _exec = v
- else:
- raise Exception("%s:%d\nUnknown value name = %s" % (_file, line, n))
-
- if name == None:
- raise Exception("%s: no name" % _file)
- if _exec == None:
- raise Exception("%s: no exec" % _file)
-
- return Engine(name, local_name, lang, icon, author, credits, _exec)
-
-if __name__ == "__main__":
- import time
- reg = Register()
- reg.start_engine("zh", "py")
- time.sleep(3)
- reg.stop_engine("zh", "py")
-
diff --git a/gconf/ibus-gconf.in b/docs/Makefile.am
index c1fcf8b..c23ca9e 100644
--- a/gconf/ibus-gconf.in
+++ b/docs/Makefile.am
@@ -1,4 +1,4 @@
-#!/bin/sh
+# vim:set noet ts=4:
#
# ibus - The Input Bus
#
@@ -19,6 +19,6 @@
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307 USA
-export IBUS_PREFIX=@prefix@
-exec python @prefix@/share/ibus/gconf/main.py $@
-
+SUBDIRS = \
+ reference \
+ $(NULL)
diff --git a/daemon/ibus-daemon.in b/docs/reference/Makefile.am
index a572c8b..70fe792 100644
--- a/daemon/ibus-daemon.in
+++ b/docs/reference/Makefile.am
@@ -1,4 +1,4 @@
-#!/bin/sh
+# vim:set noet ts=4:
#
# ibus - The Input Bus
#
@@ -19,7 +19,6 @@
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307 USA
-prefix=@prefix@
-export IBUS_DATAROOTDIR=@datarootdir@
-exec python @prefix@/share/@PACKAGE@/daemon/ibusdaemon.py $@
-
+SUBDIRS = \
+ ibus \
+ $(NULL)
diff --git a/docs/reference/ibus/.gitignore b/docs/reference/ibus/.gitignore
new file mode 100644
index 0000000..00b86a9
--- /dev/null
+++ b/docs/reference/ibus/.gitignore
@@ -0,0 +1,24 @@
+ibus-decl-list.txt
+ibus-decl.txt
+ibus-overrides.txt
+ibus-sections.txt
+ibus-undeclared.txt
+ibus-undocumented.txt
+ibus-unused.txt
+html
+tmpl
+xml
+html-build.stamp
+html.stamp
+ibus-docs.sgml
+ibus.args
+ibus.hierarchy
+ibus.interfaces
+ibus.prerequisites
+ibus.signals
+scan-build.stamp
+sgml-build.stamp
+sgml.stamp
+tmpl-build.stamp
+tmpl.stamp
+
diff --git a/docs/reference/ibus/Makefile.am b/docs/reference/ibus/Makefile.am
new file mode 100644
index 0000000..65065c9
--- /dev/null
+++ b/docs/reference/ibus/Makefile.am
@@ -0,0 +1,101 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=ibus
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=$(top_srcdir)/src
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=--rebuild-sections
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=
+CFILE_GLOB=
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files=
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+CFLAGS = \
+ @GLIB2_CFLAGS@ \
+ @GOBJECT2_CFLAGS@ \
+ @GIO2_CFLAGS@ \
+ @DBUS_CFLAGS@ \
+ $(NULL)
+LDFLAGS = \
+ @GLIB2_LIBS@ \
+ @GOBJECT2_LIBS@ \
+ @GIO2_LIBS@ \
+ @DBUS_LIBS@ \
+ $(NULL)
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+INCLUDES=-I$(top_srcdir)/src
+GTKDOC_LIBS=$(top_builddir)/src/libibus.la
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST +=
+
+# Files not to distribute
+# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
+# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
+#DISTCLEANFILES +=
+
+# Comment this out if you want your docs-status tested during 'make check'
+#TESTS = $(GTKDOC_CHECK)
+
+CLEANFILES += ibus*
diff --git a/docs/reference/ibus/ibus.types b/docs/reference/ibus/ibus.types
new file mode 100644
index 0000000..130545b
--- /dev/null
+++ b/docs/reference/ibus/ibus.types
@@ -0,0 +1,29 @@
+ibus_factory_get_type
+ibus_factory_info_get_type
+ibus_attribute_get_type
+ibus_attr_list_get_type
+ibus_input_context_get_type
+ibus_observed_path_get_type
+ibus_engine_get_type
+ibus_service_get_type
+ibus_lookup_table_get_type
+ibus_proxy_get_type
+ibus_server_get_type
+ibus_object_flags_get_type
+ibus_attr_type_get_type
+ibus_attr_underline_get_type
+ibus_prop_type_get_type
+ibus_prop_state_get_type
+ibus_modifier_type_get_type
+ibus_capabilite_get_type
+ibus_component_get_type
+ibus_connection_get_type
+ibus_property_get_type
+ibus_prop_list_get_type
+ibus_text_get_type
+ibus_serializable_get_type
+ibus_hotkey_profile_get_type
+ibus_bus_get_type
+ibus_engine_desc_get_type
+ibus_object_get_type
+ibus_config_get_type
diff --git a/gconf/.gitignore b/gconf/.gitignore
new file mode 100644
index 0000000..9459c62
--- /dev/null
+++ b/gconf/.gitignore
@@ -0,0 +1,2 @@
+ibus-gconf
+gconf.xml
diff --git a/gconf/Makefile.am b/gconf/Makefile.am
index 3175bf2..c0cd889 100644
--- a/gconf/Makefile.am
+++ b/gconf/Makefile.am
@@ -19,22 +19,54 @@
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307 USA
-gconf_PYTHON = \
- config.py \
- main.py \
+libibus = $(top_builddir)/src/libibus.la
+
+INCLUDES = \
+ -I$(top_srcdir)/src \
+ $(NULL)
+
+AM_CFLAGS = \
+ @GLIB2_CFLAGS@ \
+ @GCONF_CFLAGS@ \
+ @DBUS_CFLAGS@ \
+ -DG_LOG_DOMAIN=\"IBUS\" \
+ $(INCLUDES) \
+ $(NULL)
+AM_LDFLAGS = \
+ @GLIB2_LIBS@ \
+ @GCONF_LIBS@ \
+ @DBUS_LIBS@ \
+ $(libibus) \
+ $(NULL)
+
+libexec_PROGRAMS = \
+ ibus-gconf \
$(NULL)
-gconfdir = $(pkgdatadir)/gconf
+ibus_gconf_SOURCES = \
+ main.c \
+ config.c \
+ config.h \
+ $(NULL)
+ibus_gconf_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(NULL)
+ibus_gconf_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ $(NULL)
-bin_SCRIPTS = ibus-gconf
+component_DATA = \
+ gconf.xml \
+ $(NULL)
+componentdir = $(pkgdatadir)/component
CLEANFILES = \
*.pyc \
$(NULL)
EXTRA_DIST = \
- ibus-gconf.in \
+ gconf.xml.in \
$(NULL)
-test:
- $(ENV) PYTHONPATH=$(top_srcdir) $(PYTHON) $(srcdir)/main.py
+$(libibus):
+ $(MAKE) -C $(top_builddir)/src
diff --git a/gconf/config.c b/gconf/config.c
new file mode 100644
index 0000000..a7fa394
--- /dev/null
+++ b/gconf/config.c
@@ -0,0 +1,312 @@
+/* vim:set et sts=4: */
+
+#include <string.h>
+#include <ibus.h>
+#include "config.h"
+
+#define GCONF_PREFIX "/desktop/ibus"
+
+/* functions prototype */
+static void ibus_config_gconf_class_init (IBusConfigGConfClass *klass);
+static void ibus_config_gconf_init (IBusConfigGConf *config);
+static void ibus_config_gconf_destroy (IBusConfigGConf *config);
+static gboolean ibus_config_gconf_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value,
+ IBusError **error);
+static gboolean ibus_config_gconf_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value,
+ IBusError **error);
+
+static GConfValue *_to_gconf_value (const GValue *value);
+static void _from_gconf_value (GValue *value,
+ const GConfValue *gvalue);
+
+static IBusConfigServiceClass *parent_class = NULL;
+
+GType
+ibus_config_gconf_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusConfigGConfClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_config_gconf_class_init,
+ NULL,
+ NULL,
+ sizeof (IBusConfigGConf),
+ 0,
+ (GInstanceInitFunc) ibus_config_gconf_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_CONFIG_SERVICE,
+ "IBusConfigGConf",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_config_gconf_class_init (IBusConfigGConfClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = (IBusConfigServiceClass *) g_type_class_peek_parent (klass);
+
+ IBUS_OBJECT_CLASS (object_class)->destroy = (IBusObjectDestroyFunc) ibus_config_gconf_destroy;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->set_value = ibus_config_gconf_set_value;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->get_value = ibus_config_gconf_get_value;
+}
+
+static void
+_value_changed_cb (GConfClient *client,
+ const gchar *key,
+ GConfValue *value,
+ IBusConfigGConf *config)
+{
+ gchar *p, *section, *name;
+ GValue v = { 0 };
+
+ p = g_strdup (key);
+ section = p + sizeof (GCONF_PREFIX);
+ name = rindex (p, '/') + 1;
+ *(name - 1) = '\0';
+
+
+ _from_gconf_value (&v, value);
+ ibus_config_service_value_changed ((IBusConfigService *) config,
+ section,
+ name,
+ &v);
+ g_free (p);
+ g_value_unset (&v);
+}
+
+static void
+ibus_config_gconf_init (IBusConfigGConf *config)
+{
+ config->client = gconf_client_get_default ();
+ gconf_client_add_dir (config->client, GCONF_PREFIX, GCONF_CLIENT_PRELOAD_NONE, NULL);
+ g_signal_connect (config->client, "value-changed", G_CALLBACK (_value_changed_cb), config);
+}
+
+static void
+ibus_config_gconf_destroy (IBusConfigGConf *config)
+{
+ if (config->client) {
+ g_object_unref (config->client);
+ config->client = NULL;
+ }
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)config);
+}
+
+static GConfValue *
+_to_gconf_value (const GValue *value)
+{
+ GConfValue *gv;
+ GType type = G_VALUE_TYPE (value);
+
+ switch (type) {
+ case G_TYPE_STRING:
+ {
+ gv = gconf_value_new (GCONF_VALUE_STRING);
+ gconf_value_set_string (gv, g_value_get_string (value));
+ }
+ break;
+ case G_TYPE_INT:
+ {
+ gv = gconf_value_new (GCONF_VALUE_INT);
+ gconf_value_set_int (gv, g_value_get_int (value));
+ }
+ break;
+ case G_TYPE_UINT:
+ {
+ gv = gconf_value_new (GCONF_VALUE_INT);
+ gconf_value_set_int (gv, g_value_get_uint (value));
+ }
+ break;
+ case G_TYPE_BOOLEAN:
+ {
+ gv = gconf_value_new (GCONF_VALUE_BOOL);
+ gconf_value_set_bool (gv, g_value_get_boolean (value));
+ }
+ break;
+ case G_TYPE_DOUBLE:
+ {
+ gv = gconf_value_new (GCONF_VALUE_FLOAT);
+ gconf_value_set_float (gv, g_value_get_double (value));
+ }
+ break;
+ case G_TYPE_FLOAT:
+ {
+ gv = gconf_value_new (GCONF_VALUE_FLOAT);
+ gconf_value_set_float (gv, g_value_get_float (value));
+ }
+ break;
+ default:
+ if (type == G_TYPE_VALUE_ARRAY) {
+
+ GSList *l = NULL;
+ GType list_type = G_TYPE_STRING;
+ GValueArray *array = g_value_get_boxed (value);
+ gint i;
+
+ if (array && array->n_values > 0) {
+ list_type = G_VALUE_TYPE (&(array->values[0]));
+ }
+
+ gv = gconf_value_new (GCONF_VALUE_LIST);
+
+ switch (list_type) {
+ case G_TYPE_STRING:
+ gconf_value_set_list_type (gv, GCONF_VALUE_STRING); break;
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ gconf_value_set_list_type (gv, GCONF_VALUE_INT); break;
+ case G_TYPE_BOOLEAN:
+ gconf_value_set_list_type (gv, GCONF_VALUE_BOOL); break;
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE:
+ gconf_value_set_list_type (gv, GCONF_VALUE_FLOAT); break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ for (i = 0; array && i < array->n_values; i++) {
+ GConfValue *tmp;
+ g_assert (G_VALUE_TYPE (&(array->values[i])) == list_type);
+ tmp = _to_gconf_value (&(array->values[i]));
+ l = g_slist_append (l, tmp);
+ }
+ gconf_value_set_list_nocopy (gv, l);
+ }
+ else
+ g_assert_not_reached ();
+ }
+ return gv;
+}
+
+static void
+_from_gconf_value (GValue *value,
+ const GConfValue *gv)
+{
+ g_assert (value);
+ g_assert (gv);
+
+ switch (gv->type) {
+ case GCONF_VALUE_STRING:
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, gconf_value_get_string (gv));
+ return;
+ case GCONF_VALUE_INT:
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, gconf_value_get_int (gv));
+ return;
+ case GCONF_VALUE_FLOAT:
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, gconf_value_get_float (gv));
+ return;
+ case GCONF_VALUE_BOOL:
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, gconf_value_get_bool (gv));
+ return;
+ case GCONF_VALUE_LIST:
+ {
+ g_value_init (value, G_TYPE_VALUE_ARRAY);
+
+ GSList *list, *p;
+ GValueArray *va;
+
+ list = gconf_value_get_list (gv);
+ va = g_value_array_new (g_slist_length (list));
+ for (p = list; p != NULL; p = p->next) {
+ GValue tmp = {0};
+ _from_gconf_value (&tmp, (GConfValue *) p->data);
+ g_value_array_append (va, &tmp);
+ }
+
+ g_value_take_boxed (value, va);
+ }
+ return;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+
+static gboolean
+ibus_config_gconf_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value,
+ IBusError **error)
+{
+ gchar *key;
+ GConfValue *gv;
+ GError *gerror = NULL;
+
+ gv = _to_gconf_value (value);
+
+ key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
+
+ gconf_client_set (((IBusConfigGConf *)config)->client, key, gv, &gerror);
+ g_free (key);
+ gconf_value_free (gv);
+
+ if (gerror != NULL) {
+ if (error) {
+ *error = ibus_error_new_from_text (DBUS_ERROR_FAILED, gerror->message);
+ g_error_free (gerror);
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+static gboolean
+ibus_config_gconf_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value,
+ IBusError **error)
+{
+ gchar *key;
+ GConfValue *gv;
+
+ key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
+
+ gv = gconf_client_get (((IBusConfigGConf *) config)->client, key, NULL);
+ g_free (key);
+
+ if (gv == NULL) {
+ *error = ibus_error_new_from_printf (DBUS_ERROR_FAILED,
+ "Can not get value [%s->%s]", section, name);
+ return FALSE;
+ }
+
+ _from_gconf_value (value, gv);
+ gconf_value_free (gv);
+ return TRUE;
+}
+
+IBusConfigGConf *
+ibus_config_gconf_new (IBusConnection *connection)
+{
+ IBusConfigGConf *config;
+
+ config = (IBusConfigGConf *) g_object_new (IBUS_TYPE_CONFIG_GCONF,
+ "path", IBUS_PATH_CONFIG,
+ "connection", connection,
+ NULL);
+ return config;
+}
diff --git a/gconf/config.py b/gconf/config.py
deleted file mode 100644
index e0a3af8..0000000
--- a/gconf/config.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# vim:set et sts=4 sw=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
-
-__all__ = (
- "Config",
-)
-
-import gobject
-try:
- import gconf
-except:
- from ibus import gconf
-import dbus
-import ibus
-
-GCONF_IBUS_PATH = "/desktop/ibus"
-
-class Config(ibus.ConfigBase):
- __gsignals__ = {
- "value-changed" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)),
- }
-
- def __init__ (self, bus):
- super(Config, self).__init__(bus)
- self.__client = gconf.Client()
- self.__handler_id = self.__client.connect("value-changed", self.__value_changed_cb)
- self.__client.add_dir(GCONF_IBUS_PATH, gconf.CLIENT_PRELOAD_NONE)
-
- def get_value(self, section, name):
- key = "/".join([GCONF_IBUS_PATH, section, name])
- value = self.__client.get(key)
- if value == None:
- raise ibus.IBusException("key = \"%s\" does not exist" % key)
- return self.__to_py_value(value)
-
- def set_value(self, section, name, value):
- key = "/".join([GCONF_IBUS_PATH, section, name])
- value = self.__to_gconf_value(value)
- self.__client.set(key, value)
-
- def do_destroy(self):
- if self.__client:
- self.__client.disconnect(self.__handler_id)
- self.__client = None
- super(Config, self).do_destroy()
-
- def __to_py_value(self, value):
- if value == None:
- return None
- if value.type == gconf.VALUE_STRING:
- return unicode(value.get_string(), "utf-8")
- if value.type == gconf.VALUE_INT:
- return value.get_int()
- if value.type == gconf.VALUE_FLOAT:
- return value.get_float()
- if value.type == gconf.VALUE_BOOL:
- return value.get_bool()
- if value.type == gconf.VALUE_PAIR:
- return (self.__to_py_value(value.get_car()), self.__to_py_value(value.get_cdr()))
- if value.type == gconf.VALUE_LIST:
- signatures = {
- gconf.VALUE_STRING: "s",
- gconf.VALUE_INT: "i",
- gconf.VALUE_FLOAT: "d",
- gconf.VALUE_BOOL: "b",
- }
- return dbus.Array(map(self.__to_py_value, value.get_list()), signature=signatures.get(value.get_list_type(), "v"))
- raise ibus.IBusException("Do not support type == %s" % str(value.type))
-
- def __to_gconf_value(self, value):
- if isinstance(value, str):
- ret = gconf.Value(gconf.VALUE_STRING)
- ret.set_string(value)
- elif isinstance(value, unicode):
- ret = gconf.Value(gconf.VALUE_STRING)
- ret.set_string(value.encode("utf-8"))
- elif isinstance(value, bool):
- ret = gconf.Value(gconf.VALUE_BOOL)
- ret.set_bool(value)
- elif isinstance(value, int):
- ret = gconf.Value(gconf.VALUE_INT)
- ret.set_int(value)
- elif isinstance(value, float):
- ret = gconf.Value(gconf.VALUE_FLOAT)
- ret.set_float(value)
- elif isinstance(value, tuple):
- if len(value) != 2:
- raise ibus.IBusException("Pair must have two value")
- ret = gconf.Value(gconf.VALUE_PAIR)
- ret.set_car(self.__to_gconf_value(value[0]))
- ret.set_cdr(self.__to_gconf_value(value[1]))
- elif isinstance(value, list):
- ret = gconf.Value(gconf.VALUE_LIST)
- if len(value) > 0:
- value = map(self.__to_gconf_value, value)
- _type = value[0].type
- if any(map(lambda x: x.type != _type, value)):
- raise ibus.IBusException("Items of a list must be in same type")
- ret.set_list_type(_type)
- ret.set_list(value)
- elif len(value) == 0 and isinstance(value, dbus.Array):
- if value.signature == "i":
- ret.set_list_type(gconf.VALUE_INT)
- elif value.signature == "s":
- ret.set_list_type(gconf.VALUE_STRING)
- elif value.signature == "d":
- ret.set_list_type(gconf.VALUE_FLOAT)
- elif value.signature == "b":
- ret.set_list_type(gconf.VALUE_BOOL)
- else:
- pass
- else:
- raise ibus.IBusException("Do not support type of %s." % type(value))
- return ret
-
- def __value_changed_cb(self, gconf, key, value):
- value = self.__client.get(key)
- value = self.__to_py_value(value)
- if value == None:
- value = 0
- elif isinstance(value, list) and len(value) == 0:
- value = dbus.Array(signature="v")
- section_name = key.replace(GCONF_IBUS_PATH + "/", "")
- section_name = section_name.rsplit("/", 1)
- if len(section_name) == 1:
- self.value_changed("", section_name[0], value)
- elif len(section_name) == 2:
- self.value_changed(section_name[0], section_name[1], value)
- else:
- print "Can not process %s" % key
diff --git a/gconf/gconf.xml.in b/gconf/gconf.xml.in
new file mode 100644
index 0000000..e399230
--- /dev/null
+++ b/gconf/gconf.xml.in
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- filename: pinyin.xml -->
+<component>
+ <name>org.freedesktop.IBus.Config</name>
+ <description>GConf Config Component</description>
+ <exec>@prefix@/libexec/ibus-gconf</exec>
+ <version>@VERSION@</version>
+ <author>Peng Huang &lt;shawn.p.huang@gmail.com&gt;</author>
+ <license>GPL</license>
+ <homepage>http://code.google.com/p/ibus</homepage>
+ <textdomain>ibus</textdomain>
+</component>
diff --git a/gconf/main.c b/gconf/main.c
new file mode 100644
index 0000000..b2c6c83
--- /dev/null
+++ b/gconf/main.c
@@ -0,0 +1,65 @@
+/* vim:set et sts=4: */
+
+#include <ibus.h>
+#include <stdlib.h>
+#include <locale.h>
+#include "config.h"
+
+static IBusBus *bus = NULL;
+static IBusConfigGConf *config = NULL;
+
+/* options */
+static gboolean ibus = FALSE;
+static gboolean verbose = FALSE;
+
+static const GOptionEntry entries[] =
+{
+ { "ibus", 'i', 0, G_OPTION_ARG_NONE, &ibus, "component is executed by ibus", NULL },
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "verbose", NULL },
+ { NULL },
+};
+
+
+static void
+ibus_disconnected_cb (IBusBus *bus,
+ gpointer user_data)
+{
+ g_debug ("bus disconnected");
+ ibus_quit ();
+}
+
+static void
+ibus_gconf_start (void)
+{
+ ibus_init ();
+ bus = ibus_bus_new ();
+ if (!ibus_bus_is_connected (bus)) {
+ exit (-1);
+ }
+ g_signal_connect (bus, "disconnected", G_CALLBACK (ibus_disconnected_cb), NULL);
+ config = ibus_config_gconf_new (ibus_bus_get_connection (bus));
+ ibus_bus_request_name (bus, IBUS_SERVICE_CONFIG, 0);
+ ibus_main ();
+}
+
+int
+main (gint argc, gchar **argv)
+{
+ GError *error = NULL;
+ GOptionContext *context;
+
+ setlocale (LC_ALL, "");
+
+ context = g_option_context_new ("- ibus gconf component");
+
+ g_option_context_add_main_entries (context, entries, "ibus-gconf");
+
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_print ("Option parsing failed: %s\n", error->message);
+ exit (-1);
+ }
+
+ ibus_gconf_start ();
+
+ return 0;
+}
diff --git a/gconf/main.py b/gconf/main.py
deleted file mode 100644
index ee8f6eb..0000000
--- a/gconf/main.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# vim:set et sts=4 sw=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
-
-import os
-import sys
-import getopt
-import ibus
-import config
-import gobject
-
-class GconfApplication:
- def __init__(self):
- self.__mainloop = gobject.MainLoop()
- self.__bus = ibus.Bus()
- self.__bus.connect("destroy", self.__bus_destroy_cb)
-
- self.__config = config.Config(self.__bus)
- self.__config.connect("destroy", self.__config_destroy_cb)
- self.__bus.request_name(ibus.IBUS_CONFIG_NAME, 0)
-
- def run(self):
- self.__mainloop.run()
-
- def __config_destroy_cb(self, config):
- self.__mainloop.quit()
-
- def __bus_destroy_cb(self, _ibus):
- print "disconnected"
- self.__mainloop.quit()
-
-
-
-def launch_gconf():
- GconfApplication().run()
-
-def print_help(out, v = 0):
- print >> out, "-h, --help show this message."
- print >> out, "-d, --daemonize daemonize ibus"
- sys.exit(v)
-
-def main():
- daemonize = False
- shortopt = "hd"
- longopt = ["help", "daemonize"]
- try:
- opts, args = getopt.getopt(sys.argv[1:], shortopt, longopt)
- except getopt.GetoptError, err:
- print_help(sys.stderr, 1)
-
- for o, a in opts:
- if o in ("-h", "--help"):
- print_help(sys.stdout)
- elif o in ("-d", "--daemonize"):
- daemonize = True
- else:
- print >> sys.stderr, "Unknown argument: %s" % o
- print_help(sys.stderr, 1)
-
- if daemonize:
- if os.fork():
- sys.exit()
-
- launch_gconf()
-
-if __name__ == "__main__":
- main()
diff --git a/ibus-1.0.pc.in b/ibus-1.0.pc.in
new file mode 100644
index 0000000..9793018
--- /dev/null
+++ b/ibus-1.0.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: IBus
+Description: IBus Library
+Version: @VERSION@
+Requires: gobject-2.0 dbus-1
+Libs: -L${libdir} -libus
+Cflags: -I${includedir}/ibus-1.0
diff --git a/ibus.spec.in b/ibus.spec.in
index b567c46..65dfced 100644
--- a/ibus.spec.in
+++ b/ibus.spec.in
@@ -13,10 +13,13 @@ Source1: xinput-ibus
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+%define glib_ver %([ -a %{_libdir}/pkgconfig/glib-2.0.pc ] && pkg-config --modversion glib-2.0 | cut -d. -f 1,2 || echo -n "999")
+
BuildRequires: gettext-devel
BuildRequires: libtool
BuildRequires: python
BuildRequires: gtk2-devel
+BuildRequires: dbus-devel
BuildRequires: qt-devel
BuildRequires: dbus-glib-devel
BuildRequires: desktop-file-utils
@@ -26,6 +29,7 @@ Requires(post): %{_sbindir}/alternatives
Requires(postun): desktop-file-utils
Requires(postun): %{_sbindir}/alternatives
+Requires: glib2 >= %{glib_ver}
Requires: pygtk2
Requires: dbus-python >= 0.83.0
Requires: gnome-python2-gconf
@@ -33,6 +37,8 @@ Requires: notification-daemon
Requires: pyxdg
Requires: iso-codes
+%define _xinputconf %{_sysconfdir}/X11/xinit/xinput.d/ibus.conf
+
%description
IBus means Intelligent Input Bus. It is a new input framework for Linux OS. It provides
full featured and user friendly input method user interface. It also may help
@@ -55,7 +61,16 @@ Requires: qt >= 4.4.2
%description qt
This package contains ibus im module for qt4
-%define _xinputconf %{_sysconfdir}/X11/xinit/xinput.d/ibus.conf
+%package devel
+Summary: Development tools for ibus
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+Requires: glib2-devel
+Requires: dbus-devel
+
+%description devel
+The ibus-devel package contains the header files and developer
+docs for ibus.
%prep
%setup -q
@@ -68,8 +83,7 @@ make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
make DESTDIR=${RPM_BUILD_ROOT} install
-rm -f $RPM_BUILD_ROOT%{_libdir}/libibus-gtk.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/libibus-gtk.so
+rm -f $RPM_BUILD_ROOT%{_libdir}/libibus.la
rm -f $RPM_BUILD_ROOT%{_libdir}/gtk-2.0/%{gtk_binary_version}/immodules/im-ibus.la
# install xinput config file
@@ -112,26 +126,15 @@ fi
%dir %{python_sitelib}/ibus
%{python_sitelib}/ibus/*
%dir %{_datadir}/ibus/
-%dir %{_datadir}/ibus/daemon/
-%dir %{_datadir}/ibus/gconf/
-%dir %{_datadir}/ibus/ui
-%dir %{_datadir}/ibus/setup/
-%dir %{_datadir}/ibus/engine/
-%dir %{_datadir}/ibus/icons/
-%{_bindir}/ibus
+%{_bindir}/ibus-daemon
%{_bindir}/ibus-setup
-%{_libdir}/libibus-gtk.so*
-%{_datadir}/ibus/daemon/*
-%{_datadir}/ibus/gconf/*
-%{_datadir}/ibus/ui/*
-%{_datadir}/ibus/setup/*
-%{_datadir}/ibus/icons/*
+%{_libdir}/libibus.so*
+%{_datadir}/ibus/*
%{_datadir}/applications/*
%{_datadir}/pixmaps/*
-%{_bindir}/ibus-daemon
-%{_bindir}/ibus-gconf
-%{_bindir}/ibus-ui-gtk
-%{_bindir}/ibus-x11
+%{_libexecdir}/ibus-gconf
+%{_libexecdir}/ibus-ui-gtk
+%{_libexecdir}/ibus-x11
%config %{_xinputconf}
%files gtk
@@ -142,6 +145,13 @@ fi
%defattr(-,root,root,-)
%{_libdir}/qt4/plugins/inputmethods/libibus.so
+%files devel
+%defattr(-,root,root,-)
+%{_libdir}/lib*.so
+%{_includedir}/*
+%{_datadir}/gtk-doc/html/*
+%{_libdir}/pkgconfig/*
+
%changelog
* Thu Aug 07 2008 Huang Peng <shawn.p.huang@gmail.com> - @VERSION@-1
- The first version.
diff --git a/ibus/.gitignore b/ibus/.gitignore
new file mode 100644
index 0000000..56b6ff1
--- /dev/null
+++ b/ibus/.gitignore
@@ -0,0 +1 @@
+_config.py
diff --git a/ibus/Makefile.am b/ibus/Makefile.am
index 43b9121..fba01c6 100644
--- a/ibus/Makefile.am
+++ b/ibus/Makefile.am
@@ -28,10 +28,11 @@ ibus_PYTHON = \
attribute.py \
common.py \
bus.py \
+ inputcontext.py \
engine.py \
exception.py \
factory.py \
- gtk.py \
+ _gtk.py \
__init__.py \
keysyms.py \
lang.py \
@@ -41,6 +42,11 @@ ibus_PYTHON = \
panel.py \
notifications.py \
property.py \
+ serializable.py \
+ text.py \
+ component.py \
+ enginedesc.py \
+ observedpath.py \
utility.py \
config.py \
_config.py \
diff --git a/ibus/__init__.py b/ibus/__init__.py
index 401d31b..08432a3 100644
--- a/ibus/__init__.py
+++ b/ibus/__init__.py
@@ -27,6 +27,7 @@ from interface import *
from exception import *
from lookuptable import *
from bus import *
+from inputcontext import *
from lang import *
from utility import *
from engine import *
@@ -34,4 +35,9 @@ from factory import *
from panel import *
from notifications import *
from config import *
+from serializable import *
+from text import *
+from observedpath import *
+from enginedesc import *
+from component import *
from _config import *
diff --git a/ibus/gtk.py b/ibus/_gtk.py
index eb82929..b9874a6 100644
--- a/ibus/gtk.py
+++ b/ibus/_gtk.py
@@ -47,13 +47,13 @@ class PangoAttrList(pango.AttrList):
r = (attr.value & 0x00ff0000) >> 8
g = (attr.value & 0x0000ff00)
b = (attr.value & 0x000000ff) << 8
- pango_attr = pango.AttrForeground(r, g, b,
+ pango_attr = pango.AttrForeground(r, g, b,
start_index, end_index)
elif attr.type == ibus.ATTR_TYPE_BACKGROUND:
r = (attr.value & 0x00ff0000) >> 8
g = (attr.value & 0x0000ff00)
b = (attr.value & 0x000000ff) << 8
- pango_attr = pango.AttrBackground(r, g, b,
+ pango_attr = pango.AttrBackground(r, g, b,
start_index, end_index)
elif attr.type == ibus.ATTR_TYPE_UNDERLINE:
pango_attr = pango.AttrUnderline(int(attr.value),
diff --git a/ibus/attribute.py b/ibus/attribute.py
index 144133a..ef4b6a4 100644
--- a/ibus/attribute.py
+++ b/ibus/attribute.py
@@ -32,12 +32,12 @@ __all__ = (
"AttributeForeground",
"AttributeBackground",
"AttrList",
- "attribute_from_dbus_value",
- "attr_list_from_dbus_value",
"ARGB", "RGB"
)
import dbus
+from exception import IBusException
+from serializable import *
ATTR_TYPE_UNDERLINE = 1
ATTR_TYPE_FOREGROUND = 2
@@ -48,8 +48,10 @@ ATTR_UNDERLINE_SINGLE = 1
ATTR_UNDERLINE_DOUBLE = 2
ATTR_UNDERLINE_LOW = 3
-class Attribute:
- def __init__ (self, type, value, start_index, end_index):
+class Attribute(Serializable):
+ __NAME__ = "IBusAttribute"
+ def __init__ (self, type=0, value=0, start_index=0, end_index=0):
+ super(Attribute, self).__init__()
self.__type = type
self.__value = value
self.__start_index = start_index
@@ -72,30 +74,25 @@ class Attribute:
start_index = property(get_start_index)
end_index = property(get_end_index)
- def to_dbus_value (self):
- values = [dbus.UInt32 (self.__type),
- dbus.UInt32 (self.__value),
- dbus.UInt32 (self.__start_index),
- dbus.UInt32 (self.__end_index)]
- return dbus.Struct (values, signature="uuuu")
-
- def from_dbus_value (self, value):
- if not isinstance (value, dbus.Struct):
- raise dbus.Exception ("Attribute must be dbus.Struct uuuu")
-
- if len (value) != 4 or not all (map (lambda x: isinstance (x, dbus.UInt32), value)):
- raise dbus.Exception ("Attribute must be dbus.Struct uuuu")
-
- self.__type = value[0]
- self.__value = value[1]
- self.__start_index = value[2]
- self.__end_index = value[3]
-
-def attribute_from_dbus_value (value):
- attribute = Attribute (0, 0, 0, 0)
- attribute.from_dbus_value (value)
- return attribute
-
+ def serialize(self, struct):
+ super(Attribute, self).serialize(struct)
+ struct.append (dbus.UInt32(self.__type))
+ struct.append (dbus.UInt32(self.__value))
+ struct.append (dbus.UInt32(self.__start_index))
+ struct.append (dbus.UInt32(self.__end_index))
+
+ def deserialize(self, struct):
+ super(Attribute, self).deserialize(struct)
+ if len(struct) < 4:
+ raise IBusException ("Can not deserialize IBusAttribute")
+
+ self.__type = struct.pop(0)
+ self.__value = struct.pop(0)
+ self.__start_index = struct.pop(0)
+ self.__end_index = struct.pop(0)
+
+serializable_register(Attribute)
+
class AttributeUnderline (Attribute):
def __init__(self, value, start_index, end_index):
Attribute.__init__ (self, ATTR_TYPE_UNDERLINE, value, start_index, end_index)
@@ -114,8 +111,10 @@ def ARGB (a, r, g, b):
def RGB (r, g, b):
return ARGB (255, r, g, b)
-class AttrList:
+class AttrList(Serializable):
+ __NAME__ = "IBusAttrList"
def __init__ (self, attrs = []):
+ super(AttrList, self).__init__()
self._attrs = []
for attr in attrs:
self.append (attr)
@@ -124,29 +123,31 @@ class AttrList:
assert isinstance (attr, Attribute)
self._attrs.append (attr)
- def to_dbus_value (self):
- array = dbus.Array (signature = "v")
- for attr in self._attrs:
- array.append (attr.to_dbus_value ())
- return array
-
- def from_dbus_value (self, value):
- attrs = []
- if not isinstance (value, dbus.Array):
- raise IBusException ("AttrList must from dbus.Array (uuuu)")
-
- for v in value:
- attr = attribute_from_dbus_value (v)
- attrs.append (attr)
+ def serialize (self, struct):
+ super(AttrList, self).serialize (struct)
+ array = map (lambda a: serialize_object(a), self._attrs)
+ array = dbus.Array (array, signature = "v")
+ struct.append(array)
+ def deserialize (self, struct):
+ super(AttrList, self).deserialize(struct)
+ attrs = map(lambda v: deserialize_object(v), struct.pop(0))
self._attrs = attrs
def __iter__ (self):
return self._attrs.__iter__ ()
-def attr_list_from_dbus_value (value):
- if len(value) == 0:
- return None
- attrs = AttrList ()
- attrs.from_dbus_value (value)
- return attrs
+serializable_register(AttrList)
+
+def test():
+ attr_list = AttrList()
+ attr_list.append (Attribute())
+ attr_list.append (Attribute())
+ attr_list.append (Attribute())
+ attr_list.append (Attribute())
+ attr_list.append (Attribute())
+ value = serialize_object(attr_list)
+ attr_list = deserialize_object(value)
+
+if __name__ == "__main__":
+ test()
diff --git a/ibus/bus.py b/ibus/bus.py
index eb708a6..6ca5f7d 100644
--- a/ibus/bus.py
+++ b/ibus/bus.py
@@ -23,95 +23,27 @@ __all__ = (
"Bus",
)
-import sys
-import gobject
import dbus
import dbus.lowlevel
import dbus.connection
import dbus.mainloop.glib
-import ibus
+import gobject
+import common
+import object
+import serializable
+import config
dbus.mainloop.glib.DBusGMainLoop(set_as_default = True)
-class Bus(ibus.Object):
+class Bus(object.Object):
__gsignals__ = {
- "commit-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING)
- ),
- "update-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_INT, gobject.TYPE_BOOLEAN)
- ),
- "show-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "hide-preedit" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "update-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
- ),
- "show-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "hide-aux-string" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "update-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
- ),
- "show-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "hide-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "page-up-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "page-down-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "cursor-up-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "cursor-down-lookup-table" : (
- gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, )
- ),
- "config-value-changed" : (
- gobject.SIGNAL_RUN_FIRST,
+ "disconnected" : (
+ gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
+ ()
),
"config-reloaded" : (
- gobject.SIGNAL_RUN_FIRST,
+ gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
()
),
@@ -119,29 +51,36 @@ class Bus(ibus.Object):
def __init__(self):
super(Bus, self).__init__()
- self.__dbusconn = dbus.connection.Connection(ibus.IBUS_ADDR)
- self.__ibus = self.__dbusconn.get_object(ibus.IBUS_NAME,
- ibus.IBUS_PATH)
+ self.__dbusconn = dbus.connection.Connection(common.IBUS_ADDR)
self.__dbus = self.__dbusconn.get_object(dbus.BUS_DAEMON_NAME,
- dbus.BUS_DAEMON_PATH)
- self.__dbusconn.add_message_filter(self.__dbus_message_cb)
+ dbus.BUS_DAEMON_PATH)
self.__unique_name = self.hello()
+ self.__ibus = self.__dbusconn.get_object(common.IBUS_SERVICE_IBUS,
+ common.IBUS_PATH_IBUS)
- try:
- unique_name = self.get_name_owner(ibus.IBUS_CONFIG_NAME)
- self.__config = self.__dbusconn.get_object(unique_name,
- ibus.IBUS_CONFIG_PATH)
- except:
- self.__config = None
- self.add_match(
- "type='signal',"
- "interface='" + dbus.BUS_DAEMON_IFACE + "',"
- "member='NameOwnerChanged',"
- "arg0='" + ibus.IBUS_CONFIG_NAME + "'")
+ self.__dbusconn.call_on_disconnection(self.__dbusconn_disconnected_cb)
+ # self.__dbusconn.add_message_filter(self.__filter_cb)
+
+ def __filter_cb(self, conn, message):
+ if message.get_type() == 4:
+ print "Signal %s" % message.get_member()
+ print " sender = %s" % message.get_sender()
+ print " path = %s" % message.get_path()
+ return dbus.lowlevel.HANDLER_RESULT_NOT_YET_HANDLED
+
+ def __dbusconn_disconnected_cb(self, dbusconn):
+ assert self.__dbusconn == dbusconn
+ self.__dbusconn = None
+ self.emit("disconnected")
def get_name(self):
return self.__unique_name
+ def get_is_connected(self):
+ if self.__dbusconn == None:
+ return False
+ return self.__dbusconn.get_is_connected()
+
# define dbus methods
def get_dbus(self):
return self.__dbus
@@ -150,7 +89,7 @@ class Bus(ibus.Object):
return self.__dbus.Hello()
def request_name(self, name, flags):
- return self.__dbus.RequestName(name, flags)
+ return self.__dbus.RequestName(name, dbus.UInt32 (flags))
def release_name(self, name):
return self.__dbus.ReleaseName(name)
@@ -168,209 +107,56 @@ class Bus(ibus.Object):
return self.__dbusconn
def get_address(self):
- return ibus.IBUS_ADDR
-
- def create_input_context(self, client_name):
- return self.__ibus.CreateInputContext(client_name)
-
- def release_input_context(self, ic):
- return self.__ibus.ReleaseInputContext(ic)
-
- def process_key_event(self, ic, keyval, is_press, state):
- return self.__ibus.ProcessKeyEvent(ic, keyval, is_press, state)
-
- def set_cursor_location(self, ic, x, y, w, h):
- return self.__ibus.SetCursorLocation(ic, x, y, w, h)
-
- def foucs_in(self, ic):
- return self.__ibus.FocusIn(ic)
-
- def foucs_out(self, ic):
- return self.__ibus.FocusOut(ic)
-
- def reset(self, ic):
- return self.__ibus.Reset(ic)
+ return common.IBUS_ADDR
- def is_enabled(self, ic):
- return self.__ibus.IsEnabled(ic)
+ # define ibus methods
+ def register_component(self, component):
+ component = serializable.serialize_object(component)
+ return self.__ibus.RegisterComponent(component)
- def set_capabilities(self, ic, caps):
- return self.__ibus.SetCapabilities(ic, caps)
+ def list_engines(self):
+ engines = self.__ibus.ListEngines()
+ return map(serializable.deserialize_object, engines)
- def register_factories(self, object_paths):
- object_paths = dbus.Array(object_paths, signature="o")
- return self.__ibus.RegisterFactories(object_paths, **ibus.DEFAULT_ASYNC_HANDLERS)
+ def list_active_engines(self):
+ engines = self.__ibus.ListActiveEngines()
+ return map(serializable.deserialize_object, engines)
- def unregister_factories(self, object_paths):
- return self.__ibus.UnregisterFactories(object_paths)
-
- def register_config(self, object_path, replace = False):
- return self.__ibus.RegisterConfig(object_path, replace)
-
- def get_factories(self):
- return self.__ibus.GetFactories()
-
- def get_factory_info(self, factory_path):
- return self.__ibus.GetFactoryInfo(factory_path)
-
- def set_factory(self, factory_path):
- return self.__ibus.SetFactory(factory_path)
-
- def get_input_context_states(self, ic):
- return self.__ibus.GetInputContextStates(ic)
-
- def config_add_watch(self, section):
- return self.add_match(
- "type='signal',"
- "interface='" + ibus.IBUS_CONFIG_NAME + "',"
- "member='ValueChanged',"
- "arg0='" + section + "'"
- )
+ def create_input_context(self, client_name):
+ return self.__ibus.CreateInputContext(client_name)
- def config_remove_watch(self, section):
- return self.remove_match(
- "type='signal',"
- "interface='" + ibus.IBUS_CONFIG_NAME + "',"
- "member='ValueChanged',"
- "arg0='" + section + "'"
- )
+ def kill(self):
+ return self.__ibus.Kill()
- def config_set_value(self, section, name, value):
- return self.__config.SetValue(section, name, value)
+ def get_config(self):
+ try:
+ return self.__config
+ except:
+ self.__config = config.Config(self)
+ return self.__config
- def config_set_list(self, section, name, value, list_type):
- value = dbus.Array(value, signature = list_type)
- return self.__config.SetValue(section, name, value)
+def test():
+ import glib
+ import factory
+ import text
- def config_get_value(self, section, name, default_value = None):
- try:
- return self.__config.GetValue(section, name)
- except Exception, e:
- return default_value
+ mainloop = glib.MainLoop()
- def register_list_engines(self):
- return self.__ibus.RegisterListEngines()
+ def __disconnected_cb(*args):
+ print "Disconnected", args
+ mainloop.quit()
- def register_reload_engines(self):
- return self.__ibus.RegisterReloadEngines()
+ b = Bus()
+ b.connect("disconnected", __disconnected_cb)
- def register_start_engine(self, lang, name):
- return self.__ibus.RegisterStartEngine(lang, name)
+ print "unique_name =", b.get_name()
- def register_restart_engine(self, lang, name):
- return self.__ibus.RegisterRestartEngine(lang, name)
+ for i in b.list_factories():
+ print i.name
- def register_stop_engine(self, lang, name):
- return self.__ibus.RegisterStopEngine(lang, name)
+ mainloop.run()
+ print "Exit"
- def kill(self):
- return self.__ibus.Kill()
- def __dbus_message_cb(self, conn, message):
- # name owner changed signal
- if message.is_signal(dbus.BUS_DAEMON_IFACE, "NameOwnerChanged"):
- args = message.get_args_list()
- if args[0] == ibus.IBUS_CONFIG_NAME:
- if args[2] != "":
- self.__config = self.__dbusconn.get_object(args[2], ibus.IBUS_CONFIG_PATH)
- else:
- self.__config = None
- self.emit("config-reloaded")
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- # commit string signal
- elif message.is_signal(ibus.IBUS_IFACE, "CommitString"):
- args = message.get_args_list()
- ic, string = args[0:2]
- self.emit("commit-string", ic, string.encode("utf-8"))
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
-
- # preedit signals
- elif message.is_signal(ibus.IBUS_IFACE, "UpdatePreedit"):
- args = message.get_args_list()
- ic, preedit, attrs, cursor_pos, visible = args[0:5]
- attrs = ibus.attr_list_from_dbus_value(attrs)
- self.emit("update-preedit", ic, preedit.encode("utf-8"),
- attrs, cursor_pos, visible)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "ShowPreedit"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("show-preedit", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "HidePreedit"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("hide-preedit", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
-
- # aux string signals
- elif message.is_signal(ibus.IBUS_IFACE, "UpdateAuxString"):
- args = message.get_args_list()
- ic, aux_string, attrs, visible = args[0:4]
- attrs = ibus.attr_list_from_dbus_value(attrs)
- self.emit("update-aux-string", ic, aux_string.encode("utf-8"),
- attrs, visible)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "ShowAuxString"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("show-aux-string", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "HideAuxString"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("hide-aux-string", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
-
- # lookup table signals
- elif message.is_signal(ibus.IBUS_IFACE, "UpdateLookupTable"):
- args = message.get_args_list()
- ic, lookup_table, visible = args[0:3]
- lookup_table = ibus.lookup_table_from_dbus_value(lookup_table)
- self.emit("update-lookup-table", ic, lookup_table, visible)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "ShowLookupTable"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("show-lookup-table", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "HideLookupTable"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("hide-lookup-table", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "PageUpLookupTable"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("page-up-lookup-table", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "PageDownLookupTable"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("page-down-lookup-table", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "CursorUpLookupTable"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("cursor-up-lookup-table", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- elif message.is_signal(ibus.IBUS_IFACE, "CursorDownLookupTable"):
- args = message.get_args_list()
- ic = args[0]
- self.emit("cursor-down-lookup-table", ic)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
-
- # Config signals
- elif message.is_signal(ibus.IBUS_CONFIG_IFACE, "ValueChanged"):
- args = message.get_args_list()
- section, name, value = args[0:3]
- self.emit("config-value-changed", section, name, value)
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
-
- # DBUS Disconnected signal
- elif message.is_signal(dbus.LOCAL_IFACE, "Disconnected"):
- self.destroy()
- retval = dbus.lowlevel.HANDLER_RESULT_HANDLED
- else:
- retval = dbus.lowlevel.HANDLER_RESULT_NOT_YET_HANDLED
- return retval
+if __name__ == "__main__":
+ test()
diff --git a/ibus/common.py b/ibus/common.py
index 60323e4..e9868ee 100644
--- a/ibus/common.py
+++ b/ibus/common.py
@@ -21,14 +21,15 @@
__all__ = (
"IBUS_ADDR",
- "IBUS_IFACE",
- "IBUS_NAME",
- "IBUS_PATH",
- "IBUS_CONFIG_IFACE",
- "IBUS_ENGINE_FACTORY_IFACE",
- "IBUS_ENGINE_IFACE",
- "IBUS_PANEL_IFACE",
- "IBUS_NOTIFICATIONS_IFACE",
+ "IBUS_IFACE_IBUS",
+ "IBUS_SERVICE_IBUS",
+ "IBUS_PATH_IBUS",
+ "IBUS_IFACE_CONFIG",
+ "IBUS_IFACE_PANEL",
+ "IBUS_IFACE_ENGINE",
+ "IBUS_IFACE_ENGINE_FACTORY",
+ "IBUS_IFACE_INPUT_CONTEXT",
+ "IBUS_IFACE_NOTIFICATIONS",
"default_reply_handler",
"default_error_handler",
"DEFAULT_ASYNC_HANDLERS",
@@ -67,15 +68,16 @@ if not __username:
IBUS_ADDR = "unix:path=/tmp/ibus-%s/ibus-%s" % (__username, display.replace(":", "-"))
# IBUS_ADDR = "tcp:host=localhost,port=7799"
-IBUS_IFACE = "org.freedesktop.IBus"
-IBUS_PATH = "/org/freedesktop/IBus"
-IBUS_NAME = "org.freedesktop.IBus"
+IBUS_IFACE_IBUS = "org.freedesktop.IBus"
+IBUS_PATH_IBUS = "/org/freedesktop/IBus"
+IBUS_SERVICE_IBUS = "org.freedesktop.IBus"
-IBUS_CONFIG_IFACE = "org.freedesktop.ibus.Config"
-IBUS_ENGINE_FACTORY_IFACE = "org.freedesktop.ibus.EngineFactory"
-IBUS_ENGINE_IFACE = "org.freedesktop.ibus.Engine"
-IBUS_PANEL_IFACE = "org.freedesktop.ibus.Panel"
-IBUS_NOTIFICATIONS_IFACE = "org.freedesktop.ibus.Notifications"
+IBUS_IFACE_PANEL = "org.freedesktop.IBus.Panel"
+IBUS_IFACE_CONFIG = "org.freedesktop.IBus.Config"
+IBUS_IFACE_ENGINE = "org.freedesktop.IBus.Engine"
+IBUS_IFACE_ENGINE_FACTORY = "org.freedesktop.IBus.EngineFactory"
+IBUS_IFACE_INPUT_CONTEXT = "org.freedesktop.IBus.InputContext"
+IBUS_IFACE_NOTIFICATIONS = "org.freedesktop.IBus.Notifications"
def default_reply_handler( *args):
pass
diff --git a/ibus/component.py b/ibus/component.py
new file mode 100644
index 0000000..afdc152
--- /dev/null
+++ b/ibus/component.py
@@ -0,0 +1,131 @@
+# vim:set et sts=4 sw=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
+
+__all__ = (
+ "Component",
+ )
+
+import dbus
+from exception import IBusException
+from serializable import *
+from enginedesc import *
+from observedpath import *
+
+class Component(Serializable):
+ __NAME__ = "IBusComponent"
+ def __init__ (self, name="", description="", version="", license="", author="", homepage="", _exec="", textdomain=""):
+ super(Component, self).__init__()
+ self.__name = name
+ self.__description = description
+ self.__version = version
+ self.__license = license
+ self.__author = author
+ self.__homepage = homepage
+ self.__exec = _exec
+ self.__textdomain = textdomain
+ self.__observed_paths = []
+ self.__engines = []
+
+ def get_name(self):
+ return self.__name
+
+ def get_description(self):
+ return self.__description
+
+ def get_version(self):
+ return self.__version
+
+ def get_license(self):
+ return self.__license
+
+ def get_author(self):
+ return self.__author
+
+ def get_homepage(self):
+ return self.__homepage
+
+ def get_exec(self):
+ return self.__exec
+
+ def get_textdomain(self):
+ return self.__textdomain
+
+ def get_observed_paths(self):
+ return self.__observed_paths[:]
+
+ def get_engines(self):
+ return self.__engines[:]
+
+ name = property(get_name)
+ description = property(get_description)
+ version = property(get_version)
+ license = property(get_license)
+ author = property(get_author)
+ homepage = property(get_homepage)
+ _exec = property(get_exec)
+ textdomain = property(get_textdomain)
+ observed_paths = property(get_observed_paths)
+ engines = property(get_engines)
+
+ def add_observed_path(self, path):
+ self.__observed_paths.append(ObservedPath(path))
+
+ def add_engine(self, name="", longname="", description="", language="", license="", author="", icon="", layout=""):
+ engine = EngineDesc(name, longname, description, language, license, author, icon, layout)
+ self.__engines.append(engine)
+
+ def serialize(self, struct):
+ super(Component, self).serialize(struct)
+ struct.append (dbus.String(self.__name))
+ struct.append (dbus.String(self.__description))
+ struct.append (dbus.String(self.__version))
+ struct.append (dbus.String(self.__license))
+ struct.append (dbus.String(self.__author))
+ struct.append (dbus.String(self.__homepage))
+ struct.append (dbus.String(self.__exec))
+ struct.append (dbus.String(self.__textdomain))
+ struct.append (dbus.Array(map(serialize_object,self.__observed_paths), signature="v"))
+ struct.append (dbus.Array(map(serialize_object,self.__engines), signature="v"))
+
+ def deserialize(self, struct):
+ super(Component, self).deserialize(struct)
+
+ self.__name = struct.pop(0)
+ self.__description = struct.pop(0)
+ self.__version = struct.pop(0)
+ self.__license = struct.pop(0)
+ self.__author = struct.pop(0)
+ self.__homepage = struct.pop(0)
+ self.__exec = struct.pop(0)
+ self.__textdomain = struct.pop(0)
+
+ self.__observed_paths = map(deserialize_object, struct.pop(0))
+ self.__engines = map(deserialize_object, struct.pop(0))
+
+serializable_register(Component)
+
+def test():
+ text = Component("Hello", "", "", "", "", "", "", "")
+ value = serialize_object(text)
+ text= deserialize_object(value)
+
+if __name__ == "__main__":
+ test()
diff --git a/ibus/config.py b/ibus/config.py
index 24b4edc..70bc89a 100644
--- a/ibus/config.py
+++ b/ibus/config.py
@@ -21,17 +21,20 @@
__all__ = (
"ConfigBase",
- "IBUS_CONFIG_NAME",
- "IBUS_CONFIG_PATH"
+ "IBUS_SERVICE_CONFIG",
+ "IBUS_PATH_CONFIG"
)
-IBUS_CONFIG_NAME = "org.freedesktop.ibus.Config"
-IBUS_CONFIG_PATH = "/org/freedesktop/ibus/Config"
+IBUS_SERVICE_CONFIG = "org.freedesktop.IBus.Config"
+IBUS_PATH_CONFIG = "/org/freedesktop/IBus/Config"
-import ibus
-from ibus import interface
+import gobject
+import object
+import interface
+import dbus
+from dbus.proxies import ProxyObject
-class ConfigBase(ibus.Object):
+class ConfigBase(object.Object):
def __init__(self, bus):
super(ConfigBase, self).__init__()
self.__proxy = ConfigProxy(self, bus.get_dbusconn())
@@ -48,7 +51,7 @@ class ConfigBase(ibus.Object):
class ConfigProxy(interface.IConfig):
def __init__ (self, config, dbusconn):
- super(ConfigProxy, self).__init__(dbusconn, IBUS_CONFIG_PATH)
+ super(ConfigProxy, self).__init__(dbusconn, IBUS_PATH_CONFIG)
self.__dbusconn = dbusconn
self.__config = config
@@ -60,3 +63,80 @@ class ConfigProxy(interface.IConfig):
def Destroy(self):
self.__config.destroy()
+
+class Config(object.Object):
+ __gsignals__ = {
+ "reloaded" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "value-changed" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
+ ),
+ }
+
+ def __init__(self, bus):
+ super(Config, self).__init__()
+ self.__bus = bus
+ self.__bus_name = None
+
+ self.__bus.add_match("type='signal',\
+ sender='org.freedesktop.DBus',\
+ member='NameOwnerChanged',\
+ arg0='org.freedesktop.IBus.Config'")
+ self.__bus.get_dbusconn().add_signal_receiver(self.__name_owner_changed_cb, signal_name="NameOwnerChanged")
+
+ try:
+ self.__init_config()
+ except:
+ self.__config = None
+
+ def __name_owner_changed_cb(self, name, old_name, new_name):
+ if name == "org.freedesktop.IBus.Config":
+ if new_name == "":
+ self.__config = None
+ else:
+ self.__init_config(new_name)
+
+ def __init_config(self, bus_name=None):
+ if bus_name == None:
+ bus_name = self.__bus.get_name_owner(IBUS_SERVICE_CONFIG)
+
+ match_rule = "type='signal',\
+ sender='%s',\
+ member='ValueChanged',\
+ path='/org/freedesktop/IBus/Config'"
+
+ if self.__bus_name:
+ self.__bus.remove_match(match_rule % self.__bus_name)
+ self.__bus_name = None
+
+ self.__config = self.__bus.get_dbusconn().get_object(bus_name, IBUS_PATH_CONFIG)
+ self.__config.connect_to_signal("ValueChanged", self.__value_changed_cb)
+
+ self.__bus_name = bus_name
+ self.__bus.add_match(match_rule % self.__bus_name)
+ self.emit("reloaded")
+
+ def __value_changed_cb(self, section, name, value):
+ self.emit("value-changed", section, name, value)
+
+ def get_value(self, section, name, default_value):
+ try:
+ return self.__config.GetValue(section, name)
+ except:
+ return default_value
+
+ def set_value(self, section, name, value):
+ try:
+ return self.__config.SetValue(section, name, value)
+ except:
+ return
+
+ def set_list(self, section, name, value, signature):
+ return self.set_value(section, name, dbus.Array(value, signature=signature))
+
+gobject.type_register(Config)
diff --git a/ibus/engine.py b/ibus/engine.py
index 9a6a332..d52c97e 100644
--- a/ibus/engine.py
+++ b/ibus/engine.py
@@ -23,15 +23,16 @@ __all__ = (
"EngineBase",
)
-import ibus
-from ibus import interface
+import object
+import serializable
+import interface
-class EngineBase(ibus.Object):
+class EngineBase(object.Object):
def __init__(self, bus, object_path):
super(EngineBase, self).__init__()
self.__proxy = EngineProxy (self, bus.get_dbusconn(), object_path)
- def process_key_event(self, keyval, is_press, state):
+ def process_key_event(self, keyval, state):
return False
def focus_in(self):
@@ -73,39 +74,37 @@ class EngineBase(ibus.Object):
def property_hide(self, prop_name):
pass
- def commit_string(self, text):
- return self.__proxy.CommitString(text)
+ def commit_text(self, text):
+ text = serializable.serialize_object(text)
+ return self.__proxy.CommitText(text)
- def forward_key_event(self, keyval, is_press, state):
- return self.__proxy.ForwardKeyEvent(keyval, is_press, state)
+ def forward_key_event(self, keyval, state):
+ return self.__proxy.ForwardKeyEvent(keyval, state)
- def update_preedit(self, text, attrs, cursor_pos, visible):
- if attrs == None:
- attrs = ibus.AttrList()
- return self.__proxy.UpdatePreedit(text, attrs.to_dbus_value(), cursor_pos, visible)
+ def update_preedit_text(self, text, cursor_pos, visible):
+ text = serializable.serialize_object(text)
+ return self.__proxy.UpdatePreeditText(text, cursor_pos, visible)
- def show_preedit(self):
- return self.__proxy.ShowPreedit()
+ def show_preedit_text(self):
+ return self.__proxy.ShowPreeditText()
- def hide_preedit(self):
- return self.__proxy.HidePreedit()
+ def hide_preedit_text(self):
+ return self.__proxy.HidePreeditText()
- def update_aux_string(self, text, attrs, visible):
- if attrs == None:
- attrs = ibus.AttrList()
- return self.__proxy.UpdateAuxString(text, attrs.to_dbus_value(), visible)
+ def update_auxiliary_text(self, text, visible):
+ text = serializable.serialize_object(text)
+ return self.__proxy.UpdateAuxiliaryText(text, visible)
- def show_aux_string(self):
- return self.__proxy.ShowAuxString()
+ def show_auxiliary_text(self):
+ return self.__proxy.ShowAuxiliaryText()
- def hide_aux_string(self):
- return self.__proxy.HideAuxString()
+ def hide_auxiliary_text(self):
+ return self.__proxy.HideAuxiliaryText()
def update_lookup_table(self, lookup_table, visible, just_current_page = False):
if just_current_page:
- dbus_values = lookup_table.current_page_to_dbus_value()
- else:
- dbus_values = lookup_table.to_dbus_value()
+ lookup_table = lookup_table.get_current_page_as_lookup_table()
+ dbus_values = serializable.serialize_object(lookup_table)
return self.__proxy.UpdateLookupTable(dbus_values, visible)
def show_lookup_table(self):
@@ -127,10 +126,12 @@ class EngineBase(ibus.Object):
return self.__proxy.CursorDownLookupTable()
def register_properties(self, props):
- return self.__proxy.RegisterProperties(props.to_dbus_value())
+ dbus_values = serializable.serialize_object(props)
+ return self.__proxy.RegisterProperties(dbus_values)
def update_property(self, prop):
- return self.__proxy.UpdateProperty(prop.to_dbus_value())
+ dbus_values = serializable.serialize_object(prop)
+ return self.__proxy.UpdateProperty(dbus_values)
def get_dbus_object(self):
return self.__proxy
@@ -145,8 +146,8 @@ class EngineProxy(interface.IEngine):
super(EngineProxy, self).__init__(conn, object_path)
self.__engine = engine
- def ProcessKeyEvent(self, keyval, is_press, state):
- return self.__engine.process_key_event(keyval, is_press, state)
+ def ProcessKeyEvent(self, keyval, state):
+ return self.__engine.process_key_event(keyval, state)
def FocusIn(self):
return self.__engine.focus_in()
diff --git a/ibus/enginedesc.py b/ibus/enginedesc.py
new file mode 100644
index 0000000..430072c
--- /dev/null
+++ b/ibus/enginedesc.py
@@ -0,0 +1,106 @@
+# vim:set et sts=4 sw=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
+
+__all__ = (
+ "EngineDesc",
+ )
+
+import dbus
+from exception import IBusException
+from serializable import *
+
+class EngineDesc(Serializable):
+ __NAME__ = "IBusEngineDesc"
+ def __init__ (self, name="", longname="", description="", language="", license="", author="", icon="", layout=""):
+ super(EngineDesc, self).__init__()
+ self.__name = name
+ self.__longname = longname
+ self.__description = description
+ self.__language = language
+ self.__license = license
+ self.__author = author
+ self.__icon = icon
+ self.__layout = layout
+
+ def get_name(self):
+ return self.__name
+
+ def get_longname(self):
+ return self.__longname
+
+ def get_description(self):
+ return self.__description
+
+ def get_language(self):
+ return self.__language
+
+ def get_license(self):
+ return self.__license
+
+ def get_author(self):
+ return self.__author
+
+ def get_icon(self):
+ return self.__icon
+
+ def get_layout(self):
+ return self.__layout
+
+ name = property(get_name)
+ longname = property(get_longname)
+ description = property(get_description)
+ language = property(get_language)
+ license = property(get_license)
+ author = property(get_author)
+ icon = property(get_icon)
+ layout = property(get_layout)
+
+ def serialize(self, struct):
+ super(EngineDesc, self).serialize(struct)
+ struct.append (dbus.String(self.__name))
+ struct.append (dbus.String(self.__longname))
+ struct.append (dbus.String(self.__description))
+ struct.append (dbus.String(self.__language))
+ struct.append (dbus.String(self.__license))
+ struct.append (dbus.String(self.__author))
+ struct.append (dbus.String(self.__icon))
+ struct.append (dbus.String(self.__layout))
+
+ def deserialize(self, struct):
+ super(EngineDesc, self).deserialize(struct)
+ self.__name = struct.pop(0)
+ self.__longname = struct.pop(0)
+ self.__description = struct.pop(0)
+ self.__language = struct.pop(0)
+ self.__license = struct.pop(0)
+ self.__author = struct.pop(0)
+ self.__icon = struct.pop(0)
+ self.__layout = struct.pop(0)
+
+serializable_register(EngineDesc)
+
+def test():
+ engine = EngineDesc("Hello", "", "", "", "", "", "", "")
+ value = serialize_object(engine)
+ engine = deserialize_object(value)
+
+if __name__ == "__main__":
+ test()
diff --git a/ibus/factory.py b/ibus/factory.py
index 18deebf..82751ba 100644
--- a/ibus/factory.py
+++ b/ibus/factory.py
@@ -21,24 +21,19 @@
__all__ = (
"EngineFactoryBase",
+ "FactoryInfo"
)
-
-import ibus
-from ibus import interface
-
-class EngineFactoryBase(ibus.Object):
- def __init__(self, info, engine_class, engine_path, bus, object_path):
+import dbus
+import object
+import interface
+from serializable import *
+from exception import *
+
+class EngineFactoryBase(object.Object):
+ def __init__(self, bus):
super(EngineFactoryBase, self).__init__()
- self.__proxy = EngineFactoryProxy (self, bus.get_dbusconn(), object_path)
- self.__info = info
+ self.__proxy = EngineFactoryProxy (self, bus.get_dbusconn(), "/org/freedesktop/IBus/Factory")
self.__bus = bus
- self.__engine_class = engine_class
- self.__engine_path = engine_path
- self.__engine_id = 1
- self.__object_path = object_path
-
- def get_info(self):
- return self.__info
def initialize(self):
pass
@@ -46,21 +41,13 @@ class EngineFactoryBase(ibus.Object):
def uninitialize(self):
pass
- def register(self):
- self.__bus.register_factories([self.__object_path])
-
- def create_engine(self):
- engine = self.__engine_class(self.__bus, self.__engine_path + str(self.__engine_id))
- self.__engine_id += 1
- return engine.get_dbus_object()
+ def create_engine(self, engine_name):
+ raise IBusException("Can not create engine %s" % engine_name)
def do_destroy(self):
self.__proxy = None
self.__bus = None
- self.__info = None
- self.__engine_class = None
- self.__engine_path = None
- super(EngineFactoryBase,self).do_destroy()
+ super(EngineFactoryBase, self).do_destroy()
class EngineFactoryProxy(interface.IEngineFactory):
@@ -77,11 +64,70 @@ class EngineFactoryProxy(interface.IEngineFactory):
def Uninitialize(self):
return self.__factory.uninitialize()
- def CreateEngine(self):
- return self.__factory.create_engine()
+ def CreateEngine(self, engine_name):
+ engine = self.__factory.create_engine(engine_name)
+ return engine.get_dbus_object()
def Destroy(self):
self.__factory.destroy()
self.__factory = None
self.remove_from_connection ()
+class FactoryInfo(Serializable):
+ __NAME__ = "IBusFactoryInfo"
+ def __init__ (self, path=None, name=None, lang=None, icon=None, authors=None, credits=None):
+ super(FactoryInfo, self).__init__()
+ self.__path = path
+ self.__name = name
+ self.__lang = lang
+ self.__icon = icon
+ self.__authors = authors
+ self.__credits = credits
+
+ def get_path(self):
+ return self.__path
+
+ def get_name(self):
+ return self.__name
+
+ def get_lang(self):
+ return self.__lang
+
+ def get_icon(self):
+ return self.__icon
+ def get_authors(self):
+ return self.__authors
+
+ def get_credits(self):
+ return self.__credits
+
+ path = property(get_path)
+ name = property(get_name)
+ lang = property(get_lang)
+ icon = property(get_icon)
+ authors = property(get_authors)
+ credits = property(get_credits)
+
+ def serialize(self, struct):
+ super(FactoryInfo, self).serialize(struct)
+ struct.append (dbus.ObjectPath(self.__path))
+ struct.append (dbus.String(self.__name))
+ struct.append (dbus.String(self.__lang))
+ struct.append (dbus.String(self.__icon))
+ struct.append (dbus.String(self.__authors))
+ struct.append (dbus.String(self.__credits))
+
+ def deserialize(self, struct):
+ super(FactoryInfo, self).deserialize(struct)
+ if len(struct) < 5:
+ raise IBusException ("Can not deserialize IBusFactoryInfo")
+
+ self.__path = struct.pop(0)
+ self.__name = struct.pop(0)
+ self.__lang = struct.pop(0)
+ self.__icon = struct.pop(0)
+ self.__authors = struct.pop(0)
+ self.__credits = struct.pop(0)
+
+serializable_register(FactoryInfo)
+
diff --git a/ibus/inputcontext.py b/ibus/inputcontext.py
new file mode 100644
index 0000000..10233da
--- /dev/null
+++ b/ibus/inputcontext.py
@@ -0,0 +1,301 @@
+# vim:set et sts=4 sw=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
+
+__all__ = (
+ "InputContext",
+ )
+
+import sys
+import gobject
+import dbus
+import dbus.lowlevel
+import object
+import common
+import serializable
+
+class InputContext(object.Object):
+ __gsignals__ = {
+ "commit-text" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_PYOBJECT, )
+ ),
+ "update-preedit-text" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_PYOBJECT, gobject.TYPE_UINT, gobject.TYPE_BOOLEAN)
+ ),
+ "show-preedit-text" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "hide-preedit-text" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "update-auxiliary-text" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
+ ),
+ "show-auxiliary-text" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "hide-auxiliary-text" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "update-lookup-table" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ (gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
+ ),
+ "show-lookup-table" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "hide-lookup-table" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "page-up-lookup-table" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "page-down-lookup-table" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "cursor-up-lookup-table" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "cursor-down-lookup-table" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "enabled" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ "disabled" : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ()
+ ),
+ }
+
+ def __init__(self, bus, path):
+ super(InputContext, self).__init__()
+
+ self.__bus = bus
+ self.__context = bus.get_dbusconn().get_object(common.IBUS_SERVICE_IBUS, path)
+ self.__signal_matches = []
+
+ m = self.__context.connect_to_signal("CommitText", self.__commit_text_cb)
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("UpdatePreeditText", self.__update_preedit_text_cb)
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("UpdateAuxiliaryText", self.__update_auxiliary_text_cb)
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("UpdateLookupTable", self.__update_lookup_table_cb)
+ self.__signal_matches.append(m)
+
+ m = self.__context.connect_to_signal("Enabled", lambda *args: self.emit("enabled"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("Disabled", lambda *args: self.emit("disabled"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("ShowPreeditText", lambda *args: self.emit("show-preedit-text"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("HidePreeditText", lambda *args: self.emit("hide-preedit-text"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("ShowAuxiliaryText", lambda *args: self.emit("show-auxiliary-text"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("HideAuxiliaryText", lambda *args: self.emit("hide-auxiliary-text"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("ShowLookupTable", lambda *args: self.emit("show-lookup-table"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("HideLookupTable", lambda *argss: self.emit("hide-lookup-table"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("PageUpLookupTable", lambda *args: self.emit("page-up-lookup-table"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("PageDownLookupTable", lambda *args: self.emit("page-down-lookup-table"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("CursorUpLookupTable", lambda *args: self.emit("cursor-up-lookup-table"))
+ self.__signal_matches.append(m)
+ m = self.__context.connect_to_signal("CursorDownLookupTable", lambda *args: self.emit("cursor-down-lookup-table"))
+ self.__signal_matches.append(m)
+
+ def __commit_text_cb(self, *args):
+ text = serializable.deserialize_object(args[0])
+ self.emit("commit-text", text)
+
+ def __update_preedit_text_cb(self, *args):
+ text = serializable.deserialize_object(args[0])
+ cursor_pos = args[1]
+ visible = args[2]
+ self.emit("update-preedit-text", text, cursor_pos, visible)
+
+ def __update_auxiliary_text_cb(self, *args):
+ text = serializable.deserialize_object(args[0])
+ visible = args[1]
+ self.emit("update-auxiliray-text", text, visible)
+
+ def __update_lookup_table_cb(self, *args):
+ table = serializable.deserialize_object(args[0])
+ visible = args[1]
+ self.emit("update-lookup-table", table, visible)
+
+ def process_key_event(self, keyval, modifiers):
+ keyval = dbus.UInt32(keyval)
+ modifiers = dbus.UInt32(modifiers)
+ return self.__context.ProcessKeyEvent(keyval, modifiers)
+
+ def set_cursor_location(self, x, y, w, h):
+ x = dbus.Int32(x)
+ y = dbus.Int32(y)
+ w = dbus.Int32(w)
+ h = dbus.Int32(h)
+ return self.__context.SetCursorLocation(x, y, w, h)
+
+ def focus_in(self):
+ return self.__context.FocusIn()
+
+ def focus_out(self):
+ return self.__context.FocusOut()
+
+ def reset(self):
+ return self.__context.Reset()
+
+ def is_enabled(self):
+ return self.__context.IsEnabled()
+
+ def set_capabilities(self, caps):
+ caps = dbus.UInt32(caps)
+ return self.__context.SetCapabilities(caps)
+
+ def destroy(self):
+ self.__context.Destroy()
+ super(InputContext, self).destroy()
+
+ def get_engine(self):
+ try:
+ engine = self.__context.GetEngine()
+ engine = serializable.deserialize_object(engine)
+ return engine
+ except:
+ return None
+
+ def set_engine(self, engine):
+ return self.__context.SetEngine(engine.name)
+
+
+def test():
+ import gtk
+ import gtk.gdk
+ from bus import Bus
+ import modifier
+ import text
+ import attribute
+ import property
+ import lookuptable
+ import factory
+
+ class TestWindow(gtk.Window):
+ def __init__(self):
+ super(TestWindow,self).__init__()
+
+ self.__bus = Bus()
+ print self.__bus.get_name()
+ self.__bus.connect("disconnected", gtk.main_quit)
+ context_path = self.__bus.create_input_context("Test")
+ print context_path
+ self.__context = InputContext(self.__bus, context_path)
+ self.__context.set_capabilities (9)
+
+ self.__context.connect("commit-text", self.__commit_text_cb)
+ self.__context.connect("update-preedit-text", self.__update_preedit_text_cb)
+ self.__context.connect("show-preedit-text", self.__show_preedit_text_cb)
+ self.__context.connect("update-auxiliary-text", self.__update_auxiliary_text_cb)
+ self.__context.connect("update-lookup-table", self.__update_lookup_table_cb)
+ self.__context.connect("enabled", self.__enabled_cb)
+ self.__context.connect("disabled", self.__disabled_cb)
+
+ self.set_events(gtk.gdk.KEY_PRESS_MASK | gtk.gdk.KEY_RELEASE_MASK | gtk.gdk.FOCUS_CHANGE_MASK)
+
+ self.connect("key-press-event", self.__key_press_event_cb)
+ self.connect("key-release-event", self.__key_release_event_cb)
+ self.connect("delete-event", gtk.main_quit)
+ self.connect("focus-in-event", lambda *args: self.__context.focus_in())
+ self.connect("focus-out-event", lambda *args: self.__context.focus_out())
+
+ self.show_all()
+
+ def __commit_text_cb(self, context, text):
+ print "commit-text:", text.text
+
+ def __update_preedit_text_cb(self, context, text, cursor_pos, visible):
+ print "preedit-text:", text.text, cursor_pos, visible
+
+ def __show_preedit_text_cb(self, context):
+ print "show-preedit-text"
+
+ def __hide_preedit_text_cb(self, context):
+ print "hide-preedit-text"
+
+ def __update_auxiliary_text_cb(self, context, text, visible):
+ print "auxiliary-text:", text.text, visible
+
+ def __update_lookup_table_cb(self, context, table, visible):
+ print "update-lookup-table:", visible
+
+ def __enabled_cb(self, context):
+ print "enabled"
+ info = context.get_factory_info()
+ print "factory = %s" % info.name
+
+ def __disabled_cb(self, context):
+ print "disabled"
+
+ def __key_press_event_cb(self, widget, event):
+ self.__context.process_key_event(event.keyval, event.state)
+
+ def __key_release_event_cb(self, widget, event):
+ self.__context.process_key_event(event.keyval, event.state | modifier.RELEASE_MASK)
+
+ w = TestWindow()
+ gtk.main()
+
+if __name__ == "__main__":
+ test()
+
diff --git a/ibus/interface/Makefile.am b/ibus/interface/Makefile.am
index 0e1f8b9..ffc019c 100644
--- a/ibus/interface/Makefile.am
+++ b/ibus/interface/Makefile.am
@@ -24,6 +24,7 @@ ibus_interface_PYTHON = \
ienginefactory.py \
iengine.py \
iibus.py \
+ iinputcontext.py \
ipanel.py \
inotifications.py \
__init__.py \
diff --git a/ibus/interface/__init__.py b/ibus/interface/__init__.py
index 5348395..90af265 100644
--- a/ibus/interface/__init__.py
+++ b/ibus/interface/__init__.py
@@ -20,6 +20,7 @@
# Boston, MA 02111-1307 USA
from iibus import *
+from iinputcontext import *
from iengine import *
from ienginefactory import *
from ipanel import *
diff --git a/ibus/interface/iconfig.py b/ibus/interface/iconfig.py
index 171d17a..23954fa 100644
--- a/ibus/interface/iconfig.py
+++ b/ibus/interface/iconfig.py
@@ -23,22 +23,22 @@ __all__ = ("IConfig", )
import dbus.service
from ibus.common import \
- IBUS_CONFIG_IFACE
+ IBUS_IFACE_CONFIG
class IConfig(dbus.service.Object):
# define method decorator.
method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_CONFIG_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_CONFIG, \
**args)
# define signal decorator.
signal = lambda **args: \
- dbus.service.signal(dbus_interface=IBUS_CONFIG_IFACE, \
+ dbus.service.signal(dbus_interface=IBUS_IFACE_CONFIG, \
**args)
# define async method decorator.
async_method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_CONFIG_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_CONFIG, \
async_callbacks=("reply_cb", "error_cb"), \
**args)
diff --git a/ibus/interface/iengine.py b/ibus/interface/iengine.py
index dfe285a..32ba998 100644
--- a/ibus/interface/iengine.py
+++ b/ibus/interface/iengine.py
@@ -23,27 +23,27 @@ __all__ = ("IEngine", )
import dbus.service
from ibus.common import \
- IBUS_ENGINE_IFACE
+ IBUS_IFACE_ENGINE
class IEngine(dbus.service.Object):
# define method decorator.
method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_ENGINE_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_ENGINE, \
**args)
# define signal decorator.
signal = lambda **args: \
- dbus.service.signal(dbus_interface=IBUS_ENGINE_IFACE, \
+ dbus.service.signal(dbus_interface=IBUS_IFACE_ENGINE, \
**args)
# define async method decorator.
async_method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_ENGINE_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_ENGINE, \
async_callbacks=("reply_cb", "error_cb"), \
**args)
- @method(in_signature="ubu", out_signature="b")
- def ProcessKeyEvent(self, keyval, is_press, state):
+ @method(in_signature="uu", out_signature="b")
+ def ProcessKeyEvent(self, keyval, state):
pass
@method(in_signature="iiii")
@@ -89,29 +89,30 @@ class IEngine(dbus.service.Object):
@method()
def Destroy(self): pass
- @signal(signature="s")
- def CommitString(self, text): pass
+
+ @signal(signature="v")
+ def CommitText(self, text): pass
@signal(signature="ubu")
def ForwardKeyEvent(self, keyval, is_press, state): pass
- @signal(signature="sa(uuuu)ib")
- def UpdatePreedit(self, text, attrs, cursor_pos, visible): pass
+ @signal(signature="vub")
+ def UpdatePreeditText(self, text, cursor_pos, visible): pass
@signal()
- def ShowPreedit(self): pass
+ def ShowPreeditText(self): pass
@signal()
- def HidePreedit(self): pass
+ def HidePreeditText(self): pass
- @signal(signature="sa(uuuu)b")
- def UpdateAuxString(self, text, attrs, visible): pass
+ @signal(signature="vb")
+ def UpdateAuxiliaryText(self, text, visible): pass
@signal()
- def ShowAuxString(self): pass
+ def ShowAuxiliaryText(self): pass
@signal()
- def HideAuxString(self): pass
+ def HideAuxiliaryText(self): pass
@signal(signature="vb")
def UpdateLookupTable(self, lookup_table, visible): pass
diff --git a/ibus/interface/ienginefactory.py b/ibus/interface/ienginefactory.py
index 5670e81..5e93fd8 100644
--- a/ibus/interface/ienginefactory.py
+++ b/ibus/interface/ienginefactory.py
@@ -23,17 +23,17 @@ __all__ = ("IEngineFactory", )
import dbus.service
from ibus.common import \
- IBUS_ENGINE_FACTORY_IFACE
+ IBUS_IFACE_ENGINE_FACTORY
class IEngineFactory(dbus.service.Object):
# define method decorator.
method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_ENGINE_FACTORY_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_ENGINE_FACTORY, \
**args)
# define async method decorator.
async_method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_ENGINE_FACTORY_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_ENGINE_FACTORY, \
async_callbacks=("reply_cb", "error_cb"), \
**args)
@@ -51,8 +51,8 @@ class IEngineFactory(dbus.service.Object):
# Create an input context and return the id of the context.
# If failed, it will return "" or None.
- @method(out_signature="o")
- def CreateEngine(self): pass
+ @method(in_signature="s", out_signature="o")
+ def CreateEngine(self, engine_name): pass
# Destroy the engine
@method()
diff --git a/ibus/interface/iibus.py b/ibus/interface/iibus.py
index cc5c351..848f798 100644
--- a/ibus/interface/iibus.py
+++ b/ibus/interface/iibus.py
@@ -23,100 +23,49 @@ __all__ = ("IIBus", )
import dbus.service
from ibus.common import \
- IBUS_IFACE
+ IBUS_IFACE_IBUS
class IIBus(dbus.service.Object):
# define method decorator.
method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_IBUS, \
connection_keyword="dbusconn", \
**args)
# define async method decorator.
async_method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_IBUS, \
connection_keyword="dbusconn", \
async_callbacks=("reply_cb", "error_cb"), \
**args)
@method(out_signature="s")
- def GetIBusAddress(self, dbusconn): pass
+ def GetAddress(self, dbusconn): pass
# methods for ibus clients
- @method(in_signature="s", out_signature="s")
+ @method(in_signature="s", out_signature="o")
def CreateInputContext(self, client_name, dbusconn): pass
- @method(in_signature="s")
- def ReleaseInputContext(self, ic, dbusconn): pass
-
- @async_method(in_signature="subu", out_signature="b")
- def ProcessKeyEvent(self, ic, keyval, is_press, state, dbusconn, reply_cb, error_cb): pass
-
- @method(in_signature="siiii")
- def SetCursorLocation(self, ic, x, y, w, h, dbusconn): pass
-
- @method(in_signature="s")
- def FocusIn(self, ic, dbusconn): pass
-
- @method(in_signature="s")
- def FocusOut(self, ic, dbusconn): pass
-
- @method(in_signature="s")
- def Reset(self, ic, dbusconn): pass
-
- @method(in_signature="s", out_signature="b")
- def IsEnabled(self, ic, dbusconn): pass
-
- @method(in_signature="si")
- def SetCapabilities(self, ic, caps, dbusconn): pass
+ @method(in_signature="s", out_signature="sb")
+ def GetInputContextStates(self, ic, dbusconn): pass
# methods for ibus engine provide
- @method(in_signature="ao")
+ @method(in_signature="av")
def RegisterFactories(self, object_paths, dbusconn): pass
- @method(in_signature="ao")
+ @method(in_signature="av")
def UnregisterFactories(self, object_paths, dbusconn): pass
# general methods
- @method(out_signature="av")
- def GetFactories(self, dbusconn): pass
+ @method(in_signature="av")
+ def RegisterComponent(self, components, dbusconn): pass
- @method(in_signature="o", out_signature="av")
- def GetFactoryInfo(self, factory_path, dbusconn): pass
-
- @method(in_signature="o")
- def SetFactory(self, factory_path, dbusconn): pass
-
- @method(in_signature="s", out_signature="sb")
- def GetInputContextStates(self, ic, dbusconn): pass
-
- @method(out_signature="a(sssssssb)")
- def RegisterListEngines(self, dbusconn): pass
-
- @method()
- def RegisterReloadEngines(self, dbusconn): pass
-
- @method(in_signature="ss")
- def RegisterStartEngine(self, lang, name, dbusconn): pass
-
- @method(in_signature="ss")
- def RegisterRestartEngine(self, lang, name, dbusconn): pass
+ @method(out_signature="av")
+ def ListEngines(self, dbusconn): pass
- @method(in_signature="ss")
- def RegisterStopEngine(self, lang, name, dbusconn): pass
+ @method(out_signature="av")
+ def ListActiveEngines(self, dbusconn): pass
@async_method()
def Kill(self, dbusconn, reply_cb, error_cb): pass
- #sigals
- def CommitString(self, ic, text): pass
-
- def UpdatePreedit(self, ic, text, attrs, cursor_pos, show): pass
-
- def Enabled(self, ic): pass
-
- def Disabled(self, ic): pass
-
- def ConfigValueChanged(self, key, value): pass
-
- def ConfigReload(self): pass
diff --git a/ibus/interface/iinputcontext.py b/ibus/interface/iinputcontext.py
new file mode 100644
index 0000000..e5cf129
--- /dev/null
+++ b/ibus/interface/iinputcontext.py
@@ -0,0 +1,133 @@
+# vim:set et sts=4 sw=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
+
+__all__ = ("IInputContext", )
+
+import dbus.service
+from ibus.common import \
+ IBUS_IFACE_INPUT_CONTEXT
+
+class IInputContext(dbus.service.Object):
+ # define method decorator.
+ method = lambda **args: \
+ dbus.service.method(dbus_interface=IBUS_IFACE_INPUT_CONTEXT, \
+ **args)
+
+ # define async method decorator.
+ async_method = lambda **args: \
+ dbus.service.method(dbus_interface=IBUS_IFACE_INPUT_CONTEXT, \
+ async_callbacks=("reply_cb", "error_cb"), \
+ **args)
+
+ # define signal decorator.
+ signal = lambda **args: \
+ dbus.service.signal(dbus_interface=IBUS_IFACE_INPUT_CONTEXT, \
+ **args)
+
+ @async_method(in_signature="uu", out_signature="b")
+ def ProcessKeyEvent(self, keyval, state, reply_cb, error_cb): pass
+
+ @method(in_signature="iiii")
+ def SetCursorLocation(self, x, y, w, h): pass
+
+ @method()
+ def FocusIn(self): pass
+
+ @method()
+ def FocusOut(self): pass
+
+ @method()
+ def Reset(self): pass
+
+ @method(out_signature="b")
+ def IsEnabled(self): pass
+
+ @method(in_signature="u")
+ def SetCapabilities(self, caps): pass
+
+ @method(out_signature="v")
+ def GetEngineDesc(self): pass
+
+ @method(in_signature="s")
+ def SetEngine(self, engine_name): pass
+
+ @method()
+ def Destroy(self): pass
+
+ #sigals
+ @signal(signature="v")
+ def CommitText(self, text): pass
+
+ @signal()
+ def Enabled(self): pass
+
+ @signal()
+ def Disabled(self): pass
+
+ @signal(signature="uu")
+ def ForwardKeyEvent(self, keyval, state): pass
+
+ @signal(signature="vub")
+ def UpdatePreeditText(self, text, cursor_pos, visible): pass
+
+ @signal()
+ def ShowPreeditText(self): pass
+
+ @signal()
+ def HidePreeditText(self): pass
+
+ @signal(signature="vb")
+ def UpdateAuxiliaryText(self, text, visible): pass
+
+ @signal()
+ def ShowAuxiliaryText(self): pass
+
+ @signal()
+ def HideAuxiliaryText(self): pass
+
+ @signal(signature="vb")
+ def UpdateLookupTable(self, lookup_table, visible): pass
+
+ @signal()
+ def ShowLookupTable(self): pass
+
+ @signal()
+ def HideLookupTable(self): pass
+
+ @signal()
+ def PageUpLookupTable(self): pass
+
+ @signal()
+ def PageDownLookupTable(self): pass
+
+ @signal()
+ def CursorUpLookupTable(self): pass
+
+ @signal()
+ def CursorDownLookupTable(self): pass
+
+ @signal(signature="v")
+ def RegisterProperties(self, props): pass
+
+ @signal(signature="v")
+ def UpdateProperty(self, prop): pass
+
+
diff --git a/ibus/interface/inotifications.py b/ibus/interface/inotifications.py
index 7d667f2..74d4dcf 100644
--- a/ibus/interface/inotifications.py
+++ b/ibus/interface/inotifications.py
@@ -23,22 +23,22 @@ __all__ = ("INotifications", )
import dbus.service
from ibus.common import \
- IBUS_NOTIFICATIONS_IFACE
+ IBUS_IFACE_NOTIFICATIONS
class INotifications(dbus.service.Object):
# define method decorator.
method = lambda **args: \
- dbus.service.method(dbus_interface = IBUS_NOTIFICATIONS_IFACE, \
+ dbus.service.method(dbus_interface = IBUS_IFACE_NOTIFICATIONS, \
**args)
# define signal decorator.
signal = lambda **args: \
- dbus.service.signal(dbus_interface = IBUS_NOTIFICATIONS_IFACE, \
+ dbus.service.signal(dbus_interface = IBUS_IFACE_NOTIFICATIONS, \
**args)
# define async method decorator.
async_method = lambda **args: \
- dbus.service.method(dbus_interface = IBUS_NOTIFICATIONS_IFACE, \
+ dbus.service.method(dbus_interface = IBUS_IFACE_NOTIFICATIONS, \
async_callbacks = ("reply_cb", "error_cb"), \
**args)
diff --git a/ibus/interface/ipanel.py b/ibus/interface/ipanel.py
index 83d6585..e5d174c 100644
--- a/ibus/interface/ipanel.py
+++ b/ibus/interface/ipanel.py
@@ -23,44 +23,44 @@ __all__ = ("IPanel", )
import dbus.service
from ibus.common import \
- IBUS_PANEL_IFACE
+ IBUS_IFACE_PANEL
class IPanel(dbus.service.Object):
# define method decorator.
method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_PANEL_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_PANEL, \
**args)
# define signal decorator.
signal = lambda **args: \
- dbus.service.signal(dbus_interface=IBUS_PANEL_IFACE, \
+ dbus.service.signal(dbus_interface=IBUS_IFACE_PANEL, \
**args)
# define async method decorator.
async_method = lambda **args: \
- dbus.service.method(dbus_interface=IBUS_PANE_IFACE, \
+ dbus.service.method(dbus_interface=IBUS_IFACE_PANEL, \
async_callbacks=("reply_cb", "error_cb"), \
**args)
@method(in_signature="iiii")
def SetCursorLocation(self, x, y, w, h): pass
- @method(in_signature="svub")
- def UpdatePreedit(self, text, attrs, cursor_pos, visible): pass
+ @method(in_signature="vub")
+ def UpdatePreeditText(self, text, cursor_pos, visible): pass
@method()
- def ShowPreedit(self): pass
+ def ShowPreeditText(self): pass
@method()
- def HidePreedit(self): pass
+ def HidePreeditText(self): pass
- @method(in_signature="svb")
- def UpdateAuxString(self, text, attrs, visible): pass
+ @method(in_signature="vb")
+ def UpdateAuxiliaryText(self, text, visible): pass
@method()
- def ShowAuxString(self): pass
+ def ShowAuxiliaryText(self): pass
@method()
- def HideAuxString(self): pass
+ def HideAuxiliaryText(self): pass
@method(in_signature="vb")
def UpdateLookupTable(self, lookup_table, visible): pass
@@ -95,14 +95,14 @@ class IPanel(dbus.service.Object):
@method()
def HideLanguageBar(self): pass
- @method(in_signature="s")
+ @method(in_signature="o")
def FocusIn(self, ic): pass
- @method(in_signature="s")
+ @method(in_signature="o")
def FocusOut(self, ic): pass
@method()
- def StatesChanged(self): pass
+ def StateChanged(self): pass
@method()
def Reset(self): pass
@@ -126,12 +126,12 @@ class IPanel(dbus.service.Object):
@signal()
def CursorDown(self): pass
- @signal()
+ @signal(signature="si")
def PropertyActivate(self, prop_name, prop_state): pass
- @signal()
+ @signal(signature="s")
def PropertyShow(self, prop_name): pass
- @signal()
+ @signal(signature="s")
def PropertyHide(self, prop_name): pass
diff --git a/ibus/lookuptable.py b/ibus/lookuptable.py
index 27819ce..bedd8bf 100644
--- a/ibus/lookuptable.py
+++ b/ibus/lookuptable.py
@@ -21,54 +21,24 @@
__all__ = (
"LookupTable",
- "lookup_table_from_dbus_value"
)
import dbus
-from attribute import *
+from serializable import *
from exception import *
-class CandidateList(list):
- def __init__(self, items = []):
- super(CandidateList, self).__init__(items)
-
- def clean(self):
- del self[:]
- def __getslice__(self, i, j):
- items = super(CandidateList, self).__getslice__(i, j)
- return CandidateList(items)
-
- def to_dbus_value(self):
- value = dbus.Array([], signature="v")
- for text, attrs in self:
- value.append(dbus.Struct((dbus.String(text), attrs.to_dbus_value())))
- return value
-
- def from_dbus_value(self, value):
- candidates = []
- if not isinstance(value, dbus.Array):
- raise dbus.Exception("Candidates must from dbus.Array(a(sa(...))")
- for candidate in value:
- if not isinstance(candidate, dbus.Struct):
- raise IBusException("Candidates must from dbus.Array(a(sa(...)))")
- if len(candidate) != 2 or \
- not isinstance(candidate[0], dbus.String):
- raise IBusException("Candidates must from dbus.Array(a(sa(...)))")
- text = candidate[0]
- attrs = attr_list_from_dbus_value(candidate[1])
- candidates.append((text, attrs))
-
- self.clean()
- self[:] = candidates
-
-class LookupTable(object):
- def __init__(self, page_size=5, labels=None):
+class LookupTable(Serializable):
+ __NAME__ = "IBusLookupTable"
+ def __init__(self, page_size=5, cursor_pos=0, coursor_visible=True, candidates=None):
super(LookupTable, self).__init__()
self.__cursor_visible = True
- self.__cursor_pos = 0
- self.__candidates = CandidateList()
+ self.__cursor_pos = cursor_pos
+ if candidates == None:
+ self.__candidates = list()
+ else:
+ self.__candidates = candidates
self.set_page_size(page_size)
- self.set_labels(labels)
+ self.set_labels(None)
def set_page_size(self, page_size):
self.__page_size = page_size
@@ -159,18 +129,16 @@ class LookupTable(object):
return True
def clean(self):
- self.__candidates.clean()
+ self.__candidates = list()
self.__cursor_pos = 0
- def append_candidate(self, candidate, attrs = None):
- if attrs == None:
- attrs = AttrList()
- self.__candidates.append((candidate, attrs))
+ def append_candidate(self, text):
+ self.__candidates.append(text)
def get_candidate(self, index):
return self.__candidates[index]
- def get_canidates_in_current_page(self):
+ def get_candidates_in_current_page(self):
page = self.__cursor_pos / self.__page_size
start_index = page * self.__page_size
end_index = min((page + 1) * self.__page_size, len(self.__candidates))
@@ -185,50 +153,43 @@ class LookupTable(object):
def __len__(self):
return self.get_number_of_candidates()
- def to_dbus_value(self):
- value = (dbus.Int32(self.__page_size),
- dbus.Int32(self.__cursor_pos),
- dbus.Boolean(self.__cursor_visible),
- self.__candidates.to_dbus_value())
- return dbus.Struct(value)
-
- def current_page_to_dbus_value(self):
- candidates = self.get_canidates_in_current_page()
- value = (dbus.Int32(self.__page_size),
- dbus.Int32(self.__cursor_pos % self.__page_size),
- dbus.Boolean(self.__cursor_visible),
- candidates.to_dbus_value())
- return dbus.Struct(value)
-
- def from_dbus_value(self, value):
- if not isinstance(value, dbus.Struct):
- raise dbus.Exception("LookupTable must from dbus.Struct(uuba(...))")
-
- if len(value) != 4 or \
- not isinstance(value[0], dbus.Int32) or \
- not isinstance(value[1], dbus.Int32) or \
- not isinstance(value[2], dbus.Boolean):
- raise dbus.Exception("LookupTable must from dbus.Struct(uuba(...))")
-
- self.__candidates.from_dbus_value(value[3])
- self.__page_size = value[0]
- self.__cursor_pos = value[1]
- self.__cursor_visible = value[2]
-
-def lookup_table_from_dbus_value(value):
- lookup_table = LookupTable()
- lookup_table.from_dbus_value(value)
- return lookup_table
-
-def unit_test():
+ def serialize(self, struct):
+ super(LookupTable, self).serialize(struct)
+ struct.append(dbus.UInt32(self.__page_size))
+ struct.append(dbus.UInt32(self.__cursor_pos))
+ struct.append(dbus.Boolean(self.__cursor_visible))
+ candidates = map(lambda c: serialize_object(c), self.__candidates)
+ struct.append(dbus.Array(candidates, signature="v"))
+
+ def get_current_page_as_lookup_table(self):
+ candidates = self.get_candidates_in_current_page()
+ return LookupTable(self.__page_size,
+ self.__cursor_pos % self.__page_size,
+ self.__cursor_visible,
+ candidates)
+
+ def deserialize(self, struct):
+ super(LookupTable, self).deserialize(struct)
+
+ self.__page_size = struct.pop(0)
+ self.__cursor_pos = struct.pop(0)
+ self.__cursor_visible = struct.pop(0)
+ self.__candidates = map(deserialize_object, struct.pop(0))
+
+
+serializable_register(LookupTable)
+
+def test():
t = LookupTable()
# attrs = AttrList()
# attrs.append(AttributeBackground(RGB(233, 0,1), 0, 3))
# attrs.append(AttributeUnderline(1, 3, 5))
t.append_candidate("Hello")
- value = t.to_dbus_value()
- print value
- t = lookup_table_from_dbus_value(value)
+ value = serialize_object(t)
+ t = deserialize_object(value)
+ t = t.get_current_page_as_lookup_table()
+ value = serialize_object(t)
+ t = deserialize_object(value)
if __name__ == "__main__":
- unit_test()
+ test()
diff --git a/ibus/notifications.py b/ibus/notifications.py
index 3ae067a..0509548 100644
--- a/ibus/notifications.py
+++ b/ibus/notifications.py
@@ -21,12 +21,12 @@
__all__ = (
"NotificationsBase",
- "IBUS_NOTIFICATIONS_NAME",
- "IBUS_NOTIFICATIONS_PATH"
+ "IBUS_SERVICE_NOTIFICATIONS",
+ "IBUS_PATH_NOTIFICATIONS"
)
-IBUS_NOTIFICATIONS_NAME = "org.freedesktop.ibus.Notifications"
-IBUS_NOTIFICATIONS_PATH = "/org/freedesktop/ibus/Notifications"
+IBUS_SERVICE_NOTIFICATIONS = "org.freedesktop.IBus.Notifications"
+IBUS_PATH_NOTIFICATIONS = "/org/freedesktop/IBus/Notifications"
import ibus
from ibus import interface
@@ -50,7 +50,7 @@ class NotificationsBase(ibus.Object):
class NotificationsProxy(interface.INotifications):
def __init__ (self, notify, dbusconn):
- super(NotificationsProxy, self).__init__(dbusconn, IBUS_NOTIFICATIONS_PATH)
+ super(NotificationsProxy, self).__init__(dbusconn, IBUS_PATH_NOTIFICATIONS)
self.__dbusconn = dbusconn
self.__notify = notify
diff --git a/ibus/object.py b/ibus/object.py
index ca2b380..b00e47a 100644
--- a/ibus/object.py
+++ b/ibus/object.py
@@ -28,21 +28,30 @@ import gobject
class Object(gobject.GObject):
__gsignals__ = {
'destroy' : (
- gobject.SIGNAL_RUN_FIRST,
+ gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
())
}
def __init__(self):
super(Object, self).__init__()
- self._destroyed = False
+ self.__destroyed = False
+ self.__handlers = []
def destroy(self):
- if not self._destroyed:
+ if not self.__destroyed:
self.emit("destroy")
- self._destroyed = True
+ self.__destroyed = True
def do_destroy(self):
- pass
+ self.__disconnect_all()
+
+ def connect(self, signal_name, handler, *args):
+ id = super(Object, self).connect(signal_name, handler, *args)
+ self.__handlers.append(id)
+
+ def __disconnect_all(self):
+ map(self.disconnect, self.__handlers)
+ self.__handlers = []
gobject.type_register(Object)
diff --git a/ibus/observedpath.py b/ibus/observedpath.py
new file mode 100644
index 0000000..94b3e7e
--- /dev/null
+++ b/ibus/observedpath.py
@@ -0,0 +1,64 @@
+# vim:set et sts=4 sw=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
+
+__all__ = (
+ "ObservedPath",
+ )
+
+import dbus
+from exception import IBusException
+from serializable import *
+
+class ObservedPath(Serializable):
+ __NAME__ = "IBusObservedPath"
+ def __init__ (self, path="", mtime=0):
+ super(ObservedPath, self).__init__()
+ self.__path = path
+ self.__mtime = mtime
+
+ def get_path(self):
+ return self.__path
+
+ def get_mtime(self):
+ return self.__mtime
+
+ path = property(get_path)
+ mtime = property(get_mtime)
+
+ def serialize(self, struct):
+ super(ObservedPath, self).serialize(struct)
+ struct.append (dbus.String(self.__path))
+ struct.append (dbus.Int64(self.__mtime))
+
+ def deserialize(self, struct):
+ super(ObservedPath, self).deserialize(struct)
+ self.__path = struct.pop(0)
+ self.__mtime = struct.pop(0)
+
+serializable_register(ObservedPath)
+
+def test():
+ op = ObservedPath("/tmp", 111)
+ value = serialize_object(op)
+ op= deserialize_object(value)
+
+if __name__ == "__main__":
+ test()
diff --git a/ibus/panel.py b/ibus/panel.py
index 74b220d..9a34109 100644
--- a/ibus/panel.py
+++ b/ibus/panel.py
@@ -25,15 +25,17 @@ __all__ = (
"PanelButton",
"PanelToggleButton",
"PanelMenu",
- "IBUS_PANEL_NAME",
- "IBUS_PANEL_PATH"
+ "IBUS_SERVICE_PANEL",
+ "IBUS_PATH_PANEL"
)
-IBUS_PANEL_NAME = "org.freedesktop.ibus.Panel"
-IBUS_PANEL_PATH = "/org/freedesktop/ibus/Panel"
+IBUS_SERVICE_PANEL = "org.freedesktop.IBus.Panel"
+IBUS_PATH_PANEL = "/org/freedesktop/IBus/Panel"
-import ibus
-from ibus import interface
+from serializable import *
+from object import Object
+import interface
+import dbus
class PanelItem:
pass
@@ -47,30 +49,31 @@ class PanelToggleButton(PanelButton):
class PanelMenu(PanelItem):
pass
-class PanelBase(ibus.Object):
+class PanelBase(Object):
def __init__(self, bus):
super(PanelBase, self).__init__()
- self.__proxy = PanelProxy(self, bus.get_dbusconn())
+ self.__bus = bus
+ self.__proxy = PanelProxy(self, bus)
def set_cursor_location(self, x, y, w, h):
pass
- def update_preedit(self, text, attrs, cursor_pos, visible):
+ def update_preedit_text(self, text, cursor_pos, visible):
pass
- def show_preedit(self):
+ def show_preedit_text(self):
pass
- def hide_preedit(self):
+ def hide_preedit_text(self):
pass
- def update_aux_string(self, text, attrs, visible):
+ def update_auxiliary_text(self, text, visible):
pass
- def show_aux_string(self):
+ def show_auxiliary_text(self):
pass
- def hide_aux_string(self):
+ def hide_auxiliary_text(self):
pass
def update_lookup_table(self, lookup_table, visible):
@@ -118,7 +121,7 @@ class PanelBase(ibus.Object):
def focus_out(self, ic):
pass
- def states_changed(self):
+ def state_changed(self):
pass
def reset(self):
@@ -140,47 +143,52 @@ class PanelBase(ibus.Object):
self.__proxy.CursorDown()
def property_activate(self, prop_name, prop_state):
+ prop_name = dbus.String(prop_name)
+ prop_state = dbus.Int32(prop_state)
self.__proxy.PropertyActivate(prop_name, prop_state)
def property_show(self, prop_name):
+ prop_name = dbus.String(prop_name)
self.__proxy.PropertyShow(prop_name)
def property_hide(self, prop_name):
+ prop_name = dbus.String(prop_name)
self.__proxy.PropertyHide(prop_name)
class PanelProxy(interface.IPanel):
- def __init__ (self, panel, dbusconn):
- super(PanelProxy, self).__init__(dbusconn, IBUS_PANEL_PATH)
- self.__dbusconn = dbusconn
+ def __init__ (self, panel, bus):
+ super(PanelProxy, self).__init__(bus.get_dbusconn(), IBUS_PATH_PANEL)
+ self.__bus = bus
self.__panel = panel
+ self.__focus_ic = None
def SetCursorLocation(self, x, y, w, h):
self.__panel.set_cursor_location(x, y, w, h)
- def UpdatePreedit(self, text, attrs, cursor_pos, show):
- attrs = ibus.attr_list_from_dbus_value(attrs)
- self.__panel.update_preedit(text, attrs, cursor_pos, show)
+ def UpdatePreeditText(self, text, cursor_pos, visible):
+ text = deserialize_object(text)
+ self.__panel.update_preedit_text(text, cursor_pos, visible)
- def ShowPreedit(self):
- self.__panel.show_preedit()
+ def ShowPreeditText(self):
+ self.__panel.show_preedit_text()
- def HidePreedit(self):
- self.__panel.hide_preedit()
+ def HidePreeditText(self):
+ self.__panel.hide_preedit_text()
- def UpdateAuxString(self, text, attrs, show):
- attrs = ibus.attr_list_from_dbus_value(attrs)
- self.__panel.update_aux_string(text, attrs, show)
+ def UpdateAuxiliaryText(self, text, visible):
+ text = deserialize_object(text)
+ self.__panel.update_auxiliary_text(text, visible)
- def ShowAuxString(self):
- self.__panel.show_aux_string()
+ def ShowAuxiliaryText(self):
+ self.__panel.show_auxiliary_text()
- def HideAuxString(self):
- self.__panel.hide_aux_string()
+ def HideAuxiliaryText(self):
+ self.__panel.hide_auxiliary_text()
- def UpdateLookupTable(self, lookup_table, show):
- lookup_table = ibus.lookup_table_from_dbus_value(lookup_table)
- self.__panel.update_lookup_table(lookup_table, show)
+ def UpdateLookupTable(self, lookup_table, visible):
+ lookup_table = deserialize_object(lookup_table)
+ self.__panel.update_lookup_table(lookup_table, visible)
def ShowLookupTable(self):
self.__panel.show_lookup_table()
@@ -213,11 +221,11 @@ class PanelProxy(interface.IPanel):
self.__panel.hide_language_bar()
def RegisterProperties(self, props):
- props = ibus.prop_list_from_dbus_value(props)
+ props = deserialize_object(props)
self.__panel.register_properties(props)
def UpdateProperty(self, prop):
- prop = ibus.property_from_dbus_value(prop)
+ prop = deserialize_object(prop)
self.__panel.update_property(prop)
def FocusIn(self, ic):
@@ -226,8 +234,8 @@ class PanelProxy(interface.IPanel):
def FocusOut(self, ic):
self.__panel.focus_out(ic)
- def StatesChanged(self):
- self.__panel.states_changed()
+ def StateChanged(self):
+ self.__panel.state_changed()
def Reset(self):
self.__panel.reset()
@@ -238,3 +246,41 @@ class PanelProxy(interface.IPanel):
def Destroy(self):
self.__panel.destroy()
+def test():
+ import gtk
+ from bus import Bus
+ from inputcontext import InputContext
+ import factory
+ import attribute
+ import property
+ import text
+ import lookuptable
+
+ class TestPanel(PanelBase):
+ def __init__(self):
+ self.__bus = Bus()
+ self.__bus.connect("disconnected", gtk.main_quit)
+ super(TestPanel, self).__init__(self.__bus)
+ self.__bus.request_name(IBUS_SERVICE_PANEL, 0)
+
+ def focus_in(self, ic):
+ print "focus-in:", ic
+ context = InputContext(self.__bus, ic)
+ info = context.get_factory_info()
+ print "factory:", info.name
+
+ def focus_out(self, ic):
+ print "focus-out:", ic
+
+ def update_auxiliary_text(self, text, visible):
+ print "update-auxiliary-text:", text.text
+
+ def update_lookup_table(self, table, visible):
+ print "update-lookup-table", table
+
+ panel = TestPanel()
+ gtk.main()
+
+
+if __name__ == "__main__":
+ test()
diff --git a/ibus/property.py b/ibus/property.py
index 970975e..72f72a2 100644
--- a/ibus/property.py
+++ b/ibus/property.py
@@ -30,11 +30,11 @@ __all__ = (
"PROP_STATE_INCONSISTENT",
"Property",
"PropList",
- "property_from_dbus_value",
- "prop_list_from_dbus_value",
)
import dbus
+from text import Text
+from serializable import *
PROP_TYPE_NORMAL = 0
PROP_TYPE_TOGGLE = 1
@@ -52,18 +52,18 @@ def _to_unicode(text):
if isinstance(text, str):
return unicode(text, "utf8")
raise TypeError("text must be instance of unicode or str")
+def _to_text(text):
+ if isinstance(text, Text):
+ return text
+ text = _to_unicode(text)
+ return Text(text)
-class Property(object):
- def __init__(self, name,
- type = PROP_TYPE_NORMAL,
- label = u"",
- icon = u"",
- tooltip = u"",
- sensitive = True,
- visible = True,
- state = PROP_STATE_UNCHECKED):
+class Property(Serializable):
+ __NAME__ = "IBusProperty"
+ def __init__(self, key="", type=PROP_TYPE_NORMAL, label=u"", icon=u"", tooltip=u"",
+ sensitive=True, visible=True, state=PROP_STATE_UNCHECKED):
super(Property, self).__init__()
- self.__name = _to_unicode(name)
+ self.__key = _to_unicode(key)
self.__type = type
self.label = label
self.icon = icon
@@ -79,14 +79,14 @@ class Property(object):
def get_sub_props(self):
return self.__sub_props
- def get_name(self):
- return self.__name
+ def get_key(self):
+ return self.__key
def get_type(self):
return self.__type
def set_label(self, label):
- self.__label = _to_unicode(label)
+ self.__label = _to_text(label)
def get_label(self):
return self.__label
@@ -98,7 +98,7 @@ class Property(object):
return self.__icon
def set_tooltip(self, tooltip):
- self.__tooltip = _to_unicode(tooltip)
+ self.__tooltip = _to_text(tooltip)
def get_tooltip(self):
return self.__tooltip
@@ -121,7 +121,7 @@ class Property(object):
def get_visible(self):
return self.__visible
- name = property(get_name)
+ key = property(get_key)
type = property(get_type)
label = property(get_label, set_label)
icon = property(get_icon, set_icon)
@@ -146,38 +146,37 @@ class Property(object):
return self.__sub_props.is_same(prop.__sub_props, test_all)
- def to_dbus_value(self):
- sub_props = self.__sub_props.to_dbus_value()
- values = (dbus.String(self.__name),
- dbus.UInt32(self.__type),
- dbus.String(self.__label),
- dbus.String(self.__icon),
- dbus.String(self.__tooltip),
- dbus.Boolean(self.__sensitive),
- dbus.Boolean(self.__visible),
- dbus.UInt32(self.__state),
- sub_props)
- return dbus.Struct(values)
-
- def from_dbus_value(self, value):
- self.__name, \
- self.__type, \
- self.__label, \
- self.__icon, \
- self.__tooltip, \
- self.__sensitive, \
- self.__visible, \
- self.__state, \
- props = value
-
- self.__sub_props = prop_list_from_dbus_value(props)
-
-def property_from_dbus_value(value):
- p = Property("")
- p.from_dbus_value(value)
- return p
-
-class PropList(object):
+ def serialize(self, struct):
+ super(Property, self).serialize(struct)
+ struct.append(dbus.String(self.__key))
+ struct.append(dbus.UInt32(self.__type))
+ struct.append(serialize_object(self.__label))
+ struct.append(dbus.String(self.__icon))
+ struct.append(serialize_object(self.__tooltip))
+ struct.append(dbus.Boolean(self.__sensitive))
+ struct.append(dbus.Boolean(self.__visible))
+ struct.append(dbus.UInt32(self.__state))
+ sub_props = serialize_object(self.__sub_props)
+ struct.append(sub_props)
+
+ def deserialize(self, struct):
+ super(Property, self).deserialize(struct)
+ self.__key = struct.pop(0)
+ self.__type = struct.pop(0)
+ self.__label = deserialize_object(struct.pop(0))
+ self.__icon = struct.pop(0)
+ self.__tooltip = deserialize_object(struct.pop(0))
+ self.__sensitive = deserialize_object(struct.pop(0))
+ self.__visible = struct.pop(0)
+ self.__state = struct.pop(0)
+ props = struct.pop(0)
+
+ self.__sub_props = deserialize_object(props)
+
+serializable_register(Property)
+
+class PropList(Serializable):
+ __NAME__ = "IBusPropList"
def __init__(self):
super(PropList, self).__init__()
self.__props = []
@@ -203,14 +202,14 @@ class PropList(object):
return False
return False
- def to_dbus_value(self):
- props = map(lambda p: p.to_dbus_value(), self.__props)
- return dbus.Array(props, signature = "v")
+ def serialize(self, struct):
+ super(PropList, self).serialize(struct)
+ props = map(lambda p: serialize_object(p), self.__props)
+ struct.append (dbus.Array(props, signature = "v"))
- def from_dbus_value(self, value):
- props = []
- for p in value:
- props.append(property_from_dbus_value(p))
+ def deserialize(self, struct):
+ super(PropList, self).deserialize(struct)
+ props = map(lambda v: deserialize_object(v), struct.pop(0))
self.__props = props
def __iter__(self):
@@ -219,10 +218,7 @@ class PropList(object):
def __getitem__(self, i):
return self.__props.__getitem__(i)
-def prop_list_from_dbus_value(value):
- props = PropList()
- props.from_dbus_value(value)
- return props
+serializable_register(PropList)
def test():
props = PropList()
@@ -230,18 +226,9 @@ def test():
props.append(Property(u"b"))
props.append(Property(u"c"))
props.append(Property(u"d"))
- value = props.to_dbus_value()
- print prop_list_from_dbus_value(value)
-
- p = Property(u"z")
- p.set_sub_props(props)
- props = PropList()
- props.append(p)
- value = props.to_dbus_value()
- print prop_list_from_dbus_value(value)
- p.label = u"a"
- p.label = "a"
- p.label = 1
+ value = serialize_object(props)
+ props = deserialize_object(value)
+ print props
if __name__ == "__main__":
test()
diff --git a/ibus/serializable.py b/ibus/serializable.py
new file mode 100644
index 0000000..734940a
--- /dev/null
+++ b/ibus/serializable.py
@@ -0,0 +1,81 @@
+# vim:set et sts=4 sw=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
+
+__all__ = (
+ "serializable_register",
+ "Serializable",
+ "serialize_object",
+ "deserialize_object",
+ )
+
+from object import Object
+import dbus
+import gobject
+
+__serializable_name_dict = dict()
+
+def serializable_register(classobj):
+ if not issubclass(classobj, Serializable):
+ raise "%s is not a sub-class of Serializable" % str(classobj)
+ __serializable_name_dict[classobj.__NAME__] = classobj
+
+def serialize_object(o):
+ if isinstance(o, Serializable):
+ l = [o.__NAME__]
+ o.serialize(l)
+ return dbus.Struct(l)
+ else:
+ return o
+
+def deserialize_object(v):
+ if isinstance(v, tuple):
+ struct = list(v)
+ type_name = struct.pop(0)
+ type_class = __serializable_name_dict[type_name]
+ o = type_class()
+ o.deserialize (struct)
+ return o
+ return v
+
+class Serializable(Object):
+ __NAME__ = "IBusSerializable"
+ def __init__(self):
+ super(Serializable, self).__init__()
+ self.__attachments = dict()
+
+ def serialize(self, struct):
+ d = dbus.Dictionary(signature="sv")
+ for k, v in self.__attachments.items():
+ d[k] = serialize(v)
+ struct.append(d)
+
+ def deserialize(self, struct):
+ d = struct.pop(0)
+ self.__attachments = dict()
+ for k, v in d.items():
+ self.__atachments[k] = deserialize(v)
+
+ def do_destroy(self):
+ self.__attachments = None
+ super(Serializable, self).do_destroy()
+
+__serializable_name_dict["IBusSerializable"] = Serializable
+gobject.type_register(Serializable)
diff --git a/ibus/text.py b/ibus/text.py
new file mode 100644
index 0000000..9b47dbf
--- /dev/null
+++ b/ibus/text.py
@@ -0,0 +1,68 @@
+# vim:set et sts=4 sw=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
+
+__all__ = (
+ "Text",
+ )
+
+import dbus
+from exception import IBusException
+from serializable import *
+from attribute import AttrList
+
+class Text(Serializable):
+ __NAME__ = "IBusText"
+ def __init__ (self, text="", attrs=None):
+ super(Text, self).__init__()
+ self.__text = text
+ self.__attrs = attrs
+
+ def get_text(self):
+ return self.__text
+
+ def get_attributes(self):
+ return self.__attrs
+
+ text = property(get_text)
+ attributes = property(get_attributes)
+
+ def serialize(self, struct):
+ super(Text, self).serialize(struct)
+ struct.append (dbus.String(self.__text))
+ if self.__attrs == None:
+ self.__attrs = AttrList()
+ struct.append (serialize_object(self.__attrs))
+
+ def deserialize(self, struct):
+ super(Text, self).deserialize(struct)
+
+ self.__text = struct.pop(0)
+ self.__attrs = deserialize_object(struct.pop(0))
+
+serializable_register(Text)
+
+def test():
+ text = Text("Hello")
+ value = serialize_object(text)
+ text = deserialize_object(value)
+
+if __name__ == "__main__":
+ test()
diff --git a/launcher/Makefile.am b/launcher/Makefile.am
deleted file mode 100644
index 807f331..0000000
--- a/launcher/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
-# 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_SCRIPTS = ibus
-
-desktop_DATA = ibus.desktop
-desktopdir = $(datadir)/applications
-
-EXTRA_DIST = \
- ibus.in \
- ibus.desktop.in \
- $(NULL)
-
-CLEANFILES = \
- $(NULL)
diff --git a/launcher/ibus.desktop.in b/launcher/ibus.desktop.in
deleted file mode 100644
index 6b15b77..0000000
--- a/launcher/ibus.desktop.in
+++ /dev/null
@@ -1,11 +0,0 @@
-[Desktop Entry]
-Encoding=UTF-8
-Name=iBus
-GenericName=Intelligent Input Bus
-Comment=Intellignent Input Bus
-Exec=ibus
-Icon=ibus
-Terminal=false
-Type=Application
-StartupNotify=false
-Categories=Utility;
diff --git a/launcher/ibus.in b/launcher/ibus.in
deleted file mode 100644
index 0f8c5fd..0000000
--- a/launcher/ibus.in
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/env python
-# vim:set et sts=4 sw=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
-
-import os
-import os.path
-import atexit
-import sys
-import time
-import ibus
-import dbus
-import signal
-
-daemon = "@prefix@/bin/ibus-daemon"
-x11 = "@prefix@/bin/ibus-x11"
-ui = "@prefix@/bin/ibus-ui-gtk"
-conf = "@prefix@/bin/ibus-gconf"
-
-class Launcher(object):
- def __init__(self):
- super(Launcher, self).__init__()
- self.__daemon_pid = 0
- self.__ui_pid = 0
- self.__conf_pid = 0
- self.__x11_pid = 0
- self.__bus = None
- self.__preload_engine_completed = False
-
- def __start_process(self, path, args, cmd):
- pid = 0
- try:
- print "Starting %s" % cmd,
- pid = os.spawnv (os.P_NOWAIT, path, args)
- print "OK"
- except:
- print >> sys.stderr, "Start %s Failed" % cmd
- return pid
-
- def __bus_destroy_cb(self, bus):
- self.__bus = None
- ibus.main_quit()
-
- def __bus_config_reloaded_cb(self, bus):
- self.__launch_auto_load_engines()
-
- def __signal_cb(self, sig, stack):
- if sig == signal.SIGCHLD:
- pid, status = os.wait()
- if pid == self.__daemon_pid:
- self.__daemon_pid = 0
- self.__bus = None
- elif pid == self.__x11_pid:
- self.__x11_pid = 0
- elif pid == self.__ui_pid:
- self.__ui_pid = 0
- elif pid == self.__conf_pid:
- self.__conf_pid = 0
- elif sig == signal.SIGTERM or sig == signal.SIGINT:
- sys.exit(1)
-
- def __atexit_cb(self):
- if self.__bus:
- try:
- self.__bus.kill()
- except:
- pass
- os.kill(-os.getpid(), signal.SIGTERM)
-
- def run(self):
- try:
- bus = ibus.Bus()
- print >> sys.stderr, "Found an ibus-daemon has been started!"
- sys.exit(1)
- except dbus.DBusException, e:
- pass
-
- # make self process group leader
- if os.getpid() != os.getpgid(os.getpid()):
- os.setpgid(0, 0)
-
- signal.signal(signal.SIGCHLD, self.__signal_cb)
- signal.signal(signal.SIGINT, self.__signal_cb)
- signal.signal(signal.SIGTERM, self.__signal_cb)
- atexit.register(self.__atexit_cb)
-
- # start ibus-daemon
- self.__daemon_pid = self.__start_process(daemon, [daemon], "ibus-daemon")
- if self.__daemon_pid <= 0:
- sys.exit(1)
-
- for i in range(5):
- time.sleep (1)
- try:
- self.__bus = ibus.Bus()
- break
- except:
- pass
-
- if self.__bus == None:
- print >> sys.stderr, "Start ibus-daemon failed"
- sys.exit(1)
-
- self.__bus.connect("destroy", self.__bus_destroy_cb)
- self.__bus.connect("config-reloaded", self.__bus_config_reloaded_cb)
-
- self.__conf_pid = self.__start_process(conf, [conf], "ibus-conf")
- self.__ui_pid = self.__start_process(ui, [ui], "ibus-ui-gtk")
- self.__x11_pid = self.__start_process(x11, [x11, "--kill-daemon"], "ibus-x11")
- ibus.main()
-
- def __launch_auto_load_engines(self):
- if self.__preload_engine_completed:
- return
- engines = []
- try:
- engines = self.__bus.config_get_value("general", "preload_engines", None)
- if not engines:
- engines = []
- else:
- self.__preload_engine_completed = True
- except:
- pass
- for e in engines:
- try:
- lang, name = e.split(":")
- self.__bus.register_start_engine(lang, name)
- except:
- import traceback
- traceback.print_exc()
-
-
-
-if __name__ == "__main__":
- Launcher().run()
diff --git a/lib/gtk2/Makefile.am b/lib/gtk2/Makefile.am
deleted file mode 100644
index e4b1cd1..0000000
--- a/lib/gtk2/Makefile.am
+++ /dev/null
@@ -1,71 +0,0 @@
-# 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
-
-INCLUDES = \
- -I$(top_srcdir) \
- $(NULL)
-
-BUILT_SOURCES = \
- ibusmarshalers.h \
- ibusmarshalers.c \
- $(NULL)
-
-lib_LTLIBRARIES = libibus-gtk.la
-libibus_gtk_la_SOURCES = \
- ibusmarshalers.h \
- ibusmarshalers.c \
- ibusimclient.h \
- ibusimclient.c \
- ibusattribute.h \
- ibusattribute.c \
- $(NULL)
-libibus_gtk_la_CFLAGS = \
- @X11_CFLAGS@ \
- @GDK2_CFLAGS@ \
- @DBUS_CFLAGS@ \
- -DG_LOG_DOMAIN=\"IBUS\" \
- $(NULL)
-libibus_gtk_la_LDFLAGS = \
- @X11_LIBS@ \
- @GDK2_LIBS@ \
- @DBUS_LIBS@ \
- $(NULL)
-
-# gen marshal
-ibusmarshalers.h: stamp-ibusmarshalers.h
- @true
-stamp-ibusmarshalers.h: ibusmarshalers.list
- $(GLIB_GENMARSHAL) --prefix=ibus_marshal $(srcdir)/ibusmarshalers.list --header >> xgen-gmh \
- && (cmp -s xgen-gmh ibusmarshalers.h || cp xgen-gmh ibusmarshalers.h) \
- && rm -f xgen-gmh \
- && echo timestamp > $(@F)
-ibusmarshalers.c: ibusmarshalers.list
- (echo "#include \"ibusmarshalers.h\""; \
- $(GLIB_GENMARSHAL) --prefix=ibus_marshal $(srcdir)/ibusmarshalers.list --body; \
- echo ) >> xgen-gmc \
- && cp xgen-gmc ibusmarshalers.c \
- && rm -f xgen-gmc
-
-EXTRA_DIST = \
- ibusmarshalers.list \
- $(NULL)
-
-CLEANFILES = $(BUILT_SOURCES) stamp-ibusmarshalers.h
diff --git a/lib/gtk2/ibusattribute.c b/lib/gtk2/ibusattribute.c
deleted file mode 100644
index 2237509..0000000
--- a/lib/gtk2/ibusattribute.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/* vim:set et sts=4: */
-/* IBus - The Input Bus
- * Copyright (C) 2008-2009 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#include <glib.h>
-#include "ibusattribute.h"
-
-GType
-ibus_attribute_get_type ()
-{
- static GType type = 0;
- if (type == 0) {
- type = g_boxed_type_register_static ("IBusAttribute",
- (GBoxedCopyFunc)ibus_attribute_copy,
- (GBoxedFreeFunc)ibus_attribute_free);
- }
- return type;
-}
-
-IBusAttribute *
-ibus_attribute_new (guint type, guint value, guint start_index, guint end_index)
-{
- g_return_val_if_fail (
- type == IBUS_ATTR_TYPE_UNDERLINE ||
- type == IBUS_ATTR_TYPE_FOREGROUND ||
- type == IBUS_ATTR_TYPE_BACKGROUND, NULL);
-
- IBusAttribute *attr = g_slice_new (IBusAttribute);
-
- attr->type = type;
- attr->value = value;
- attr->start_index = start_index;
- attr->end_index = end_index;
- return attr;
-}
-
-IBusAttribute *
-ibus_attribute_copy (IBusAttribute * attr)
-{
- g_assert (attr != NULL);
- return ibus_attribute_new (attr->type, attr->value, attr->start_index, attr->end_index);
-}
-
-void
-ibus_attribute_free (IBusAttribute *attr)
-{
- g_assert (attr != NULL);
- g_slice_free (IBusAttribute, attr);
-}
-
-IBusAttribute *
-ibus_attr_underline_new (guint underline_type, guint start_index, guint end_index)
-{
- g_return_val_if_fail (
- underline_type == IBUS_ATTR_UNDERLINE_NONE ||
- underline_type == IBUS_ATTR_UNDERLINE_SINGLE ||
- underline_type == IBUS_ATTR_UNDERLINE_DOUBLE ||
- underline_type == IBUS_ATTR_UNDERLINE_LOW, NULL);
-
- return ibus_attribute_new (IBUS_ATTR_TYPE_UNDERLINE, underline_type, start_index, end_index);
-}
-
-IBusAttribute *
-ibus_attr_foreground_new (guint color, guint start_index, guint end_index)
-{
- return ibus_attribute_new (IBUS_ATTR_TYPE_FOREGROUND, color, start_index, end_index);
-}
-
-IBusAttribute *
-ibus_attr_background_new (guint color, guint start_index, guint end_index)
-{
- return ibus_attribute_new (IBUS_ATTR_TYPE_BACKGROUND, color, start_index, end_index);
-}
-
-GType
-ibus_attr_list_get_type ()
-{
- static GType type = 0;
- if (type == 0) {
- type = g_boxed_type_register_static ("IBusAttrList",
- (GBoxedCopyFunc)ibus_attr_list_copy,
- (GBoxedFreeFunc)ibus_attr_list_unref);
- }
- return type;
-}
-
-IBusAttrList *
-ibus_attr_list_new ()
-{
- IBusAttrList *attr_list = g_slice_new(IBusAttrList);
- attr_list->refcount = 1;
- attr_list->attributes = g_array_new (TRUE, TRUE, sizeof (IBusAttribute *));
- return attr_list;
-}
-
-IBusAttrList *
-ibus_attr_list_copy (IBusAttrList *attr_list)
-{
- IBusAttrList *new_list = ibus_attr_list_new ();
- guint i;
- for (i = 0;; i++) {
- IBusAttribute *attr = ibus_attr_list_get (attr_list, i);
- if (attr == NULL) {
- break;
- }
- ibus_attr_list_append (new_list, ibus_attribute_copy (attr));
- }
- return new_list;
-}
-
-IBusAttrList *
-ibus_attr_list_ref (IBusAttrList *attr_list)
-{
- if (attr_list == NULL) {
- return NULL;
- }
- attr_list->refcount ++;
- return attr_list;
-}
-
-void
-ibus_attr_list_unref (IBusAttrList *attr_list)
-{
- if (attr_list == NULL) {
- return;
- }
-
- attr_list->refcount --;
- if (attr_list->refcount <= 0) {
- guint i;
- for (i = 0; i < attr_list->attributes->len; i++) {
- IBusAttribute *attr = g_array_index (attr_list->attributes,
- IBusAttribute *, i);
- if (attr != NULL) {
- ibus_attribute_free (attr);
- }
- }
- g_array_free (attr_list->attributes, TRUE);
- g_slice_free (IBusAttrList, attr_list);
- }
-}
-
-void
-ibus_attr_list_append (IBusAttrList *attr_list, IBusAttribute *attr)
-{
- g_return_if_fail (attr_list != NULL);
- g_return_if_fail (attr != NULL);
- g_array_append_val (attr_list->attributes, attr);
-}
-
-IBusAttribute *
-ibus_attr_list_get (IBusAttrList *attr_list, guint index)
-{
- g_return_val_if_fail (attr_list != NULL, NULL);
- IBusAttribute *attr = NULL;
- if (index < attr_list->attributes->len) {
- attr = g_array_index (attr_list->attributes, IBusAttribute *, index);
- }
- return attr;
-}
-
-IBusAttribute *
-ibus_attribute_from_dbus_message (DBusMessageIter *iter)
-{
- gint type;
- DBusMessageIter sub_iter;
-
- guint _type, value, start_index, end_index;
-
- type = dbus_message_iter_get_arg_type (iter);
- g_return_val_if_fail (type == DBUS_TYPE_STRUCT, NULL);
-
- dbus_message_iter_recurse (iter, &sub_iter);
-
- g_return_val_if_fail (dbus_message_iter_get_arg_type (&sub_iter) == DBUS_TYPE_UINT32, NULL);
- dbus_message_iter_get_basic (&sub_iter, &_type);
- dbus_message_iter_next (&sub_iter);
-
- g_return_val_if_fail (dbus_message_iter_get_arg_type (&sub_iter) == DBUS_TYPE_UINT32, NULL);
- dbus_message_iter_get_basic (&sub_iter, &value);
- dbus_message_iter_next (&sub_iter);
-
- g_return_val_if_fail (dbus_message_iter_get_arg_type (&sub_iter) == DBUS_TYPE_UINT32, NULL);
- dbus_message_iter_get_basic (&sub_iter, &start_index);
- dbus_message_iter_next (&sub_iter);
-
- g_return_val_if_fail (dbus_message_iter_get_arg_type (&sub_iter) == DBUS_TYPE_UINT32, NULL);
- dbus_message_iter_get_basic (&sub_iter, &end_index);
- dbus_message_iter_next (&sub_iter);
-
- dbus_message_iter_next (iter);
-
- return ibus_attribute_new (_type, value, start_index, end_index);
-}
-
-IBusAttrList *
-ibus_attr_list_from_dbus_message (DBusMessageIter *iter)
-{
- gint type;
- DBusMessageIter sub_iter;
- IBusAttrList *attr_list;
-
- type = dbus_message_iter_get_arg_type (iter);
- g_return_val_if_fail (type == DBUS_TYPE_ARRAY, NULL);
-
- attr_list = ibus_attr_list_new ();
-
- dbus_message_iter_recurse (iter, &sub_iter);
-
- while (dbus_message_iter_get_arg_type (&sub_iter) != DBUS_TYPE_INVALID) {
- IBusAttribute *attr = ibus_attribute_from_dbus_message (&sub_iter);
- if (attr == NULL)
- break;
- ibus_attr_list_append (attr_list, attr);
- }
-
- dbus_message_iter_next (iter);
- return attr_list;
-}
-
-gboolean
-ibus_attribute_to_dbus_message (IBusAttribute *attr, DBusMessageIter *iter)
-{
- g_assert (attr != NULL);
- g_assert (iter != NULL);
-
- DBusMessageIter sub_iter;
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, 0, &sub_iter);
- dbus_message_iter_append_basic (&sub_iter, DBUS_TYPE_UINT32, &attr->type);
- dbus_message_iter_append_basic (&sub_iter, DBUS_TYPE_UINT32, &attr->value);
- dbus_message_iter_append_basic (&sub_iter, DBUS_TYPE_UINT32, &attr->start_index);
- dbus_message_iter_append_basic (&sub_iter, DBUS_TYPE_UINT32, &attr->end_index);
- dbus_message_iter_close_container (iter, &sub_iter);
-
- return TRUE;
-}
-
-
-gboolean
-ibus_attr_list_to_dbus_message (IBusAttrList *attr_list, DBusMessageIter *iter)
-{
- g_assert (attr_list != NULL);
- g_assert (iter != NULL);
-
- gint i;
- DBusMessageIter sub_iter;
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(uuuu)", &sub_iter);
- for (i = 0;; i++) {
- IBusAttribute *attr = ibus_attr_list_get (attr_list, i);
- if (attr == NULL)
- break;
- ibus_attribute_to_dbus_message (attr, &sub_iter);
- }
- dbus_message_iter_close_container (iter, &sub_iter);
- return TRUE;
-}
-
-
-
diff --git a/lib/gtk2/ibusattribute.h b/lib/gtk2/ibusattribute.h
deleted file mode 100644
index 4678522..0000000
--- a/lib/gtk2/ibusattribute.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* vim:set et sts=4: */
-/* IBus - The Input Bus
- * Copyright (C) 2008-2009 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __IBUS_ATTRIBUTE_H_
-#define __IBUS_ATTRIBUTE_H_
-
-#include <glib-object.h>
-#include <dbus/dbus.h>
-
-/*
- * Type macros.
- */
-#define IBUS_TYPE_ATTRIBUTE (ibus_attribute_get_type ())
-#define IBUS_TYPE_ATTR_LIST (ibus_attr_list_get_type ())
-
-/* define GOBJECT macros */
-
-#define IBUS_ATTR_TYPE_UNDERLINE 1
-#define IBUS_ATTR_TYPE_FOREGROUND 2
-#define IBUS_ATTR_TYPE_BACKGROUND 3
-
-#define IBUS_ATTR_UNDERLINE_NONE 0
-#define IBUS_ATTR_UNDERLINE_SINGLE 1
-#define IBUS_ATTR_UNDERLINE_DOUBLE 2
-#define IBUS_ATTR_UNDERLINE_LOW 3
-
-G_BEGIN_DECLS
-typedef struct _IBusAttribute IBusAttribute;
-typedef struct _IBusAttrList IBusAttrList;
-
-struct _IBusAttribute {
- guint type;
- guint value;
- guint start_index;
- guint end_index;
-};
-
-struct _IBusAttrList {
- gint refcount;
- GArray *attributes;
-};
-
-GType ibus_attribute_get_type ();
-IBusAttribute *ibus_attribute_new (guint type,
- guint value,
- guint start_index,
- guint end_index);
-IBusAttribute *ibus_attribute_copy (IBusAttribute
- *attr);
-void ibus_attribute_free (IBusAttribute
- *attr);
-IBusAttribute *ibus_attr_underline_new (guint underline_type,
- guint start_index,
- guint end_index);
-IBusAttribute *ibus_attr_foreground_new (guint color,
- guint start_index,
- guint end_index);
-IBusAttribute *ibus_attr_background_new (guint color,
- guint start_index,
- guint end_index);
-IBusAttribute *ibus_attribute_from_dbus_message
- (DBusMessageIter *iter);
-gboolean ibus_attribute_to_dbus_message
- (IBusAttribute *attr,
- DBusMessageIter *iter);
-
-
-GType ibus_attr_list_get_type ();
-IBusAttrList *ibus_attr_list_new ();
-IBusAttrList *ibus_attr_list_copy (IBusAttrList *attr_list);
-IBusAttrList *ibus_attr_list_ref (IBusAttrList *attr_list);
-void ibus_attr_list_unref (IBusAttrList *attr_list);
-void ibus_attr_list_append (IBusAttrList *attr_list,
- IBusAttribute *attr);
-IBusAttribute *ibus_attr_list_get (IBusAttrList *attr_list,
- guint index);
-IBusAttrList *ibus_attr_list_from_dbus_message
- (DBusMessageIter *iter);
-gboolean ibus_attr_list_to_dbus_message
- (IBusAttrList *attr_list,
- DBusMessageIter *iter);
-G_END_DECLS
-#endif
-
diff --git a/lib/gtk2/ibusimclient.c b/lib/gtk2/ibusimclient.c
deleted file mode 100644
index 31de0a8..0000000
--- a/lib/gtk2/ibusimclient.c
+++ /dev/null
@@ -1,1536 +0,0 @@
-/* vim:set et ts=4: */
-/* ibus - The Input Bus
- * Copyright (C) 2008-2009 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#include <config.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <pwd.h>
-#include <glib/gstdio.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-#include <gdk/gdkkeysyms.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
-#ifdef HAVE_X11_XKBLIB_H
-# define HAVE_XKB
-# include <X11/XKBlib.h>
-#endif
-
-#ifdef HAVE_SYS_INOTIFY_H
-#define HAVE_INOTIFY
-# include <sys/inotify.h>
-#endif
-
-#include "ibusmarshalers.h"
-#include "ibusattribute.h"
-#include "ibusimclient.h"
-#define IBUS_NAME "org.freedesktop.IBus"
-#define IBUS_IFACE "org.freedesktop.IBus"
-#define IBUS_PATH "/org/freedesktop/IBus"
-
-#define I_(string) g_intern_static_string (string)
-
-enum {
- CONNECTED,
- DISCONNECTED,
- FORWARD_EVENT,
- COMMIT_STRING,
- UPDATE_PREEDIT,
- SHOW_PREEDIT,
- HIDE_PREEDIT,
- ENABLED,
- DISABLED,
- LAST_SIGNAL,
-};
-
-
-/* IBusIMClientPriv */
-struct _IBusIMClientPrivate {
-#if USE_DBUS_SESSION_BUS
- DBusConnection *dbus;
-#endif
-
-#ifdef HAVE_INOTIFY
- /* inotify */
- gint inotify_wd;
- GIOChannel *inotify_channel;
- guint inotify_source;
-#endif
-
- GdkKeymap *keymap;
- gulong keymap_handler_id;
-
- /* hack japanese [yen bar] & [backslash underbar] key */
- guint japan_groups;
- GArray *japan_yen_bar_keys;
-
- DBusConnection *ibus;
-
-};
-
-typedef struct _KeyPressCallData KeyPressCallData;
-
-
-/* variables */
-static guint client_signals[LAST_SIGNAL] = { 0 };
-
-/* functions prototype */
-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);
-
-static void _keymap_find_japan_groups (IBusIMClient *client);
-static void _keymap_find_yen_bar_keys (IBusIMClient *client);
-static void _keymap_keys_changed_cb (GdkKeymap *keymap,
- IBusIMClient *client);
-
-static void _ibus_im_client_ibus_open (IBusIMClient *client);
-static void _ibus_im_client_ibus_close (IBusIMClient *client);
-
-static gboolean _ibus_call_with_reply_and_block
- (DBusConnection *connection,
- const gchar *method,
- int first_arg_type,
- ...);
-static gboolean _ibus_call_with_reply (DBusConnection *connection,
- const gchar *method,
- DBusPendingCallNotifyFunction
- function,
- void *data,
- DBusFreeFunction free_function,
- int first_arg_type,
- ...);
-static gboolean _dbus_call_with_reply_and_block
- (DBusConnection *connection,
- const gchar *dest,
- const gchar *path,
- const gchar *iface,
- const char *method,
- int first_arg_type,
- ...);
-
-/* callback functions */
-static DBusHandlerResult
- _ibus_im_client_message_filter_cb
- (DBusConnection *connection,
- DBusMessage *message,
- void *user_data);
-static void _ibus_filter_keypress_reply_cb
- (DBusPendingCall *pending,
- void *user_data);
-static KeyPressCallData *
- _key_press_call_data_new (IBusIMClient *client,
- const gchar *ic,
- GdkEvent *event);
-static void _key_press_call_data_free (KeyPressCallData *call_data);
-
-
-static GType _ibus_type_im_client = 0;
-static GObjectClass *_parent_class = NULL;
-
-
-GType
-ibus_im_client_get_type (void)
-{
- if (_ibus_type_im_client == 0) {
- ibus_im_client_register_type (NULL);
- }
-
- g_assert (_ibus_type_im_client != 0);
- return _ibus_type_im_client;
-}
-
-void
-ibus_im_client_register_type (GTypeModule *type_module)
-{
- 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 */
- sizeof (IBusIMClient),
- 0,
- (GInstanceInitFunc) ibus_im_client_init,
- };
-
- if (_ibus_type_im_client == 0) {
- if (type_module) {
- _ibus_type_im_client =
- g_type_module_register_type (type_module,
- G_TYPE_OBJECT,
- "IBusIMClient",
- &ibus_im_client_info,
- (GTypeFlags)0);
- }
- else {
- _ibus_type_im_client =
- g_type_register_static (G_TYPE_OBJECT,
- "IBusIMClient",
- &ibus_im_client_info,
- (GTypeFlags)0);
- }
- }
-}
-
-IBusIMClient *
-ibus_im_client_new (void)
-{
- IBusIMClient *client;
-
- client = IBUS_IM_CLIENT (g_object_new (IBUS_TYPE_IM_CLIENT, NULL));
-
- return client;
-}
-
-static void
-ibus_im_client_class_init (IBusIMClientClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- _parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
-
- g_type_class_add_private (klass, sizeof (IBusIMClientPrivate));
-
- gobject_class->finalize = ibus_im_client_finalize;
-
- 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,
- ibus_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,
- ibus_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- client_signals[FORWARD_EVENT] =
- g_signal_new (I_("forward-event"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (IBusIMClientClass, commit_string),
- NULL, NULL,
- ibus_marshal_VOID__STRING_BOXED,
- G_TYPE_NONE, 2,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
- GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-
- client_signals[COMMIT_STRING] =
- g_signal_new (I_("commit-string"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (IBusIMClientClass, commit_string),
- NULL, NULL,
- ibus_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- client_signals[UPDATE_PREEDIT] =
- g_signal_new (I_("update-preedit"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (IBusIMClientClass, update_preedit),
- NULL, NULL,
- ibus_marshal_VOID__STRING_STRING_BOXED_INT_BOOLEAN,
- G_TYPE_NONE, 5,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
- IBUS_TYPE_ATTR_LIST | G_SIGNAL_TYPE_STATIC_SCOPE,
- G_TYPE_INT | G_SIGNAL_TYPE_STATIC_SCOPE,
- G_TYPE_BOOLEAN | G_SIGNAL_TYPE_STATIC_SCOPE
- );
-
- client_signals[SHOW_PREEDIT] =
- g_signal_new (I_("show-preedit"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (IBusIMClientClass, show_preedit),
- NULL, NULL,
- ibus_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- client_signals[HIDE_PREEDIT] =
- g_signal_new (I_("hide-preedit"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (IBusIMClientClass, hide_preedit),
- NULL, NULL,
- ibus_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- client_signals[ENABLED] =
- g_signal_new (I_("enabled"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (IBusIMClientClass, enabled),
- NULL, NULL,
- ibus_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- client_signals[DISABLED] =
- g_signal_new (I_("disabled"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (IBusIMClientClass, disabled),
- NULL, NULL,
- ibus_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-}
-
-/*
- * open ibus connection
- */
-static void
-_ibus_im_client_ibus_open (IBusIMClient *client)
-{
- gchar *ibus_addr = NULL;
- DBusError error;
-
- IBusIMClientPrivate *priv = client->priv;
-
- if (priv->ibus != NULL)
- return;
-
-#if USE_DBUS_SESSION_BUS
- dbus_connection_setup_with_g_main (priv->dbus, NULL);
- if (!_dbus_call_with_reply_and_block (priv->dbus,
- 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;
- }
- }
-
- username = g_strdup (getlogin());
- if (username == NULL)
- username = g_strdup (g_getenv("SUDO_USER"));
- if (username == NULL) {
- const gchar *uid = g_getenv ("USERHELPER_UID");
- if (uid != NULL) {
- gchar *end;
- uid_t id = (uid_t)strtol(uid, &end, 10);
- if (uid != end) {
- struct passwd *pw = getpwuid (id);
- if (pw != NULL) {
- username = g_strdup (pw->pw_name);
- }
- }
- }
- }
- if (username == NULL)
- username = g_strdup (g_getenv("USERNAME"));
- if (username == NULL)
- username = g_strdup (g_getenv("LOGNAME"));
- if (username == NULL)
- username = g_strdup (g_getenv("USER"));
- if (username == NULL)
- username = g_strdup (g_getenv("LNAME"));
-
- ibus_addr = g_strdup_printf (
- "unix:path=/tmp/ibus-%s/ibus-%s-%s.%s",
- username, hostname, displaynumber, screennumber);
-
- g_free (display);
- g_free (username);
- }
-
- /*
- * Init ibus and proxy object
- */
- dbus_error_init (&error);
- priv->ibus = dbus_connection_open_private (ibus_addr, &error);
- g_free (ibus_addr);
- if (priv->ibus == NULL) {
- g_warning ("Error: %s", error.message);
- dbus_error_free (&error);
- return;
- }
-
- if (!dbus_connection_add_filter (priv->ibus,
- _ibus_im_client_message_filter_cb,
- client, NULL)) {
- g_warning ("Out of memory");
- return;
- }
-
- dbus_connection_setup_with_g_main (priv->ibus, NULL);
-
- g_signal_emit (client, client_signals[CONNECTED], 0);
-
-}
-
-/*
- * close ibus connection
- */
-static void
-_ibus_im_client_ibus_close (IBusIMClient *client)
-{
- IBusIMClientPrivate *priv = client->priv;
-
- if (priv->ibus) {
- dbus_connection_close (priv->ibus);
- dbus_connection_unref (priv->ibus);
- priv->ibus = NULL;
- g_signal_emit (client, client_signals[DISCONNECTED], 0);
- }
-}
-
-
-
-#ifdef HAVE_INOTIFY
-static gboolean
-_ibus_im_client_inotify_cb (GIOChannel *source, GIOCondition condition, IBusIMClient *client)
-{
- struct inotify_event *p = NULL;
- gchar *name;
- 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) {
- if (p->mask & IN_CREATE) {
- g_usleep (1000);
- _ibus_im_client_ibus_open (client);
- }
- }
- g_free (name);
- g_free (p);
-
- return TRUE;
-}
-#endif
-
-
-static void
-ibus_im_client_init (IBusIMClient *obj)
-{
- DEBUG_FUNCTION_IN;
-
- IBusIMClient *client = IBUS_IM_CLIENT (obj);
- IBusIMClientPrivate *priv;
-
- gchar *watch_path;
- struct stat stat_buf;
-
-#ifdef HAVE_INOTIFY
- gint inotify_fd = inotify_init ();
-#endif
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (client, IBUS_TYPE_IM_CLIENT, IBusIMClientPrivate);
- client->priv = priv;
-
- 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);
- }
-
-#ifdef HAVE_INOTIFY
- /* init inotify */
- 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,
- (GIOFunc)_ibus_im_client_inotify_cb,
- (gpointer)client);
-#endif
- g_free (watch_path);
-
-#if USE_DBUS_SESSION_BUS
- /*
- * Init dbus
- */
- 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
-
- _ibus_im_client_ibus_open (client);
-
-#if USE_DBUS_SESSION_BUS
- if (!dbus_connection_add_filter (priv->dbus,
- _ibus_im_client_message_filter_cb,
- client, NULL)) {
- g_warning ("Out of memory");
- return;
- }
-
- gchar *rule =
- "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,
- 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 ((priv->keymap = gdk_keymap_get_default ()) != NULL) {
- g_object_ref (priv->keymap);
- _keymap_find_japan_groups (client);
- _keymap_find_yen_bar_keys (client);
- // g_debug ("japan_groups = 0x%x", priv->japan_groups);
-
- priv->keymap_handler_id =
- g_signal_connect (priv->keymap, "keys-changed",
- G_CALLBACK (_keymap_keys_changed_cb), client);
- }
-
-#if USE_DBUS_SESSION_BUS
- /* 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);
-
- /* 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",
- 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',"
- "arg0='" IBUS_DBUS_SERVICE "'",
- &dbus_error);
-
- _ibus_im_client_reinit_imm (client);
-#endif
-
-}
-
-
-static void
-ibus_im_client_finalize (GObject *obj)
-{
- DEBUG_FUNCTION_IN;
-
- IBusIMClient *client = IBUS_IM_CLIENT (obj);
- IBusIMClientPrivate *priv = client->priv;
-
- if (priv->keymap) {
- g_signal_handler_disconnect (priv->keymap, priv->keymap_handler_id);
- g_object_unref (priv->keymap);
- }
-
-#ifdef HAVE_INOTIFY
- g_source_remove (priv->inotify_source);
- g_io_channel_unref (priv->inotify_channel);
-#endif
-
-#if USE_DBUS_SESSION_BUS
- if (priv->dbus) {
- dbus_connection_unref (priv->dbus);
- }
-#endif
- _ibus_im_client_ibus_close (client);
-
- G_OBJECT_CLASS(_parent_class)->finalize (obj);
-
-}
-
-/*
- * create an input context
- */
-const gchar *
-ibus_im_client_create_input_context (IBusIMClient *client)
-{
- g_return_val_if_fail (IBUS_IS_IM_CLIENT (client), NULL);
-
- IBusIMClientPrivate *priv = client->priv;
-
- if (priv->ibus == NULL)
- return NULL;
-
- 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;
-}
-
-/*
- * release an input context
- */
-void
-ibus_im_client_release_input_context (IBusIMClient *client, const gchar *ic)
-{
- g_return_if_fail (IBUS_IS_IM_CLIENT (client));
- g_return_if_fail (ic != NULL);
-
- IBusIMClientPrivate *priv = client->priv;
-
- _ibus_call_with_reply_and_block (priv->ibus, "ReleaseInputContext",
- DBUS_TYPE_STRING, &ic,
- DBUS_TYPE_INVALID,
- DBUS_TYPE_INVALID);
-
-}
-
-
-gboolean
-ibus_im_client_filter_keypress (IBusIMClient *client, const gchar *ic, GdkEventKey *event, gboolean block)
-{
- g_return_val_if_fail (IBUS_IS_IM_CLIENT(client), FALSE);
- g_return_val_if_fail (ic != NULL, FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- IBusIMClientPrivate *priv = client->priv;
-
- guint state = event->state;
- gboolean is_press = event->type == GDK_KEY_PRESS;
-
- if ((event->state & IBUS_FORWARD_MASK) != 0) {
- return FALSE;
- }
-
- /* add forward mask, and will not process this event again */
- event->state |= IBUS_FORWARD_MASK;
-
- /* hack for [yen bar] and [backslash underscore] keys in Japan keyboard */
- guint keyval = event->keyval;
- if (event->keyval == GDK_backslash &&
- priv->japan_yen_bar_keys != NULL &&
- (1L << event->group) & priv->japan_groups)
- {
- int i;
- for (i = 0; i < priv->japan_yen_bar_keys->len; i++) {
- GdkKeymapKey *key = &g_array_index (priv->japan_yen_bar_keys, GdkKeymapKey, i);
- if (event->hardware_keycode == key->keycode && event->group == key->group) {
- keyval = GDK_yen;
- break;
- }
- }
- }
-
- /* Call IBus ProcessKeyEvent method */
- if (!block) {
- if (!_ibus_call_with_reply (priv->ibus,
- "ProcessKeyEvent",
- _ibus_filter_keypress_reply_cb,
- _key_press_call_data_new (client, ic, (GdkEvent *)event),
- (DBusFreeFunction)_key_press_call_data_free,
- DBUS_TYPE_STRING, &ic,
- DBUS_TYPE_UINT32, &keyval,
- DBUS_TYPE_BOOLEAN, &is_press,
- DBUS_TYPE_UINT32, &state,
- DBUS_TYPE_INVALID))
- return FALSE;
- else
- return TRUE;
- }
- else {
- gboolean result = FALSE;
- if (!_ibus_call_with_reply_and_block (priv->ibus,
- "ProcessKeyEvent",
- DBUS_TYPE_STRING, &ic,
- DBUS_TYPE_UINT32, &keyval,
- DBUS_TYPE_BOOLEAN, &is_press,
- DBUS_TYPE_UINT32, &state,
- DBUS_TYPE_INVALID,
- DBUS_TYPE_BOOLEAN, &result,
- DBUS_TYPE_INVALID))
- return FALSE;
-
- return result;
- }
-}
-
-
-void
-ibus_im_client_focus_in (IBusIMClient *client, const gchar *ic)
-{
- g_return_if_fail (IBUS_IS_IM_CLIENT (client));
- g_return_if_fail (ic != NULL);
-
- IBusIMClientPrivate *priv = client->priv;
-
- /* Call IBus FocusIn method */
- _ibus_call_with_reply_and_block (priv->ibus,
- "FocusIn",
- DBUS_TYPE_STRING, &ic,
- DBUS_TYPE_INVALID,
- DBUS_TYPE_INVALID);
-}
-
-void
-ibus_im_client_focus_out (IBusIMClient *client, const gchar *ic)
-{
- g_return_if_fail (IBUS_IS_IM_CLIENT (client));
- g_return_if_fail (ic != NULL);
-
- IBusIMClientPrivate *priv = client->priv;
-
- /* Call IBus FocusOut method */
- _ibus_call_with_reply_and_block (priv->ibus,
- "FocusOut",
- DBUS_TYPE_STRING, &ic,
- DBUS_TYPE_INVALID,
- DBUS_TYPE_INVALID);
-
-}
-
-void
-ibus_im_client_reset (IBusIMClient *client, const gchar *ic)
-{
- g_return_if_fail (IBUS_IS_IM_CLIENT (client));
- g_return_if_fail (ic != NULL);
-
- IBusIMClientPrivate *priv = client->priv;
-
- /* Call IBus Reset method */
- _ibus_call_with_reply_and_block (priv->ibus,
- "Reset",
- DBUS_TYPE_STRING, &ic,
- DBUS_TYPE_INVALID,
- DBUS_TYPE_INVALID);
-
-}
-
-void
-ibus_im_client_set_cursor_location (IBusIMClient *client, const gchar *ic, GdkRectangle *area)
-{
- g_return_if_fail (IBUS_IS_IM_CLIENT (client));
- g_return_if_fail (ic != NULL);
- g_return_if_fail (area != NULL);
-
- _ibus_call_with_reply_and_block (client->priv->ibus,
- "SetCursorLocation",
- DBUS_TYPE_STRING, &ic,
- 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);
-}
-
-void
-ibus_im_client_set_capabilities (IBusIMClient *client, const gchar *ic, gint caps)
-{
- g_return_if_fail (IBUS_IS_IM_CLIENT (client));
- g_return_if_fail (ic != NULL);
-
- _ibus_call_with_reply_and_block (client->priv->ibus,
- "SetCapabilities",
- DBUS_TYPE_STRING, &ic,
- DBUS_TYPE_INT32, &caps,
- DBUS_TYPE_INVALID,
- DBUS_TYPE_INVALID);
-}
-
-void
-ibus_im_client_kill_daemon (IBusIMClient *client)
-{
- g_return_if_fail (IBUS_IS_IM_CLIENT (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)
-{
- g_return_val_if_fail (IBUS_IS_IM_CLIENT (client), FALSE);
-
- IBusIMClientPrivate *priv = client->priv;
- if (priv->ibus == NULL)
- return FALSE;
- return dbus_connection_get_is_connected (priv->ibus);
-}
-
-static void
-_keymap_find_japan_groups (IBusIMClient *client)
-{
-
-#ifdef HAVE_XKB
- /* If have XKB, we will find Japan groups by groups' names */
- gboolean retval = FALSE;
- Status status;
- XkbDescPtr desc;
-
- IBusIMClientPrivate *priv = client->priv;
-
- priv->japan_groups = 0;
-
- desc = XkbGetMap (GDK_DISPLAY (), 0, XkbUseCoreKbd);
- if (desc == NULL) {
- g_warning ("Can not allocate XkbDescRec!");
- return;
- }
-
- retval =
- Success == (status = XkbGetControls (GDK_DISPLAY (),
- XkbSlowKeysMask,
- desc)) &&
- Success == (status = XkbGetNames (GDK_DISPLAY (),
- XkbGroupNamesMask | XkbIndicatorNamesMask,
- desc)) &&
- Success == (status = XkbGetIndicatorMap (GDK_DISPLAY (),
- XkbAllIndicatorsMask,
- desc));
- if (retval) {
- Atom *pa = desc->names->groups;
- int i;
- for (i = 0; i < desc->ctrls->num_groups; pa++, i++) {
- gchar *group_name = NULL;
- if (*pa == None)
- continue;
- group_name = XGetAtomName (GDK_DISPLAY (), *pa);
- if (g_strcmp0(group_name, "Japan") == 0) {
- priv->japan_groups |= (1 << i);
- }
- }
- }
- else {
- g_warning ("Can not get groups' names from Xkb");
- }
-
- XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
-#else
- /* if not have XKB, we assume only Japan group has key [backslash, underscore]
- * and [backslash bar].
- * */
- gint backslash_num, bar_num, underscore_num;
- GdkKeymapKey *backslash_keys, *bar_keys, *underscore_keys;
- gboolean retval;
-
- IBusIMClientPrivate *priv = client->priv;
-
- priv->japan_groups = 0;
-
- retval = gdk_keymap_get_entries_for_keyval (priv->keymap, GDK_backslash, &backslash_keys, &backslash_num);
- if (!retval) {
- g_warning ("Can not get keycode for backslash key!");
- return;
- }
-
- retval = gdk_keymap_get_entries_for_keyval (priv->keymap, GDK_bar, &bar_keys, &bar_num);
- if (!retval) {
- g_warning ("Can not get keycode for bar key!");
- g_free (backslash_keys);
- return;
- }
-
- retval = gdk_keymap_get_entries_for_keyval (priv->keymap, GDK_underscore, &underscore_keys, &underscore_num);
- if (!retval) {
- g_warning ("Can not get keycode for underscore key!");
- g_free (backslash_keys);
- g_free (bar_keys);
- return;
- }
-
- int i, j;
- guint groups_have_backslash_and_bar = 0;
- guint groups_have_backslash_and_underscore = 0;
-
- for (i = 0; i < backslash_num; i++) {
- for (j = 0; j < bar_num; j++) {
- if (backslash_keys[i].keycode != bar_keys[j].keycode ||
- backslash_keys[i].group != bar_keys[j].group)
- continue;
- groups_have_backslash_and_bar |= (1L << backslash_keys[i].group);
- }
- }
-
- for (i = 0; i < backslash_num; i++) {
- for (j = 0; j < underscore_num; j++) {
- if (backslash_keys[i].keycode != underscore_keys[j].keycode ||
- backslash_keys[i].group != underscore_keys[j].group)
- continue;
- groups_have_backslash_and_underscore |= (1 << backslash_keys[i].group);
- }
- }
- priv->japan_groups = groups_have_backslash_and_bar & groups_have_backslash_and_underscore;
-
- g_free (backslash_keys);
- g_free (bar_keys);
- g_free (underscore_keys);
-#endif
-}
-
-
-static void
-_keymap_find_yen_bar_keys (IBusIMClient *client)
-{
- IBusIMClientPrivate *priv = client->priv;
- gint backslash_num, bar_num;
- GdkKeymapKey *backslash_keys, *bar_keys;
- gboolean retval;
-
- if (priv->japan_yen_bar_keys == NULL) {
- priv->japan_yen_bar_keys = g_array_new (TRUE, TRUE, sizeof(GdkKeymapKey));
- }
- else if (priv->japan_yen_bar_keys->len > 0) {
- g_array_remove_range (priv->japan_yen_bar_keys, 0, priv->japan_yen_bar_keys->len);
- }
-
- if (priv->japan_groups == 0)
- return;
-
- retval = gdk_keymap_get_entries_for_keyval (priv->keymap, GDK_backslash, &backslash_keys, &backslash_num);
- if (!retval) {
- g_warning ("Can not get keycode for backslash key!");
- return;
- }
-
- retval = gdk_keymap_get_entries_for_keyval (priv->keymap, GDK_bar, &bar_keys, &bar_num);
- if (!retval) {
- g_warning ("Can not get keycode for bar key!");
- g_free (backslash_keys);
- return;
- }
-
- int i, j;
- for (i = 0; i < backslash_num; i++) {
- for (j = 0; j < bar_num; j++) {
- if (backslash_keys[i].keycode != bar_keys[j].keycode ||
- backslash_keys[i].group != bar_keys[j].group)
- continue;
-
- if (0 == (priv->japan_groups & (1 << backslash_keys[i].group)))
- continue;
- g_array_append_val (priv->japan_yen_bar_keys, backslash_keys[i]);
- }
- }
-
- g_free (backslash_keys);
- g_free (bar_keys);
-}
-
-static void
-_keymap_keys_changed_cb (GdkKeymap *keymap, IBusIMClient *client)
-{
- _keymap_find_japan_groups (client);
- _keymap_find_yen_bar_keys (client);
- /*
- g_debug ("keymap changed japan_groups = 0x%x",
- client->priv->japan_groups);
- */
-}
-
-static void
-_ibus_signal_commit_string_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
-{
- /* Handle CommitString signal */
- DBusError error = {0};
- gchar *ic = NULL;
- gchar *string = NULL;
-
- if (!dbus_message_get_args (message, &error,
- DBUS_TYPE_STRING, &ic,
- DBUS_TYPE_STRING, &string,
- DBUS_TYPE_INVALID)) {
- g_warning ("%s", error.message);
- dbus_error_free (&error);
- }
- else {
- g_signal_emit (client, client_signals[COMMIT_STRING], 0, ic, string);
- }
-}
-
-static void
-_ibus_signal_update_preedit_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
-{
- /* Handle UpdatePreedit signal */
- DBusMessageIter iter, sub_iter;
- int type, sub_type;
-
- gchar *ic = NULL;
- gchar *string = NULL;
- IBusAttrList *attrs = NULL;
- int cursor = 0;
- gboolean visible = FALSE;
-
- if (!dbus_message_iter_init (message, &iter)) {
- g_warning ("The UpdatePreedit signal does have args!");
- 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");
- return;
- }
- dbus_message_iter_get_basic (&iter, &string);
- dbus_message_iter_next (&iter);
-
-
- 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");
- return;
- }
-
- attrs = ibus_attr_list_from_dbus_message (&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);
- ibus_attr_list_unref (attrs);
- return;
- }
- dbus_message_iter_get_basic (&iter, &cursor);
- dbus_message_iter_next (&iter);
-
- 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);
- ibus_attr_list_unref (attrs);
- return;
- }
- dbus_message_iter_get_basic (&iter, &visible);
- dbus_message_iter_next (&iter);
- g_signal_emit (client, client_signals[UPDATE_PREEDIT], 0,
- ic, string, attrs, cursor, visible);
- ibus_attr_list_unref (attrs);
-}
-
-static void
-_ibus_signal_show_preedit_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
-{
- /* Handle CommitString signal */
- 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 {
- g_signal_emit (client, client_signals[SHOW_PREEDIT], 0, ic);
- }
-}
-
-static void
-_ibus_signal_hide_preedit_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
-{
- /* Handle CommitString signal */
- 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 {
- g_signal_emit (client, client_signals[HIDE_PREEDIT], 0, ic);
- }
-}
-
-#ifdef USE_DBUS_SESSION_BUS
-static void
-_ibus_signal_name_owner_changed_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
-{
- 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,
- 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);
-
- if (g_strcmp0 (new_name, "") == 0) {
- _ibus_im_client_ibus_close (client);
- priv->enable = FALSE;
- }
- else {
- _ibus_im_client_ibus_open (client);
- priv->enable = TRUE;
- }
-}
-#endif
-
-static void
-_ibus_signal_disconnected_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
-{
- _ibus_im_client_ibus_close (client);
-}
-
-static void
-_ibus_signal_enabled_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
-{
- DEBUG_FUNCTION_IN;
- /* Handle CommitString signal */
- 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 {
- g_signal_emit (client, client_signals[ENABLED], 0, ic);
- }
-}
-
-
-static void
-_ibus_signal_disabled_handler (DBusConnection *connection, DBusMessage *message, IBusIMClient *client)
-{
- DEBUG_FUNCTION_IN;
- /* Handle CommitString signal */
- 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 {
- g_signal_emit (client, client_signals[DISABLED], 0, ic);
- }
-}
-
-
-static DBusHandlerResult
-_ibus_im_client_message_filter_cb (DBusConnection *connection, DBusMessage *message, void *user_data)
-{
- IBusIMClient *client = (IBusIMClient *) user_data;
-
- static struct SIGNAL_HANDLER {
- const gchar *iface;
- const gchar *name;
- void (* handler) (DBusConnection *, DBusMessage *, IBusIMClient *);
- } handlers[] = {
-#ifdef USE_DBUS_SESSION_BUS
- { DBUS_INTERFACE_DBUS, "NameOwnerChanged", _ibus_signal_name_owner_changed_handler },
-#endif
- { DBUS_INTERFACE_LOCAL, "Disconnected", _ibus_signal_disconnected_handler },
- { IBUS_IFACE, "CommitString", _ibus_signal_commit_string_handler },
- { IBUS_IFACE, "UpdatePreedit", _ibus_signal_update_preedit_handler },
- { IBUS_IFACE, "ShowPreedit", _ibus_signal_show_preedit_handler },
- { IBUS_IFACE, "HidePreedit", _ibus_signal_hide_preedit_handler },
- { IBUS_IFACE, "Enabled", _ibus_signal_enabled_handler },
- { IBUS_IFACE, "Disabled", _ibus_signal_disabled_handler },
- {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;
- }
- }
- g_debug ("Unknown message %s", dbus_message_get_member (message));
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-inline static gboolean
-_dbus_call_with_reply_and_block_valist (DBusConnection *connection,
- const gchar *dest, const gchar *path, const gchar* iface, const char *method,
- int first_arg_type, va_list args)
-{
-
- DBusMessage *message, *reply;
- DBusError error = {0};
- int type;
- va_list tmp;
-
- if (connection == NULL)
- return FALSE;
-
- message = dbus_message_new_method_call (dest,
- path, iface, method);
- if (!message) {
- g_warning ("Out of memory!");
- return FALSE;
- }
-
- va_copy (tmp, args);
- if (!dbus_message_append_args_valist (message, first_arg_type, tmp)) {
- dbus_message_unref (message);
- g_warning ("Can not create call message");
- return FALSE;
- }
-
- reply = dbus_connection_send_with_reply_and_block (connection,
- 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 {
- va_arg (args, void *);
- }
- 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);
-
- 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,
- gint first_arg_type, ...)
-{
- va_list args;
- gboolean retval;
-
- if (connection == NULL)
- return FALSE;
-
- va_start (args, first_arg_type);
- retval = _dbus_call_with_reply_and_block_valist (connection,
- 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;
-
- if (connection == NULL)
- return FALSE;
-
- va_start (args, first_arg_type);
- retval = _dbus_call_with_reply_and_block_valist (connection,
- 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,
- void *user_data, DBusFreeFunction free_function,
- gint first_arg_type, va_list args)
-{
- DBusMessage *message = NULL;
- DBusPendingCall *pendingcall = NULL;
-
- if (connection == NULL) {
- goto error;
- }
-
- message = dbus_message_new_method_call (dest,
- path, iface, method);
- if (!message) {
- g_warning ("Out of memory!");
- goto error;
- }
-
- 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,
- message, &pendingcall, -1)) {
- g_warning ("Out of memory!");
- goto error;
- }
-
- /* If we got a NULL pending, that means the connection was disconnected,
- * and we need to abort this call
- * https://bugs.freedesktop.org/show_bug.cgi?id=12675
- */
- if (pendingcall == 0) {
- g_warning ("Connection is breaken!");
- 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;
-
-error:
- if (message)
- dbus_message_unref (message);
- if (pendingcall)
- dbus_pending_call_cancel (pendingcall);
- if (user_data && free_function)
- free_function (user_data);
- return FALSE;
-}
-
-inline static gboolean
-_dbus_call_with_reply (DBusConnection *connection,
- const gchar *dest, const gchar *path, const gchar* iface, const char *method,
- DBusPendingCallNotifyFunction notify_function,
- void *user_data, DBusFreeFunction free_function,
- gint first_arg_type, ...)
-{
- va_list args;
- gboolean retval;
-
- if (connection == NULL)
- return FALSE;
-
- va_start (args, first_arg_type);
- retval = _dbus_call_with_reply_valist (connection,
- 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,
- void *user_data, DBusFreeFunction free_function,
- int first_arg_type, ...)
-{
- va_list args;
- gboolean retval;
-
- if (connection == NULL)
- return FALSE;
-
- 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,
- first_arg_type, args);
- va_end (args);
-
- return retval;
-}
-
-struct _KeyPressCallData {
- IBusIMClient *client;
- gchar *ic;
- GdkEvent *event;
-};
-
-static KeyPressCallData *
-_key_press_call_data_new (IBusIMClient *client, const gchar *ic, GdkEvent *event)
-{
- KeyPressCallData *p = g_slice_new (KeyPressCallData);
- p->client = g_object_ref (client);
- p->ic = g_strdup (ic);
- p->event = gdk_event_copy (event);
- return p;
-}
-
-static void
-_key_press_call_data_free (KeyPressCallData *p)
-{
- if (p) {
- g_object_unref (p->client);
- g_free (p->ic);
- gdk_event_free (p->event);
- }
- g_slice_free (KeyPressCallData, p);
-}
-
-static void
-_ibus_filter_keypress_reply_cb (DBusPendingCall *pending, void *user_data)
-{
- DBusMessage *reply;
- DBusError error = {0};
- KeyPressCallData *call_data = (KeyPressCallData *) user_data;
- gboolean retval;
-
-
- 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,
- DBUS_TYPE_BOOLEAN, &retval, DBUS_TYPE_INVALID)) {
- g_warning ("%s", error.message);
- dbus_error_free (&error);
- retval = FALSE;
- }
- }
-
- if (!retval) {
- g_signal_emit (call_data->client, client_signals[FORWARD_EVENT], 0,
- call_data->ic, call_data->event);
- }
-}
-
-
diff --git a/lib/gtk2/ibusimclient.h b/lib/gtk2/ibusimclient.h
deleted file mode 100644
index 9a42332..0000000
--- a/lib/gtk2/ibusimclient.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* vim:set et ts=4: */
-/* ibus - The Input Bus
- * Copyright (C) 2008-2009 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __IBUS_IM_CLIENT_H_
-#define __IBUS_IM_CLIENT_H_
-
-#include <glib-object.h>
-/*
- * Type macros.
- */
-
-/* define GOBJECT macros */
-#define IBUS_TYPE_IM_CLIENT \
- (ibus_im_client_get_type ())
-#define IBUS_IM_CLIENT(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_IM_CLIENT, IBusIMClient))
-#define IBUS_IM_CLIENT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_IM_CLIENT, IBusIMClientClass))
-#define IBUS_IS_IM_CLIENT(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_IM_CLIENT))
-#define IBUS_IS_IM_CLIENT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_IM_CLIENT))
-#define IBUS_IM_CLIENT_GET_CLASS(obj) \
- (G_TYPE_CHECK_GET_CLASS ((obj), IBUS_TYPE_IM_CLIENT, IBusIMClientClass))
-
-#define IBUS_FORWARD_MASK (1 << 25)
-
-#if 0
-#define DEBUG_FUNCTION_IN g_debug("%s IN", __FUNCTION__);
-#define DEBUG_FUNCTION_OUT g_debug("%s OUT", __FUNCTION__);
-#else
-#define DEBUG_FUNCTION_IN
-#define DEBUG_FUNCTION_OUT
-#endif
-
-
-
-#define IBUS_DBUS_SERVICE "org.freedesktop.ibus"
-#define IBUS_DBUS_INTERFACE "org.freedesktop.ibus.Manager"
-#define IBUS_DBUS_PATH "/org/freedesktop/ibus/Manager"
-
-G_BEGIN_DECLS
-enum IBusCap {
- IBUS_CAP_PREEDIT = (1),
- IBUS_CAP_AUX_STRING = (1 << 1),
- IBUS_CAP_LOOKUP_TABLE = (1 << 2),
- IBUS_CAP_FOCUS = (1 << 3),
-};
-
-typedef struct _IBusIMClient IBusIMClient;
-typedef struct _IBusIMClientClass IBusIMClientClass;
-typedef struct _IBusIMClientPrivate IBusIMClientPrivate;
-
-struct _IBusIMClient {
- GObject parent;
- /* instance members */
- IBusIMClientPrivate *priv;
-};
-
-struct _IBusIMClientClass {
- GObjectClass parent;
- /* class members */
- void (* connected) (IBusIMClient *client);
- void (* disconnected) (IBusIMClient *client);
- void (* commit_string) (IBusIMClient *client,
- const gchar *ic,
- const gchar *text);
- void (* update_preedit) (IBusIMClient *client,
- const gchar *ic,
- const gchar *text,
- gpointer *attrs,
- gint cursor_pos,
- gboolean visible);
- void (* show_preedit) (IBusIMClient *client,
- const gchar *ic);
- void (* hide_preedit) (IBusIMClient *client,
- const gchar *ic);
- void (* enabled) (IBusIMClient *client,
- const gchar *ic);
- void (* disabled) (IBusIMClient *client,
- const gchar *ic);
-};
-
-GType ibus_im_client_get_type (void);
-void ibus_im_client_register_type (GTypeModule *type_module);
-IBusIMClient *ibus_im_client_new (void);
-const gchar *ibus_im_client_create_input_context
- (IBusIMClient *client);
-void ibus_im_client_shutdown (void);
-void ibus_im_client_focus_in (IBusIMClient *client,
- const gchar *ic);
-void ibus_im_client_focus_out (IBusIMClient *client,
- const gchar *ic);
-void ibus_im_client_reset (IBusIMClient *client,
- const gchar *ic);
-gboolean ibus_im_client_filter_keypress (IBusIMClient *client,
- const gchar *ic,
- GdkEventKey *key,
- gboolean block);
-void ibus_im_client_set_cursor_location
- (IBusIMClient *client,
- const gchar *ic,
- GdkRectangle *area);
-void ibus_im_client_set_capabilities (IBusIMClient *client,
- const gchar *ic,
- gint caps);
-gboolean ibus_im_client_is_enabled (IBusIMClient *client);
-void ibus_im_client_release_input_context
- (IBusIMClient *client,
- const gchar *ic);
-void ibus_im_client_kill_daemon (IBusIMClient *client);
-gboolean ibus_im_client_get_connected (IBusIMClient *client);
-
-
-G_END_DECLS
-#endif
-
diff --git a/lib/gtk2/ibusmarshalers.list b/lib/gtk2/ibusmarshalers.list
deleted file mode 100644
index 25c85db..0000000
--- a/lib/gtk2/ibusmarshalers.list
+++ /dev/null
@@ -1,5 +0,0 @@
-NONE:NONE
-NONE:STRING
-NONE:STRING,STRING
-NONE:STRING,BOXED
-NONE:STRING,STRING,BOXED,INT,BOOL
diff --git a/po/.gitignore b/po/.gitignore
index 3dc4511..76425a9 100644
--- a/po/.gitignore
+++ b/po/.gitignore
@@ -11,3 +11,8 @@ insert-header.sin
quot.sed
remove-potcdate.sed
remove-potcdate.sin
+ja.gmo
+pa.gmo
+zh_CN.gmo
+ibus.pot
+stamp-po
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 775475e..444ed03 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -19,7 +19,7 @@
./ibus/lang.py
./ibus/lookuptable.py
./ibus/property.py
-./ibus/gtk.py
+./ibus/_gtk.py
./ibus/ascii.py
./ibus/factory.py
./ui/gtk/menu.py
@@ -31,20 +31,6 @@
./ui/gtk/panel.py
./ui/gtk/propitem.py
./ui/gtk/languagebar.py
-./gconf/main.py
-./gconf/config.py
./setup/main.py
./setup/keyboardshortcut.py
-./daemon/bus.py
-./daemon/register.py
-./daemon/contextmanager.py
-./daemon/ibusdaemon.py
-./daemon/factorymanager.py
-./daemon/engine.py
-./daemon/panel.py
-./daemon/config.py
-./daemon/inputcontext.py
-./daemon/lookuptable.py
-./daemon/enginefactory.py
-./daemon/connection.py
./setup/setup.glade
diff --git a/po/ja.po b/po/ja.po
index 9415eb2..abdbf0e 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ibus VERSION\n"
"Report-Msgid-Bugs-To: http://code.google.com/p/ibus/issues/entry\n"
-"POT-Creation-Date: 2008-10-19 09:45+0800\n"
+"POT-Creation-Date: 2009-02-05 10:29+0800\n"
"PO-Revision-Date: 2008-08-28 17:31+0900\n"
"Last-Translator: UTUMI Hirosi <utuhiro78@yahoo.co.jp>\n"
"Language-Team: Japanese <gnome-translation@gnome.gr.jp>\n"
@@ -16,20 +16,20 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ibus/lang.py:40 ui/gtk/panel.py:294 ui/gtk/panel.py:295 ui/gtk/panel.py:296
-#: ui/gtk/panel.py:297 setup/main.py:361 setup/main.py:362 setup/main.py:363
+#: ibus/lang.py:40 ui/gtk/panel.py:307 ui/gtk/panel.py:308 ui/gtk/panel.py:309
+#: ui/gtk/panel.py:310
msgid "Other"
msgstr ""
-#: ui/gtk/panel.py:94
+#: ui/gtk/panel.py:99
msgid "iBus - Running"
msgstr "iBus - 実行中"
-#: ui/gtk/panel.py:356
+#: ui/gtk/panel.py:370
msgid "IBus is an intelligent input bus for Linux/Unix."
msgstr ""
-#: ui/gtk/panel.py:360
+#: ui/gtk/panel.py:374
msgid "translator-credits"
msgstr "UTUMI Hirosi <utuhiro78@yahoo.co.jp>"
@@ -37,23 +37,23 @@ msgstr "UTUMI Hirosi <utuhiro78@yahoo.co.jp>"
msgid "Switch engine"
msgstr ""
-#: setup/main.py:100
+#: setup/main.py:99
msgid "trigger"
msgstr "トリガー"
-#: setup/main.py:110
+#: setup/main.py:109
msgid "next engine"
msgstr "次のエンジン"
-#: setup/main.py:120
+#: setup/main.py:119
msgid "prev engine"
msgstr "前のエンジン"
-#: setup/main.py:165
+#: setup/main.py:197
msgid "IBus daemon is not started. Do you want to start it now?"
msgstr "IBus デーモンが動いていません。起動しますか?"
-#: setup/main.py:180
+#: setup/main.py:212
msgid ""
"IBus has been started! If you can not use IBus, please add below lines in "
"$HOME/.bashrc, and relogin your desktop.\n"
@@ -67,19 +67,7 @@ msgstr ""
" export XMODIFIERS=@im=ibus\n"
" export QT_IM_MODULE=ibus"
-#: setup/main.py:202 setup/setup.glade:368
-msgid "Engine"
-msgstr "エンジン"
-
-#: setup/main.py:229
-msgid "Started"
-msgstr "開始"
-
-#: setup/main.py:239
-msgid "Preload"
-msgstr "プリロード"
-
-#: setup/main.py:249
+#: setup/main.py:227
#, python-format
msgid "Select keyboard shortcut for %s"
msgstr "%s のキーボードショートカットを選択"
@@ -108,25 +96,6 @@ msgstr ""
msgid "Please press a key (or a key combination)"
msgstr "キーもしくはキーの組み合わせを入力してください"
-#: daemon/bus.py:221
-msgid "Cannot enable input engine"
-msgstr ""
-
-#: daemon/bus.py:222
-msgid ""
-"IBus can not enable input engine, because IBus does not load any input "
-"engines!\n"
-"Please use ibus-setup program to load some input engines."
-msgstr ""
-
-#: daemon/bus.py:224
-msgid "Setup"
-msgstr ""
-
-#: daemon/bus.py:224
-msgid "Don't show this again"
-msgstr ""
-
#: setup/setup.glade:7
msgid "IBus - Setup"
msgstr "IBus - セットアップ"
@@ -183,7 +152,28 @@ msgstr ""
msgid "General"
msgstr "一般"
-#: setup/setup.glade:385
+#: setup/setup.glade:399
+msgid "gtk-add"
+msgstr ""
+
+#: setup/setup.glade:409
+#, fuzzy
+msgid "gtk-remove"
+msgstr "gtk-close"
+
+#: setup/setup.glade:422
+msgid "gtk-go-up"
+msgstr ""
+
+#: setup/setup.glade:435
+msgid "gtk-go-down"
+msgstr ""
+
+#: setup/setup.glade:460
+msgid "Engine"
+msgstr "エンジン"
+
+#: setup/setup.glade:477
msgid ""
"<big><b>iBus</b></big>\n"
"<small>The intelligent input bus</small>\n"
@@ -193,10 +183,16 @@ msgid ""
"\n"
msgstr ""
-#: setup/setup.glade:410
+#: setup/setup.glade:502
msgid "About"
msgstr "About"
-#: setup/setup.glade:432
+#: setup/setup.glade:524
msgid "gtk-close"
msgstr "gtk-close"
+
+#~ msgid "Started"
+#~ msgstr "開始"
+
+#~ msgid "Preload"
+#~ msgstr "プリロード"
diff --git a/po/pa.po b/po/pa.po
index ddeb6af..483967b 100644
--- a/po/pa.po
+++ b/po/pa.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ibus\n"
"Report-Msgid-Bugs-To: http://code.google.com/p/ibus/issues/entry\n"
-"POT-Creation-Date: 2008-10-19 09:45+0800\n"
+"POT-Creation-Date: 2009-02-05 10:29+0800\n"
"PO-Revision-Date: 2008-10-17 14:15+0530\n"
"Last-Translator: Amanpreet Singh <aalam@users.sf.net>\n"
"Language-Team: Punjabi/Panjabi <punjabi-l10n@lists.sf.net>\n"
@@ -16,20 +16,20 @@ msgstr ""
"X-Generator: Lokalize 0.2\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-#: ibus/lang.py:40 ui/gtk/panel.py:294 ui/gtk/panel.py:295 ui/gtk/panel.py:296
-#: ui/gtk/panel.py:297 setup/main.py:361 setup/main.py:362 setup/main.py:363
+#: ibus/lang.py:40 ui/gtk/panel.py:307 ui/gtk/panel.py:308 ui/gtk/panel.py:309
+#: ui/gtk/panel.py:310
msgid "Other"
msgstr "ਹੋਰ"
-#: ui/gtk/panel.py:94
+#: ui/gtk/panel.py:99
msgid "iBus - Running"
msgstr "iBus -  ਚੱਲ ਰਿਹਾ ਹੈ"
-#: ui/gtk/panel.py:356
+#: ui/gtk/panel.py:370
msgid "IBus is an intelligent input bus for Linux/Unix."
msgstr "iBus ਲੀਨਕਸ/ਯੂਨੈਕਸ ਲਈ ਮਾਹਰ ਇੰਪੁੱਟ ਬੱਸ ਹੈ।"
-#: ui/gtk/panel.py:360
+#: ui/gtk/panel.py:374
msgid "translator-credits"
msgstr "ਅਮਨਪਰੀਤ ਸਿੰਘ ਆਲਮ"
@@ -37,23 +37,23 @@ msgstr "ਅਮਨਪਰੀਤ ਸਿੰਘ ਆਲਮ"
msgid "Switch engine"
msgstr "ਇੰਜਣ ਬਦਲੋ"
-#: setup/main.py:100
+#: setup/main.py:99
msgid "trigger"
msgstr "ਟਰਿੱਗਰ"
-#: setup/main.py:110
+#: setup/main.py:109
msgid "next engine"
msgstr "ਅਗਲਾ ਇੰਜਣ"
-#: setup/main.py:120
+#: setup/main.py:119
msgid "prev engine"
msgstr "ਪਿਛਲਾ ਇੰਜਣ"
-#: setup/main.py:165
+#: setup/main.py:197
msgid "IBus daemon is not started. Do you want to start it now?"
msgstr "iBus ਡੈਮਨ ਚੱਲਦੀ ਨਹੀਂ ਹੈ। ਕੀ ਤੁਸੀਂ ਇਸ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"
-#: setup/main.py:180
+#: setup/main.py:212
msgid ""
"IBus has been started! If you can not use IBus, please add below lines in "
"$HOME/.bashrc, and relogin your desktop.\n"
@@ -66,19 +66,7 @@ msgstr ""
"
 export XMODIFIERS=@im=ibus\n"
"
 export QT_IM_MODULE=ibus"
-#: setup/main.py:202 setup/setup.glade:368
-msgid "Engine"
-msgstr "ਇੰਜਣ"
-
-#: setup/main.py:229
-msgid "Started"
-msgstr "ਚਾਲੂ ਹੈ"
-
-#: setup/main.py:239
-msgid "Preload"
-msgstr "ਪ੍ਰੀ-ਲੋਡ"
-
-#: setup/main.py:249
+#: setup/main.py:227
#, python-format
msgid "Select keyboard shortcut for %s"
msgstr "%s ਲਈ ਕੀਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਚੁਣੋ"
@@ -107,28 +95,6 @@ msgstr ""
msgid "Please press a key (or a key combination)"
msgstr "ਕੋਈ ਵੀ ਸਵਿੱਚ ਦੱਬੋ (ਜਾਂ ਸਵਿੱਚ ਜੋੜ)"
-#: daemon/bus.py:221
-msgid "Cannot enable input engine"
-msgstr "ਇੰਪੁੱਟ ਇੰਜਣ ਯੋਗ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"
-
-#: daemon/bus.py:222
-msgid ""
-"IBus can not enable input engine, because IBus does not load any input "
-"engines!\n"
-"Please use ibus-setup program to load some input engines."
-msgstr ""
-"iBus ਕੋਈ ਇੰਪੁੱਟ ਇੰਜਣ ਯੋਗ ਨਹੀਂ ਕਰ ਸਕਦੀ ਹੈ, ਕਿਉਂਕਿ ਆਈ-ਬੱਸ ਕਿਸੇ ਇੰਪੁੱਟ ਇੰਜਣ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕਰ ਸਕਦੀ "
-"ਹੈ!\n"
-"
ਕੁਝ ਇੰਪੁੱਟ ਇੰਜਣ ਨੂੰ ਲੋਡ ਕਰਨ ਵਾਸਤੇ ibus-setup ਪਰੋਗਰਾਮ ਵਰਤੋਂ।"
-
-#: daemon/bus.py:224
-msgid "Setup"
-msgstr "ਸੈੱਟਅੱਪ"
-
-#: daemon/bus.py:224
-msgid "Don't show this again"
-msgstr "ਇਹ ਮੁੜ ਨਾ ਵੇਖਾਓ"
-
#: setup/setup.glade:7
msgid "IBus - Setup"
msgstr "IBus - ਸੈੱਟਅੱਪ"
@@ -185,7 +151,28 @@ msgstr "<b>UI</b>"
msgid "General"
msgstr "ਆਮ"
-#: setup/setup.glade:385
+#: setup/setup.glade:399
+msgid "gtk-add"
+msgstr ""
+
+#: setup/setup.glade:409
+#, fuzzy
+msgid "gtk-remove"
+msgstr "gtk-close"
+
+#: setup/setup.glade:422
+msgid "gtk-go-up"
+msgstr ""
+
+#: setup/setup.glade:435
+msgid "gtk-go-down"
+msgstr ""
+
+#: setup/setup.glade:460
+msgid "Engine"
+msgstr "ਇੰਜਣ"
+
+#: setup/setup.glade:477
msgid ""
"<big><b>iBus</b></big>\n"
"<small>The intelligent input bus</small>\n"
@@ -201,10 +188,34 @@ msgstr ""
"
\n"
"
\n"
-#: setup/setup.glade:410
+#: setup/setup.glade:502
msgid "About"
msgstr "ਇਸ ਬਾਰੇ"
-#: setup/setup.glade:432
+#: setup/setup.glade:524
msgid "gtk-close"
msgstr "gtk-close"
+
+#~ msgid "Started"
+#~ msgstr "ਚਾਲੂ ਹੈ"
+
+#~ msgid "Preload"
+#~ msgstr "ਪ੍ਰੀ-ਲੋਡ"
+
+#~ msgid "Cannot enable input engine"
+#~ msgstr "ਇੰਪੁੱਟ ਇੰਜਣ ਯੋਗ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"
+
+#~ msgid ""
+#~ "IBus can not enable input engine, because IBus does not load any input "
+#~ "engines!\n"
+#~ "Please use ibus-setup program to load some input engines."
+#~ msgstr ""
+#~ "iBus ਕੋਈ ਇੰਪੁੱਟ ਇੰਜਣ ਯੋਗ ਨਹੀਂ ਕਰ ਸਕਦੀ ਹੈ, ਕਿਉਂਕਿ ਆਈ-ਬੱਸ ਕਿਸੇ ਇੰਪੁੱਟ ਇੰਜਣ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕਰ "
+#~ "ਸਕਦੀ ਹੈ!\n"
+#~ "
ਕੁਝ ਇੰਪੁੱਟ ਇੰਜਣ ਨੂੰ ਲੋਡ ਕਰਨ ਵਾਸਤੇ ibus-setup ਪਰੋਗਰਾਮ ਵਰਤੋਂ।"
+
+#~ msgid "Setup"
+#~ msgstr "ਸੈੱਟਅੱਪ"
+
+#~ msgid "Don't show this again"
+#~ msgstr "ਇਹ ਮੁੜ ਨਾ ਵੇਖਾਓ"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index fdb59b7..7c5b745 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1.1.20080813\n"
"Report-Msgid-Bugs-To: http://code.google.com/p/ibus/issues/entry\n"
-"POT-Creation-Date: 2008-10-19 09:45+0800\n"
+"POT-Creation-Date: 2009-02-05 10:29+0800\n"
"PO-Revision-Date: 2008-08-13 21:59+0800\n"
"Last-Translator: Huang Peng <shawn.p.huang@gmail.com>\n"
"Language-Team: Huang Peng <shawn.p.huang@gmail.com>\n"
@@ -16,20 +16,20 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: ibus/lang.py:40 ui/gtk/panel.py:294 ui/gtk/panel.py:295 ui/gtk/panel.py:296
-#: ui/gtk/panel.py:297 setup/main.py:361 setup/main.py:362 setup/main.py:363
+#: ibus/lang.py:40 ui/gtk/panel.py:307 ui/gtk/panel.py:308 ui/gtk/panel.py:309
+#: ui/gtk/panel.py:310
msgid "Other"
msgstr "其他"
-#: ui/gtk/panel.py:94
+#: ui/gtk/panel.py:99
msgid "iBus - Running"
msgstr "iBus - 运行"
-#: ui/gtk/panel.py:356
+#: ui/gtk/panel.py:370
msgid "IBus is an intelligent input bus for Linux/Unix."
msgstr ""
-#: ui/gtk/panel.py:360
+#: ui/gtk/panel.py:374
msgid "translator-credits"
msgstr "Huang Peng <shawn.p.huang@gmail.com>"
@@ -37,23 +37,23 @@ msgstr "Huang Peng <shawn.p.huang@gmail.com>"
msgid "Switch engine"
msgstr "切换引擎"
-#: setup/main.py:100
+#: setup/main.py:99
msgid "trigger"
msgstr "开关"
-#: setup/main.py:110
+#: setup/main.py:109
msgid "next engine"
msgstr "下一个引擎"
-#: setup/main.py:120
+#: setup/main.py:119
msgid "prev engine"
msgstr "上一个引擎"
-#: setup/main.py:165
+#: setup/main.py:197
msgid "IBus daemon is not started. Do you want to start it now?"
msgstr "IBus守护进程没有启动,您是否想现在启动它?"
-#: setup/main.py:180
+#: setup/main.py:212
msgid ""
"IBus has been started! If you can not use IBus, please add below lines in "
"$HOME/.bashrc, and relogin your desktop.\n"
@@ -66,19 +66,7 @@ msgstr ""
" export XMODIFIERS=@im=ibus\n"
" export QT_IM_MODULE=ibus"
-#: setup/main.py:202 setup/setup.glade:368
-msgid "Engine"
-msgstr "输入法引擎"
-
-#: setup/main.py:229
-msgid "Started"
-msgstr "启动"
-
-#: setup/main.py:239
-msgid "Preload"
-msgstr "预加载"
-
-#: setup/main.py:249
+#: setup/main.py:227
#, python-format
msgid "Select keyboard shortcut for %s"
msgstr "选择%s的快捷键"
@@ -107,27 +95,6 @@ msgstr ""
msgid "Please press a key (or a key combination)"
msgstr "请按一个键盘按键(或者一个组合按键)"
-#: daemon/bus.py:221
-msgid "Cannot enable input engine"
-msgstr "不能启动输入引擎"
-
-#: daemon/bus.py:222
-msgid ""
-"IBus can not enable input engine, because IBus does not load any input "
-"engines!\n"
-"Please use ibus-setup program to load some input engines."
-msgstr ""
-"IBus不能启动输入引擎,因为IBus没有加载任何输入引擎!\n"
-"请运行ibus-setup程序,启动需要的输入法引擎。"
-
-#: daemon/bus.py:224
-msgid "Setup"
-msgstr "设置"
-
-#: daemon/bus.py:224
-msgid "Don't show this again"
-msgstr "不再显示该信息"
-
#: setup/setup.glade:7
msgid "IBus - Setup"
msgstr "IBus - 设置"
@@ -184,7 +151,27 @@ msgstr "<b>用户界面</b>"
msgid "General"
msgstr "通用"
-#: setup/setup.glade:385
+#: setup/setup.glade:399
+msgid "gtk-add"
+msgstr ""
+
+#: setup/setup.glade:409
+msgid "gtk-remove"
+msgstr ""
+
+#: setup/setup.glade:422
+msgid "gtk-go-up"
+msgstr ""
+
+#: setup/setup.glade:435
+msgid "gtk-go-down"
+msgstr ""
+
+#: setup/setup.glade:460
+msgid "Engine"
+msgstr "输入法引擎"
+
+#: setup/setup.glade:477
msgid ""
"<big><b>iBus</b></big>\n"
"<small>The intelligent input bus</small>\n"
@@ -194,10 +181,33 @@ msgid ""
"\n"
msgstr ""
-#: setup/setup.glade:410
+#: setup/setup.glade:502
msgid "About"
msgstr "关于"
-#: setup/setup.glade:432
+#: setup/setup.glade:524
msgid "gtk-close"
msgstr ""
+
+#~ msgid "Started"
+#~ msgstr "启动"
+
+#~ msgid "Preload"
+#~ msgstr "预加载"
+
+#~ msgid "Cannot enable input engine"
+#~ msgstr "不能启动输入引擎"
+
+#~ msgid ""
+#~ "IBus can not enable input engine, because IBus does not load any input "
+#~ "engines!\n"
+#~ "Please use ibus-setup program to load some input engines."
+#~ msgstr ""
+#~ "IBus不能启动输入引擎,因为IBus没有加载任何输入引擎!\n"
+#~ "请运行ibus-setup程序,启动需要的输入法引擎。"
+
+#~ msgid "Setup"
+#~ msgstr "设置"
+
+#~ msgid "Don't show this again"
+#~ msgstr "不再显示该信息"
diff --git a/setup/.gitignore b/setup/.gitignore
index bcebcbe..1a6aff2 100644
--- a/setup/.gitignore
+++ b/setup/.gitignore
@@ -1 +1,2 @@
ibus-setup
+ibus-setup.desktop
diff --git a/setup/Makefile.am b/setup/Makefile.am
index ad2e9d4..0e144e9 100644
--- a/setup/Makefile.am
+++ b/setup/Makefile.am
@@ -21,6 +21,9 @@
ibussetup_PYTHON = \
main.py \
+ icon.py \
+ enginecombobox.py \
+ enginetreeview.py \
keyboardshortcut.py \
$(NULL)
diff --git a/setup/enginecombobox.py b/setup/enginecombobox.py
new file mode 100644
index 0000000..c8eaa15
--- /dev/null
+++ b/setup/enginecombobox.py
@@ -0,0 +1,92 @@
+# vim:set et sts=4 sw=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
+
+import gtk
+import gobject
+import ibus
+
+from icon import load_icon
+
+class EngineComboBox(gtk.ComboBox):
+ def __init__(self, engines):
+ super(EngineComboBox, self).__init__()
+
+ self.__model = gtk.TreeStore(gobject.TYPE_PYOBJECT)
+
+ lang = {}
+ for e in engines:
+ l = ibus.get_language_name(e.language)
+ if l not in lang:
+ lang[l] = []
+ lang[l].append(e)
+
+ for l in lang.keys():
+ iter1 = self.__model.append(None)
+ self.__model.set(iter1, 0, l)
+ for e in lang[l]:
+ iter2 = self.__model.append(iter1)
+ self.__model.set(iter2, 0, e)
+
+ self.set_model(self.__model)
+
+ renderer = gtk.CellRendererPixbuf()
+ renderer.set_property("xalign", 0)
+ self.pack_start(renderer, False)
+ self.set_cell_data_func(renderer, self.__icon_cell_data_cb)
+
+ renderer = gtk.CellRendererText()
+ renderer.set_property("xalign", 0)
+ self.pack_start(renderer, True)
+ self.set_cell_data_func(renderer, self.__name_cell_data_cb)
+
+ def __icon_cell_data_cb(self, celllayout, renderer, model, iter):
+ engine = self.__model.get_value(iter, 0)
+
+ icon_size = gtk.icon_size_lookup(gtk.ICON_SIZE_LARGE_TOOLBAR)[0]
+ if isinstance (engine, str) or isinstance (engine, unicode):
+ renderer.set_property("visible", False)
+ renderer.set_property("sensitive", False)
+ else:
+ renderer.set_property("visible", True)
+ renderer.set_property("sensitive", True)
+ pixbuf = load_icon(engine.icon, gtk.ICON_SIZE_LARGE_TOOLBAR)
+ if pixbuf == None:
+ pixbuf = load_icon("default-engine", gtk.ICON_SIZE_LARGE_TOOLBAR)
+ if pixbuf == None:
+ pixbuf = load_icon("gtk-missing-image", gtk.ICON_SIZE_LARGE_TOOLBAR)
+ renderer.set_property("pixbuf", pixbuf)
+
+ def __name_cell_data_cb(self, celllayout, renderer, model, iter):
+ engine = self.__model.get_value(iter, 0)
+
+ if isinstance (engine, str) or isinstance (engine, unicode):
+ renderer.set_property("sensitive", False)
+ renderer.set_property("text", engine)
+ else:
+ renderer.set_property("sensitive", True)
+ renderer.set_property("text", engine.longname)
+
+ def get_active_engine(self):
+ iter = self.get_active_iter()
+ if iter == None:
+ return None
+ return self.get_model()[iter][0]
+
diff --git a/setup/enginetreeview.py b/setup/enginetreeview.py
new file mode 100644
index 0000000..4e4c131
--- /dev/null
+++ b/setup/enginetreeview.py
@@ -0,0 +1,157 @@
+# vim:set et sts=4 sw=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
+
+import gtk
+import gobject
+import ibus
+
+from icon import load_icon
+
+class EngineTreeView(gtk.TreeView):
+ __gsignals__ = {
+ 'changed' : (
+ gobject.SIGNAL_RUN_LAST,
+ gobject.TYPE_NONE,
+ ())
+ }
+
+ def __init__(self, engines):
+ super(EngineTreeView, self).__init__()
+
+ self.__engines = set([])
+
+ self.__model = gtk.TreeStore(gobject.TYPE_PYOBJECT)
+ self.set_model(self.__model)
+
+ self.set_headers_visible(False)
+
+ column = gtk.TreeViewColumn()
+
+ renderer = gtk.CellRendererPixbuf()
+ renderer.set_property("xalign", 0)
+ column.pack_start(renderer, False)
+ column.set_cell_data_func(renderer, self.__icon_cell_data_cb)
+
+ renderer = gtk.CellRendererText()
+ renderer.set_property("xalign", 0)
+ column.pack_start(renderer, True)
+ column.set_cell_data_func(renderer, self.__name_cell_data_cb)
+ self.append_column (column)
+
+ self.set_engines(engines)
+
+ def __icon_cell_data_cb(self, celllayout, renderer, model, iter):
+ engine = self.__model.get_value(iter, 0)
+
+ icon_size = gtk.icon_size_lookup(gtk.ICON_SIZE_LARGE_TOOLBAR)[0]
+ pixbuf = load_icon(engine.icon, gtk.ICON_SIZE_LARGE_TOOLBAR)
+
+ if pixbuf == None:
+ pixbuf = load_icon("default-engine", gtk.ICON_SIZE_LARGE_TOOLBAR)
+ if pixbuf == None:
+ pixbuf = load_icon("gtk-missing-image", gtk.ICON_SIZE_LARGE_TOOLBAR)
+
+ renderer.set_property("pixbuf", pixbuf)
+
+ def __name_cell_data_cb(self, celllayout, renderer, model, iter):
+ engine = self.__model.get_value(iter, 0)
+ renderer.set_property("sensitive", True)
+ renderer.set_property("text", engine.longname)
+
+ def set_engines(self, engines):
+ self.__model.clear()
+ self.__engines = set([])
+ for e in engines:
+ if e in self.__engines:
+ continue
+ iter = self.__model.append(None)
+ self.__model.set(iter, 0, e)
+ self.__engines.add(e)
+ self.emit("changed")
+
+ def get_selected_iter(self):
+ selection = self.get_selection()
+ if selection:
+ return selection.get_selected()[1]
+
+ def get_engines(self):
+ return map(lambda r: r[0], self.__model)
+
+ def get_select_engine(self):
+ iter = self.get_selected_iter()
+ if iter == None:
+ return None
+ row = self.__model.get(iter)
+ return row[0]
+
+ def prepend_engine(self, engine):
+ if engine == None or engine in self.__engines:
+ return
+ iter = self.__model.prepend(None)
+ self.__model.set(iter, 0, engine)
+ self.__engines.add(engine)
+ self.emit("changed")
+ self.scroll_to_cell(self.__model[0].path, None)
+
+ def remove_engine(self):
+ iter = self.get_selected_iter()
+ if iter == None:
+ return
+ row = self.__model[iter]
+ engine = row[0]
+ self.__engines.remove(engine)
+ index = row.path[0]
+ self.__model.remove(iter)
+ self.emit("changed")
+ try:
+ row = self.__model[index]
+ selection = self.get_selection()
+ selection.select_path(row.path)
+ except:
+ pass
+
+ def move_up_engine(self):
+ iter = self.get_selected_iter()
+ if iter == None:
+ return
+ row = self.__model[iter]
+ index = row.path[0]
+ if index == 0:
+ return
+ self.__model.swap(iter, self.__model[index - 1].iter)
+ self.emit("changed")
+ self.scroll_to_cell(row.path, None)
+
+ def move_down_engine(self):
+ iter = self.get_selected_iter()
+ if iter == None:
+ return
+ row = self.__model[iter]
+ index = row.path[0]
+ last_row = self.__model[-1]
+ last_index = last_row.path[0]
+ if index == last_index:
+ return
+ self.__model.swap(iter, self.__model[index + 1].iter)
+ self.emit("changed")
+ self.scroll_to_cell(row.path, None)
+
+gobject.type_register(EngineTreeView)
diff --git a/setup/icon.py b/setup/icon.py
new file mode 100644
index 0000000..fedd2cf
--- /dev/null
+++ b/setup/icon.py
@@ -0,0 +1,60 @@
+# vim:set et sts=4 sw=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
+
+__all__ = (
+ "load_icon"
+)
+
+import gtk
+from gtk import gdk
+from os import path
+
+
+icon_theme = gtk.icon_theme_get_default()
+dir = path.dirname(__file__)
+icondir = path.join(dir, "..", "icons")
+icon_theme.prepend_search_path(icondir)
+
+icon_cache = {}
+
+def load_icon(icon, size):
+ if (icon, size) in icon_cache:
+ return icon_cache[(icon, size)]
+
+ icon_size = gtk.icon_size_lookup(size)[0]
+ pixbuf = None
+ try:
+ pixbuf = gdk.pixbuf_new_from_file(icon)
+ w, h = pixbuf.get_width(), pixbuf.get_height()
+ rate = max(w, h) / float(icon_size)
+ w = int(w / rate)
+ h = int(h / rate)
+ pixbuf = pixbuf.scale_simple(w, h, gdk.INTERP_BILINEAR)
+ except:
+ pass
+ if pixbuf == None:
+ try:
+ theme = gtk.icon_theme_get_default()
+ pixbuf = theme.load_icon(icon, icon_size, 0)
+ except:
+ pass
+ icon_cache[(icon, size)] = pixbuf
+ return pixbuf
diff --git a/setup/keyboardshortcut.py b/setup/keyboardshortcut.py
index c667903..c30dbcc 100644
--- a/setup/keyboardshortcut.py
+++ b/setup/keyboardshortcut.py
@@ -80,7 +80,7 @@ class KeyboardShortcutSelection(gtk.VBox):
table = gtk.Table(4, 2)
self.__modifier_buttons = []
- self.__modifier_buttons.append(("Ctrl", gtk.CheckButton("_Ctrl"), gdk.CONTROL_MASK))
+ self.__modifier_buttons.append(("Control", gtk.CheckButton("_Control"), gdk.CONTROL_MASK))
self.__modifier_buttons.append(("Alt", gtk.CheckButton("A_lt"), gdk.MOD1_MASK))
self.__modifier_buttons.append(("Shift", gtk.CheckButton("_Shift"), gdk.SHIFT_MASK))
self.__modifier_buttons.append(("Meta", gtk.CheckButton("_Meta"), gdk.META_MASK))
@@ -258,7 +258,7 @@ if __name__ == "__main__":
dlg = KeyboardShortcutSelectionDialog(
title = "Select test",
buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
- dlg.add_shortcut("Ctrl+Shift+space")
+ dlg.add_shortcut("Control+Shift+space")
dlg.set_shortcuts(None)
print dlg.run()
print dlg.get_shortcuts()
diff --git a/setup/main.py b/setup/main.py
index 7fe9f2e..e3349d0 100644
--- a/setup/main.py
+++ b/setup/main.py
@@ -33,6 +33,9 @@ from os import path
from xdg import BaseDirectory
from gtk import gdk
from gtk import glade
+from enginecombobox import EngineComboBox
+from enginetreeview import EngineTreeView
+from icon import load_icon
_ = lambda a : gettext.dgettext("ibus", a)
N_ = lambda a : a
@@ -75,12 +78,6 @@ class Setup(object):
def __init_ui(self):
# add icon search path
- icon_theme = gtk.icon_theme_get_default()
- dir = path.dirname(__file__)
- icondir = path.join(dir, "..", "icons")
- icon_theme.prepend_search_path(icondir)
-
-
self.__dialog = self.__xml.get_widget("dialog_setup")
# auto start ibus
@@ -90,76 +87,111 @@ class Setup(object):
# keyboard shortcut
# trigger
- shortcuts = self.__bus.config_get_value(
- "general", "keyboard_shortcut_trigger",
+ self.__config = self.__bus.get_config()
+ shortcuts = self.__config.get_value(
+ "general/hotkey", "trigger",
ibus.CONFIG_GENERAL_SHORTCUT_TRIGGER_DEFAULT)
+
button = self.__xml.get_widget("button_trigger")
entry = self.__xml.get_widget("entry_trigger")
entry.set_text("; ".join(shortcuts))
button.connect("clicked", self.__shortcut_button_clicked_cb,
- N_("trigger"), "general", "keyboard_shortcut_trigger", entry)
+ N_("trigger"), "general/hotkey", "trigger", entry)
# next engine
- shortcuts = self.__bus.config_get_value(
- "general", "keyboard_shortcut_next_engine",
+ shortcuts = self.__config.get_value(
+ "general/hotkey", "next_engine",
ibus.CONFIG_GENERAL_SHORTCUT_NEXT_ENGINE_DEFAULT)
button = self.__xml.get_widget("button_next_engine")
entry = self.__xml.get_widget("entry_next_engine")
entry.set_text("; ".join(shortcuts))
button.connect("clicked", self.__shortcut_button_clicked_cb,
- N_("next engine"), "general", "keyboard_shortcut_next_engine", entry)
+ N_("next engine"), "general/hotkey", "next_engine", entry)
# prev engine
- shortcuts = self.__bus.config_get_value(
- "general", "keyboard_shortcut_prev_engine",
+ shortcuts = self.__config.get_value(
+ "general/hotkey", "prev_engine",
ibus.CONFIG_GENERAL_SHORTCUT_PREV_ENGINE_DEFAULT)
button = self.__xml.get_widget("button_prev_engine")
entry = self.__xml.get_widget("entry_prev_engine")
entry.set_text("; ".join(shortcuts))
button.connect("clicked", self.__shortcut_button_clicked_cb,
- N_("prev engine"), "general", "keyboard_shortcut_prev_engine", entry)
-
-
+ N_("prev engine"), "general/hotkey", "prev_engine", entry)
# lookup table orientation
self.__combobox_lookup_table_orientation = self.__xml.get_widget("combobox_lookup_table_orientation")
self.__combobox_lookup_table_orientation.set_active(
- self.__bus.config_get_value("panel", "lookup_table_orientation", 0))
+ self.__config.get_value("panel", "lookup_table_orientation", 0))
self.__combobox_lookup_table_orientation.connect("changed",
self.__combobox_lookup_table_orientation_changed_cb)
# auto hide
self.__checkbutton_auto_hide = self.__xml.get_widget("checkbutton_auto_hide")
self.__checkbutton_auto_hide.set_active(
- self.__bus.config_get_value("panel", "auto_hide", False))
+ self.__config.get_value("panel", "auto_hide", False))
self.__checkbutton_auto_hide.connect("toggled", self.__checkbutton_auto_hide_toggled_cb)
# custom font
self.__checkbutton_custom_font = self.__xml.get_widget("checkbutton_custom_font")
self.__checkbutton_custom_font.set_active(
- self.__bus.config_get_value("panel", "use_custom_font", False))
+ self.__config.get_value("panel", "use_custom_font", False))
self.__checkbutton_custom_font.connect("toggled", self.__checkbutton_custom_font_toggled_cb)
self.__fontbutton_custom_font = self.__xml.get_widget("fontbutton_custom_font")
- if self.__bus.config_get_value("panel", "use_custom_font", False):
+ if self.__config.get_value("panel", "use_custom_font", False):
self.__fontbutton_custom_font.set_sensitive(True)
else:
self.__fontbutton_custom_font.set_sensitive(False)
font_name = gtk.settings_get_default().get_property("gtk-font-name")
font_name = unicode(font_name, "utf-8")
- font_name = self.__bus.config_get_value("panel", "custom_font", font_name)
+ font_name = self.__config.get_value("panel", "custom_font", font_name)
self.__fontbutton_custom_font.connect("notify::font-name", self.__fontbutton_custom_font_notify_cb)
self.__fontbutton_custom_font.set_font_name(font_name)
- self.__init_engine_view()
+ # init engine page
+ self.__engines = self.__bus.list_engines()
+ self.__combobox = EngineComboBox(self.__engines)
+ self.__combobox.show()
+ self.__xml.get_widget("alignment_engine_combobox").add(self.__combobox)
+
+ tmp_dict = {}
+ for e in self.__engines:
+ tmp_dict[e.name] = e
+ engine_names = self.__config.get_value("general", "preload_engines", [])
+ engines = []
+ for n in engine_names:
+ if n in tmp_dict:
+ engines.append(tmp_dict[n])
+ self.__treeview = EngineTreeView(engines)
+ self.__treeview.show()
+ self.__xml.get_widget("scrolledwindow_engine_treeview").add(self.__treeview)
+
+ self.__treeview.connect("changed", self.__treeview_changed_cb)
+
+ button = self.__xml.get_widget("button_engine_add")
+ button.connect("clicked",
+ lambda *args:self.__treeview.prepend_engine(self.__combobox.get_active_engine()))
+ button = self.__xml.get_widget("button_engine_remove")
+ button.connect("clicked", lambda *args:self.__treeview.remove_engine())
+ button = self.__xml.get_widget("button_engine_up")
+ button.connect("clicked", lambda *args:self.__treeview.move_up_engine())
+
+ button = self.__xml.get_widget("button_engine_down")
+ button.connect("clicked", lambda *args:self.__treeview.move_down_engine())
+
+ def __treeview_changed_cb(self, treeview):
+ engines = self.__treeview.get_engines()
+ engine_names = map(lambda e: e.name, engines)
+ self.__config.set_list("general", "preload_engines", engine_names, "s")
def __init_bus(self):
try:
self.__bus = ibus.Bus()
# self.__bus.connect("config-value-changed", self.__config_value_changed_cb)
- self.__bus.connect("config-reloaded", self.__config_reloaded_cb)
- self.__bus.config_add_watch("/general")
- self.__bus.config_add_watch("/panel")
+ # self.__bus.connect("config-reloaded", self.__config_reloaded_cb)
+ # self.__bus.config_add_watch("/general")
+ # self.__bus.config_add_watch("/general/hotkey")
+ # self.__bus.config_add_watch("/panel")
except:
while self.__bus == None:
message = _("IBus daemon is not started. Do you want to start it now?")
@@ -190,60 +222,6 @@ class Setup(object):
dlg.destroy()
self.__flush_gtk_events()
- def __init_engine_view(self):
- # engines tree
- self.__tree = self.__xml.get_widget("treeview_engines")
- self.__preload_engines = set(self.__bus.config_get_value("general", "preload_engines", []))
- model = self.__create_model()
- self.__tree.set_model(model)
-
- # column for engine
- column = gtk.TreeViewColumn()
- column.set_title(_("Engine"))
- column.set_resizable(True)
- column.set_min_width(120)
-
- renderer = gtk.CellRendererPixbuf()
- renderer.set_property("xalign", 0.5)
-
- column.pack_start(renderer, False)
- column.set_attributes(renderer, pixbuf = COLUMN_ICON, visible = COLUMN_VISIBLE)
-
- renderer = gtk.CellRendererText()
- renderer.set_property("xalign", 0.0)
- renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
-
- # column.set_clickable(True)
- column.pack_start(renderer)
- column.set_attributes(renderer, text = COLUMN_NAME)
-
- self.__tree.append_column(column)
-
- # column for started
- renderer = gtk.CellRendererToggle()
- renderer.set_data('column', COLUMN_ENABLE)
- renderer.set_property("xalign", 0.5)
- renderer.connect("toggled", self.__item_started_column_toggled_cb, model)
-
- #col_offset = gtk.TreeViewColumn("Holiday", renderer, text=HOLIDAY_NAME)
- column = gtk.TreeViewColumn(_("Started"), renderer, active = COLUMN_ENABLE, visible = COLUMN_VISIBLE)
- column.set_resizable(True)
- self.__tree.append_column(column)
-
- # column for preload
- renderer = gtk.CellRendererToggle()
- renderer.set_data('column', COLUMN_PRELOAD)
- renderer.set_property("xalign", 0.5)
- renderer.connect("toggled", self.__item_preload_column_toggled_cb, model)
-
- column = gtk.TreeViewColumn(_("Preload"), renderer, active = COLUMN_PRELOAD, visible = COLUMN_VISIBLE)
- column.set_resizable(True)
- self.__tree.append_column(column)
-
- renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn("", renderer)
- self.__tree.append_column(column)
-
def __shortcut_button_clicked_cb(self, button, name, section, _name, entry):
buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)
title = _("Select keyboard shortcut for %s") % _(name)
@@ -259,7 +237,7 @@ class Setup(object):
dialog.destroy()
if id != gtk.RESPONSE_OK:
return
- self.__bus.config_set_value(section, _name, shortcuts)
+ self.__config.set_value(section, _name, shortcuts)
entry.set_text("; ".join(shortcuts))
@@ -309,94 +287,15 @@ class Setup(object):
if data[DATA_PRELOAD]:
if engine not in self.__preload_engines:
self.__preload_engines.add(engine)
- self.__bus.config_set_list("general", "preload_engines", list(self.__preload_engines), "s")
+ self.__config.set_list("general", "preload_engines", list(self.__preload_engines), "s")
else:
if engine in self.__preload_engines:
self.__preload_engines.remove(engine)
- self.__bus.config_set_list("general", "preload_engines", list(self.__preload_engines), "s")
+ self.__config.set_list("general", "preload_engines", list(self.__preload_engines), "s")
# set new value
model.set(iter, COLUMN_PRELOAD, data[DATA_PRELOAD])
- def __load_icon(self, icon, icon_size):
- pixbuf = None
- try:
- pixbuf = gdk.pixbuf_new_from_file(icon)
- w, h = pixbuf.get_width(), pixbuf.get_height()
- rate = max(w, h) / float(icon_size)
- w = int(w / rate)
- h = int(h / rate)
- pixbuf = pixbuf.scale_simple(w, h, gdk.INTERP_BILINEAR)
- except:
- pass
- if pixbuf == None:
- try:
- theme = gtk.icon_theme_get_default()
- pixbuf = theme.load_icon(icon, icon_size, 0)
- except:
- pass
- return pixbuf
-
- def __create_model(self):
- # create tree store
- model = gtk.TreeStore(
- gobject.TYPE_STRING,
- gobject.TYPE_BOOLEAN,
- gobject.TYPE_BOOLEAN,
- gobject.TYPE_BOOLEAN,
- gdk.Pixbuf,
- gobject.TYPE_PYOBJECT)
-
- langs = dict()
-
- self.__bus.register_reload_engines()
- for name, local_name, lang, icon, author, credits, _exec, started in self.__bus.register_list_engines():
- _lang = ibus.get_language_name(lang)
- if _lang not in langs:
- langs[_lang] = list()
- langs[_lang].append([name, local_name, lang, icon, author, credits, _exec, started])
-
- keys = langs.keys()
- keys.sort()
- if _("Other") in keys:
- keys.remove(_("Other"))
- keys.append(_("Other"))
-
- icon_size = gtk.icon_size_lookup(gtk.ICON_SIZE_LARGE_TOOLBAR)[0]
- pixbuf_missing = self.__load_icon("engine-default", icon_size)
- if pixbuf_missing == None:
- pixbuf_missing = self.__load_icon("gtk-missing-image", icon_size)
-
- for key in keys:
- iter = model.append(None)
- model.set(iter,
- COLUMN_NAME, key,
- COLUMN_ENABLE, False,
- COLUMN_PRELOAD, False,
- COLUMN_VISIBLE, False,
- COLUMN_ICON, None,
- COLUMN_DATA, None)
- langs[key].sort()
-
- for name, local_name, lang, icon, author, credits, _exec, started in langs[key]:
- child_iter = model.append(iter)
- is_preload = "%s:%s" % (lang, name) in self.__preload_engines
-
- pixbuf = self.__load_icon(icon, icon_size)
- if pixbuf == None:
- pixbuf = pixbuf_missing
-
- model.set(child_iter,
- COLUMN_NAME, local_name,
- COLUMN_ENABLE, started,
- COLUMN_PRELOAD, is_preload,
- COLUMN_VISIBLE, True,
- COLUMN_ICON, pixbuf,
- COLUMN_DATA,
- [name, local_name, lang, icon, author, credits, _exec, started, is_preload])
-
- return model
-
def __is_auto_start(self):
link_file = path.join(BaseDirectory.xdg_config_home, "autostart/ibus.desktop")
ibus_desktop = path.join(os.getenv("IBUS_PREFIX"), "share/applications/ibus.desktop")
@@ -425,27 +324,27 @@ class Setup(object):
os.symlink(ibus_desktop, link_file)
def __combobox_lookup_table_orientation_changed_cb(self, combobox):
- self.__bus.config_set_value(
+ self.__config.set_value(
"panel", "lookup_table_orientation",
self.__combobox_lookup_table_orientation.get_active())
def __checkbutton_auto_hide_toggled_cb(self, button):
- self.__bus.config_set_value(
+ self.__config.set_value(
"panel", "auto_hide",
self.__checkbutton_auto_hide.get_active())
def __checkbutton_custom_font_toggled_cb(self, button):
if self.__checkbutton_custom_font.get_active():
self.__fontbutton_custom_font.set_sensitive(True)
- self.__bus.config_set_value("panel", "use_custom_font", True)
+ self.__config.set_value("panel", "use_custom_font", True)
else:
self.__fontbutton_custom_font.set_sensitive(False)
- self.__bus.config_set_value("panel", "use_custom_font", False)
+ self.__config.set_value("panel", "use_custom_font", False)
def __fontbutton_custom_font_notify_cb(self, button, arg):
font_name = self.__fontbutton_custom_font.get_font_name()
font_name = unicode(font_name, "utf-8")
- self.__bus.config_set_value("panel", "custom_font", font_name)
+ self.__config.set_value("panel", "custom_font", font_name)
def __config_value_changed_cb(self, bus, section, name, value):
pass
diff --git a/setup/setup.glade b/setup/setup.glade
index 72854d9..c8e63ed 100644
--- a/setup/setup.glade
+++ b/setup/setup.glade
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.5 on Thu Oct 9 11:25:43 2008 -->
+<!--Generated with glade3 3.4.5 on Wed Feb 4 15:58:20 2009 -->
<glade-interface>
<widget class="GtkDialog" id="dialog_setup">
<property name="border_width">5</property>
@@ -340,20 +340,112 @@ Vertical</property>
<property name="left_padding">2</property>
<property name="right_padding">2</property>
<child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="width_request">300</property>
- <property name="height_request">350</property>
+ <widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
<child>
- <widget class="GtkTreeView" id="treeview_engines">
+ <widget class="GtkAlignment" id="alignment6">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="reorderable">True</property>
+ <property name="top_padding">4</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment_engine_combobox">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow_engine_treeview">
+ <property name="width_request">240</property>
+ <property name="height_request">350</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="top_padding">8</property>
+ <property name="bottom_padding">8</property>
+ <property name="left_padding">8</property>
+ <property name="right_padding">8</property>
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox1">
+ <property name="visible">True</property>
+ <property name="spacing">5</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <child>
+ <widget class="GtkButton" id="button_engine_add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_engine_remove">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_engine_up">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-go-up</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_engine_down">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-go-down</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
</widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
</child>
</widget>
</child>
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..f39eb28
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1,12 @@
+ibusmarshalers.c
+ibusmarshalers.h
+test-attribute
+test-bus
+test-engine
+test-keynames
+test-lookuptable
+test-proxy
+test-server
+test-text
+stamp-ibusenumtypes.h
+stamp-ibusmarshalers.h
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..e8c6614
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,209 @@
+# 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
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ $(NULL)
+
+# ibus library
+lib_LTLIBRARIES = libibus.la
+ibus_built_public_h_sources = \
+ ibusmarshalers.h \
+ ibusenumtypes.h \
+ $(NULl)
+ibus_built_c_sources = \
+ ibusmarshalers.c \
+ ibusenumtypes.c \
+ $(NULL)
+ibus_built_sources = \
+ $(ibus_built_public_h_sources) \
+ $(ibus_built_c_sources) \
+ $(NULL)
+ibus_public_h_sources = \
+ ibus.h \
+ ibusshare.h \
+ ibusdebug.h \
+ ibusobject.h \
+ ibusserializable.h \
+ ibusconnection.h \
+ ibusserver.h \
+ ibusproxy.h \
+ ibusservice.h \
+ ibusfactory.h \
+ ibusengine.h \
+ ibustext.h \
+ ibusattribute.h \
+ ibusproperty.h \
+ ibuslookuptable.h \
+ ibusinputcontext.h \
+ ibusconfig.h \
+ ibusconfigservice.h \
+ ibusmessage.h \
+ ibuspendingcall.h \
+ ibuserror.h \
+ ibuskeysyms.h \
+ ibustypes.h \
+ ibusbus.h \
+ ibushotkey.h \
+ ibusxml.h \
+ ibusenginedesc.h \
+ ibusobservedpath.h \
+ ibuscomponent.h \
+ $(NULL)
+ibus_h_sources = \
+ ibusinternal.h \
+ ibusconfigprivate.h \
+ keyname-table.h \
+ $(ibus_public_h_sources) \
+ $(ibus_built_public_h_sources) \
+ $(NULL)
+ibus_c_sources = \
+ ibusshare.c \
+ ibusinternal.c \
+ ibusobject.c \
+ ibusserializable.c \
+ ibusconnection.c \
+ ibusserver.c \
+ ibusproxy.c \
+ ibusservice.c \
+ ibusfactory.c \
+ ibusengine.c \
+ ibustext.c \
+ ibusattribute.c \
+ ibusproperty.c \
+ ibuslookuptable.c \
+ ibusinputcontext.c \
+ ibusconfig.c \
+ ibusconfigservice.c \
+ ibusmessage.c \
+ ibuspendingcall.c \
+ ibuserror.c \
+ ibusbus.c \
+ ibuskeynames.c \
+ ibushotkey.c \
+ ibusxml.c \
+ ibusenginedesc.c \
+ ibusobservedpath.c \
+ ibuscomponent.c \
+ $(ibus_built_c_sources) \
+ $(NULL)
+
+ibusincludedir = $(includedir)/ibus-1.0
+ibusinclude_HEADERS = \
+ $(ibus_public_h_sources) \
+ $(ibus_built_public_h_sources) \
+ $(NULL)
+
+libibus_la_SOURCES = \
+ $(ibus_h_sources) \
+ $(ibus_c_sources) \
+ $(NULL)
+libibus_la_CFLAGS = \
+ @X11_CFLAGS@ \
+ @GLIB2_CFLAGS@ \
+ @GOBJECT2_CFLAGS@ \
+ @GIO2_CFLAGS@ \
+ @DBUS_CFLAGS@ \
+ -DG_LOG_DOMAIN=\"IBUS\" \
+ $(NULL)
+libibus_la_LDFLAGS = \
+ @X11_LIBS@ \
+ @GLIB2_LIBS@ \
+ @GOBJECT2_LIBS@ \
+ @GIO2_LIBS@ \
+ @DBUS_LIBS@ \
+ -version-info @LT_VERSION_INFO@ \
+ $(NULL)
+
+BUILT_SOURCES = \
+ $(ibus_built_sources) \
+ $(NULL)
+
+
+# test programs
+DEPS = \
+ libibus.la \
+ $(NULL)
+AM_CFLAGS = \
+ @X11_CFLAGS@ \
+ @GLIB2_CFLAGS@ \
+ @GOBJECT2_CFLAGS@ \
+ @GIO2_CFLAGS@ \
+ @DBUS_CFLAGS@ \
+ -DG_LOG_DOMAIN=\"IBUS\" \
+ $(NULL)
+AM_LDFLAGS = \
+ $(DEPS) \
+ $(NULL)
+
+TESTS = \
+ test-text \
+ test-keynames \
+ test-attribute \
+ test-lookuptable \
+ $(NULL)
+noinst_PROGRAMS = $(TESTS)
+test_text_DEPENDENCIES = $(DEPS)
+test_keynames_DEPENDENCIES = $(DEPS)
+test_attribute_DEPENDENCIES = $(DEPS)
+test_lookuptable_DEPENDENCIES = $(DEPS)
+
+# gen enum types
+ibusenumtypes.h: stamp-ibusenumtypes.h
+ @true
+stamp-ibusenumtypes.h: @REBUILD@ $(ibus_public_h_sources) ibusenumtypes.h.template
+ ( cd $(srcdir) && $(GLIB_MKENUMS) --template ibusenumtypes.h.template \
+ $(ibus_public_h_sources) ) | sed 's/i_bus_/ibus_/g' | sed 's/I_TYPE_BUS_/IBUS_TYPE_/g' >> xgen-geth \
+ && (cmp -s xgen-geth ibusenumtypes.h || cp xgen-geth ibusenumtypes.h ) \
+ && rm -f xgen-geth \
+ && echo timestamp > $(@F)
+ibusenumtypes.c: @REBUILD@ $(ibus_public_h_sources) ibusenumtypes.c.template
+ ( cd $(srcdir) && $(GLIB_MKENUMS) --template ibusenumtypes.c.template \
+ $(ibus_public_h_sources) ) | sed 's/i_bus_/ibus_/g' | sed 's/I_TYPE_BUS_/IBUS_TYPE_/g' > xgen-getc \
+ && cp xgen-getc ibusenumtypes.c \
+ && rm -f xgen-getc
+
+# gen marshal
+ibusmarshalers.h: stamp-ibusmarshalers.h
+ @true
+stamp-ibusmarshalers.h: ibusmarshalers.list
+ $(GLIB_GENMARSHAL) --prefix=ibus_marshal $(srcdir)/ibusmarshalers.list --header >> xgen-gmh \
+ && (cmp -s xgen-gmh ibusmarshalers.h || cp xgen-gmh ibusmarshalers.h) \
+ && rm -f xgen-gmh \
+ && echo timestamp > $(@F)
+ibusmarshalers.c: ibusmarshalers.list
+ (echo "#include \"ibusmarshalers.h\""; \
+ $(GLIB_GENMARSHAL) --prefix=ibus_marshal $(srcdir)/ibusmarshalers.list --body; \
+ echo ) >> xgen-gmc \
+ && cp xgen-gmc ibusmarshalers.c \
+ && rm -f xgen-gmc
+
+EXTRA_DIST = \
+ ibusmarshalers.list \
+ ibusenumtypes.h.template \
+ ibusenumtypes.c.template \
+ $(NULL)
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ stamp-ibusmarshalers.h \
+ stamp-ibusenumtypes.h \
+ $(NULL)
diff --git a/src/ibus.h b/src/ibus.h
new file mode 100644
index 0000000..23b270a
--- /dev/null
+++ b/src/ibus.h
@@ -0,0 +1,51 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_H_
+#define __IBUS_H_
+
+#include <ibusshare.h>
+#include <ibusobject.h>
+#include <ibusserializable.h>
+#include <ibustext.h>
+#include <ibusconnection.h>
+#include <ibusserver.h>
+#include <ibusproxy.h>
+#include <ibusservice.h>
+#include <ibusfactory.h>
+#include <ibusengine.h>
+#include <ibusattribute.h>
+#include <ibusproperty.h>
+#include <ibuslookuptable.h>
+#include <ibusbus.h>
+#include <ibuskeysyms.h>
+#include <ibusmessage.h>
+#include <ibuspendingcall.h>
+#include <ibuserror.h>
+#include <ibusenumtypes.h>
+#include <ibushotkey.h>
+#include <ibusxml.h>
+#include <ibusenginedesc.h>
+#include <ibusobservedpath.h>
+#include <ibuscomponent.h>
+#include <ibusconfig.h>
+#include <ibusconfigservice.h>
+
+#endif
+
diff --git a/src/ibusattribute.c b/src/ibusattribute.c
new file mode 100644
index 0000000..7b41ab2
--- /dev/null
+++ b/src/ibusattribute.c
@@ -0,0 +1,433 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibusattribute.h"
+
+/* functions prototype */
+static void ibus_attribute_class_init (IBusAttributeClass *klass);
+static void ibus_attribute_init (IBusAttribute *attr);
+// static void ibus_attribute_destroy (IBusAttribute *attr);
+static gboolean ibus_attribute_serialize (IBusAttribute *attr,
+ IBusMessageIter *iter);
+static gboolean ibus_attribute_deserialize (IBusAttribute *attr,
+ IBusMessageIter *iter);
+static gboolean ibus_attribute_copy (IBusAttribute *dest,
+ const IBusAttribute *src);
+
+static void ibus_attr_list_class_init (IBusAttrListClass *klass);
+static void ibus_attr_list_init (IBusAttrList *attr_list);
+static void ibus_attr_list_destroy (IBusAttrList *attr_list);
+static gboolean ibus_attr_list_serialize (IBusAttrList *attr_list,
+ IBusMessageIter *iter);
+static gboolean ibus_attr_list_deserialize (IBusAttrList *attr_list,
+ IBusMessageIter *iter);
+static gboolean ibus_attr_list_copy (IBusAttrList *dest,
+ const IBusAttrList *src);
+
+static IBusSerializableClass *parent_class = NULL;
+
+GType
+ibus_attribute_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusAttributeClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_attribute_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusAttribute),
+ 0,
+ (GInstanceInitFunc) ibus_attribute_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusAttribute",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_attribute_class_init (IBusAttributeClass *klass)
+{
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ // object_class->destroy = (IBusObjectDestroyFunc) ibus_attribute_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_attribute_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_attribute_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_attribute_copy;
+
+ g_string_append (serializable_class->signature, "uuuu");
+}
+
+static void
+ibus_attribute_init (IBusAttribute *attr)
+{
+}
+
+// static void
+// ibus_attribute_destroy (IBusAttribute *attr)
+// {
+// IBUS_OBJECT (parent_class)->destroy ((IBusObject *)attr);
+// }
+
+static gboolean
+ibus_attribute_serialize (IBusAttribute *attr,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = parent_class->serialize ((IBusSerializable *) attr, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_ATTRIBUTE (attr), FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &attr->type);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &attr->value);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &attr->start_index);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &attr->end_index);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_attribute_deserialize (IBusAttribute *attr,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = parent_class->deserialize ((IBusSerializable *) attr, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_ATTRIBUTE (attr), FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &attr->type);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &attr->value);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &attr->start_index);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &attr->end_index);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+
+}
+
+static gboolean
+ibus_attribute_copy (IBusAttribute *dest,
+ const IBusAttribute *src)
+{
+ gboolean retval;
+
+ retval = parent_class->copy ((IBusSerializable *)dest,
+ (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_ATTRIBUTE (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_ATTRIBUTE (src), FALSE);
+
+ dest->type = src->type;
+ dest->value = src->value;
+ dest->start_index = src->start_index;
+ dest->end_index = src->end_index;
+
+ return TRUE;
+}
+
+IBusAttribute *
+ibus_attribute_new (guint type,
+ guint value,
+ guint start_index,
+ guint end_index)
+{
+ g_return_val_if_fail (
+ type == IBUS_ATTR_TYPE_UNDERLINE ||
+ type == IBUS_ATTR_TYPE_FOREGROUND ||
+ type == IBUS_ATTR_TYPE_BACKGROUND, NULL);
+
+ IBusAttribute *attr = IBUS_ATTRIBUTE (g_object_new (IBUS_TYPE_ATTRIBUTE, 0));
+
+ attr->type = type;
+ attr->value = value;
+ attr->start_index = start_index;
+ attr->end_index = end_index;
+
+ return attr;
+}
+
+IBusAttribute *
+ibus_attr_underline_new (guint underline_type,
+ guint start_index,
+ guint end_index)
+{
+ g_return_val_if_fail (
+ underline_type == IBUS_ATTR_UNDERLINE_NONE ||
+ underline_type == IBUS_ATTR_UNDERLINE_SINGLE ||
+ underline_type == IBUS_ATTR_UNDERLINE_DOUBLE ||
+ underline_type == IBUS_ATTR_UNDERLINE_LOW, NULL);
+
+ return ibus_attribute_new (IBUS_ATTR_TYPE_UNDERLINE,
+ underline_type,
+ start_index,
+ end_index);
+}
+
+IBusAttribute *
+ibus_attr_foreground_new (guint color,
+ guint start_index,
+ guint end_index)
+{
+ return ibus_attribute_new (IBUS_ATTR_TYPE_FOREGROUND,
+ color,
+ start_index,
+ end_index);
+}
+
+IBusAttribute *
+ibus_attr_background_new (guint color,
+ guint start_index,
+ guint end_index)
+{
+ return ibus_attribute_new (IBUS_ATTR_TYPE_BACKGROUND,
+ color,
+ start_index,
+ end_index);
+}
+
+GType
+ibus_attr_list_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusAttrListClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_attr_list_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusAttrList),
+ 0,
+ (GInstanceInitFunc) ibus_attr_list_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusAttrList",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_attr_list_class_init (IBusAttrListClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_attr_list_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_attr_list_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_attr_list_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_attr_list_copy;
+
+ g_string_append (serializable_class->signature, "av");
+}
+
+static void
+ibus_attr_list_init (IBusAttrList *attr_list)
+{
+ attr_list->attributes = g_array_new (TRUE, TRUE, sizeof (IBusAttribute *));
+}
+
+static void
+ibus_attr_list_destroy (IBusAttrList *attr_list)
+{
+ g_return_if_fail (IBUS_IS_ATTR_LIST (attr_list));
+
+ gint i;
+ for (i = 0;; i++) {
+ IBusAttribute *attr;
+
+ attr = ibus_attr_list_get (attr_list, i);
+ if (attr == NULL)
+ break;
+
+ g_object_unref (attr);
+ }
+
+ g_array_free (attr_list->attributes, TRUE);
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)attr_list);
+}
+
+static gboolean
+ibus_attr_list_serialize (IBusAttrList *attr_list,
+ IBusMessageIter *iter)
+{
+ IBusMessageIter array_iter;
+ gboolean retval;
+ guint i;
+
+ retval = parent_class->serialize ((IBusSerializable *)attr_list, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_ATTR_LIST (attr_list), FALSE);
+
+ retval = ibus_message_iter_open_container (iter,
+ IBUS_TYPE_ARRAY,
+ "v",
+ &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ for (i = 0;; i++) {
+ IBusAttribute *attr;
+
+ attr = ibus_attr_list_get (attr_list, i);
+ if (attr == NULL)
+ break;
+
+ retval = ibus_message_iter_append (&array_iter, IBUS_TYPE_ATTRIBUTE, &attr);
+ g_return_val_if_fail (retval, FALSE);
+ }
+
+ retval = ibus_message_iter_close_container (iter, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_attr_list_deserialize (IBusAttrList *attr_list,
+ IBusMessageIter *iter)
+{
+ DBusMessageIter array_iter;
+ gboolean retval;
+
+ retval = parent_class->deserialize ((IBusSerializable *)attr_list, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_recurse (iter, IBUS_TYPE_ARRAY, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ while (ibus_message_iter_get_arg_type (&array_iter) != G_TYPE_INVALID) {
+ IBusAttribute *attr;
+
+ retval = ibus_message_iter_get (&array_iter, IBUS_TYPE_ATTRIBUTE, &attr);
+
+ g_return_val_if_fail (retval, FALSE);
+
+ ibus_attr_list_append (attr_list, attr);
+ }
+
+ ibus_message_iter_next (iter);
+
+ return TRUE;
+}
+
+
+
+static gboolean
+ibus_attr_list_copy (IBusAttrList *dest,
+ const IBusAttrList *src)
+{
+ gboolean retval;
+
+ retval = parent_class->copy ((IBusSerializable *)dest,
+ (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_ATTRIBUTE (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_ATTRIBUTE (src), FALSE);
+
+ gint i;
+ for (i = 0; ; i++) {
+ IBusAttribute *attr = ibus_attr_list_get ((IBusAttrList *)src, i);
+ if (attr == NULL) {
+ break;
+ }
+
+ attr = (IBusAttribute *) ibus_serializable_copy ((IBusSerializable *) attr);
+ if (attr == NULL) {
+ g_warning ("can not copy attribute");
+ continue;
+ }
+
+ ibus_attr_list_append (dest, attr);
+ }
+ return TRUE;
+}
+
+IBusAttrList *
+ibus_attr_list_new ()
+{
+ IBusAttrList *attr_list;
+ attr_list = g_object_new (IBUS_TYPE_ATTR_LIST, 0);
+ return attr_list;
+}
+
+void
+ibus_attr_list_append (IBusAttrList *attr_list,
+ IBusAttribute *attr)
+{
+ g_return_if_fail (IBUS_IS_ATTR_LIST (attr_list));
+ g_return_if_fail (IBUS_IS_ATTRIBUTE (attr));
+
+ g_array_append_val (attr_list->attributes, attr);
+}
+
+IBusAttribute *
+ibus_attr_list_get (IBusAttrList *attr_list,
+ guint index)
+{
+ g_return_val_if_fail (attr_list != NULL, NULL);
+ IBusAttribute *attr = NULL;
+
+ if (index < attr_list->attributes->len) {
+ attr = g_array_index (attr_list->attributes, IBusAttribute *, index);
+ }
+
+ return attr;
+}
+
+
diff --git a/src/ibusattribute.h b/src/ibusattribute.h
new file mode 100644
index 0000000..3a0ff7f
--- /dev/null
+++ b/src/ibusattribute.h
@@ -0,0 +1,126 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_ATTRIBUTE_H_
+#define __IBUS_ATTRIBUTE_H_
+
+#include "ibusserializable.h"
+
+/*
+ * Type macros.
+ */
+/* define IBusAttribute macros */
+#define IBUS_TYPE_ATTRIBUTE \
+ (ibus_attribute_get_type ())
+#define IBUS_ATTRIBUTE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_ATTRIBUTE, IBusAttribute))
+#define IBUS_ATTRIBUTE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_ATTRIBUTE, IBusAttributeClass))
+#define IBUS_IS_ATTRIBUTE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_ATTRIBUTE))
+#define IBUS_IS_ATTRIBUTE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_ATTRIBUTE))
+#define IBUS_ATTRIBUTE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_ATTRIBUTE, IBusAttributeClass))
+
+/* define IBusAttrList macros */
+#define IBUS_TYPE_ATTR_LIST \
+ (ibus_attr_list_get_type ())
+#define IBUS_ATTR_LIST(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_ATTR_LIST, IBusAttrList))
+#define IBUS_ATTR_LIST_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_ATTR_LIST, IBusAttrListClass))
+#define IBUS_IS_ATTR_LIST(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_ATTR_LIST))
+#define IBUS_IS_ATTR_LIST_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_ATTR_LIST))
+#define IBUS_ATTR_LIST_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_ATTR_LIST, IBusAttrListClass))
+
+typedef enum {
+ IBUS_ATTR_TYPE_UNDERLINE = 1,
+ IBUS_ATTR_TYPE_FOREGROUND = 2,
+ IBUS_ATTR_TYPE_BACKGROUND = 3,
+} IBusAttrType;
+
+typedef enum {
+ IBUS_ATTR_UNDERLINE_NONE = 0,
+ IBUS_ATTR_UNDERLINE_SINGLE = 1,
+ IBUS_ATTR_UNDERLINE_DOUBLE = 2,
+ IBUS_ATTR_UNDERLINE_LOW = 3,
+} IBusAttrUnderline;
+
+G_BEGIN_DECLS
+
+typedef struct _IBusAttribute IBusAttribute;
+typedef struct _IBusAttributeClass IBusAttributeClass;
+typedef struct _IBusAttrList IBusAttrList;
+typedef struct _IBusAttrListClass IBusAttrListClass;
+
+struct _IBusAttribute {
+ IBusSerializable parent;
+
+ /* members */
+ guint type;
+ guint value;
+ guint start_index;
+ guint end_index;
+};
+
+struct _IBusAttributeClass {
+ IBusSerializableClass parent;
+};
+
+struct _IBusAttrList {
+ IBusSerializable parent;
+
+ /* members */
+ GArray *attributes;
+};
+
+struct _IBusAttrListClass {
+ IBusSerializableClass parent;
+};
+
+GType ibus_attribute_get_type ();
+IBusAttribute *ibus_attribute_new (guint type,
+ guint value,
+ guint start_index,
+ guint end_index);
+IBusAttribute *ibus_attr_underline_new (guint underline_type,
+ guint start_index,
+ guint end_index);
+IBusAttribute *ibus_attr_foreground_new (guint color,
+ guint start_index,
+ guint end_index);
+IBusAttribute *ibus_attr_background_new (guint color,
+ guint start_index,
+ guint end_index);
+
+
+GType ibus_attr_list_get_type ();
+IBusAttrList *ibus_attr_list_new ();
+void ibus_attr_list_append (IBusAttrList *attr_list,
+ IBusAttribute *attr);
+IBusAttribute *ibus_attr_list_get (IBusAttrList *attr_list,
+ guint index);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusbus.c b/src/ibusbus.c
new file mode 100644
index 0000000..be72770
--- /dev/null
+++ b/src/ibusbus.c
@@ -0,0 +1,773 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gio/gio.h>
+#include "ibusbus.h"
+#include "ibusinternal.h"
+#include "ibusshare.h"
+#include "ibusconnection.h"
+
+#define IBUS_BUS_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_BUS, IBusBusPrivate))
+
+enum {
+ CONNECTED,
+ DISCONNECTED,
+ NAME_OWNER_CHANGED,
+ LAST_SIGNAL,
+};
+
+
+/* IBusBusPriv */
+struct _IBusBusPrivate {
+ GFileMonitor *monitor;
+ IBusConnection *connection;
+ gboolean watch_dbus_signal;
+};
+typedef struct _IBusBusPrivate IBusBusPrivate;
+
+static guint bus_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_bus_class_init (IBusBusClass *klass);
+static void ibus_bus_init (IBusBus *bus);
+static void ibus_bus_destroy (IBusObject *object);
+static void ibus_bus_watch_dbus_signal
+ (IBusBus *bus);
+static void ibus_bus_unwatch_dbus_signal
+ (IBusBus *bus);
+static IBusObjectClass *parent_class = NULL;
+
+GType
+ibus_bus_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusBusClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_bus_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusBus),
+ 0,
+ (GInstanceInitFunc) ibus_bus_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_OBJECT,
+ "IBusBus",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+IBusBus *
+ibus_bus_new (void)
+{
+ IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS, NULL));
+
+ return bus;
+}
+
+static void
+ibus_bus_class_init (IBusBusClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusBusPrivate));
+
+ ibus_object_class->destroy = ibus_bus_destroy;
+
+ // install signals
+ bus_signals[CONNECTED] =
+ g_signal_new (I_("connected"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ bus_signals[DISCONNECTED] =
+ g_signal_new (I_("disconnected"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+#if 0
+ bus_signals[NAME_OWNER_CHANGED] =
+ g_signal_new (I_("name-owner-changed"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__STRING_STRING_STRING,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE
+ );
+#endif
+}
+
+#if 0
+static gboolean
+_connection_dbus_signal_cb (IBusConnection *connection,
+ DBusMessage *message,
+ IBusBus *bus)
+{
+ g_assert (IBUS_IS_BUS (bus));
+ g_assert (message != NULL);
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
+ DBusError error;
+ const gchar *name;
+ const gchar *old_name;
+ const gchar *new_name;
+ gboolean retval;
+
+ dbus_error_init (&error);
+ retval = dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &old_name,
+ DBUS_TYPE_STRING, &new_name,
+ DBUS_TYPE_INVALID);
+ if (!retval) {
+ g_warning ("%s: %s", error.name, error.message);
+ dbus_error_free (&error);
+ }
+ else {
+ g_signal_emit (bus,
+ bus_signals[NAME_OWNER_CHANGED],
+ 0,
+ name,
+ old_name,
+ new_name);
+ }
+ }
+
+ return FALSE;
+}
+#endif
+
+static void
+_connection_destroy_cb (IBusConnection *connection,
+ IBusBus *bus)
+{
+ g_assert (IBUS_IS_BUS (bus));
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ g_assert (priv->connection == connection);
+ g_object_unref (priv->connection);
+ priv->connection = NULL;
+
+ g_signal_emit (bus, bus_signals[DISCONNECTED], 0);
+}
+
+static void
+ibus_bus_connect (IBusBus *bus)
+{
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ g_assert (priv->connection == NULL);
+
+ priv->connection = ibus_connection_open (ibus_get_address ());
+
+ if (priv->connection) {
+ ibus_bus_hello (bus);
+#if 0
+ g_signal_connect (priv->connection,
+ "dbus-signal",
+ (GCallback) _connection_dbus_signal_cb,
+ bus);
+#endif
+ g_signal_connect (priv->connection,
+ "destroy",
+ (GCallback) _connection_destroy_cb,
+ bus);
+ g_signal_emit (bus, bus_signals[CONNECTED], 0);
+
+ if (priv->watch_dbus_signal) {
+ ibus_bus_watch_dbus_signal (bus);
+ }
+ }
+}
+
+static void
+_changed_cb (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ IBusBus *bus)
+{
+ static GFile *socket_file = NULL;
+
+ if (socket_file == NULL) {
+ socket_file = g_file_new_for_path (ibus_get_socket_path ());
+ }
+
+ if (event_type == G_FILE_MONITOR_EVENT_CREATED) {
+ if (g_file_equal (file, socket_file)) {
+ ibus_bus_connect (bus);
+ }
+ }
+}
+
+static void
+ibus_bus_init (IBusBus *bus)
+{
+ gchar *path;
+ GFile *file;
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ priv->connection = NULL;
+ priv->watch_dbus_signal = FALSE;
+
+ ibus_bus_connect (bus);
+
+ path = g_strdup_printf ("/tmp/ibus-%s/", ibus_get_user_name ());
+ file = g_file_new_for_path (path);
+ priv->monitor = g_file_monitor_directory (file, 0, NULL, NULL);
+
+ g_signal_connect (priv->monitor, "changed", (GCallback) _changed_cb, bus);
+
+ g_object_unref (file);
+ g_free (path);
+}
+
+static void
+ibus_bus_destroy (IBusObject *object)
+{
+ IBusBus *bus;
+ IBusBusPrivate *priv;
+
+ bus = IBUS_BUS (object);
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ if (priv->monitor) {
+ g_object_unref (priv->monitor);
+ priv->monitor = NULL;
+ }
+
+ if (priv->connection) {
+ ibus_object_destroy (IBUS_OBJECT (priv->connection));
+ priv->connection = NULL;
+ }
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+gboolean
+ibus_bus_is_connected (IBusBus *bus)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ if (priv->connection) {
+ return ibus_connection_is_connected (priv->connection);
+ }
+
+ return FALSE;
+}
+
+
+IBusInputContext *
+ibus_bus_create_input_context (IBusBus *bus,
+ const gchar *client_name)
+{
+ g_assert (IBUS_IS_BUS (bus));
+ g_assert (client_name != NULL);
+ g_assert (ibus_bus_is_connected (bus));
+
+ gchar *path;
+ DBusMessage *call = NULL;
+ DBusMessage *reply = NULL;
+ IBusError *error;
+ IBusInputContext *context = NULL;
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ call = ibus_message_new_method_call (IBUS_SERVICE_IBUS,
+ IBUS_PATH_IBUS,
+ IBUS_INTERFACE_IBUS,
+ "CreateInputContext");
+ ibus_message_append_args (call,
+ G_TYPE_STRING, &client_name,
+ G_TYPE_INVALID);
+
+ reply = ibus_connection_send_with_reply_and_block (priv->connection,
+ call,
+ -1,
+ &error);
+ ibus_message_unref (call);
+
+ if (reply == NULL) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ return NULL;
+ }
+
+ if ((error = ibus_error_new_from_message (reply)) != NULL) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_message_unref (reply);
+ ibus_error_free (error);
+ return NULL;
+ }
+
+ if (!ibus_message_get_args (reply,
+ &error,
+ IBUS_TYPE_OBJECT_PATH, &path,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_message_unref (reply);
+ ibus_error_free (error);
+
+ return NULL;
+ }
+
+ context = ibus_input_context_new (path, priv->connection);
+ ibus_message_unref (reply);
+
+ return context;
+}
+
+static void
+ibus_bus_watch_dbus_signal (IBusBus *bus)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ const gchar *rule;
+
+ rule = "type='signal'," \
+ "path='" DBUS_PATH_DBUS "'," \
+ "interface='" DBUS_INTERFACE_DBUS "'";
+
+ ibus_bus_add_match (bus, rule);
+
+}
+
+static void
+ibus_bus_unwatch_dbus_signal (IBusBus *bus)
+{
+ g_assert (IBUS_IS_BUS (bus));
+ g_assert (ibus_bus_is_connected (bus));
+
+ const gchar *rule;
+
+ rule = "type='signal'," \
+ "path='" DBUS_PATH_DBUS "'," \
+ "interface='" DBUS_INTERFACE_DBUS "'";
+
+ ibus_bus_remove_match (bus, rule);
+}
+
+void
+ibus_bus_set_watch_dbus_signal (IBusBus *bus,
+ gboolean watch)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ if (priv->watch_dbus_signal == watch)
+ return;
+
+ priv->watch_dbus_signal = watch;
+
+ if (ibus_bus_is_connected (bus)) {
+ if (watch) {
+ ibus_bus_watch_dbus_signal (bus);
+ }
+ else {
+ ibus_bus_unwatch_dbus_signal (bus);
+ }
+ }
+}
+
+
+static gboolean
+ibus_bus_call (IBusBus *bus,
+ const gchar *name,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *member,
+ GType first_arg_type,
+ ...)
+{
+ g_assert (IBUS_IS_BUS (bus));
+ g_assert (ibus_bus_is_connected (bus));
+ g_assert (name != NULL);
+ g_assert (path != NULL);
+ g_assert (interface != NULL);
+ g_assert (member);
+
+ IBusMessage *message, *reply;
+ IBusError *error;
+ va_list args;
+ GType type;
+ gboolean retval;
+ IBusBusPrivate *priv;
+
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ message = ibus_message_new_method_call (name, path, interface, member);
+
+ va_start (args, first_arg_type);
+ ibus_message_append_args_valist (message, first_arg_type, args);
+ va_end (args);
+
+ reply = ibus_connection_send_with_reply_and_block (
+ priv->connection,
+ message,
+ -1,
+ &error);
+ ibus_message_unref (message);
+
+ if (reply == NULL) {
+ g_warning ("%s : %s", error->name, error->message);
+ ibus_error_free (error);
+ return FALSE;
+ }
+
+ if ((error = ibus_error_new_from_message (reply)) != NULL) {
+ g_warning ("%s : %s", error->name, error->message);
+ ibus_error_free (error);
+ ibus_message_unref (reply);
+ return FALSE;
+ }
+
+ va_start (args, first_arg_type);
+
+ type = first_arg_type;
+
+ while (type != G_TYPE_INVALID) {
+ va_arg (args, gpointer);
+ type = va_arg (args, GType);
+ }
+
+ type = va_arg (args, GType);
+ if (type != G_TYPE_INVALID) {
+ retval = ibus_message_get_args_valist (reply, &error, type, args);
+ }
+ else {
+ retval = TRUE;
+ }
+ va_end (args);
+
+ ibus_message_unref (reply);
+
+ if (!retval) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+const gchar *
+ibus_bus_hello (IBusBus *bus)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ gchar *unique_name = NULL;
+ gboolean result;
+
+ result = ibus_bus_call (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "Hello",
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &unique_name,
+ G_TYPE_INVALID);
+
+ if (result)
+ return unique_name;
+
+ return NULL;
+}
+
+guint
+ibus_bus_request_name (IBusBus *bus,
+ const gchar *name,
+ guint flags)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ guint retval;
+ gboolean result;
+
+ result = ibus_bus_call (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "RequestName",
+ G_TYPE_STRING, &name,
+ G_TYPE_UINT, &flags,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &retval,
+ G_TYPE_INVALID);
+
+ if (result)
+ return retval;
+
+ return 0;
+}
+
+guint
+ibus_bus_release_name (IBusBus *bus,
+ const gchar *name)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ guint retval;
+ gboolean result;
+
+ result = ibus_bus_call (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "ReleaseName",
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &retval,
+ G_TYPE_INVALID);
+
+ if (result)
+ return retval;
+
+ return 0;
+}
+
+gboolean
+ibus_bus_name_has_owner (IBusBus *bus,
+ const gchar *name)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ gboolean retval;
+ gboolean result;
+
+ result = ibus_bus_call (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "NameHasOwner",
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &retval,
+ G_TYPE_INVALID);
+
+ if (result)
+ return retval;
+
+ return FALSE;
+}
+
+GList *
+ibus_bus_list_names (IBusBus *bus)
+{
+ return NULL;
+}
+
+void
+ibus_bus_add_match (IBusBus *bus,
+ const gchar *rule)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ gboolean result;
+
+ result = ibus_bus_call (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "AddMatch",
+ G_TYPE_STRING, &rule,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_bus_remove_match (IBusBus *bus,
+ const gchar *rule)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ gboolean result;
+
+ result = ibus_bus_call (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "RemoveMatch",
+ G_TYPE_STRING, &rule,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+}
+
+const gchar *
+ibus_bus_get_name_owner (IBusBus *bus,
+ const gchar *name)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ gchar *owner = NULL;
+ gboolean result;
+
+ result = ibus_bus_call (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "RemoveMatch",
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &owner,
+ G_TYPE_INVALID);
+
+ if (result)
+ return owner;
+
+ return NULL;
+}
+
+IBusConnection *
+ibus_bus_get_connection (IBusBus *bus)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ return priv->connection;
+}
+
+gboolean
+ibus_bus_kill (IBusBus *bus)
+{
+ g_assert (IBUS_IS_BUS (bus));
+
+ gboolean result;
+ result = ibus_bus_call (bus,
+ IBUS_SERVICE_IBUS,
+ IBUS_PATH_IBUS,
+ IBUS_INTERFACE_IBUS,
+ "Kill",
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ return result;
+}
+
+gboolean
+ibus_bus_register_component (IBusBus *bus,
+ IBusComponent *component)
+{
+ g_assert (IBUS_IS_BUS (bus));
+ g_assert (IBUS_IS_COMPONENT (component));
+
+ gboolean result;
+
+ result = ibus_bus_call (bus,
+ IBUS_SERVICE_IBUS,
+ IBUS_PATH_IBUS,
+ IBUS_INTERFACE_IBUS,
+ "RegisterComponent",
+ IBUS_TYPE_COMPONENT, &component,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ return result;
+
+
+#if 0
+ IBusMessage *message, *reply;
+ IBusError *error;
+
+ IBusBusPrivate *priv;
+ priv = IBUS_BUS_GET_PRIVATE (bus);
+
+ message = ibus_message_new_method_call (IBUS_SERVICE_IBUS,
+ IBUS_PATH_IBUS,
+ IBUS_INTERFACE_IBUS,
+ "RegisterComponent");
+
+ ibus_message_append_args (message,
+ IBUS_TYPE_COMPONENT, &component,
+ G_TYPE_INVALID);
+
+ reply = ibus_connection_send_with_reply_and_block (
+ priv->connection,
+ message,
+ -1,
+ &error);
+ ibus_message_unref (message);
+
+ if (reply == NULL) {
+ g_warning ("%s : %s", error->name, error->message);
+ ibus_error_free (error);
+ return FALSE;
+ }
+
+ if ((error = ibus_error_from_message (reply)) != NULL) {
+ g_warning ("%s : %s", error->name, error->message);
+ ibus_error_free (error);
+ ibus_message_unref (reply);
+ return FALSE;
+ }
+
+ return TRUE;
+#endif
+}
+
+GList *
+ibus_bus_list_engines (IBusBus *bus)
+{
+ return NULL;
+}
+
+GList *
+ibus_bus_list_active_engines (IBusBus *bus)
+{
+ return NULL;
+}
diff --git a/src/ibusbus.h b/src/ibusbus.h
new file mode 100644
index 0000000..e548c82
--- /dev/null
+++ b/src/ibusbus.h
@@ -0,0 +1,97 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_BUS_H_
+#define __IBUS_BUS_H_
+
+#include <dbus/dbus.h>
+#include "ibusinputcontext.h"
+#include "ibusconfig.h"
+#include "ibuscomponent.h"
+
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_BUS \
+ (ibus_bus_get_type ())
+#define IBUS_BUS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_BUS, IBusBus))
+#define IBUS_BUS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_BUS, IBusBusClass))
+#define IBUS_IS_BUS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_BUS))
+#define IBUS_IS_BUS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_BUS))
+#define IBUS_BUS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_BUS, IBusBusClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusBus IBusBus;
+typedef struct _IBusBusClass IBusBusClass;
+
+struct _IBusBus {
+ IBusObject parent;
+ /* instance members */
+};
+
+struct _IBusBusClass {
+ IBusObjectClass parent;
+ /* class members */
+};
+
+GType ibus_bus_get_type (void);
+IBusBus *ibus_bus_new (void);
+gboolean ibus_bus_is_connected (IBusBus *bus);
+IBusConnection
+ *ibus_bus_get_connection (IBusBus *bus);
+/* declare dbus methods */
+const gchar *ibus_bus_hello (IBusBus *bus);
+guint ibus_bus_request_name (IBusBus *bus,
+ const gchar *name,
+ guint flags);
+guint ibus_bus_release_name (IBusBus *bus,
+ const gchar *name);
+gboolean ibus_bus_name_has_owner (IBusBus *bus,
+ const gchar *name);
+GList *ibus_bus_list_names (IBusBus *bus);
+void ibus_bus_add_match (IBusBus *bus,
+ const gchar *rule);
+void ibus_bus_remove_match (IBusBus *bus,
+ const gchar *rule);
+const gchar *ibus_bus_get_name_owner (IBusBus *bus,
+ const gchar *name);
+/* declare ibus methods */
+gboolean ibus_bus_kill (IBusBus *bus);
+IBusInputContext
+ *ibus_bus_create_input_context
+ (IBusBus *bus,
+ const gchar *client_name);
+gboolean ibus_bus_register_component(IBusBus *bus,
+ IBusComponent *component);
+GList *ibus_bus_list_engines (IBusBus *bus);
+GList *ibus_bus_list_active_engines
+ (IBusBus *bus);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibuscomponent.c b/src/ibuscomponent.c
new file mode 100644
index 0000000..9ca487d
--- /dev/null
+++ b/src/ibuscomponent.c
@@ -0,0 +1,743 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib/gstdio.h>
+#include "ibuscomponent.h"
+
+enum {
+ LAST_SIGNAL,
+};
+
+
+/* IBusComponentPriv */
+struct _IBusComponentPrivate {
+ gpointer pad;
+};
+typedef struct _IBusComponentPrivate IBusComponentPrivate;
+
+#define IBUS_COMPONENT_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_COMPONENT, IBusComponentPrivate))
+
+// static guint _signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_component_class_init (IBusComponentClass *klass);
+static void ibus_component_init (IBusComponent *component);
+static void ibus_component_destroy (IBusComponent *component);
+static gboolean ibus_component_serialize (IBusComponent *component,
+ IBusMessageIter *iter);
+static gboolean ibus_component_deserialize (IBusComponent *component,
+ IBusMessageIter *iter);
+static gboolean ibus_component_copy (IBusComponent *dest,
+ const IBusComponent *src);
+static gboolean ibus_component_parse_xml_node
+ (IBusComponent *component,
+ XMLNode *node,
+ gboolean access_fs);
+
+static void ibus_component_parse_engines(IBusComponent *component,
+ XMLNode *node);
+static void ibus_component_parse_observed_paths
+ (IBusComponent *component,
+ XMLNode *node,
+ gboolean access_fs);
+
+static IBusSerializableClass *parent_class = NULL;
+
+GType
+ibus_component_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusComponentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_component_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusComponent),
+ 0,
+ (GInstanceInitFunc) ibus_component_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusComponent",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+
+static void
+ibus_component_class_init (IBusComponentClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_component_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_component_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_component_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_component_copy;
+
+ g_string_append (serializable_class->signature, "ssssssssavav");
+}
+
+
+
+static void
+ibus_component_init (IBusComponent *component)
+{
+ component->name = NULL;
+ component->description = NULL;
+ component->version = NULL;
+ component->license = NULL;
+ component->author = NULL;
+ component->homepage = NULL;
+ component->exec = NULL;
+ component->textdomain = NULL;
+ component->engines = NULL;
+ component->observed_paths = NULL;
+}
+
+static void
+ibus_component_destroy (IBusComponent *component)
+{
+ GList *p;
+
+ g_free (component->name);
+ g_free (component->description);
+ g_free (component->version);
+ g_free (component->license);
+ g_free (component->author);
+ g_free (component->homepage);
+ g_free (component->exec);
+ g_free (component->textdomain);
+
+ component->name = NULL;
+ component->description = NULL;
+ component->version = NULL;
+ component->license = NULL;
+ component->author = NULL;
+ component->homepage = NULL;
+ component->exec = NULL;
+ component->textdomain = NULL;
+
+ g_list_foreach (component->observed_paths, (GFunc)g_object_unref, NULL);
+ g_list_free (component->observed_paths);
+ component->observed_paths = NULL;
+
+ for (p = component->engines; p != NULL; p = p->next) {
+ g_object_steal_data ((GObject *)p->data, "component");
+ ibus_object_destroy ((IBusObject *)p->data);
+ g_object_unref (p->data);
+ }
+ g_list_free (component->engines);
+ component->engines = NULL;
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy (IBUS_OBJECT (component));
+}
+
+static gboolean
+ibus_component_serialize (IBusComponent *component,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ IBusMessageIter array_iter;
+ GList *p;
+
+ retval = parent_class->serialize ((IBusSerializable *)component, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &component->name);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &component->description);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &component->version);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &component->license);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &component->author);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &component->homepage);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &component->exec);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &component->textdomain);
+ g_return_val_if_fail (retval, FALSE);
+
+ /* serialize observed paths */
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_ARRAY, "v", &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ for (p = component->observed_paths; p != NULL; p = p->next) {
+ retval = ibus_message_iter_append (&array_iter, IBUS_TYPE_OBSERVED_PATH, &(p->data));
+ g_return_val_if_fail (retval, FALSE);
+ }
+ retval = ibus_message_iter_close_container (iter, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ /* serialize engine desc */
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_ARRAY, "v", &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ for (p = component->engines; p != NULL; p = p->next) {
+ retval = ibus_message_iter_append (&array_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
+ g_return_val_if_fail (retval, FALSE);
+ }
+ retval = ibus_message_iter_close_container (iter, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_component_deserialize (IBusComponent *component,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ gchar *str;
+ IBusMessageIter array_iter;
+
+ retval = parent_class->deserialize ((IBusSerializable *)component, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ component->name = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ component->description = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ component->version = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ component->license = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ component->author = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ component->homepage = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ component->exec = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ component->textdomain = g_strdup (str);
+
+ retval = ibus_message_iter_recurse (iter, IBUS_TYPE_ARRAY, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+ while (ibus_message_iter_get_arg_type (&array_iter) != G_TYPE_INVALID) {
+ IBusObservedPath *path;
+ retval = ibus_message_iter_get (&array_iter, IBUS_TYPE_OBSERVED_PATH, &path);
+ component->observed_paths = g_list_append (component->observed_paths, path);
+ }
+ ibus_message_iter_next (iter);
+
+ retval = ibus_message_iter_recurse (iter, IBUS_TYPE_ARRAY, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ while (ibus_message_iter_get_arg_type (&array_iter) != G_TYPE_INVALID) {
+ IBusEngineDesc *engine;
+ retval = ibus_message_iter_get (&array_iter, IBUS_TYPE_ENGINE_DESC, &engine);
+ ibus_component_add_engine (component, engine);
+ }
+ ibus_message_iter_next (iter);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_component_copy (IBusComponent *dest,
+ const IBusComponent *src)
+{
+ gboolean retval;
+
+ retval = parent_class->copy ((IBusSerializable *)dest,
+ (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+
+ dest->name = g_strdup (src->name);
+ dest->description = g_strdup (src->description);
+ dest->version = g_strdup (src->version);
+ dest->license = g_strdup (src->license);
+ dest->author = g_strdup (src->author);
+ dest->homepage = g_strdup (src->homepage);
+ dest->exec = g_strdup (src->exec);
+ dest->textdomain = g_strdup (src->textdomain);
+
+ dest->observed_paths = g_list_copy (src->observed_paths);
+ g_list_foreach (dest->observed_paths, (GFunc) g_object_ref, NULL);
+
+ dest->engines = g_list_copy (src->engines);
+ g_list_foreach (dest->engines, (GFunc) g_object_ref, NULL);
+
+ return TRUE;
+}
+
+
+#define g_string_append_indent(string, indent) \
+ { \
+ gint i; \
+ for (i = 0; i < (indent); i++) { \
+ g_string_append (string, " "); \
+ } \
+ }
+
+void
+ibus_component_output (IBusComponent *component,
+ GString *output,
+ gint indent)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+ GList *p;
+
+ g_string_append_indent (output, indent);
+ g_string_append (output, "<component>\n");
+
+#define OUTPUT_ENTRY(field, element) \
+ { \
+ gchar *escape_text = g_markup_escape_text (component->field, -1); \
+ g_string_append_indent (output, indent + 1); \
+ g_string_append_printf (output, "<"element">%s</"element">\n", \
+ escape_text); \
+ g_free (escape_text); \
+ }
+#define OUTPUT_ENTRY_1(name) OUTPUT_ENTRY(name, #name)
+ OUTPUT_ENTRY_1 (name);
+ OUTPUT_ENTRY_1 (description);
+ OUTPUT_ENTRY_1 (version);
+ OUTPUT_ENTRY_1 (license);
+ OUTPUT_ENTRY_1 (author);
+ OUTPUT_ENTRY_1 (homepage);
+ OUTPUT_ENTRY_1 (exec);
+ OUTPUT_ENTRY_1 (textdomain);
+#undef OUTPUT_ENTRY
+#undef OUTPUT_ENTRY_1
+
+ if (component->observed_paths) {
+ g_string_append_indent (output, indent + 1);
+ g_string_append (output, "<observed-paths>\n");
+
+ for (p = component->observed_paths; p != NULL; p = p->next ) {
+ IBusObservedPath *path = (IBusObservedPath *) p->data;
+
+ g_string_append_indent (output, indent + 2);
+ g_string_append_printf (output, "<path mtime=\"%ld\" >%s</path>\n",
+ path->mtime,
+ path->path);
+ }
+
+ g_string_append_indent (output, indent + 1);
+ g_string_append (output, "</observed-paths>\n");
+ }
+
+ ibus_component_output_engines (component, output, indent + 1);
+
+ g_string_append_indent (output, indent);
+ g_string_append (output, "</component>\n");
+}
+
+void
+ibus_component_output_engines (IBusComponent *component,
+ GString *output,
+ gint indent)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+ g_assert (output);
+
+ GList *p;
+
+ g_string_append_indent (output, indent);
+ g_string_append (output, "<engines>\n");
+
+ for (p = component->engines; p != NULL; p = p->next) {
+ ibus_engine_desc_output ((IBusEngineDesc *)p->data, output, indent + 2);
+ }
+
+ g_string_append_indent (output, indent);
+ g_string_append (output, "</engines>\n");
+}
+
+static gboolean
+ibus_component_parse_xml_node (IBusComponent *component,
+ XMLNode *node,
+ gboolean access_fs)
+{
+ g_assert (component);
+ g_assert (node);
+
+ if (G_UNLIKELY (g_strcmp0 (node->name, "component") != 0)) {
+ return FALSE;
+ }
+
+ GList *p;
+ for (p = node->sub_nodes; p != NULL; p = p->next) {
+ XMLNode *sub_node = (XMLNode *)p->data;
+
+#define PARSE_ENTRY(field_name, element_name) \
+ if (g_strcmp0 (sub_node->name, element_name) == 0) { \
+ if (component->field_name != NULL) { \
+ g_free (component->field_name); \
+ } \
+ component->field_name = g_strdup (sub_node->text); \
+ continue; \
+ }
+#define PARSE_ENTRY_1(name) PARSE_ENTRY (name, #name)
+ PARSE_ENTRY_1 (name);
+ PARSE_ENTRY_1 (description);
+ PARSE_ENTRY_1 (version);
+ PARSE_ENTRY_1 (license);
+ PARSE_ENTRY_1 (author);
+ PARSE_ENTRY_1 (homepage);
+ PARSE_ENTRY_1 (exec);
+ PARSE_ENTRY_1 (textdomain);
+#undef PARSE_ENTRY
+#undef PARSE_ENTRY_1
+
+ if (g_strcmp0 (sub_node->name, "engines") == 0) {
+ ibus_component_parse_engines (component, sub_node);
+ continue;
+ }
+
+ if (g_strcmp0 (sub_node->name, "observed-paths") == 0) {
+ ibus_component_parse_observed_paths (component, sub_node, access_fs);
+ continue;
+ }
+
+ g_warning ("<component> element contains invalidate element <%s>", sub_node->name);
+ }
+
+ return TRUE;
+}
+
+
+static void
+ibus_component_parse_engines (IBusComponent *component,
+ XMLNode *node)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+ g_assert (node);
+
+ gchar *exec = NULL;
+ gchar **p;
+ XMLNode *engines_node = NULL;
+
+ if (g_strcmp0 (node->name, "engines") != 0) {
+ return;
+ }
+
+ for (p = node->attributes; *p != NULL; p += 2) {
+ if (g_strcmp0 (*p, "exec") == 0) {
+ exec = *(p + 1);
+ break;
+ }
+ }
+
+ if (exec != NULL) {
+ gchar *output = NULL;
+ if (g_spawn_command_line_sync (exec, &output, NULL, NULL, NULL)) {
+ engines_node = ibus_xml_parse_buffer (output);
+ g_free (output);
+
+ if (engines_node) {
+ if (g_strcmp0 (engines_node->name, "engines") != 0) {
+ ibus_xml_free (engines_node);
+ engines_node = NULL;
+ }
+ }
+ node = engines_node;
+ }
+ }
+
+ GList *pl;
+ for (pl = node->sub_nodes; pl != NULL; pl = pl->next) {
+ IBusEngineDesc *engine;
+ engine = ibus_engine_desc_new_from_xml_node ((XMLNode *)pl->data);
+
+ if (G_UNLIKELY (engine == NULL))
+ continue;
+ ibus_component_add_engine (component, engine);
+ }
+
+ if (engines_node) {
+ ibus_xml_free (engines_node);
+ }
+}
+
+static void
+ibus_component_parse_observed_paths (IBusComponent *component,
+ XMLNode *node,
+ gboolean access_fs)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+ g_assert (node);
+
+ if (g_strcmp0 (node->name, "observed-paths") != 0) {
+ return;
+ }
+
+ GList *p;
+ for (p = node->sub_nodes; p != NULL; p = p->next) {
+ IBusObservedPath *path;
+
+ path = ibus_observed_path_new_from_xml_node ((XMLNode *)p->data, access_fs);
+ component->observed_paths = g_list_append (component->observed_paths, path);
+
+ if (access_fs && path->is_dir && path->is_exist) {
+ component->observed_paths = g_list_concat (component->observed_paths,
+ ibus_observed_path_traverse (path));
+ }
+ }
+}
+
+IBusComponent *
+ibus_component_new (const gchar *name,
+ const gchar *descritpion,
+ const gchar *version,
+ const gchar *license,
+ const gchar *author,
+ const gchar *homepage,
+ const gchar *exec,
+ const gchar *textdomain)
+{
+
+ IBusComponent *component;
+ component = (IBusComponent *)g_object_new (IBUS_TYPE_COMPONENT, NULL);
+
+ component->name = g_strdup (name);
+ component->description = g_strdup (descritpion);
+ component->version = g_strdup (version);
+ component->license = g_strdup (license);
+ component->author = g_strdup (author);
+ component->homepage = g_strdup (homepage);
+ component->exec = g_strdup (exec);
+ component->textdomain = g_strdup (textdomain);
+
+ return component;
+}
+
+
+IBusComponent *
+ibus_component_new_from_xml_node (XMLNode *node)
+{
+ g_assert (node);
+
+ IBusComponent *component;
+
+ component = (IBusComponent *)g_object_new (IBUS_TYPE_COMPONENT, NULL);
+ if (!ibus_component_parse_xml_node (component, node, FALSE)) {
+ g_object_unref (component);
+ component = NULL;
+ }
+
+ return component;
+}
+
+IBusComponent *
+ibus_component_new_from_file (const gchar *filename)
+{
+ g_assert (filename);
+
+ XMLNode *node;
+ struct stat buf;
+ IBusComponent *component;
+ gboolean retval;
+
+ if (g_stat (filename, &buf) != 0) {
+ g_warning ("Can not get stat of file %s", filename);
+ return NULL;
+ }
+
+ node = ibus_xml_parse_file (filename);
+
+ if (!node) {
+ return NULL;
+ }
+
+ component = (IBusComponent *)g_object_new (IBUS_TYPE_COMPONENT, NULL);
+ retval = ibus_component_parse_xml_node (component, node, TRUE);
+ ibus_xml_free (node);
+
+ if (!retval) {
+ g_object_unref (component);
+ component = NULL;
+ }
+ else {
+ IBusObservedPath *path;
+ path = ibus_observed_path_new (filename, TRUE);
+ component->observed_paths = g_list_prepend (component->observed_paths, path);
+ }
+
+ return component;
+}
+
+void
+ibus_component_add_observed_path (IBusComponent *component,
+ const gchar *path,
+ gboolean access_fs)
+{
+ IBusObservedPath *p;
+
+ p = ibus_observed_path_new (path, access_fs);
+ component->observed_paths = g_list_append (component->observed_paths, p);
+
+ if (access_fs && p->is_dir && p->is_exist) {
+ component->observed_paths = g_list_concat (component->observed_paths,
+ ibus_observed_path_traverse (p));
+ }
+}
+
+void
+ibus_component_add_engine (IBusComponent *component,
+ IBusEngineDesc *engine)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+ g_assert (IBUS_IS_ENGINE_DESC (engine));
+
+ component->engines = g_list_append (component->engines, engine);
+ g_object_set_data ((GObject *)engine, "component", component);
+}
+
+GList *
+ibus_component_get_engines (IBusComponent *component)
+{
+ return g_list_copy (component->engines);
+}
+
+static void
+ibus_component_child_cb (GPid pid,
+ gint status,
+ IBusComponent *component)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+ g_assert (component->pid == pid);
+
+ g_spawn_close_pid (pid);
+ component->pid = 0;
+}
+
+gboolean
+ibus_component_start (IBusComponent *component)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+
+ if (component->pid != 0)
+ return TRUE;
+
+ gint argc;
+ gchar **argv;
+ gboolean retval;
+ GError *error;
+
+ error = NULL;
+ if (!g_shell_parse_argv (component->exec, &argc, &argv, &error)) {
+ g_warning ("Can not parse component %s exec: %s", component->name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ error = NULL;
+ retval = g_spawn_async (NULL, argv, NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL,
+ &(component->pid), &error);
+ g_strfreev (argv)
+ ;
+ if (!retval) {
+ g_warning ("Can not execute component %s: %s", component->name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ g_child_watch_add (component->pid, (GChildWatchFunc) ibus_component_child_cb, component);
+
+ return TRUE;
+}
+
+gboolean
+ibus_component_stop (IBusComponent *component)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+
+ if (component->pid == 0)
+ return TRUE;
+
+ kill (component->pid, SIGTERM);
+ return TRUE;
+}
+
+gboolean
+ibus_component_is_running (IBusComponent *component)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+
+ return (component->pid != 0);
+}
+
+
+gboolean
+ibus_component_check_modification (IBusComponent *component)
+{
+ g_assert (IBUS_IS_COMPONENT (component));
+
+ GList *p;
+
+ for (p = component->observed_paths; p != NULL; p = p->next) {
+ if (ibus_observed_path_check_modification ((IBusObservedPath *)p->data))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+IBusComponent *
+ibus_component_get_from_engine (IBusEngineDesc *engine)
+{
+ g_assert (IBUS_IS_ENGINE_DESC (engine));
+
+ IBusComponent *component;
+
+ component = (IBusComponent *)g_object_get_data ((GObject *)engine, "component");
+ return component;
+}
diff --git a/src/ibuscomponent.h b/src/ibuscomponent.h
new file mode 100644
index 0000000..1d5d25a
--- /dev/null
+++ b/src/ibuscomponent.h
@@ -0,0 +1,115 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_COMPONENT_H_
+#define __IBUS_COMPONENT_H_
+
+#include "ibusserializable.h"
+#include "ibusobservedpath.h"
+#include "ibusenginedesc.h"
+#include "ibusxml.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_COMPONENT \
+ (ibus_component_get_type ())
+#define IBUS_COMPONENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_COMPONENT, IBusComponent))
+#define IBUS_COMPONENT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_COMPONENT, IBusComponentClass))
+#define IBUS_IS_COMPONENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_COMPONENT))
+#define IBUS_IS_COMPONENT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_COMPONENT))
+#define IBUS_COMPONENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_COMPONENT, IBusComponentClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusComponent IBusComponent;
+typedef struct _IBusComponentClass IBusComponentClass;
+
+struct _IBusComponent {
+ IBusSerializable parent;
+ /* instance members */
+
+ gchar *name;
+ gchar *description;
+ gchar *version;
+ gchar *license;
+ gchar *author;
+ gchar *homepage;
+ gchar *exec;
+
+ /* text domain for dgettext */
+ gchar *textdomain;
+
+ /* engines */
+ GList *engines;
+
+ /* observed paths */
+ GList *observed_paths;
+
+ GPid pid;
+};
+
+struct _IBusComponentClass {
+ IBusSerializableClass parent;
+
+ /* class members */
+};
+
+GType ibus_component_get_type (void);
+IBusComponent *ibus_component_new (const gchar *name,
+ const gchar *descritpion,
+ const gchar *version,
+ const gchar *license,
+ const gchar *author,
+ const gchar *homepage,
+ const gchar *exec,
+ const gchar *textdomain);
+IBusComponent *ibus_component_new_from_xml_node
+ (XMLNode *node);
+IBusComponent *ibus_component_new_from_file (const gchar *filename);
+void ibus_component_add_observed_path
+ (IBusComponent *component,
+ const gchar *path,
+ gboolean access_fs);
+void ibus_component_add_engine (IBusComponent *component,
+ IBusEngineDesc *engine);
+GList *ibus_component_get_engines (IBusComponent *component);
+void ibus_component_output (IBusComponent *component,
+ GString *output,
+ gint indent);
+void ibus_component_output_engines (IBusComponent *component,
+ GString *output,
+ gint indent);
+gboolean ibus_component_check_modification
+ (IBusComponent *component);
+gboolean ibus_component_start (IBusComponent *component);
+gboolean ibus_component_stop (IBusComponent *component);
+gboolean ibus_component_is_running (IBusComponent *component);
+IBusComponent *ibus_component_get_from_engine (IBusEngineDesc *engine);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusconfig.c b/src/ibusconfig.c
new file mode 100644
index 0000000..9ebc799
--- /dev/null
+++ b/src/ibusconfig.c
@@ -0,0 +1,357 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusinternal.h"
+#include "ibusmarshalers.h"
+#include "ibusshare.h"
+#include "ibusconfig.h"
+
+#define IBUS_CONFIG_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_CONFIG, IBusConfigPrivate))
+
+enum {
+ VALUE_CHANGED,
+ LAST_SIGNAL,
+};
+
+
+/* IBusConfigPriv */
+struct _IBusConfigPrivate {
+ gpointer pad;
+};
+typedef struct _IBusConfigPrivate IBusConfigPrivate;
+
+#if 0
+struct _BusPair {
+ GValue car;
+ GValue cdr;
+};
+typedef struct _BusPair BusPair;
+#endif
+
+static guint config_signals[LAST_SIGNAL] = { 0 };
+
+#if 0
+/* functions prototype */
+static BusPair *bus_pair_new (GType car_type,
+ GType cdr_type,
+ gpointer car,
+ gpointer cdr);
+static BusPair *bus_pair_copy (BusPair *pair);
+static void bus_pair_free (BusPair *pair);
+#endif
+static void ibus_config_class_init (IBusConfigClass *klass);
+static void ibus_config_init (IBusConfig *config);
+static void ibus_config_real_destroy (IBusConfig *config);
+
+static gboolean ibus_config_ibus_signal (IBusProxy *proxy,
+ IBusMessage *message);
+
+static IBusProxyClass *parent_class = NULL;
+
+#if 0
+static BusPair *
+bus_pair_new (GType car_type,
+ GType cdr_type,
+ gpointer car,
+ gpointer cdr)
+{
+
+ g_assert (car_type == G_TYPE_STRING ||
+ car_type == G_TYPE_INT ||
+ car_type == G_TYPE_BOOLEAN ||
+ car_type == G_TYPE_DOUBLE);
+ g_assert (cdr_type == G_TYPE_STRING ||
+ cdr_type == G_TYPE_INT ||
+ cdr_type == G_TYPE_BOOLEAN ||
+ cdr_type == G_TYPE_DOUBLE);
+ g_assert (car != NULL);
+ g_assert (cdr != NULL);
+
+ BusPair *pair;
+
+ pair = g_slice_new0 (BusPair);
+
+ g_value_init (&(pair->car), car_type);
+ g_value_init (&(pair->cdr), cdr_type);
+
+ switch (car_type) {
+ case G_TYPE_STRING:
+ g_value_set_string (&(pair->car), *(gchar **)car);
+ break;
+ case G_TYPE_INT:
+ g_value_set_int (&(pair->car), *(gint32 *)car);
+ break;
+ case G_TYPE_BOOLEAN:
+ g_value_set_boolean (&(pair->car), *(gboolean *)car);
+ break;
+ case G_TYPE_DOUBLE:
+ g_value_set_double (&(pair->car), *(gdouble *)car);
+ break;
+ }
+
+ switch (cdr_type) {
+ case G_TYPE_STRING:
+ g_value_set_string (&(pair->cdr), *(gchar **)cdr);
+ break;
+ case G_TYPE_INT:
+ g_value_set_int (&(pair->cdr), *(gint32 *)car);
+ break;
+ case G_TYPE_BOOLEAN:
+ g_value_set_boolean (&(pair->cdr), *(gboolean *)cdr);
+ break;
+ case G_TYPE_DOUBLE:
+ g_value_set_double (&(pair->cdr), *(gdouble *)cdr);
+ break;
+ }
+ return pair;
+}
+
+static BusPair *
+bus_pair_copy (BusPair *pair)
+{
+ g_assert (pair != NULL);
+
+ BusPair *new_pair;
+
+ new_pair = g_slice_new0 (BusPair);
+ g_value_copy (&(pair->car), &(new_pair->car));
+ g_value_copy (&(pair->cdr), &(new_pair->cdr));
+ return new_pair;
+}
+
+static void
+bus_pair_free (BusPair *pair)
+{
+ g_assert (pair == NULL);
+
+ g_value_unset (&(pair->car));
+ g_value_unset (&(pair->cdr));
+
+ g_slice_free (BusPair, pair);
+}
+
+#endif
+
+GType
+ibus_config_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusConfigClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_config_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusConfig),
+ 0,
+ (GInstanceInitFunc) ibus_config_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_PROXY,
+ "IBusConfig",
+ &type_info,
+ (GTypeFlags)0);
+ }
+ return type;
+}
+
+IBusConfig *
+ibus_config_new (IBusConnection *connection)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ GObject *obj;
+ obj = g_object_new (IBUS_TYPE_CONFIG,
+ "name", IBUS_SERVICE_CONFIG,
+ "path", IBUS_PATH_CONFIG,
+ "connection", connection,
+ NULL);
+
+ return IBUS_CONFIG (obj);
+}
+
+static void
+ibus_config_class_init (IBusConfigClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+ IBusProxyClass *proxy_class = IBUS_PROXY_CLASS (klass);
+
+
+ parent_class = (IBusProxyClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusConfigPrivate));
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_config_real_destroy;
+
+ proxy_class->ibus_signal = ibus_config_ibus_signal;
+
+ /* install signals */
+ config_signals[VALUE_CHANGED] =
+ g_signal_new (I_("value-changed"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__STRING_STRING_BOXED,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_VALUE | G_SIGNAL_TYPE_STATIC_SCOPE);
+}
+
+static void
+ibus_config_init (IBusConfig *config)
+{
+ IBusConfigPrivate *priv;
+ priv = IBUS_CONFIG_GET_PRIVATE (config);
+}
+
+static void
+ibus_config_real_destroy (IBusConfig *config)
+{
+ if (ibus_proxy_get_connection ((IBusProxy *) config) != NULL) {
+ ibus_proxy_call ((IBusProxy *) config,
+ "Destroy",
+ G_TYPE_INVALID);
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (config));
+}
+
+
+static gboolean
+ibus_config_ibus_signal (IBusProxy *proxy,
+ IBusMessage *message)
+{
+ g_assert (IBUS_IS_CONFIG (proxy));
+ g_assert (message != NULL);
+
+ IBusConfig *config;
+ config = IBUS_CONFIG (proxy);
+
+ if (ibus_message_is_signal (message, IBUS_INTERFACE_CONFIG, "ValueChanged")) {
+ gchar *section;
+ gchar *name;
+ GValue value = { 0 };
+ IBusError *error = NULL;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &section,
+ G_TYPE_STRING, &name,
+ G_TYPE_VALUE, &value,
+ G_TYPE_INVALID);
+ if (!retval) {
+ g_warning ("%s: Can not parse arguments of ValueChanges.", DBUS_ERROR_INVALID_ARGS);
+ return FALSE;
+ }
+
+ g_signal_emit (config,
+ config_signals[VALUE_CHANGED],
+ 0,
+ section,
+ name,
+ &value);
+ g_value_unset (&value);
+
+ g_signal_stop_emission_by_name (config, "ibus-signal");
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+ibus_config_get_value (IBusConfig *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value)
+{
+ g_assert (IBUS_IS_CONFIG (config));
+ g_assert (section != NULL);
+ g_assert (name != NULL);
+ g_assert (value != NULL);
+
+ IBusMessage *reply;
+ IBusError *error;
+ gboolean retval;
+
+ reply = ibus_proxy_call_with_reply_and_block ((IBusProxy *) config,
+ "GetValue",
+ -1,
+ &error,
+ G_TYPE_STRING, &section,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID);
+ if (reply == NULL) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ return FALSE;
+ }
+
+ if ((error = ibus_error_new_from_message (reply)) != NULL) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ ibus_message_unref (reply);
+ return FALSE;
+ }
+
+ retval = ibus_message_get_args (reply,
+ &error,
+ G_TYPE_VALUE, value,
+ G_TYPE_INVALID);
+ ibus_message_unref (reply);
+ if (!retval) {
+ g_warning ("%s: %s", error->name, error->message);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+ibus_config_set_value (IBusConfig *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value)
+{
+ g_assert (IBUS_IS_CONFIG (config));
+ g_assert (section != NULL);
+ g_assert (name != NULL);
+ g_assert (value != NULL);
+
+ gboolean retval;
+
+ retval = ibus_proxy_call ((IBusProxy *) config,
+ "SetValue",
+ G_TYPE_STRING, &section,
+ G_TYPE_STRING, &name,
+ G_TYPE_VALUE, value,
+ G_TYPE_INVALID);
+ g_assert (retval);
+ return TRUE;
+}
diff --git a/src/ibusconfig.h b/src/ibusconfig.h
new file mode 100644
index 0000000..734218f
--- /dev/null
+++ b/src/ibusconfig.h
@@ -0,0 +1,70 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __CONFIG_H_
+#define __CONFIG_H_
+
+#include "ibusproxy.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_CONFIG \
+ (ibus_config_get_type ())
+#define IBUS_CONFIG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_CONFIG, IBusConfig))
+#define IBUS_CONFIG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_CONFIG, IBusConfigClass))
+#define IBUS_IS_CONFIG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_CONFIG))
+#define IBUS_IS_CONFIG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_CONFIG))
+#define IBUS_CONFIG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_CONFIG, IBusConfigClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusConfig IBusConfig;
+typedef struct _IBusConfigClass IBusConfigClass;
+
+struct _IBusConfig {
+ IBusProxy parent;
+ /* instance members */
+};
+
+struct _IBusConfigClass {
+ IBusProxyClass parent;
+ /* class members */
+};
+
+GType ibus_config_get_type (void);
+IBusConfig *ibus_config_new (IBusConnection *connection);
+gboolean ibus_config_get_value (IBusConfig *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value);
+gboolean ibus_config_set_value (IBusConfig *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value);
+G_END_DECLS
+#endif
+
diff --git a/src/ibusconfigprivate.h b/src/ibusconfigprivate.h
new file mode 100644
index 0000000..0bd3b8e
--- /dev/null
+++ b/src/ibusconfigprivate.h
@@ -0,0 +1,221 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_CONFIG_PRIVATE_H_
+#define __IBUS_CONFIG_PRIVATE_H_
+
+static void
+_from_dbus_value (IBusMessageIter *iter,
+ GValue *value)
+{
+ g_assert (iter != NULL);
+ g_assert (value != NULL);
+
+ gint type;
+ IBusMessageIter sub_iter;
+
+ type = ibus_message_iter_get_arg_type (iter);
+ if (type == IBUS_TYPE_VARIANT) {
+ ibus_message_iter_recurse (iter, IBUS_TYPE_VARIANT, &sub_iter);
+ ibus_message_iter_next (iter);
+ iter = &sub_iter;
+ type = ibus_message_iter_get_arg_type (iter);
+ }
+
+ switch (type) {
+ case G_TYPE_STRING:
+ {
+ gchar *v;
+ g_value_init (value, G_TYPE_STRING);
+ ibus_message_iter_get_basic (iter, &v);
+ g_value_set_string (value, v);
+ }
+ break;
+ case G_TYPE_INT:
+ {
+ gint v;
+ g_value_init (value, G_TYPE_INT);
+ ibus_message_iter_get_basic (iter, &v);
+ g_value_set_int (value, v);
+ }
+ break;
+ case G_TYPE_UINT:
+ {
+ guint v;
+ g_value_init (value, G_TYPE_UINT);
+ ibus_message_iter_get_basic (iter, &v);
+ g_value_set_uint (value, v);
+ }
+ break;
+ case G_TYPE_BOOLEAN:
+ {
+ gboolean v;
+ g_value_init (value, G_TYPE_BOOLEAN);
+ ibus_message_iter_get_basic (iter, &v);
+ g_value_set_boolean (value, v);
+ }
+ break;
+ case G_TYPE_DOUBLE:
+ {
+ gdouble v;
+ g_value_init (value, G_TYPE_DOUBLE);
+ ibus_message_iter_get_basic (iter, &v);
+ g_value_set_double (value, v);
+ }
+ break;
+ default:
+ if (type == IBUS_TYPE_ARRAY) {
+ GValue v = { 0 };
+ IBusMessageIter sub_iter;
+ gint sub_type;
+ GValueArray *array;
+
+
+ sub_type = ibus_message_iter_get_element_type (iter);
+ g_assert (sub_type == G_TYPE_STRING ||
+ sub_type == G_TYPE_INT ||
+ sub_type == G_TYPE_UINT ||
+ sub_type == G_TYPE_BOOLEAN ||
+ sub_type == G_TYPE_DOUBLE ||
+ sub_type == IBUS_TYPE_VARIANT);
+
+ g_value_init (value, G_TYPE_VALUE_ARRAY);
+ array = g_value_array_new (0);
+ ibus_message_iter_recurse (iter, IBUS_TYPE_ARRAY, &sub_iter);
+ while (ibus_message_iter_get_arg_type (&sub_iter) != G_TYPE_INVALID) {
+ _from_dbus_value (&sub_iter, &v);
+ g_value_array_append (array, &v);
+ g_value_unset (&v);
+ }
+ g_value_take_boxed (value, array);
+ ibus_message_iter_next (iter);
+ break;
+ }
+
+ g_debug ("type=%s", g_type_name (type));
+
+ g_assert_not_reached();
+ }
+}
+
+static void
+_to_dbus_value (IBusMessageIter *iter,
+ const GValue *value)
+{
+ IBusMessageIter sub_iter;
+ gboolean retval;
+
+
+ switch (G_VALUE_TYPE (value)) {
+ case G_TYPE_STRING:
+ {
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_VARIANT, "s", &sub_iter);
+ g_assert (retval);
+
+ const gchar *v = g_value_get_string (value);
+ ibus_message_iter_append (&sub_iter,
+ G_TYPE_STRING,
+ &v);
+ ibus_message_iter_close_container (iter, &sub_iter);
+ }
+ break;
+ case G_TYPE_INT:
+ {
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_VARIANT, "i", &sub_iter);
+ g_assert (retval);
+
+ gint v = g_value_get_int (value);
+ ibus_message_iter_append (&sub_iter,
+ G_TYPE_INT,
+ &v);
+ ibus_message_iter_close_container (iter, &sub_iter);
+ }
+ break;
+ case G_TYPE_UINT:
+ {
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_VARIANT, "u", &sub_iter);
+ g_assert (retval);
+
+ guint v = g_value_get_uint (value);
+ ibus_message_iter_append (&sub_iter,
+ G_TYPE_UINT,
+ &v);
+ ibus_message_iter_close_container (iter, &sub_iter);
+ }
+ break;
+ case G_TYPE_BOOLEAN:
+ {
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_VARIANT, "b", &sub_iter);
+ g_assert (retval);
+
+ gboolean v = g_value_get_boolean (value);
+ ibus_message_iter_append (&sub_iter,
+ G_TYPE_BOOLEAN,
+ &v);
+ ibus_message_iter_close_container (iter, &sub_iter);
+ }
+ break;
+ case G_TYPE_DOUBLE:
+ {
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_VARIANT, "d", &sub_iter);
+ g_assert (retval);
+
+ gdouble v = g_value_get_double (value);
+ ibus_message_iter_append (&sub_iter,
+ G_TYPE_DOUBLE,
+ &v);
+ ibus_message_iter_close_container (iter, &sub_iter);
+ }
+ break;
+ default:
+ if (G_TYPE_VALUE_ARRAY == G_VALUE_TYPE (value)) {
+ IBusMessageIter sub_sub_iter;
+ GType type = G_TYPE_INVALID;
+ gint i;
+
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_VARIANT, "av", &sub_iter);
+ g_assert (retval);
+
+ GValueArray *array = (GValueArray *)g_value_get_boxed (value);
+ ibus_message_iter_open_container (&sub_iter,
+ IBUS_TYPE_ARRAY,
+ "v",
+ &sub_sub_iter);
+ if (array->n_values > 0) {
+ type = G_VALUE_TYPE (&array->values[0]);
+ g_assert (type == G_TYPE_STRING ||
+ type == G_TYPE_INT ||
+ type == G_TYPE_UINT ||
+ type == G_TYPE_BOOLEAN ||
+ type == G_TYPE_DOUBLE);
+ }
+ for (i = 0; i < array->n_values; i++) {
+ g_assert (type == G_VALUE_TYPE (&array->values[i]));
+ _to_dbus_value (&sub_sub_iter, &array->values[i]);
+ }
+ ibus_message_iter_close_container (&sub_iter, &sub_sub_iter);
+ ibus_message_iter_close_container (iter, &sub_iter);
+ break;
+ }
+ g_assert_not_reached();
+ }
+
+}
+#endif
+
diff --git a/src/ibusconfigservice.c b/src/ibusconfigservice.c
new file mode 100644
index 0000000..6465add
--- /dev/null
+++ b/src/ibusconfigservice.c
@@ -0,0 +1,314 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusshare.h"
+#include "ibusconfigservice.h"
+
+enum {
+ LAST_SIGNAL,
+};
+
+enum {
+ PROP_0,
+ PROP_CONNECTION,
+};
+
+// static guint config_service_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_config_service_class_init (IBusConfigServiceClass *klass);
+static void ibus_config_service_init (IBusConfigService *config);
+static void ibus_config_service_set_property (IBusConfigService *config,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ibus_config_service_get_property (IBusConfigService *config,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void ibus_config_service_destroy (IBusConfigService *config);
+static gboolean ibus_config_service_ibus_message (IBusConfigService *config,
+ IBusConnection *connection,
+ IBusMessage *message);
+static gboolean ibus_config_service_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value,
+ IBusError **error);
+static gboolean ibus_config_service_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value,
+ IBusError **error);
+
+static IBusServiceClass *parent_class = NULL;
+
+GType
+ibus_config_service_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusConfigServiceClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_config_service_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusConfigService),
+ 0,
+ (GInstanceInitFunc) ibus_config_service_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERVICE,
+ "IBusConfigService",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+ return type;
+}
+
+IBusConfigService *
+ibus_config_service_new (IBusConnection *connection)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ IBusConfigService *config;
+
+ config = (IBusConfigService *) g_object_new (IBUS_TYPE_CONFIG_SERVICE,
+ "path", IBUS_PATH_CONFIG,
+ "connection", connection,
+ NULL);
+
+ return config;
+}
+
+static void
+ibus_config_service_class_init (IBusConfigServiceClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
+
+ gobject_class->set_property = (GObjectSetPropertyFunc) ibus_config_service_set_property;
+ gobject_class->get_property = (GObjectGetPropertyFunc) ibus_config_service_get_property;
+
+ IBUS_OBJECT_CLASS (gobject_class)->destroy = (IBusObjectDestroyFunc) ibus_config_service_destroy;
+
+ IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_config_service_ibus_message;
+
+ klass->set_value = ibus_config_service_set_value;
+ klass->get_value = ibus_config_service_get_value;
+
+ g_object_class_install_property (gobject_class,
+ PROP_CONNECTION,
+ g_param_spec_object ("connection",
+ "connection",
+ "The connection of config object",
+ IBUS_TYPE_CONNECTION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+ibus_config_service_init (IBusConfigService *config)
+{
+}
+
+static void
+ibus_config_service_set_property (IBusConfigService *config,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_CONNECTION:
+ ibus_service_add_to_connection ((IBusService *) config,
+ g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (config, prop_id, pspec);
+ }
+}
+
+static void
+ibus_config_service_get_property (IBusConfigService *config,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_CONNECTION:
+ {
+ GList *connections = ibus_service_get_connections ((IBusService *) config);
+ if (connections) {
+ g_value_set_object (value, connections->data);
+ }
+ else {
+ g_value_set_object (value, NULL);
+ }
+ g_list_foreach (connections, (GFunc) g_object_unref, NULL);
+ g_list_free (connections);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (config, prop_id, pspec);
+ }
+}
+
+static void
+ibus_config_service_destroy (IBusConfigService *config)
+{
+ IBUS_OBJECT_CLASS(parent_class)->destroy ((IBusObject *) config);
+}
+
+static gboolean
+ibus_config_service_ibus_message (IBusConfigService *config,
+ IBusConnection *connection,
+ IBusMessage *message)
+{
+ g_assert (IBUS_IS_CONFIG_SERVICE (config));
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+
+ IBusMessage *reply = NULL;
+
+ if (ibus_message_is_method_call (message, IBUS_INTERFACE_CONFIG, "SetValue")) {
+ gchar *section;
+ gchar *name;
+ GValue value = { 0 };
+ IBusError *error = NULL;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &section,
+ G_TYPE_STRING, &name,
+ G_TYPE_VALUE, &value,
+ G_TYPE_INVALID);
+ if (!retval) {
+ reply = ibus_message_new_error_printf (message,
+ DBUS_ERROR_INVALID_ARGS,
+ "Can not parse arguments 1 of SetValue");
+ ibus_error_free (error);
+ }
+ else if (!IBUS_CONFIG_SERVICE_GET_CLASS (config)->set_value (config, section, name, &value, &error)) {
+ reply = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ }
+ else {
+ reply = ibus_message_new_method_return (message);
+ }
+ }
+ else if (ibus_message_is_method_call (message, IBUS_INTERFACE_CONFIG, "GetValue")) {
+ gchar *section;
+ gchar *name;
+ GValue value = { 0 };
+ IBusError *error = NULL;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &section,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID);
+
+ if (!retval) {
+ reply = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ }
+ else if (!IBUS_CONFIG_SERVICE_GET_CLASS (config)->get_value (config, section, name, &value, &error)) {
+ reply = ibus_message_new_error (message,
+ error->name,
+ error->message);
+ ibus_error_free (error);
+ }
+ else {
+ reply = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply,
+ G_TYPE_VALUE, &value,
+ G_TYPE_INVALID);
+ g_value_unset (&value);
+ }
+ }
+
+ if (reply) {
+ ibus_connection_send (connection, reply);
+ ibus_message_unref (reply);
+ return TRUE;
+ }
+
+ return parent_class->ibus_message ((IBusService *) config, connection, message);
+}
+
+static gboolean
+ibus_config_service_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value,
+ IBusError **error)
+{
+ if (error) {
+ *error = ibus_error_new_from_printf (DBUS_ERROR_FAILED,
+ "Can not set value [%s, %s]",
+ section, name);
+ }
+ return FALSE;
+}
+
+static gboolean
+ibus_config_service_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value,
+ IBusError **error)
+{
+ if (error) {
+ *error = ibus_error_new_from_printf (DBUS_ERROR_FAILED,
+ "Can not get value [%s, %s]",
+ section, name);
+ }
+ return FALSE;
+}
+
+void
+ibus_config_service_value_changed (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value)
+{
+ g_assert (IBUS_IS_CONFIG_SERVICE (config));
+ g_assert (section);
+ g_assert (name);
+ g_assert (G_IS_VALUE (value));
+
+ ibus_service_send_signal ((IBusService *) config,
+ IBUS_INTERFACE_CONFIG,
+ "ValueChanged",
+ G_TYPE_STRING, &section,
+ G_TYPE_STRING, &name,
+ G_TYPE_VALUE, value,
+ G_TYPE_INVALID);
+}
diff --git a/src/ibusconfigservice.h b/src/ibusconfigservice.h
new file mode 100644
index 0000000..f04a5eb
--- /dev/null
+++ b/src/ibusconfigservice.h
@@ -0,0 +1,85 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_CONFIG_SERVICE_H_
+#define __IBUS_CONFIG_SERVICE_H_
+
+#include "ibuserror.h"
+#include "ibusservice.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_CONFIG_SERVICE \
+ (ibus_config_service_get_type ())
+#define IBUS_CONFIG_SERVICE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_CONFIG_SERVICE, IBusConfigService))
+#define IBUS_CONFIG_SERVICE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_CONFIG_SERVICE, IBusConfigServiceClass))
+#define IBUS_IS_CONFIG_SERVICE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_CONFIG_SERVICE))
+#define IBUS_IS_CONFIG_SERVICE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_CONFIG_SERVICE))
+#define IBUS_CONFIG_SERVICE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_CONFIG_SERVICE, IBusConfigServiceClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusConfigService IBusConfigService;
+typedef struct _IBusConfigServiceClass IBusConfigServiceClass;
+
+struct _IBusConfigService {
+ IBusService parent;
+
+ /* instance members */
+};
+
+struct _IBusConfigServiceClass {
+ IBusServiceClass parent;
+
+ /* class members */
+ gboolean (* set_value) (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value,
+ IBusError **error);
+ gboolean (* get_value) (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value,
+ IBusError **error);
+
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[14];
+};
+
+GType ibus_config_service_get_type (void);
+IBusConfigService *ibus_config_service_new (IBusConnection *connection);
+void ibus_config_service_value_changed
+ (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusconnection.c b/src/ibusconnection.c
new file mode 100644
index 0000000..90776cd
--- /dev/null
+++ b/src/ibusconnection.c
@@ -0,0 +1,697 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <stdarg.h>
+#include "ibusmessage.h"
+#include "ibusconnection.h"
+#include "ibusinternal.h"
+
+#define IBUS_CONNECTION_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_CONNECTION, IBusConnectionPrivate))
+
+enum {
+ IBUS_SIGNAL,
+ IBUS_MESSAGE,
+ IBUS_MESSAGE_SENT,
+ DISCONNECTED,
+ LAST_SIGNAL,
+};
+
+
+/* IBusConnectionPriv */
+struct _IBusConnectionPrivate {
+ DBusConnection *connection;
+ gboolean shared;
+};
+typedef struct _IBusConnectionPrivate IBusConnectionPrivate;
+
+static guint connection_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_connection_class_init (IBusConnectionClass *klass);
+static void ibus_connection_init (IBusConnection *connection);
+static void ibus_connection_destroy (IBusConnection *connection);
+
+static gboolean ibus_connection_ibus_message(IBusConnection *connection,
+ IBusMessage *message);
+static gboolean ibus_connection_ibus_signal (IBusConnection *connection,
+ IBusMessage *message);
+static void ibus_connection_disconnected(IBusConnection *connection);
+static DBusHandlerResult
+ _connection_handle_message_cb(DBusConnection *dbus_connection,
+ IBusMessage *message,
+ IBusConnection *connection);
+
+static IBusObjectClass *parent_class = NULL;
+static GHashTable *_connections = NULL;
+
+GType
+ibus_connection_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusConnectionClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_connection_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusConnection),
+ 0,
+ (GInstanceInitFunc) ibus_connection_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_OBJECT,
+ "IBusConnection",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+IBusConnection *
+ibus_connection_new (void)
+{
+ GObject *object;
+ object = g_object_new (IBUS_TYPE_CONNECTION, NULL);
+ return IBUS_CONNECTION (object);
+}
+
+static void
+ibus_connection_class_init (IBusConnectionClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusConnectionPrivate));
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_connection_destroy;
+
+ klass->ibus_message = ibus_connection_ibus_message;
+ klass->ibus_signal = ibus_connection_ibus_signal;
+ klass->disconnected = ibus_connection_disconnected;
+
+ connection_signals[IBUS_MESSAGE] =
+ g_signal_new (I_("ibus-message"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusConnectionClass, ibus_message),
+ NULL, NULL,
+ ibus_marshal_BOOLEAN__POINTER,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_POINTER);
+
+ connection_signals[IBUS_SIGNAL] =
+ g_signal_new (I_("ibus-signal"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusConnectionClass, ibus_signal),
+ NULL, NULL,
+ ibus_marshal_BOOL__POINTER,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_POINTER);
+
+ connection_signals[IBUS_MESSAGE_SENT] =
+ g_signal_new (I_("ibus-message-sent"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusConnectionClass, ibus_message_sent),
+ NULL, NULL,
+ ibus_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ connection_signals[DISCONNECTED] =
+ g_signal_new (I_("disconnected"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusConnectionClass, disconnected),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+}
+
+static void
+ibus_connection_init (IBusConnection *connection)
+{
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ priv->connection = NULL;
+ priv->shared = FALSE;
+}
+
+static void
+ibus_connection_destroy (IBusConnection *connection)
+{
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ if (priv->connection) {
+ dbus_connection_remove_filter (priv->connection,
+ (DBusHandleMessageFunction) _connection_handle_message_cb,
+ connection);
+ }
+
+ if (!priv->shared && priv->connection) {
+ dbus_connection_close (priv->connection);
+ dbus_connection_unref (priv->connection);
+ priv->connection = NULL;
+ goto _out;
+ }
+
+ if (priv->shared && priv->connection) {
+ g_warn_if_fail (_connections != NULL);
+ if (_connections != NULL) {
+ g_hash_table_remove (_connections, priv->connection);
+ }
+ dbus_connection_unref (priv->connection);
+ priv->connection = NULL;
+ goto _out;
+ }
+_out:
+ parent_class->destroy (IBUS_OBJECT (connection));
+}
+
+static gboolean
+ibus_connection_ibus_message (IBusConnection *connection,
+ IBusMessage *message)
+{
+ gboolean retval = FALSE;
+
+ if (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
+ g_signal_emit (connection, connection_signals[IBUS_SIGNAL], 0, message, &retval);
+
+ return retval;
+}
+
+static gboolean
+ibus_connection_ibus_signal (IBusConnection *connection, IBusMessage *message)
+{
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ if (ibus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
+ g_signal_emit (connection, connection_signals[DISCONNECTED], 0);
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static void
+ibus_connection_disconnected (IBusConnection *connection)
+{
+ ibus_object_destroy (IBUS_OBJECT (connection));
+}
+
+static DBusHandlerResult
+_connection_handle_message_cb (DBusConnection *dbus_connection,
+ IBusMessage *message,
+ IBusConnection *connection)
+{
+ gboolean retval = FALSE;
+
+ gint type;
+
+ type = ibus_message_get_type (message);
+ g_signal_emit (connection, connection_signals[IBUS_MESSAGE], 0, message, &retval);
+
+ if (retval)
+ return DBUS_HANDLER_RESULT_HANDLED;
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static gint
+_get_slot ()
+{
+ static gint slot = -1;
+ if (slot == -1) {
+ dbus_connection_allocate_data_slot (&slot);
+ }
+ return slot;
+}
+
+void
+ibus_connection_set_connection (IBusConnection *connection, DBusConnection *dbus_connection, gboolean shared)
+{
+ gboolean result;
+ IBusConnectionPrivate *priv;
+
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (dbus_connection != NULL);
+ g_assert (dbus_connection_get_is_connected (dbus_connection));
+
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+ g_assert (priv->connection == NULL);
+
+ priv->connection = dbus_connection_ref (dbus_connection);
+ priv->shared = shared;
+
+ dbus_connection_set_data (priv->connection, _get_slot(), connection, NULL);
+
+ result = dbus_connection_add_filter (priv->connection,
+ (DBusHandleMessageFunction) _connection_handle_message_cb,
+ connection, NULL);
+
+ dbus_connection_setup (priv->connection, NULL);
+ g_warn_if_fail (result);
+}
+
+IBusConnection *
+ibus_connection_open (const gchar *address)
+{
+ g_assert (address != NULL);
+
+ DBusError error;
+ DBusConnection *dbus_connection;
+ IBusConnection *connection;
+
+ if (_connections == NULL) {
+ _connections = g_hash_table_new (g_direct_hash, g_direct_equal);
+ }
+
+
+ dbus_error_init (&error);
+ dbus_connection = dbus_connection_open (address, &error);
+ if (dbus_connection == NULL) {
+ g_warning ("Connect to %s failed. %s.", address, error.message);
+ dbus_error_free (&error);
+ return NULL;
+ }
+
+ connection = g_hash_table_lookup (_connections, dbus_connection);
+
+ if (connection) {
+ dbus_connection_unref (dbus_connection);
+ g_object_ref (connection);
+ return connection;
+ }
+
+ connection = ibus_connection_new ();
+ ibus_connection_set_connection (connection, dbus_connection, TRUE);
+ g_hash_table_insert (_connections, dbus_connection, connection);
+
+ return connection;
+}
+
+IBusConnection *
+ibus_connection_open_private (const gchar *address)
+{
+ g_assert (address != NULL);
+
+ DBusError error;
+ DBusConnection *dbus_connection;
+ IBusConnection *connection;
+
+ dbus_error_init (&error);
+ dbus_connection = dbus_connection_open_private (address, &error);
+ if (dbus_connection == NULL) {
+ g_warning ("Connect to %s failed. %s.", address, error.message);
+ dbus_error_free (&error);
+ return NULL;
+ }
+
+ connection = ibus_connection_new ();
+ ibus_connection_set_connection (connection, dbus_connection, FALSE);
+
+ return connection;
+}
+
+void ibus_connection_close (IBusConnection *connection)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ dbus_connection_close (priv->connection);
+}
+
+gboolean
+ibus_connection_is_connected (IBusConnection *connection)
+{
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ if (priv->connection == NULL) {
+ return FALSE;
+ }
+ return dbus_connection_get_is_connected (priv->connection);
+}
+
+DBusConnection *
+ibus_connection_get_connection (IBusConnection *connection)
+{
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ return priv->connection;
+}
+
+typedef struct _VTableCallData {
+ IBusMessageFunc message_func;
+ gpointer user_data;
+}VTableCallData;
+
+void
+_unregister_function (DBusConnection *dbus_connection, VTableCallData *data)
+{
+ g_slice_free (VTableCallData, data);
+}
+
+DBusHandlerResult
+_message_function (DBusConnection *dbus_connection,
+ DBusMessage *message,
+ VTableCallData *data)
+{
+ gboolean retval;
+ IBusConnection *connection;
+
+ connection = IBUS_CONNECTION (dbus_connection_get_data (dbus_connection, _get_slot()));
+ retval = data->message_func (connection, message, data->user_data);
+
+ return retval ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+gboolean
+ibus_connection_register_object_path (IBusConnection *connection,
+ const gchar *path, IBusMessageFunc message_func, gpointer user_data)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (path != NULL);
+ g_assert (message_func != NULL);
+
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ gboolean retval;
+ DBusObjectPathVTable vtable = {0};
+ VTableCallData *data;
+
+ vtable.unregister_function = (DBusObjectPathUnregisterFunction) _unregister_function;
+ vtable.message_function = (DBusObjectPathMessageFunction) _message_function;
+
+ data = g_slice_new (VTableCallData);
+ data->message_func = message_func;
+ data->user_data = user_data;
+
+ retval = dbus_connection_register_object_path (priv->connection, path, &vtable, data);
+ if (!retval) {
+ g_warning ("Out of memory!");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+gboolean
+ibus_connection_unregister_object_path (IBusConnection *connection, const gchar *path)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (path != NULL);
+
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ gboolean retval;
+
+ retval = dbus_connection_unregister_object_path (priv->connection, path);
+ if (!retval) {
+ g_warning ("Out of memory!");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+gboolean
+ibus_connection_send (IBusConnection *connection,
+ IBusMessage *message)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+
+ gboolean retval;
+ IBusConnectionPrivate *priv;
+
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+ retval = dbus_connection_send (priv->connection, message, NULL);
+
+ if (retval) {
+ g_signal_emit (connection,
+ connection_signals[IBUS_MESSAGE_SENT],
+ 0,
+ message);
+ }
+
+ return retval;
+}
+
+
+gboolean
+ibus_connection_send_signal (IBusConnection *connection,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *name,
+ GType first_arg_type,
+ ...)
+{
+ va_list args;
+ gboolean retval;
+
+ va_start (args, first_arg_type);
+ retval = ibus_connection_send_signal_valist (connection,
+ path,
+ interface,
+ name,
+ first_arg_type,
+ args);
+ va_end (args);
+ return retval;
+}
+
+gboolean
+ibus_connection_send_signal_valist (IBusConnection *connection,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *name,
+ GType first_arg_type,
+ va_list args)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (interface != NULL);
+ g_assert (name != NULL);
+
+ gboolean retval;
+ IBusMessage *message;
+
+ message = ibus_message_new_signal (path, interface, name);
+
+ ibus_message_append_args_valist (message, first_arg_type, args);
+ retval = ibus_connection_send (connection, message);
+ ibus_message_unref (message);
+
+ return retval;
+}
+
+gboolean
+ibus_connection_send_valist (IBusConnection *connection,
+ gint message_type,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *name,
+ GType first_arg_type,
+ va_list args)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (interface != NULL);
+ g_assert (name != NULL);
+
+ gboolean retval;
+ IBusMessage *message;
+
+ message = ibus_message_new (message_type);
+ ibus_message_set_path (message, path);
+ ibus_message_set_interface (message, interface);
+ ibus_message_set_member (message, name);
+
+ ibus_message_append_args_valist (message, first_arg_type, args);
+ retval = ibus_connection_send (connection, message);
+ ibus_message_unref (message);
+
+ return retval;
+}
+
+gboolean
+ibus_connection_send_with_reply (IBusConnection *connection,
+ IBusMessage *message,
+ IBusPendingCall **pending_return,
+ gint timeout_milliseconds)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+ g_assert (pending_return != NULL);
+ g_assert (timeout_milliseconds > 0 || timeout_milliseconds == -1);
+
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ return dbus_connection_send_with_reply (priv->connection,
+ message,
+ pending_return,
+ timeout_milliseconds);
+}
+
+IBusMessage *
+ibus_connection_send_with_reply_and_block (IBusConnection *connection,
+ IBusMessage *message,
+ gint timeout_milliseconds,
+ IBusError **error)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+ g_assert (timeout_milliseconds > 0 || timeout_milliseconds == -1);
+
+ IBusError *_error;
+ IBusMessage *reply;
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ _error = ibus_error_new ();
+
+ reply = dbus_connection_send_with_reply_and_block (priv->connection,
+ message,
+ timeout_milliseconds,
+ _error);
+
+ if (reply != NULL) {
+ g_signal_emit (connection,
+ connection_signals[IBUS_MESSAGE_SENT],
+ 0,
+ message);
+ }
+
+ if (reply == NULL && error != NULL) {
+ *error = _error;
+ }
+ else
+ ibus_error_free (_error);
+
+ return reply;
+}
+
+gboolean
+ibus_connection_call (IBusConnection *connection,
+ const gchar *name,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *member,
+ IBusError **error,
+ GType first_arg_type,
+ ...)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (name != NULL);
+ g_assert (path != NULL);
+ g_assert (interface != NULL);
+ g_assert (member != NULL);
+
+ IBusConnectionPrivate *priv;
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ g_assert (dbus_connection_get_is_connected (priv->connection));
+
+ IBusMessage *message, *reply;
+ IBusError *tmp_error;
+ va_list args;
+ GType type;
+ gboolean retval;
+
+ message = ibus_message_new_method_call (name, path, interface, member);
+
+ va_start (args, first_arg_type);
+
+ ibus_message_append_args_valist (message, first_arg_type, args);
+
+ va_end (args);
+
+ reply = ibus_connection_send_with_reply_and_block (
+ connection,
+ message,
+ -1,
+ error);
+ ibus_message_unref (message);
+
+ if (reply == NULL) {
+ return FALSE;
+ }
+
+ if ((tmp_error = ibus_error_new_from_message (reply)) != NULL) {
+ if (error) {
+ *error = tmp_error;
+ }
+ else
+ ibus_error_free (tmp_error);
+ ibus_message_unref (reply);
+ return FALSE;
+ }
+
+ va_start (args, first_arg_type);
+
+ type = first_arg_type;
+
+ while (type != DBUS_TYPE_INVALID) {
+ va_arg (args, gpointer);
+ type = va_arg (args, GType);
+ }
+ type = va_arg (args, GType);
+
+ if (type != G_TYPE_INVALID) {
+ retval = ibus_message_get_args_valist (reply, error, type, args);
+ }
+
+ va_end (args);
+
+ ibus_message_unref (reply);
+
+ if (!retval) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+ibus_connection_flush (IBusConnection *connection)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (ibus_connection_is_connected (connection));
+
+ IBusConnectionPrivate *priv;
+
+ priv = IBUS_CONNECTION_GET_PRIVATE (connection);
+
+ dbus_connection_flush (priv->connection);
+}
diff --git a/src/ibusconnection.h b/src/ibusconnection.h
new file mode 100644
index 0000000..e4a70f7
--- /dev/null
+++ b/src/ibusconnection.h
@@ -0,0 +1,147 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_CONNECTION_H_
+#define __IBUS_CONNECTION_H_
+
+#include <dbus/dbus.h>
+#include "ibusmessage.h"
+#include "ibuspendingcall.h"
+#include "ibusobject.h"
+#include "ibuserror.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_CONNECTION \
+ (ibus_connection_get_type ())
+#define IBUS_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_CONNECTION, IBusConnection))
+#define IBUS_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_CONNECTION, IBusConnectionClass))
+#define IBUS_IS_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_CONNECTION))
+#define IBUS_IS_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_CONNECTION))
+#define IBUS_CONNECTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_CONNECTION, IBusConnectionClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusConnection IBusConnection;
+typedef struct _IBusConnectionClass IBusConnectionClass;
+
+typedef gboolean (* IBusIBusMessageFunc)(IBusConnection *connection,
+ IBusMessage *message);
+typedef gboolean (* IBusIBusSignalFunc) (IBusConnection *connection,
+ IBusMessage *message);
+typedef gboolean (* IBusMessageFunc) (IBusConnection *connection,
+ IBusMessage *message,
+ gpointer user_data);
+typedef void (* IBusConnectionReplyFunc)
+ (IBusConnection *connection,
+ IBusMessage *reply,
+ gpointer user_data);
+
+struct _IBusConnection {
+ IBusObject parent;
+ /* instance members */
+};
+
+struct _IBusConnectionClass {
+ IBusObjectClass parent;
+
+ /* signals */
+ gboolean (* ibus_message) (IBusConnection *connection,
+ IBusMessage *message);
+ gboolean (* ibus_signal) (IBusConnection *connection,
+ IBusMessage *message);
+ void (* ibus_message_sent)
+ (IBusConnection *connection,
+ IBusMessage *message);
+ void (* disconnected) (IBusConnection *connection);
+
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[4];
+};
+
+GType ibus_connection_get_type (void);
+IBusConnection *ibus_connection_new (void);
+void ibus_connection_set_connection (IBusConnection *connection,
+ DBusConnection *dbus_connection,
+ gboolean shared);
+IBusConnection *ibus_connection_open (const gchar *address);
+IBusConnection *ibus_connection_open_private (const gchar *address);
+void ibus_connection_close (IBusConnection *connection);
+gboolean ibus_connection_is_connected (IBusConnection *connection);
+DBusConnection *ibus_connection_get_connection (IBusConnection *connection);
+gboolean ibus_connection_send (IBusConnection *connection,
+ IBusMessage *message);
+gboolean ibus_connection_send_signal (IBusConnection *connection,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *name,
+ GType first_arg_type,
+ ...);
+gboolean ibus_connection_send_signal_valist (IBusConnection *connection,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *name,
+ GType first_arg_type,
+ va_list args);
+gboolean ibus_connection_send_valist (IBusConnection *connection,
+ gint message_type,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *name,
+ GType first_arg_type,
+ va_list args);
+gboolean ibus_connection_send_with_reply (IBusConnection *connection,
+ IBusMessage *message,
+ IBusPendingCall **pending_return,
+ gint timeout_milliseconds);
+IBusMessage *ibus_connection_send_with_reply_and_block
+ (IBusConnection *connection,
+ IBusMessage *message,
+ gint timeout_milliseconds,
+ IBusError **error);
+gboolean ibus_connection_call (IBusConnection *connection,
+ const gchar *name,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *member,
+ IBusError **error,
+ GType first_arg_type,
+ ...);
+void ibus_connection_flush (IBusConnection *connection);
+gboolean ibus_connection_register_object_path
+ (IBusConnection *connection,
+ const gchar *path,
+ IBusMessageFunc message_func,
+ gpointer user_data);
+gboolean ibus_connection_unregister_object_path
+ (IBusConnection *connection,
+ const gchar *path);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusdebug.h b/src/ibusdebug.h
new file mode 100644
index 0000000..7a59a8d
--- /dev/null
+++ b/src/ibusdebug.h
@@ -0,0 +1,27 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_DEBUG_H_
+#define __IBUS_DEBUG_H_
+
+#define ibus_warning(msg, args...) \
+ g_warning("%s:%d, " msg, __FILE__, __LINE__, ##args)
+
+#endif
+
diff --git a/src/ibusengine.c b/src/ibusengine.c
new file mode 100644
index 0000000..ddedcde
--- /dev/null
+++ b/src/ibusengine.c
@@ -0,0 +1,957 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdarg.h>
+#include "ibusengine.h"
+#include "ibusinternal.h"
+#include "ibusshare.h"
+
+#define IBUS_ENGINE_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_ENGINE, IBusEnginePrivate))
+
+enum {
+ PROCESS_KEY_EVENT,
+ FOCUS_IN,
+ FOCUS_OUT,
+ RESET,
+ ENABLE,
+ DISABLE,
+ SET_CURSOR_LOCATION,
+ SET_CAPABILITIES,
+ PAGE_UP,
+ PAGE_DOWN,
+ CURSOR_UP,
+ CURSOR_DOWN,
+ PROPERTY_ACTIVATE,
+ PROPERTY_SHOW,
+ PROPERTY_HIDE,
+ LAST_SIGNAL,
+};
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ PROP_CONNECTION,
+};
+
+
+/* IBusEnginePriv */
+struct _IBusEnginePrivate {
+ gchar *name;
+ IBusConnection *connection;
+};
+typedef struct _IBusEnginePrivate IBusEnginePrivate;
+
+static guint engine_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_engine_class_init (IBusEngineClass *klass);
+static void ibus_engine_init (IBusEngine *engine);
+static void ibus_engine_destroy (IBusEngine *engine);
+static void ibus_engine_set_property (IBusEngine *engine,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ibus_engine_get_property (IBusEngine *engine,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static gboolean ibus_engine_ibus_message (IBusEngine *engine,
+ IBusConnection *connection,
+ IBusMessage *message);
+static gboolean ibus_engine_process_key_event
+ (IBusEngine *engine,
+ guint keyval,
+ guint state);
+static void ibus_engine_focus_in (IBusEngine *engine);
+static void ibus_engine_focus_out (IBusEngine *engine);
+static void ibus_engine_reset (IBusEngine *engine);
+static void ibus_engine_enable (IBusEngine *engine);
+static void ibus_engine_disable (IBusEngine *engine);
+static void ibus_engine_set_cursor_location
+ (IBusEngine *engine,
+ gint x,
+ gint y,
+ gint w,
+ gint h);
+static void ibus_engine_set_capabilities
+ (IBusEngine *engine,
+ guint caps);
+static void ibus_engine_page_up (IBusEngine *engine);
+static void ibus_engine_page_down (IBusEngine *engine);
+static void ibus_engine_cursor_up (IBusEngine *engine);
+static void ibus_engine_cursor_down (IBusEngine *engine);
+static void ibus_engine_property_activate
+ (IBusEngine *engine,
+ const gchar *prop_name,
+ gint prop_state);
+static void ibus_engine_property_show (IBusEngine *engine,
+ const gchar *prop_name);
+static void ibus_engine_property_hide (IBusEngine *engine,
+ const gchar *prop_name);
+
+
+static IBusServiceClass *parent_class = NULL;
+
+GType
+ibus_engine_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusEngineClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_engine_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusEngine),
+ 0,
+ (GInstanceInitFunc) ibus_engine_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERVICE,
+ "IBusEngine",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+ return type;
+}
+
+IBusEngine *
+ibus_engine_new (const gchar *name,
+ const gchar *path,
+ IBusConnection *connection)
+{
+ g_assert (path);
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ IBusEngine *engine;
+
+ engine = (IBusEngine *) g_object_new (IBUS_TYPE_ENGINE,
+ "name", name,
+ "path", path,
+ "connection", connection,
+ NULL);
+
+ return engine;
+}
+
+static void
+ibus_engine_class_init (IBusEngineClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusEnginePrivate));
+
+ gobject_class->set_property = (GObjectSetPropertyFunc) ibus_engine_set_property;
+ gobject_class->get_property = (GObjectGetPropertyFunc) ibus_engine_get_property;
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_engine_destroy;
+
+ IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_engine_ibus_message;
+
+ klass->process_key_event = ibus_engine_process_key_event;
+ klass->focus_in = ibus_engine_focus_in;
+ klass->focus_out = ibus_engine_focus_out;
+ klass->reset = ibus_engine_reset;
+ klass->enable = ibus_engine_enable;
+ klass->disable = ibus_engine_disable;
+ klass->page_up = ibus_engine_page_up;
+ klass->page_down = ibus_engine_page_down;
+ klass->cursor_up = ibus_engine_cursor_up;
+ klass->cursor_down = ibus_engine_cursor_down;
+ klass->property_activate = ibus_engine_property_activate;
+ klass->property_show = ibus_engine_property_show;
+ klass->property_hide = ibus_engine_property_hide;
+ klass->set_cursor_location = ibus_engine_set_cursor_location;
+ klass->set_capabilities = ibus_engine_set_capabilities;
+
+
+ /* install properties */
+ g_object_class_install_property (gobject_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ "name",
+ "engine name",
+ "noname",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_CONNECTION,
+ g_param_spec_object ("connection",
+ "connection",
+ "The connection of engine object",
+ IBUS_TYPE_CONNECTION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /* install signals */
+ engine_signals[PROCESS_KEY_EVENT] =
+ g_signal_new (I_("process-key-event"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, process_key_event),
+ NULL, NULL,
+ ibus_marshal_BOOL__UINT_UINT,
+ G_TYPE_BOOLEAN,
+ 2,
+ G_TYPE_UINT,
+ G_TYPE_UINT);
+
+ engine_signals[FOCUS_IN] =
+ g_signal_new (I_("focus-in"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, focus_in),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[FOCUS_OUT] =
+ g_signal_new (I_("focus-out"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, focus_out),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[RESET] =
+ g_signal_new (I_("reset"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, reset),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[ENABLE] =
+ g_signal_new (I_("enable"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, enable),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[DISABLE] =
+ g_signal_new (I_("disable"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, disable),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[SET_CURSOR_LOCATION] =
+ g_signal_new (I_("set-cursor-location"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, set_cursor_location),
+ NULL, NULL,
+ ibus_marshal_VOID__INT_INT_INT_INT,
+ G_TYPE_NONE, 4,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+ engine_signals[SET_CAPABILITIES] =
+ g_signal_new (I_("set-capabilities"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, set_capabilities),
+ NULL, NULL,
+ ibus_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ engine_signals[PAGE_UP] =
+ g_signal_new (I_("page-up"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, page_up),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[PAGE_DOWN] =
+ g_signal_new (I_("page-down"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, page_down),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[CURSOR_UP] =
+ g_signal_new (I_("cursor-up"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, cursor_up),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[CURSOR_DOWN] =
+ g_signal_new (I_("cursor-down"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, cursor_down),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ engine_signals[PROPERTY_ACTIVATE] =
+ g_signal_new (I_("property-activate"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, property_activate),
+ NULL, NULL,
+ ibus_marshal_VOID__STRING_INT,
+ G_TYPE_NONE, 0);
+
+ engine_signals[PROPERTY_SHOW] =
+ g_signal_new (I_("property-show"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, property_show),
+ NULL, NULL,
+ ibus_marshal_VOID__STRING,
+ G_TYPE_NONE, 0);
+
+ engine_signals[PROPERTY_HIDE] =
+ g_signal_new (I_("property-hide"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, property_hide),
+ NULL, NULL,
+ ibus_marshal_VOID__STRING,
+ G_TYPE_NONE, 0);
+
+}
+
+static void
+ibus_engine_init (IBusEngine *engine)
+{
+ IBusEnginePrivate *priv;
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
+
+ priv->name = NULL;
+ priv->connection = NULL;
+}
+
+static void
+ibus_engine_destroy (IBusEngine *engine)
+{
+ IBusEnginePrivate *priv;
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
+
+ g_free (priv->name);
+
+ if (priv->connection) {
+ g_object_unref (priv->connection);
+ priv->connection = NULL;
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (engine));
+}
+
+static void
+ibus_engine_set_property (IBusEngine *engine,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IBusEnginePrivate *priv;
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ priv->name = g_strdup (g_value_dup_string (value));
+ break;
+
+ case PROP_CONNECTION:
+ priv->connection = g_value_get_object (value);
+ g_object_ref (priv->connection);
+ ibus_service_add_to_connection ((IBusService *) engine,
+ priv->connection);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec);
+ }
+}
+
+static void
+ibus_engine_get_property (IBusEngine *engine,
+ guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ IBusEnginePrivate *priv;
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, priv->name);
+ break;
+
+ case PROP_CONNECTION:
+ g_value_set_object (value, priv->connection);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec);
+ }
+}
+
+static gboolean
+ibus_engine_ibus_message (IBusEngine *engine,
+ IBusConnection *connection,
+ IBusMessage *message)
+{
+ g_assert (IBUS_IS_ENGINE (engine));
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+
+ IBusEnginePrivate *priv;
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
+
+ g_assert (priv->connection == connection);
+
+ IBusMessage *return_message = NULL;
+ IBusMessage *error_message = NULL;
+
+ static const struct {
+ gchar *member;
+ guint signal_id;
+ } no_arg_methods[] = {
+ {"FocusIn", FOCUS_IN},
+ {"FocusOut", FOCUS_OUT},
+ {"Reset", RESET},
+ {"Enable", ENABLE},
+ {"Disable", DISABLE},
+ {"PageUp", PAGE_UP},
+ {"PageDown", PAGE_DOWN},
+ {"CursorUp", CURSOR_UP},
+ {"CursorDown", CURSOR_DOWN},
+ {NULL, 0},
+ };
+ gint i;
+
+ for (i = 0; no_arg_methods[i].member != NULL; i++) {
+ if (!ibus_message_is_method_call (message, IBUS_INTERFACE_ENGINE, no_arg_methods[i].member))
+ continue;
+
+ IBusMessageIter iter;
+ ibus_message_iter_init (message, &iter);
+ if (ibus_message_iter_has_next (&iter)) {
+ error_message = ibus_message_new_error_printf (message,
+ "%s.%s: Method does not have arguments",
+ IBUS_INTERFACE_ENGINE, no_arg_methods[i].member);
+ ibus_connection_send (connection, error_message);
+ ibus_message_unref (error_message);
+ return TRUE;
+ }
+
+ g_signal_emit (engine, engine_signals[no_arg_methods[i].signal_id], 0);
+ return_message = ibus_message_new_method_return (message);
+ ibus_connection_send (connection, return_message);
+ ibus_message_unref (return_message);
+ return TRUE;
+ }
+
+
+ if (ibus_message_is_method_call (message, IBUS_INTERFACE_ENGINE, "ProcessKeyEvent")) {
+ guint keyval, state;
+ gboolean retval;
+ IBusError *error = NULL;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_UINT, &keyval,
+ G_TYPE_UINT, &state,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto _keypress_fail;
+
+ retval = FALSE;
+ g_signal_emit (engine,
+ engine_signals[PROCESS_KEY_EVENT],
+ 0,
+ keyval,
+ state,
+ &retval);
+
+ return_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (return_message,
+ G_TYPE_BOOLEAN, &retval,
+ DBUS_TYPE_INVALID);
+ ibus_connection_send (connection, return_message);
+ ibus_message_unref (return_message);
+ return TRUE;
+
+ _keypress_fail:
+ error_message = ibus_message_new_error_printf (message,
+ "%s.%s: Can not match signature (ubu) of method",
+ IBUS_INTERFACE_ENGINE, "ProcessKeyEvent");
+ ibus_connection_send (connection, error_message);
+ ibus_message_unref (error_message);
+ return TRUE;
+ }
+ else if (ibus_message_is_method_call (message, IBUS_INTERFACE_ENGINE, "PropertyActivate")) {
+ gchar *name;
+ gint state;
+ gboolean retval;
+ IBusError *error = NULL;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &name,
+ G_TYPE_INT, &state,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto _property_activate_fail;
+
+ g_signal_emit (engine,
+ engine_signals[PROPERTY_ACTIVATE],
+ 0,
+ name,
+ state);
+
+ return_message = ibus_message_new_method_return (message);
+ ibus_connection_send (connection, return_message);
+ ibus_message_unref (return_message);
+ return TRUE;
+
+ _property_activate_fail:
+ error_message = ibus_message_new_error_printf (message,
+ "%s.%s: Can not match signature (si) of method",
+ IBUS_INTERFACE_ENGINE,
+ "PropertyActivate");
+ ibus_connection_send (connection, error_message);
+ ibus_message_unref (error_message);
+ return TRUE;
+
+ }
+ else if (ibus_message_is_method_call (message, IBUS_INTERFACE_ENGINE, "PropertyShow")) {
+ gchar *name;
+ gboolean retval;
+ IBusError *error;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto _property_show_fail;
+
+ g_signal_emit (engine,
+ engine_signals[PROPERTY_SHOW],
+ 0,
+ name);
+
+ return_message = ibus_message_new_method_return (message);
+ ibus_connection_send (connection, return_message);
+ ibus_message_unref (return_message);
+ return TRUE;
+
+ _property_show_fail:
+ error_message = ibus_message_new_error_printf (message,
+ "%s.%s: Can not match signature (s) of method",
+ IBUS_INTERFACE_ENGINE,
+ "PropertyShow");
+ ibus_connection_send (connection, error_message);
+ ibus_message_unref (error_message);
+ return TRUE;
+ }
+ else if (ibus_message_is_method_call (message, IBUS_INTERFACE_ENGINE, "PropertyHide")) {
+ gchar *name;
+ gboolean retval;
+ IBusError *error = NULL;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &name,
+ G_TYPE_INVALID);
+ if (!retval)
+ goto _property_hide_fail;
+
+ g_signal_emit (engine, engine_signals[PROPERTY_HIDE], 0, name);
+
+ return_message = ibus_message_new_method_return (message);
+ ibus_connection_send (connection, return_message);
+ ibus_message_unref (return_message);
+ return TRUE;
+
+ _property_hide_fail:
+ error_message = ibus_message_new_error_printf (message,
+ "%s.%s: Can not match signature (s) of method",
+ IBUS_INTERFACE_ENGINE, "PropertyHide");
+ ibus_connection_send (connection, error_message);
+ ibus_message_unref (error_message);
+ return TRUE;
+ }
+ else if (ibus_message_is_method_call (message, IBUS_INTERFACE_ENGINE, "SetCursorLocation")) {
+ gint x, y, w, h;
+ gboolean retval;
+ IBusError *error = NULL;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_INT, &x,
+ G_TYPE_INT, &y,
+ G_TYPE_INT, &w,
+ G_TYPE_INT, &h,
+ G_TYPE_INVALID);
+ if (!retval)
+ goto _set_cursor_location_fail;
+
+ engine->cursor_area.x = x;
+ engine->cursor_area.y = y;
+ engine->cursor_area.width = w;
+ engine->cursor_area.height = h;
+
+ g_signal_emit (engine,
+ engine_signals[SET_CURSOR_LOCATION],
+ 0,
+ x, y, w, h);
+
+ return_message = ibus_message_new_method_return (message);
+ ibus_connection_send (connection, return_message);
+ ibus_message_unref (return_message);
+ return TRUE;
+
+ _set_cursor_location_fail:
+ error_message = ibus_message_new_error_printf (message,
+ "%s.%s: Can not match signature (iiii) of method",
+ IBUS_INTERFACE_ENGINE,
+ "SetCursorLocation");
+ ibus_connection_send (connection, error_message);
+ ibus_message_unref (error_message);
+ return TRUE;
+ }
+ else if (ibus_message_is_method_call (message, IBUS_INTERFACE_ENGINE, "SetCapabilities")) {
+ guint caps;
+ gboolean retval;
+ IBusError *error = NULL;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_UINT, &caps,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto _set_capabilities_fail;
+
+ engine->client_capabilities = caps;
+
+ g_signal_emit (engine, engine_signals[SET_CAPABILITIES], 0, caps);
+
+ return_message = ibus_message_new_method_return (message);
+ ibus_connection_send (connection, return_message);
+ ibus_message_unref (return_message);
+ return TRUE;
+
+ _set_capabilities_fail:
+ error_message = ibus_message_new_error_printf (message,
+ "%s.%s: Can not match signature (u) of method",
+ IBUS_INTERFACE_ENGINE, "SetCapabilities");
+ ibus_connection_send (connection, error_message);
+ ibus_message_unref (error_message);
+ return TRUE;
+ }
+ else if (ibus_message_is_method_call (message, IBUS_INTERFACE_ENGINE, "Destroy")) {
+ return_message = ibus_message_new_method_return (message);
+
+ ibus_connection_send (connection, return_message);
+ ibus_message_unref (return_message);
+
+ ibus_object_destroy ((IBusObject *) engine);
+ }
+
+ return parent_class->ibus_message ((IBusService *) engine, connection, message);
+}
+
+static gboolean
+ibus_engine_process_key_event (IBusEngine *engine,
+ guint keyval,
+ guint state)
+{
+ // g_debug ("process-key-event (%d, %d)", keyval, state);
+ return FALSE;
+}
+
+static void
+ibus_engine_focus_in (IBusEngine *engine)
+{
+ // g_debug ("focus-in");
+}
+
+static void
+ibus_engine_focus_out (IBusEngine *engine)
+{
+ // g_debug ("focus-out");
+}
+
+static void
+ibus_engine_reset (IBusEngine *engine)
+{
+ // g_debug ("reset");
+}
+
+static void
+ibus_engine_enable (IBusEngine *engine)
+{
+ // g_debug ("enable");
+}
+
+static void
+ibus_engine_disable (IBusEngine *engine)
+{
+ // g_debug ("disable");
+}
+
+static void
+ibus_engine_set_cursor_location (IBusEngine *engine,
+ gint x,
+ gint y,
+ gint w,
+ gint h)
+{
+ // g_debug ("set-cursor-location (%d, %d, %d, %d)", x, y, w, h);
+}
+
+static void
+ibus_engine_set_capabilities (IBusEngine *engine,
+ guint caps)
+{
+ // g_debug ("set-capabilities (0x%04x)", caps);
+}
+
+static void
+ibus_engine_page_up (IBusEngine *engine)
+{
+ // g_debug ("page-up");
+}
+
+static void
+ibus_engine_page_down (IBusEngine *engine)
+{
+ // g_debug ("page-down");
+}
+
+static void
+ibus_engine_cursor_up (IBusEngine *engine)
+{
+ // g_debug ("cursor-up");
+}
+
+static void
+ibus_engine_cursor_down (IBusEngine *engine)
+{
+ // g_debug ("cursor-down");
+}
+
+static void
+ibus_engine_property_activate (IBusEngine *engine,
+ const gchar *prop_name, gint prop_state)
+{
+ // g_debug ("property-activate ('%s', %d)", prop_name, prop_state);
+}
+
+static void
+ibus_engine_property_show (IBusEngine *engine, const gchar *prop_name)
+{
+ // g_debug ("property-show ('%s')", prop_name);
+}
+
+static void
+ibus_engine_property_hide (IBusEngine *engine, const gchar *prop_name)
+{
+ // g_debug ("property-hide ('%s')", prop_name);
+}
+
+static void
+_send_signal (IBusEngine *engine,
+ const gchar *name,
+ GType first_arg_type,
+ ...)
+{
+ g_assert (IBUS_IS_ENGINE (engine));
+ g_assert (name != NULL);
+
+ va_list args;
+ const gchar *path;
+ IBusEnginePrivate *priv;
+
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
+
+ path = ibus_service_get_path ((IBusService *)engine);
+
+ va_start (args, first_arg_type);
+ ibus_connection_send_signal_valist (priv->connection,
+ path,
+ IBUS_INTERFACE_ENGINE,
+ name,
+ first_arg_type,
+ args);
+ va_end (args);
+}
+
+void
+ibus_engine_commit_text (IBusEngine *engine,
+ IBusText *text)
+{
+ _send_signal (engine,
+ "CommitText",
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_engine_update_preedit_text (IBusEngine *engine,
+ IBusText *text,
+ guint cursor_pos,
+ gboolean visible)
+{
+ _send_signal (engine,
+ "UpdatePreeditText",
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_UINT, &cursor_pos,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_engine_show_preedit_text (IBusEngine *engine)
+{
+ _send_signal (engine,
+ "ShowPreeditText",
+ G_TYPE_INVALID);
+}
+
+void ibus_engine_hide_preedit_text (IBusEngine *engine)
+{
+ _send_signal (engine,
+ "HidePreeditText",
+ G_TYPE_INVALID);
+}
+
+void ibus_engine_update_auxiliary_text (IBusEngine *engine,
+ IBusText *text,
+ gboolean visible)
+{
+ _send_signal (engine,
+ "UpdateAuxiliaryText",
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_engine_show_auxiliary_text (IBusEngine *engine)
+{
+ _send_signal (engine,
+ "ShowAuxiliaryText",
+ G_TYPE_INVALID);
+}
+
+void
+ibus_engine_hide_auxiliary_text (IBusEngine *engine)
+{
+ _send_signal (engine,
+ "HideAuxiliaryText",
+ G_TYPE_INVALID);
+}
+
+void ibus_engine_update_lookup_table (IBusEngine *engine,
+ IBusLookupTable *table,
+ gboolean visible)
+{
+ _send_signal (engine,
+ "UpdateLookupTable",
+ IBUS_TYPE_LOOKUP_TABLE, &table,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+}
+
+void ibus_engine_show_lookup_table (IBusEngine *engine)
+{
+ _send_signal (engine,
+ "ShowLookupTable",
+ G_TYPE_INVALID);
+}
+
+void ibus_engine_hide_lookup_table (IBusEngine *engine)
+{
+ _send_signal (engine,
+ "HideLookupTable",
+ G_TYPE_INVALID);
+}
+
+void ibus_engine_forward_key_event (IBusEngine *engine,
+ guint keyval,
+ gboolean is_press,
+ guint state)
+{
+ _send_signal (engine,
+ "HideLookupTable",
+ G_TYPE_UINT, &keyval,
+ G_TYPE_BOOLEAN, &is_press,
+ G_TYPE_UINT, &state,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_engine_register_properties (IBusEngine *engine,
+ IBusPropList *prop_list)
+{
+ _send_signal (engine,
+ "RegisterProperties",
+ IBUS_TYPE_PROP_LIST, &prop_list,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_engine_update_property (IBusEngine *engine,
+ IBusProperty *prop)
+{
+ _send_signal (engine,
+ "UpdateProperty",
+ IBUS_TYPE_PROPERTY, &prop,
+ G_TYPE_INVALID);
+}
+
+const gchar *
+ibus_engine_get_name (IBusEngine *engine)
+{
+ g_assert (IBUS_IS_ENGINE (engine));
+
+ IBusEnginePrivate *priv;
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
+
+ return priv->name;
+}
+
diff --git a/src/ibusengine.h b/src/ibusengine.h
new file mode 100644
index 0000000..0a827af
--- /dev/null
+++ b/src/ibusengine.h
@@ -0,0 +1,152 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_ENGINE_H_
+#define __IBUS_ENGINE_H_
+
+#include <dbus/dbus.h>
+#include "ibusservice.h"
+#include "ibusattribute.h"
+#include "ibuslookuptable.h"
+#include "ibusproperty.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_ENGINE \
+ (ibus_engine_get_type ())
+#define IBUS_ENGINE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_ENGINE, IBusEngine))
+#define IBUS_ENGINE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_ENGINE, IBusEngineClass))
+#define IBUS_IS_ENGINE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_ENGINE))
+#define IBUS_IS_ENGINE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_ENGINE))
+#define IBUS_ENGINE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_ENGINE, IBusEngineClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusEngine IBusEngine;
+typedef struct _IBusEngineClass IBusEngineClass;
+
+struct _IBusEngine {
+ IBusService parent;
+ /* instance members */
+ gboolean enabled;
+ gboolean has_focus;
+
+ /* cursor location */
+ IBusRectangle cursor_area;
+ guint client_capabilities;
+};
+
+struct _IBusEngineClass {
+ IBusServiceClass parent;
+
+ /* class members */
+ gboolean (* process_key_event)
+ (IBusEngine *engine,
+ guint keyval,
+ guint state);
+ void (* focus_in) (IBusEngine *engine);
+ void (* focus_out) (IBusEngine *engine);
+ void (* reset) (IBusEngine *engine);
+ void (* enable) (IBusEngine *engine);
+ void (* disable) (IBusEngine *engine);
+ void (* set_cursor_location)
+ (IBusEngine *engine,
+ gint x,
+ gint y,
+ gint w,
+ gint h);
+ void (* set_capabilities)
+ (IBusEngine *engine,
+ guint caps);
+
+ void (* page_up) (IBusEngine *engine);
+ void (* page_down) (IBusEngine *engine);
+ void (* cursor_up) (IBusEngine *engine);
+ void (* cursor_down) (IBusEngine *engine);
+
+ void (* property_activate)
+ (IBusEngine *engine,
+ const gchar *prop_name,
+ gint prop_state);
+ void (* property_show) (IBusEngine *engine,
+ const gchar *prop_name);
+ void (* property_hide) (IBusEngine *engine,
+ const gchar *prop_name);
+
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[9];
+};
+
+GType ibus_engine_get_type (void);
+IBusEngine *ibus_engine_new (const gchar *name,
+ const gchar *path,
+ IBusConnection *connection);
+void ibus_engine_commit_text (IBusEngine *engine,
+ IBusText *text);
+void ibus_engine_update_preedit_text
+ (IBusEngine *engine,
+ IBusText *text,
+ guint cursor_pos,
+ gboolean visible);
+void ibus_engine_show_preedit_text
+ (IBusEngine *engine);
+void ibus_engine_hide_preedit_text
+ (IBusEngine *engine);
+void ibus_engine_update_auxiliary_text
+ (IBusEngine *engine,
+ IBusText *text,
+ gboolean visible);
+void ibus_engine_show_auxiliary_text
+ (IBusEngine *engine);
+void ibus_engine_hide_auxiliary_text
+ (IBusEngine *engine);
+void ibus_engine_update_lookup_table
+ (IBusEngine *engine,
+ IBusLookupTable *lookup_table,
+ gboolean visible);
+void ibus_engine_show_lookup_table
+ (IBusEngine *engine);
+void ibus_engine_hide_lookup_table
+ (IBusEngine *engine);
+
+void ibus_engine_forward_key_event
+ (IBusEngine *engine,
+ guint keyval,
+ gboolean is_press,
+ guint state);
+
+void ibus_engine_register_properties
+ (IBusEngine *engine,
+ IBusPropList *prop_list);
+void ibus_engine_update_property(IBusEngine *engine,
+ IBusProperty *prop);
+const gchar *ibus_engine_get_name (IBusEngine *engine);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c
new file mode 100644
index 0000000..0410b67
--- /dev/null
+++ b/src/ibusenginedesc.c
@@ -0,0 +1,356 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibusenginedesc.h"
+#include "ibusxml.h"
+
+enum {
+ LAST_SIGNAL,
+};
+
+
+/* IBusEngineDescPriv */
+struct _IBusEngineDescPrivate {
+ gpointer pad;
+};
+typedef struct _IBusEngineDescPrivate IBusEngineDescPrivate;
+
+#define IBUS_ENGINE_DESC_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_ENGINE_INFO, IBusEngineDescPrivate))
+
+// static guint _signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_engine_desc_class_init (IBusEngineDescClass *klass);
+static void ibus_engine_desc_init (IBusEngineDesc *desc);
+static void ibus_engine_desc_destroy (IBusEngineDesc *desc);
+static gboolean ibus_engine_desc_serialize (IBusEngineDesc *desc,
+ IBusMessageIter *iter);
+static gboolean ibus_engine_desc_deserialize (IBusEngineDesc *desc,
+ IBusMessageIter *iter);
+static gboolean ibus_engine_desc_copy (IBusEngineDesc *dest,
+ const IBusEngineDesc *src);
+static gboolean ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc,
+ XMLNode *node);
+
+static IBusSerializableClass *parent_class = NULL;
+
+GType
+ibus_engine_desc_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusEngineDescClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_engine_desc_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusEngineDesc),
+ 0,
+ (GInstanceInitFunc) ibus_engine_desc_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusEngineDesc",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+
+static void
+ibus_engine_desc_class_init (IBusEngineDescClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_engine_desc_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_engine_desc_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_engine_desc_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_engine_desc_copy;
+
+ g_string_append (serializable_class->signature, "ssssssss");
+}
+
+static void
+ibus_engine_desc_init (IBusEngineDesc *desc)
+{
+
+ desc->name = NULL;
+ desc->longname = NULL;
+ desc->description = NULL;
+ desc->language = NULL;
+ desc->license = NULL;
+ desc->author = NULL;
+ desc->icon = NULL;
+ desc->layout = NULL;
+}
+
+static void
+ibus_engine_desc_destroy (IBusEngineDesc *desc)
+{
+ g_free (desc->name);
+ g_free (desc->longname);
+ g_free (desc->description);
+ g_free (desc->language);
+ g_free (desc->license);
+ g_free (desc->author);
+ g_free (desc->icon);
+ g_free (desc->layout);
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy (IBUS_OBJECT (desc));
+}
+
+static gboolean
+ibus_engine_desc_serialize (IBusEngineDesc *desc,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = parent_class->serialize ((IBusSerializable *)desc, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &desc->name);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &desc->longname);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &desc->description);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &desc->language);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &desc->license);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &desc->author);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &desc->icon);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &desc->layout);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_engine_desc_deserialize (IBusEngineDesc *desc,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ gchar *str;
+
+ retval = parent_class->deserialize ((IBusSerializable *)desc, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ desc->name = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ desc->longname = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ desc->description = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ desc->language = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ desc->license = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ desc->author = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ desc->icon = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ desc->layout = g_strdup (str);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_engine_desc_copy (IBusEngineDesc *dest,
+ const IBusEngineDesc *src)
+{
+ gboolean retval;
+
+ retval = parent_class->copy ((IBusSerializable *)dest,
+ (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+
+ dest->name = g_strdup (src->name);
+ dest->longname = g_strdup (src->longname);
+ dest->description = g_strdup (src->description);
+ dest->language = g_strdup (src->language);
+ dest->license = g_strdup (src->license);
+ dest->author = g_strdup (src->author);
+ dest->icon = g_strdup (src->icon);
+ dest->layout = g_strdup (src->layout);
+
+ return TRUE;
+}
+
+#define g_string_append_indent(string, indent) \
+ { \
+ gint i; \
+ for (i = 0; i < (indent); i++) { \
+ g_string_append (string, " "); \
+ } \
+ }
+
+void
+ibus_engine_desc_output (IBusEngineDesc *desc,
+ GString *output,
+ gint indent)
+{
+ g_string_append_indent (output, indent);
+ g_string_append (output, "<engine>\n");
+#define OUTPUT_ENTRY(field, element) \
+ { \
+ gchar *escape_text = g_markup_escape_text (desc->field, -1); \
+ g_string_append_indent (output, indent + 1); \
+ g_string_append_printf (output, "<"element">%s</"element">\n", \
+ escape_text); \
+ g_free (escape_text); \
+ }
+#define OUTPUT_ENTRY_1(name) OUTPUT_ENTRY(name, #name)
+ OUTPUT_ENTRY_1(name);
+ OUTPUT_ENTRY_1(longname);
+ OUTPUT_ENTRY_1(description);
+ OUTPUT_ENTRY_1(language);
+ OUTPUT_ENTRY_1(license);
+ OUTPUT_ENTRY_1(author);
+ OUTPUT_ENTRY_1(icon);
+ OUTPUT_ENTRY_1(layout);
+#undef OUTPUT_ENTRY
+#undef OUTPUT_ENTRY_1
+ g_string_append_indent (output, indent);
+ g_string_append (output, "</engine>\n");
+}
+
+static gboolean
+ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc,
+ XMLNode *node)
+{
+ GList *p;
+ for (p = node->sub_nodes; p != NULL; p = p->next) {
+ XMLNode *sub_node = (XMLNode *) p->data;
+
+#define PARSE_ENTRY(field_name, element_name) \
+ if (g_strcmp0 (sub_node->name, element_name) == 0) { \
+ if (desc->field_name != NULL) { \
+ g_free (desc->field_name); \
+ } \
+ desc->field_name = g_strdup (sub_node->text); \
+ continue; \
+ }
+#define PARSE_ENTRY_1(name) PARSE_ENTRY(name, #name)
+ PARSE_ENTRY_1(name);
+ PARSE_ENTRY_1(longname);
+ PARSE_ENTRY_1(description);
+ PARSE_ENTRY_1(language);
+ PARSE_ENTRY_1(license);
+ PARSE_ENTRY_1(author);
+ PARSE_ENTRY_1(icon);
+ PARSE_ENTRY_1(layout);
+#undef PARSE_ENTRY
+#undef PARSE_ENTRY1
+ g_warning ("<engines> element contains invalidate element <%s>", sub_node->name);
+ }
+ return TRUE;
+}
+
+IBusEngineDesc *
+ibus_engine_desc_new (const gchar *name,
+ const gchar *longname,
+ const gchar *description,
+ const gchar *language,
+ const gchar *license,
+ const gchar *author,
+ const gchar *icon,
+ const gchar *layout)
+{
+ g_assert (name);
+ g_assert (longname);
+ g_assert (description);
+ g_assert (language);
+ g_assert (license);
+ g_assert (author);
+ g_assert (icon);
+ g_assert (layout);
+
+ IBusEngineDesc *desc;
+ desc = (IBusEngineDesc *)g_object_new (IBUS_TYPE_ENGINE_DESC, NULL);
+
+ desc->name = g_strdup (name);
+ desc->longname = g_strdup (longname);
+ desc->description = g_strdup (description);
+ desc->language = g_strdup (language);
+ desc->license = g_strdup (license);
+ desc->author = g_strdup (author);
+ desc->icon = g_strdup (icon);
+ desc->layout = g_strdup (layout);
+
+ return desc;
+}
+
+IBusEngineDesc *
+ibus_engine_desc_new_from_xml_node (XMLNode *node)
+{
+ g_assert (node);
+
+ IBusEngineDesc *desc;
+
+ if (G_UNLIKELY (g_strcmp0 (node->name, "engine") != 0)) {
+ return NULL;
+ }
+
+ desc = (IBusEngineDesc *)g_object_new (IBUS_TYPE_ENGINE_DESC, NULL);
+
+ if (!ibus_engine_desc_parse_xml_node (desc, node)) {
+ g_object_unref (desc);
+ desc = NULL;
+ }
+
+ return desc;
+}
+
diff --git a/src/ibusenginedesc.h b/src/ibusenginedesc.h
new file mode 100644
index 0000000..ffc5a52
--- /dev/null
+++ b/src/ibusenginedesc.h
@@ -0,0 +1,86 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __ENGINE_DESC_H_
+#define __ENGINE_DESC_H_
+
+#include "ibusserializable.h"
+#include "ibusxml.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_ENGINE_DESC \
+ (ibus_engine_desc_get_type ())
+#define IBUS_ENGINE_DESC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_ENGINE_DESC, IBusEngineDesc))
+#define IBUS_ENGINE_DESC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_ENGINE_DESC, IBusEngineDescClass))
+#define IBUS_IS_ENGINE_DESC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_ENGINE_DESC))
+#define IBUS_IS_ENGINE_DESC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_ENGINE_DESC))
+#define IBUS_ENGINE_DESC_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_ENGINE_DESC, IBusEngineDescClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusEngineDesc IBusEngineDesc;
+typedef struct _IBusEngineDescClass IBusEngineDescClass;
+typedef struct _BusComponent BusComponent;
+
+struct _IBusEngineDesc {
+ IBusSerializable parent;
+ /* instance members */
+
+ gchar *name;
+ gchar *longname;
+ gchar *description;
+ gchar *language;
+ gchar *license;
+ gchar *author;
+ gchar *icon;
+ gchar *layout;
+};
+
+struct _IBusEngineDescClass {
+ IBusSerializableClass parent;
+
+ /* class members */
+};
+
+GType ibus_engine_desc_get_type (void);
+IBusEngineDesc *ibus_engine_desc_new (const gchar *name,
+ const gchar *longname,
+ const gchar *description,
+ const gchar *language,
+ const gchar *license,
+ const gchar *author,
+ const gchar *icon,
+ const gchar *layout);
+IBusEngineDesc *ibus_engine_desc_new_from_xml_node
+ (XMLNode *node);
+void ibus_engine_desc_output (IBusEngineDesc *info,
+ GString *output,
+ gint indent);
+G_END_DECLS
+#endif
+
diff --git a/src/ibusenumtypes.c b/src/ibusenumtypes.c
new file mode 100644
index 0000000..591b3f0
--- /dev/null
+++ b/src/ibusenumtypes.c
@@ -0,0 +1,146 @@
+
+/* Generated data (by glib-mkenums) */
+
+#include "ibus.h"
+
+/* enumerations from "ibusobject.h" */
+GType
+ibus_object_flags_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const GFlagsValue values[] = {
+ { IBUS_IN_DESTRUCTION, "IBUS_IN_DESTRUCTION", "in-destruction" },
+ { IBUS_DESTROYED, "IBUS_DESTROYED", "destroyed" },
+ { IBUS_RESERVED_1, "IBUS_RESERVED_1", "reserved-1" },
+ { IBUS_RESERVED_2, "IBUS_RESERVED_2", "reserved-2" },
+ { 0, NULL, NULL }
+ };
+ etype = g_flags_register_static (g_intern_static_string ("IBusObjectFlags"), values);
+ }
+ return etype;
+}
+
+/* enumerations from "ibusattribute.h" */
+GType
+ibus_attr_type_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const GEnumValue values[] = {
+ { IBUS_ATTR_TYPE_UNDERLINE, "IBUS_ATTR_TYPE_UNDERLINE", "underline" },
+ { IBUS_ATTR_TYPE_FOREGROUND, "IBUS_ATTR_TYPE_FOREGROUND", "foreground" },
+ { IBUS_ATTR_TYPE_BACKGROUND, "IBUS_ATTR_TYPE_BACKGROUND", "background" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static (g_intern_static_string ("IBusAttrType"), values);
+ }
+ return etype;
+}
+
+GType
+ibus_attr_underline_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const GEnumValue values[] = {
+ { IBUS_ATTR_UNDERLINE_NONE, "IBUS_ATTR_UNDERLINE_NONE", "none" },
+ { IBUS_ATTR_UNDERLINE_SINGLE, "IBUS_ATTR_UNDERLINE_SINGLE", "single" },
+ { IBUS_ATTR_UNDERLINE_DOUBLE, "IBUS_ATTR_UNDERLINE_DOUBLE", "double" },
+ { IBUS_ATTR_UNDERLINE_LOW, "IBUS_ATTR_UNDERLINE_LOW", "low" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static (g_intern_static_string ("IBusAttrUnderline"), values);
+ }
+ return etype;
+}
+
+/* enumerations from "ibusproperty.h" */
+GType
+ibus_prop_type_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const GEnumValue values[] = {
+ { PROP_TYPE_NORMAL, "PROP_TYPE_NORMAL", "normal" },
+ { PROP_TYPE_TOGGLE, "PROP_TYPE_TOGGLE", "toggle" },
+ { PROP_TYPE_RADIO, "PROP_TYPE_RADIO", "radio" },
+ { PROP_TYPE_MENU, "PROP_TYPE_MENU", "menu" },
+ { PROP_TYPE_SEPARATOR, "PROP_TYPE_SEPARATOR", "separator" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static (g_intern_static_string ("IBusPropType"), values);
+ }
+ return etype;
+}
+
+GType
+ibus_prop_state_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const GEnumValue values[] = {
+ { PROP_STATE_UNCHECKED, "PROP_STATE_UNCHECKED", "unchecked" },
+ { PROP_STATE_CHECKED, "PROP_STATE_CHECKED", "checked" },
+ { PROP_STATE_INCONSISTENT, "PROP_STATE_INCONSISTENT", "inconsistent" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static (g_intern_static_string ("IBusPropState"), values);
+ }
+ return etype;
+}
+
+/* enumerations from "ibustypes.h" */
+GType
+ibus_modifier_type_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const GFlagsValue values[] = {
+ { IBUS_SHIFT_MASK, "IBUS_SHIFT_MASK", "shift-mask" },
+ { IBUS_LOCK_MASK, "IBUS_LOCK_MASK", "lock-mask" },
+ { IBUS_CONTROL_MASK, "IBUS_CONTROL_MASK", "control-mask" },
+ { IBUS_MOD1_MASK, "IBUS_MOD1_MASK", "mod1-mask" },
+ { IBUS_MOD2_MASK, "IBUS_MOD2_MASK", "mod2-mask" },
+ { IBUS_MOD3_MASK, "IBUS_MOD3_MASK", "mod3-mask" },
+ { IBUS_MOD4_MASK, "IBUS_MOD4_MASK", "mod4-mask" },
+ { IBUS_MOD5_MASK, "IBUS_MOD5_MASK", "mod5-mask" },
+ { IBUS_BUTTON1_MASK, "IBUS_BUTTON1_MASK", "button1-mask" },
+ { IBUS_BUTTON2_MASK, "IBUS_BUTTON2_MASK", "button2-mask" },
+ { IBUS_BUTTON3_MASK, "IBUS_BUTTON3_MASK", "button3-mask" },
+ { IBUS_BUTTON4_MASK, "IBUS_BUTTON4_MASK", "button4-mask" },
+ { IBUS_BUTTON5_MASK, "IBUS_BUTTON5_MASK", "button5-mask" },
+ { IBUS_FORWARD_MASK, "IBUS_FORWARD_MASK", "forward-mask" },
+ { IBUS_SUPER_MASK, "IBUS_SUPER_MASK", "super-mask" },
+ { IBUS_HYPER_MASK, "IBUS_HYPER_MASK", "hyper-mask" },
+ { IBUS_META_MASK, "IBUS_META_MASK", "meta-mask" },
+ { IBUS_RELEASE_MASK, "IBUS_RELEASE_MASK", "release-mask" },
+ { IBUS_MODIFIER_MASK, "IBUS_MODIFIER_MASK", "modifier-mask" },
+ { 0, NULL, NULL }
+ };
+ etype = g_flags_register_static (g_intern_static_string ("IBusModifierType"), values);
+ }
+ return etype;
+}
+
+GType
+ibus_capabilite_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const GFlagsValue values[] = {
+ { IBUS_CAP_PREEDIT_TEXT, "IBUS_CAP_PREEDIT_TEXT", "preedit-text" },
+ { IBUS_CAP_AUXILIARY_TEXT, "IBUS_CAP_AUXILIARY_TEXT", "auxiliary-text" },
+ { IBUS_CAP_LOOKUP_TABLE, "IBUS_CAP_LOOKUP_TABLE", "lookup-table" },
+ { IBUS_CAP_FOCUS, "IBUS_CAP_FOCUS", "focus" },
+ { IBUS_CAP_PROPERTY, "IBUS_CAP_PROPERTY", "property" },
+ { 0, NULL, NULL }
+ };
+ etype = g_flags_register_static (g_intern_static_string ("IBusCapabilite"), values);
+ }
+ return etype;
+}
+
+
+/* Generated data ends here */
+
diff --git a/src/ibusenumtypes.c.template b/src/ibusenumtypes.c.template
new file mode 100644
index 0000000..9f607a0
--- /dev/null
+++ b/src/ibusenumtypes.c.template
@@ -0,0 +1,34 @@
+/*** BEGIN file-header ***/
+#include "ibus.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ etype = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+ }
+ return etype;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+/*** END file-tail ***/
diff --git a/src/ibusenumtypes.h b/src/ibusenumtypes.h
new file mode 100644
index 0000000..2e977a0
--- /dev/null
+++ b/src/ibusenumtypes.h
@@ -0,0 +1,37 @@
+
+/* Generated data (by glib-mkenums) */
+
+#ifndef __IBUS_ENUM_TYPES_H__
+#define __IBUS_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* enumerations from "ibusobject.h" */
+GType ibus_object_flags_get_type (void) G_GNUC_CONST;
+#define IBUS_TYPE_OBJECT_FLAGS (ibus_object_flags_get_type ())
+
+/* enumerations from "ibusattribute.h" */
+GType ibus_attr_type_get_type (void) G_GNUC_CONST;
+#define IBUS_TYPE_ATTR_TYPE (ibus_attr_type_get_type ())
+GType ibus_attr_underline_get_type (void) G_GNUC_CONST;
+#define IBUS_TYPE_ATTR_UNDERLINE (ibus_attr_underline_get_type ())
+
+/* enumerations from "ibusproperty.h" */
+GType ibus_prop_type_get_type (void) G_GNUC_CONST;
+#define IBUS_TYPE_PROP_TYPE (ibus_prop_type_get_type ())
+GType ibus_prop_state_get_type (void) G_GNUC_CONST;
+#define IBUS_TYPE_PROP_STATE (ibus_prop_state_get_type ())
+
+/* enumerations from "ibustypes.h" */
+GType ibus_modifier_type_get_type (void) G_GNUC_CONST;
+#define IBUS_TYPE_MODIFIER_TYPE (ibus_modifier_type_get_type ())
+GType ibus_capabilite_get_type (void) G_GNUC_CONST;
+#define IBUS_TYPE_CAPABILITE (ibus_capabilite_get_type ())
+G_END_DECLS
+
+#endif /* __IBUS_ENUM_TYPES_H__ */
+
+/* Generated data ends here */
+
diff --git a/src/ibusenumtypes.h.template b/src/ibusenumtypes.h.template
new file mode 100644
index 0000000..15c1f02
--- /dev/null
+++ b/src/ibusenumtypes.h.template
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef __IBUS_ENUM_TYPES_H__
+#define __IBUS_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __IBUS_ENUM_TYPES_H__ */
+/*** END file-tail ***/
diff --git a/src/ibuserror.c b/src/ibuserror.c
new file mode 100644
index 0000000..c55f4a4
--- /dev/null
+++ b/src/ibuserror.c
@@ -0,0 +1,87 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibuserror.h"
+
+IBusError *
+ibus_error_new (void)
+{
+ IBusError *error;
+
+ error = g_slice_new0 (IBusError);
+ dbus_error_init (error);
+
+ return error;
+}
+
+IBusError *
+ibus_error_new_from_text (const gchar *name,
+ const gchar *message)
+{
+ IBusError *error = ibus_error_new ();
+
+ dbus_set_error (error, name, "%s", message);
+
+ return error;
+}
+
+IBusError *
+ibus_error_new_from_printf (const gchar *name,
+ const gchar *format_message,
+ ...)
+{
+ IBusError *error;
+ gchar *message;
+ va_list va_args;
+
+ va_start (va_args, format_message);
+ message = g_strdup_vprintf (format_message, va_args);
+
+ error = ibus_error_new_from_text (name, message);
+ g_free (message);
+
+ return error;
+}
+
+IBusError *
+ibus_error_new_from_message (DBusMessage *message)
+{
+ g_assert (message != NULL);
+
+ IBusError *error;
+
+ if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
+ return NULL;
+
+ error = ibus_error_new ();
+
+ if (dbus_set_error_from_message (error, message))
+ return error;
+
+ dbus_error_free (error);
+ return NULL;
+}
+
+void
+ibus_error_free (IBusError *error)
+{
+ dbus_error_free (error);
+ g_slice_free (IBusError, error);
+}
+
diff --git a/src/ibuserror.h b/src/ibuserror.h
new file mode 100644
index 0000000..05733d5
--- /dev/null
+++ b/src/ibuserror.h
@@ -0,0 +1,41 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_ERROR_H_
+#define __IBUS_ERROR_H_
+
+#include <glib.h>
+#include <dbus/dbus.h>
+
+G_BEGIN_DECLS
+
+typedef DBusError IBusError;
+
+IBusError *ibus_error_new (void);
+IBusError *ibus_error_new_from_text (const gchar *name,
+ const gchar *message);
+IBusError *ibus_error_new_from_printf (const gchar *name,
+ const gchar *format_message,
+ ...);
+IBusError *ibus_error_new_from_message
+ (DBusMessage *message);
+void ibus_error_free (IBusError *error);
+
+G_END_DECLS
+#endif
diff --git a/src/ibusfactory.c b/src/ibusfactory.c
new file mode 100644
index 0000000..af9d887
--- /dev/null
+++ b/src/ibusfactory.c
@@ -0,0 +1,483 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusfactory.h"
+#include "ibusengine.h"
+#include "ibusshare.h"
+#include "ibusinternal.h"
+
+#define IBUS_FACTORY_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_FACTORY, IBusFactoryPrivate))
+
+enum {
+ LAST_SIGNAL,
+};
+
+/* IBusFactoryPriv */
+struct _IBusFactoryPrivate {
+ guint id;
+ IBusConnection *connection;
+ GList *engine_list;
+ GHashTable *engine_table;
+};
+typedef struct _IBusFactoryPrivate IBusFactoryPrivate;
+
+/* functions prototype */
+static void ibus_factory_class_init (IBusFactoryClass *klass);
+static void ibus_factory_init (IBusFactory *factory);
+static void ibus_factory_destroy (IBusFactory *factory);
+static gboolean ibus_factory_ibus_message (IBusFactory *factory,
+ IBusConnection *connection,
+ IBusMessage *message);
+
+static void _engine_destroy_cb (IBusEngine *engine,
+ IBusFactory *factory);
+static void ibus_factory_info_class_init(IBusFactoryInfoClass *klass);
+static void ibus_factory_info_init (IBusFactoryInfo *info);
+static void ibus_factory_info_destroy (IBusFactoryInfo *info);
+static gboolean ibus_factory_info_serialize (IBusFactoryInfo *info,
+ IBusMessageIter *iter);
+static gboolean ibus_factory_info_deserialize
+ (IBusFactoryInfo *info,
+ IBusMessageIter *iter);
+static gboolean ibus_factory_info_copy (IBusFactoryInfo *dest,
+ const IBusFactoryInfo *src);
+
+static IBusServiceClass *factory_parent_class = NULL;
+static IBusSerializableClass *factory_info_parent_class = NULL;
+
+GType
+ibus_factory_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusFactoryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_factory_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusFactory),
+ 0,
+ (GInstanceInitFunc) ibus_factory_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERVICE,
+ "IBusFactory",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+ return type;
+}
+
+IBusFactory *
+ibus_factory_new (IBusConnection *connection)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ IBusFactory *factory;
+ IBusFactoryPrivate *priv;
+
+ factory = (IBusFactory *) g_object_new (IBUS_TYPE_FACTORY,
+ "path", IBUS_PATH_FACTORY,
+ 0);
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ priv->connection = g_object_ref (connection);
+ ibus_service_add_to_connection ((IBusService *)factory, connection);
+
+ return factory;
+}
+
+static void
+ibus_factory_class_init (IBusFactoryClass *klass)
+{
+ // GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ factory_parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusFactoryPrivate));
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
+
+ IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_factory_ibus_message;
+
+}
+
+static void
+ibus_factory_init (IBusFactory *factory)
+{
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ priv->id = 0;
+ priv->connection = NULL;
+ priv->engine_table = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+ priv->engine_list = NULL;
+}
+
+static void
+ibus_factory_destroy (IBusFactory *factory)
+{
+ GList *list;
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ list = g_list_copy (priv->engine_list);
+ g_list_foreach (list, (GFunc) ibus_object_destroy, NULL);
+ g_list_free (priv->engine_list);
+ g_list_free (list);
+ priv->engine_list = NULL;
+
+ if (priv->engine_table) {
+ g_hash_table_destroy (priv->engine_table);
+ }
+
+ if (priv->connection) {
+ ibus_service_remove_from_connection ((IBusService *)factory,
+ priv->connection);
+ g_object_unref (priv->connection);
+ }
+
+ IBUS_OBJECT_CLASS(factory_parent_class)->destroy (IBUS_OBJECT (factory));
+}
+
+static void
+_engine_destroy_cb (IBusEngine *engine,
+ IBusFactory *factory)
+{
+ GList *list;
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ list = g_list_remove (priv->engine_list, engine);
+
+ if (list) {
+ g_object_unref (engine);
+ g_list_free_1 (list);
+ }
+}
+
+static gboolean
+ibus_factory_ibus_message (IBusFactory *factory,
+ IBusConnection *connection,
+ IBusMessage *message)
+{
+ g_assert (IBUS_IS_FACTORY (factory));
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+
+ IBusMessage *reply_message;
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ g_assert (priv->connection == connection);
+
+ if (ibus_message_is_method_call (message,
+ IBUS_INTERFACE_FACTORY,
+ "CreateEngine")) {
+ gchar *engine_name;
+ gchar *path;
+ IBusError *error;
+ IBusEngine *engine;
+ gboolean retval;
+ GType engine_type;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &engine_name,
+ G_TYPE_INVALID);
+
+ if (!retval) {
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_INVALID_ARGS,
+ "The 1st arg should be engine name");
+ ibus_connection_send (connection, reply_message);
+ ibus_message_unref (reply_message);
+ return TRUE;
+ }
+
+ engine_type = (GType )g_hash_table_lookup (priv->engine_table, engine_name);
+
+ if (engine_type == G_TYPE_INVALID) {
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_FAILED,
+ "Can not create engine %s", engine_name);
+ ibus_connection_send (connection, reply_message);
+ ibus_message_unref (reply_message);
+ return TRUE;
+
+ }
+
+ path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d", ++priv->id);
+
+ engine = g_object_new (engine_type,
+ "name", engine_name,
+ "path", path,
+ "connection", priv->connection,
+ 0);
+
+ priv->engine_list = g_list_append (priv->engine_list, engine);
+ g_signal_connect (engine,
+ "destroy",
+ G_CALLBACK (_engine_destroy_cb),
+ factory);
+
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ IBUS_TYPE_OBJECT_PATH, &path,
+ G_TYPE_INVALID);
+ g_free (path);
+ ibus_connection_send (connection, reply_message);
+ ibus_message_unref (reply_message);
+ return TRUE;
+ }
+
+ return factory_parent_class->ibus_message ((IBusService *)factory,
+ connection,
+ message);
+}
+
+void
+ibus_factory_add_engine (IBusFactory *factory,
+ const gchar *engine_name,
+ GType engine_type)
+{
+ g_assert (IBUS_IS_FACTORY (factory));
+ g_assert (engine_name);
+ g_assert (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
+
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ g_hash_table_insert (priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);
+}
+
+#if 0
+IBusFactoryInfo *
+ibus_factory_get_info (IBusFactory *factory)
+{
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ return priv->info;
+}
+#endif
+
+GType
+ibus_factory_info_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusFactoryInfoClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_factory_info_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusFactoryInfo),
+ 0,
+ (GInstanceInitFunc) ibus_factory_info_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusFactoryInfo",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_factory_info_class_init (IBusFactoryInfoClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ factory_info_parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_info_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_factory_info_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_factory_info_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_factory_info_copy;
+
+ g_string_append (serializable_class->signature, "osssss");
+}
+
+static void
+ibus_factory_info_init (IBusFactoryInfo *info)
+{
+ info->path = NULL;
+ info->name = NULL;
+ info->lang = NULL;
+ info->icon = NULL;
+ info->authors = NULL;
+ info->credits = NULL;
+}
+
+static void
+ibus_factory_info_destroy (IBusFactoryInfo *info)
+{
+ g_free (info->path);
+ g_free (info->name);
+ g_free (info->lang);
+ g_free (info->icon);
+ g_free (info->authors);
+ g_free (info->credits);
+
+ info->path = NULL;
+ info->lang = NULL;
+ info->name = NULL;
+ info->icon = NULL;
+ info->authors = NULL;
+ info->credits = NULL;
+
+ IBUS_OBJECT_CLASS (factory_info_parent_class)->destroy ((IBusObject *)info);
+}
+
+static gboolean
+ibus_factory_info_serialize (IBusFactoryInfo *info,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = factory_info_parent_class->serialize ((IBusSerializable *)info, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, IBUS_TYPE_OBJECT_PATH, &info->path);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->name);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->lang);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->icon);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->authors);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->credits);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_factory_info_deserialize (IBusFactoryInfo *info,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = factory_info_parent_class->deserialize ((IBusSerializable *)info, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, IBUS_TYPE_OBJECT_PATH, &info->path);
+ g_return_val_if_fail (retval, FALSE);
+ info->path = g_strdup (info->path);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->name);
+ g_return_val_if_fail (retval, FALSE);
+ info->name = g_strdup (info->name);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->lang);
+ g_return_val_if_fail (retval, FALSE);
+ info->lang = g_strdup (info->lang);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->icon);
+ g_return_val_if_fail (retval, FALSE);
+ info->icon = g_strdup (info->icon);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->authors);
+ g_return_val_if_fail (retval, FALSE);
+ info->authors = g_strdup (info->authors);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->credits);
+ g_return_val_if_fail (retval, FALSE);
+ info->credits = g_strdup (info->credits);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_factory_info_copy (IBusFactoryInfo *dest,
+ const IBusFactoryInfo *src)
+{
+ gboolean retval;
+
+ retval = factory_info_parent_class->copy ((IBusSerializable *)dest,
+ (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_FACTORY_INFO (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_FACTORY_INFO (src), FALSE);
+
+ dest->path = g_strdup (src->path);
+ dest->name = g_strdup (src->name);
+ dest->lang = g_strdup (src->lang);
+ dest->icon = g_strdup (src->icon);
+ dest->authors = g_strdup (src->authors);
+ dest->credits = g_strdup (src->credits);
+
+ return TRUE;
+}
+
+IBusFactoryInfo *
+ibus_factory_info_new (const gchar *path,
+ const gchar *name,
+ const gchar *lang,
+ const gchar *icon,
+ const gchar *authors,
+ const gchar *credits)
+{
+ g_assert (path);
+ g_assert (name);
+ g_assert (lang);
+ g_assert (icon);
+ g_assert (authors);
+ g_assert (credits);
+
+ IBusFactoryInfo *info;
+
+ info = (IBusFactoryInfo *)g_object_new (IBUS_TYPE_FACTORY_INFO, 0);
+
+ info->path = g_strdup (path);
+ info->name = g_strdup (name);
+ info->lang = g_strdup (lang);
+ info->icon = g_strdup (icon);
+ info->authors = g_strdup (authors);
+ info->credits = g_strdup (credits);
+
+ return info;
+}
+
+
diff --git a/src/ibusfactory.h b/src/ibusfactory.h
new file mode 100644
index 0000000..02c883c
--- /dev/null
+++ b/src/ibusfactory.h
@@ -0,0 +1,120 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_FACTORY_H_
+#define __IBUS_FACTORY_H_
+
+#include <dbus/dbus.h>
+#include "ibusservice.h"
+#include "ibusserializable.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_FACTORY \
+ (ibus_factory_get_type ())
+#define IBUS_FACTORY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_FACTORY, IBusFactory))
+#define IBUS_FACTORY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_FACTORY, IBusFactoryClass))
+#define IBUS_IS_FACTORY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_FACTORY))
+#define IBUS_IS_FACTORY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_FACTORY))
+#define IBUS_FACTORY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_FACTORY, IBusFactoryClass))
+
+#define IBUS_TYPE_FACTORY_INFO \
+ (ibus_factory_info_get_type ())
+#define IBUS_FACTORY_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_FACTORY_INFO, IBusFactoryInfo))
+#define IBUS_FACTORY_INFO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_FACTORY_INFO, IBusFactoryInfoClass))
+#define IBUS_IS_FACTORY_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_FACTORY_INFO))
+#define IBUS_IS_FACTORY_INFO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_FACTORY_INFO))
+#define IBUS_FACTORY_INFO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_FACTORY_INFO, IBusFactoryInfoClass))
+
+
+G_BEGIN_DECLS
+
+typedef struct _IBusFactory IBusFactory;
+typedef struct _IBusFactoryClass IBusFactoryClass;
+typedef struct _IBusFactoryInfo IBusFactoryInfo;
+typedef struct _IBusFactoryInfoClass IBusFactoryInfoClass;
+
+struct _IBusFactory {
+ IBusService parent;
+
+ /* instance members */
+};
+
+struct _IBusFactoryClass {
+ IBusServiceClass parent;
+
+ /* signals */
+
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[8];
+};
+
+struct _IBusFactoryInfo {
+ IBusSerializable parent;
+
+ /* instance members */
+ gchar *path;
+ gchar *name;
+ gchar *lang;
+ gchar *icon;
+ gchar *authors;
+ gchar *credits;
+};
+
+struct _IBusFactoryInfoClass {
+ IBusSerializableClass parent;
+
+ /* signals */
+
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[8];
+};
+
+GType ibus_factory_get_type (void);
+IBusFactory *ibus_factory_new (IBusConnection *connection);
+void ibus_factory_add_engine (IBusFactory *factory,
+ const gchar *engine_name,
+ GType engine_type);
+IBusFactoryInfo *ibus_factory_get_info (IBusFactory *factory);
+GType ibus_factory_info_get_type (void);
+IBusFactoryInfo *ibus_factory_info_new (const gchar *path,
+ const gchar *name,
+ const gchar *lang,
+ const gchar *icon,
+ const gchar *authors,
+ const gchar *credits);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibushotkey.c b/src/ibushotkey.c
new file mode 100644
index 0000000..16aad70
--- /dev/null
+++ b/src/ibushotkey.c
@@ -0,0 +1,479 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibushotkey.h"
+#include "ibuskeysyms.h"
+#include "ibusinternal.h"
+#include "ibusshare.h"
+
+#define IBUS_HOTKEY_PROFILE_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_HOTKEY_PROFILE, IBusHotkeyProfilePrivate))
+
+enum {
+ TRIGGER,
+ LAST_SIGNAL,
+};
+
+typedef struct _IBusHotkey IBusHotkey;
+typedef struct _IBusHotkeyEvent IBusHotkeyEvent;
+typedef struct _IBusHotkeyProfilePrivate IBusHotkeyProfilePrivate;
+
+struct _IBusHotkey {
+ guint keyval;
+ guint modifiers;
+};
+
+struct _IBusHotkeyEvent {
+ GQuark event;
+ GList *hotkeys;
+};
+
+struct _IBusHotkeyProfilePrivate {
+ GTree *hotkeys;
+ GArray *events;
+ guint mask;
+};
+
+
+
+/* functions prototype */
+static IBusHotkey *ibus_hotkey_new (guint keyval,
+ guint modifiers);
+static IBusHotkey *ibus_hotkey_copy (const IBusHotkey *src);
+static void ibus_hotkey_free (IBusHotkey *hotkey);
+static gboolean ibus_hotkey_serialize (IBusHotkey *hotkey,
+ IBusMessageIter *iter);
+static gboolean ibus_hotkey_deserialize (IBusHotkey *hotkey,
+ IBusMessageIter *iter);
+
+static void ibus_hotkey_profile_class_init (IBusHotkeyProfileClass *klass);
+static void ibus_hotkey_profile_init (IBusHotkeyProfile *profile);
+static void ibus_hotkey_profile_destroy (IBusHotkeyProfile *profile);
+static gboolean ibus_hotkey_profile_serialize (IBusHotkeyProfile *profile,
+ IBusMessageIter *iter);
+static gboolean ibus_hotkey_profile_deserialize(IBusHotkeyProfile *profile,
+ IBusMessageIter *iter);
+static gboolean ibus_hotkey_profile_copy (IBusHotkeyProfile *dest,
+ const IBusHotkeyProfile*src);
+static void ibus_hotkey_profile_trigger (IBusHotkeyProfile *profile,
+ GQuark event);
+
+static IBusSerializableClass *parent_class = NULL;
+
+static guint profile_signals[LAST_SIGNAL] = { 0 };
+
+GType
+ibus_hotkey_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static ("IBusHotkey",
+ (GBoxedCopyFunc) ibus_hotkey_copy,
+ (GBoxedFreeFunc) ibus_hotkey_free);
+ }
+
+ return type;
+}
+
+static gboolean
+ibus_hotkey_serialize (IBusHotkey *hotkey,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &hotkey->keyval);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &hotkey->modifiers);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_hotkey_deserialize (IBusHotkey *hotkey,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &hotkey->keyval);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &hotkey->modifiers);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+
+static IBusHotkey *
+ibus_hotkey_new (guint keyval,
+ guint modifiers)
+{
+ IBusHotkey *hotkey = g_slice_new (IBusHotkey);
+
+ hotkey->keyval = keyval;
+ hotkey->modifiers = modifiers;
+
+ return hotkey;
+}
+
+static void
+ibus_hotkey_free (IBusHotkey *hotkey)
+{
+ g_slice_free (IBusHotkey, hotkey);
+}
+
+
+static IBusHotkey *
+ibus_hotkey_copy (const IBusHotkey *src)
+{
+ return ibus_hotkey_new (src->keyval, src->modifiers);
+}
+
+static gint
+ibus_hotkey_cmp_with_data (IBusHotkey *hotkey1,
+ IBusHotkey *hotkey2,
+ gpointer user_data)
+{
+ gint retval;
+
+ if (hotkey1 == hotkey2)
+ return 0;
+
+ retval = hotkey1->keyval - hotkey2->keyval;
+ if (retval == 0)
+ retval = hotkey1->modifiers - hotkey2->modifiers;
+
+ return retval;
+}
+
+
+
+GType
+ibus_hotkey_profile_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusHotkeyProfileClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_hotkey_profile_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusHotkeyProfile),
+ 0,
+ (GInstanceInitFunc) ibus_hotkey_profile_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusHotkeyProfile",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_hotkey_profile_class_init (IBusHotkeyProfileClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusHotkeyProfilePrivate));
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_hotkey_profile_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_hotkey_profile_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_hotkey_profile_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_hotkey_profile_copy;
+
+ klass->trigger = ibus_hotkey_profile_trigger;
+
+ g_string_append (serializable_class->signature, "av");
+
+ /* install signals */
+ profile_signals[TRIGGER] =
+ g_signal_new (I_("trigger"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ G_STRUCT_OFFSET (IBusHotkeyProfileClass, trigger),
+ NULL, NULL,
+ ibus_marshal_VOID__UINT_POINTER,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_UINT,
+ G_TYPE_POINTER);
+}
+
+static void
+ibus_hotkey_profile_init (IBusHotkeyProfile *profile)
+{
+ IBusHotkeyProfilePrivate *priv;
+ priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile);
+
+ priv->hotkeys = g_tree_new_full ((GCompareDataFunc) ibus_hotkey_cmp_with_data,
+ NULL,
+ (GDestroyNotify) ibus_hotkey_free,
+ NULL);
+ priv->events = g_array_new (TRUE, TRUE, sizeof (IBusHotkeyEvent));
+
+ priv->mask = IBUS_SHIFT_MASK |
+ IBUS_CONTROL_MASK |
+ IBUS_MOD1_MASK |
+ IBUS_RELEASE_MASK;
+}
+
+static void
+ibus_hotkey_profile_destroy (IBusHotkeyProfile *profile)
+{
+ IBusHotkeyProfilePrivate *priv;
+ priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile);
+
+ if (priv->hotkeys) {
+ g_tree_destroy (priv->hotkeys);
+ priv->hotkeys = NULL;
+ }
+
+ if (priv->events) {
+ IBusHotkeyEvent *events, *p;
+ p = events = (IBusHotkeyEvent *)g_array_free (priv->events, FALSE);
+ priv->events = NULL;
+
+ while (p->event != 0) {
+ if (p->hotkeys)
+ g_list_free (p->hotkeys);
+ p ++;
+ }
+ g_free (events);
+ }
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)profile);
+}
+
+static gboolean
+ibus_hotkey_profile_serialize (IBusHotkeyProfile *profile,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = parent_class->serialize ((IBusSerializable *) profile, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_hotkey_profile_deserialize (IBusHotkeyProfile *profile,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = parent_class->deserialize ((IBusSerializable *) profile, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_hotkey_profile_copy (IBusHotkeyProfile *dest,
+ const IBusHotkeyProfile *src)
+{
+ gboolean retval;
+
+ retval = parent_class->copy ((IBusSerializable *)dest,
+ (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_HOTKEY_PROFILE (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_HOTKEY_PROFILE (src), FALSE);
+
+ return TRUE;
+}
+
+IBusHotkeyProfile *
+ibus_hotkey_profile_new (void)
+{
+ IBusHotkeyProfile *profile = g_object_new (IBUS_TYPE_HOTKEY_PROFILE, 0);
+
+ return profile;
+}
+
+static void
+ibus_hotkey_profile_trigger (IBusHotkeyProfile *profile,
+ GQuark event)
+{
+ // g_debug ("%s is triggerred", g_quark_to_string (event));
+}
+
+gboolean
+ibus_hotkey_profile_add_hotkey (IBusHotkeyProfile *profile,
+ guint keyval,
+ guint modifiers,
+ GQuark event)
+{
+ IBusHotkeyProfilePrivate *priv;
+ priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile);
+
+ IBusHotkey *hotkey = ibus_hotkey_new (keyval, modifiers);
+
+ /* has the same hotkey in profile */
+ if (g_tree_lookup (priv->hotkeys, hotkey) != NULL) {
+ ibus_hotkey_free (hotkey);
+ g_return_val_if_reached (FALSE);
+ }
+
+ g_tree_insert (priv->hotkeys, hotkey, (gpointer)event);
+
+ gint i;
+ IBusHotkeyEvent *p = NULL;
+ for ( i = 0; i < priv->events->len; i++) {
+ p = &g_array_index (priv->events, IBusHotkeyEvent, i);
+ if (p->event == event)
+ break;
+ }
+
+ if (i >= priv->events->len) {
+ g_array_set_size (priv->events, i + 1);
+ p = &g_array_index (priv->events, IBusHotkeyEvent, i);
+ p->event = event;
+ }
+
+ p->hotkeys = g_list_append (p->hotkeys, hotkey);
+
+ return TRUE;
+}
+
+
+gboolean
+ibus_hotkey_profile_add_hotkey_from_string (IBusHotkeyProfile *profile,
+ const gchar *str,
+ GQuark event)
+{
+ guint keyval;
+ guint modifiers;
+
+ if (ibus_key_event_from_string (str, &keyval, &modifiers) == FALSE) {
+ return FALSE;
+ }
+
+ return ibus_hotkey_profile_add_hotkey (profile, keyval, modifiers, event);
+}
+
+gboolean
+ibus_hotkey_profile_remove_hotkey (IBusHotkeyProfile *profile,
+ guint keyval,
+ guint modifiers)
+{
+ IBusHotkeyProfilePrivate *priv;
+ priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile);
+
+ IBusHotkey hotkey = {
+ keyval : keyval,
+ modifiers : modifiers
+ };
+
+ IBusHotkey *p1;
+ GQuark event;
+ gboolean retval;
+
+ retval = g_tree_lookup_extended (priv->hotkeys,
+ &hotkey,
+ (gpointer)&p1,
+ (gpointer)&event);
+
+ if (!retval)
+ return FALSE;
+
+ gint i;
+ IBusHotkeyEvent *p2 = NULL;
+ for ( i = 0; i < priv->events->len; i++) {
+ p2 = &g_array_index (priv->events, IBusHotkeyEvent, i);
+ if (p2->event == event)
+ break;
+ }
+
+ g_assert (p2->event == event);
+
+ p2->hotkeys = g_list_remove (p2->hotkeys, p1);
+ if (p2->hotkeys == NULL) {
+ g_array_remove_index_fast (priv->events, i);
+ }
+
+ g_tree_remove (priv->hotkeys, p1);
+
+ return TRUE;
+}
+
+gboolean
+ibus_hotkey_profile_remove_hotkey_by_event (IBusHotkeyProfile *profile,
+ GQuark event)
+{
+ IBusHotkeyProfilePrivate *priv;
+ priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile);
+
+ gint i;
+ IBusHotkeyEvent *p = NULL;
+ for ( i = 0; i < priv->events->len; i++) {
+ p = &g_array_index (priv->events, IBusHotkeyEvent, i);
+ if (p->event == event)
+ break;
+ }
+
+ if (p == NULL || p->event != event)
+ return FALSE;
+
+ GList *list;
+ for (list = p->hotkeys; list != NULL; list = list->next) {
+ g_tree_remove (priv->hotkeys, (IBusHotkey *)list->data);
+ }
+
+ g_list_free (p->hotkeys);
+ g_array_remove_index_fast (priv->events, i);
+
+ return TRUE;
+}
+
+GQuark
+ibus_hotkey_profile_filter_key_event (IBusHotkeyProfile *profile,
+ guint keyval,
+ guint modifiers,
+ gpointer user_data)
+{
+ IBusHotkeyProfilePrivate *priv;
+ priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile);
+
+ IBusHotkey hotkey = {
+ keyval : keyval,
+ modifiers : modifiers & priv->mask,
+ };
+
+ GQuark event = (GQuark) g_tree_lookup (priv->hotkeys, &hotkey);
+
+ if (event != 0) {
+ g_signal_emit (profile, profile_signals[TRIGGER], event, event, user_data);
+ }
+
+ return event;
+}
diff --git a/src/ibushotkey.h b/src/ibushotkey.h
new file mode 100644
index 0000000..75b0844
--- /dev/null
+++ b/src/ibushotkey.h
@@ -0,0 +1,87 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_HOTKEY_H_
+#define __IBUS_HOTKEY_H_
+
+#include "ibusserializable.h"
+
+/*
+ * Type macros.
+ */
+/* define IBusHotkeyProfile macros */
+#define IBUS_TYPE_HOTKEY_PROFILE \
+ (ibus_hotkey_profile_get_type ())
+#define IBUS_HOTKEY_PROFILE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_HOTKEY_PROFILE, IBusHotkeyProfile))
+#define IBUS_HOTKEY_PROFILE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_HOTKEY_PROFILE, IBusHotkeyProfileClass))
+#define IBUS_IS_HOTKEY_PROFILE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_HOTKEY_PROFILE))
+#define IBUS_IS_HOTKEY_PROFILE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_HOTKEY_PROFILE))
+#define IBUS_HOTKEY_PROFILE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_HOTKEY_PROFILE, IBusHotkeyProfileClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusHotkeyProfile IBusHotkeyProfile;
+typedef struct _IBusHotkeyProfileClass IBusHotkeyProfileClass;
+
+struct _IBusHotkeyProfile {
+ IBusSerializable parent;
+
+ /* members */
+};
+
+struct _IBusHotkeyProfileClass {
+ IBusSerializableClass parent;
+
+ void (* trigger) (IBusHotkeyProfile *profile,
+ GQuark event);
+};
+
+/* hotkey profile functions */
+GType ibus_hotkey_profile_get_type (void);
+IBusHotkeyProfile
+ *ibus_hotkey_profile_new (void);
+gboolean ibus_hotkey_profile_add_hotkey (IBusHotkeyProfile *profile,
+ guint keyval,
+ guint modifiers,
+ GQuark event);
+gboolean ibus_hotkey_profile_add_hotkey_from_string
+ (IBusHotkeyProfile *profile,
+ const gchar *str,
+ GQuark event);
+gboolean ibus_hotkey_profile_remove_hotkey
+ (IBusHotkeyProfile *profile,
+ guint keyval,
+ guint modifiers);
+gboolean ibus_hotkey_profile_remove_hotkey_by_event
+ (IBusHotkeyProfile *profile,
+ GQuark event);
+GQuark ibus_hotkey_profile_filter_key_event
+ (IBusHotkeyProfile *profile,
+ guint keyval,
+ guint modifiers,
+ gpointer user_data);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c
new file mode 100644
index 0000000..71de8fb
--- /dev/null
+++ b/src/ibusinputcontext.c
@@ -0,0 +1,695 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibusshare.h"
+#include "ibusinternal.h"
+#include "ibusinputcontext.h"
+#include "ibusattribute.h"
+#include "ibuslookuptable.h"
+#include "ibusproperty.h"
+
+#define IBUS_INPUT_CONTEXT_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_INPUT_CONTEXT, IBusInputContextPrivate))
+
+enum {
+ ENABLED,
+ DISABLED,
+ COMMIT_TEXT,
+ FORWARD_KEY_EVENT,
+ UPDATE_PREEDIT_TEXT,
+ SHOW_PREEDIT_TEXT,
+ HIDE_PREEDIT_TEXT,
+ UPDATE_AUXILIARY_TEXT,
+ SHOW_AUXILIARY_TEXT,
+ HIDE_AUXILIARY_TEXT,
+ UPDATE_LOOKUP_TABLE,
+ SHOW_LOOKUP_TABLE,
+ HIDE_LOOKUP_TABLE,
+ PAGE_UP_LOOKUP_TABLE,
+ PAGE_DOWN_LOOKUP_TABLE,
+ CURSOR_UP_LOOKUP_TABLE,
+ CURSOR_DOWN_LOOKUP_TABLE,
+ REGISTER_PROPERTIES,
+ UPDATE_PROPERTY,
+ LAST_SIGNAL,
+};
+
+
+/* BusInputContextPriv */
+struct _IBusInputContextPrivate {
+ void *pad;
+};
+typedef struct _IBusInputContextPrivate IBusInputContextPrivate;
+
+static guint context_signals[LAST_SIGNAL] = { 0 };
+// static guint context_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_input_context_class_init (IBusInputContextClass *klass);
+static void ibus_input_context_init (IBusInputContext *context);
+static void ibus_input_context_real_destroy (IBusInputContext *context);
+static gboolean ibus_input_context_ibus_signal (IBusProxy *proxy,
+ DBusMessage *message);
+
+static IBusProxyClass *parent_class = NULL;
+
+GType
+ibus_input_context_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusInputContextClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_input_context_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusInputContext),
+ 0,
+ (GInstanceInitFunc) ibus_input_context_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_PROXY,
+ "IBusInputContext",
+ &type_info,
+ (GTypeFlags)0);
+ }
+ return type;
+}
+
+IBusInputContext *
+ibus_input_context_new (const gchar *path,
+ IBusConnection *connection)
+{
+ g_assert (path != NULL);
+ g_assert (IBUS_IS_CONNECTION (connection));
+ GObject *obj;
+
+ obj = g_object_new (IBUS_TYPE_INPUT_CONTEXT,
+ "name", IBUS_SERVICE_IBUS,
+ "path", path,
+ "connection", connection,
+ NULL);
+
+ return IBUS_INPUT_CONTEXT (obj);
+}
+
+static void
+ibus_input_context_class_init (IBusInputContextClass *klass)
+{
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+ IBusProxyClass *proxy_class = IBUS_PROXY_CLASS (klass);
+
+
+ parent_class = (IBusProxyClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusInputContextPrivate));
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_input_context_real_destroy;
+
+ proxy_class->ibus_signal = ibus_input_context_ibus_signal;
+
+ /* install signals */
+ context_signals[ENABLED] =
+ g_signal_new (I_("enabled"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[DISABLED] =
+ g_signal_new (I_("disabled"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[COMMIT_TEXT] =
+ g_signal_new (I_("commit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IBUS_TYPE_TEXT);
+
+ context_signals[FORWARD_KEY_EVENT] =
+ g_signal_new (I_("forward-key-event"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_UINT,
+ G_TYPE_UINT);
+
+ context_signals[UPDATE_PREEDIT_TEXT] =
+ g_signal_new (I_("update-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT_UINT_BOOLEAN,
+ G_TYPE_NONE,
+ 3,
+ IBUS_TYPE_TEXT,
+ G_TYPE_UINT,
+ G_TYPE_BOOLEAN);
+
+ context_signals[SHOW_PREEDIT_TEXT] =
+ g_signal_new (I_("show-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[HIDE_PREEDIT_TEXT] =
+ g_signal_new (I_("hide-preedit-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[UPDATE_AUXILIARY_TEXT] =
+ g_signal_new (I_("update-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE, 2,
+ IBUS_TYPE_TEXT,
+ G_TYPE_BOOLEAN);
+
+ context_signals[SHOW_AUXILIARY_TEXT] =
+ g_signal_new (I_("show-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[HIDE_AUXILIARY_TEXT] =
+ g_signal_new (I_("hide-auxiliary-text"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[UPDATE_LOOKUP_TABLE] =
+ g_signal_new (I_("update-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE, 2,
+ IBUS_TYPE_LOOKUP_TABLE,
+ G_TYPE_BOOLEAN);
+
+ context_signals[SHOW_LOOKUP_TABLE] =
+ g_signal_new (I_("show-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[HIDE_LOOKUP_TABLE] =
+ g_signal_new (I_("hide-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[PAGE_UP_LOOKUP_TABLE] =
+ g_signal_new (I_("page-up-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[PAGE_DOWN_LOOKUP_TABLE] =
+ g_signal_new (I_("page-down-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[CURSOR_UP_LOOKUP_TABLE] =
+ g_signal_new (I_("cursor-up-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ context_signals[CURSOR_DOWN_LOOKUP_TABLE] =
+ g_signal_new (I_("cursor-down-lookup-table"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ context_signals[REGISTER_PROPERTIES] =
+ g_signal_new (I_("register-properties"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IBUS_TYPE_PROP_LIST);
+
+ context_signals[UPDATE_PROPERTY] =
+ g_signal_new (I_("update-property"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IBUS_TYPE_PROPERTY);
+}
+
+static void
+ibus_input_context_init (IBusInputContext *context)
+{
+ IBusInputContextPrivate *priv;
+ priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
+}
+
+static void
+ibus_input_context_real_destroy (IBusInputContext *context)
+{
+ if (ibus_proxy_get_connection ((IBusProxy *) context) != NULL) {
+ ibus_proxy_call (IBUS_PROXY (context),
+ "Destroy",
+ G_TYPE_INVALID);
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (context));
+}
+
+static gboolean
+ibus_input_context_ibus_signal (IBusProxy *proxy,
+ IBusMessage *message)
+{
+ g_assert (IBUS_IS_INPUT_CONTEXT (proxy));
+ g_assert (message != NULL);
+
+ IBusInputContext *context;
+ IBusError *error = NULL;
+ gint i;
+
+ context = IBUS_INPUT_CONTEXT (proxy);
+
+ static const struct {
+ const gchar *member;
+ guint signal_id;
+ } signals [] = {
+ { "Enabled", ENABLED },
+ { "Disabled", DISABLED },
+ { "ShowPreeditText", SHOW_PREEDIT_TEXT },
+ { "HidePreeditText", HIDE_PREEDIT_TEXT },
+ { "ShowAuxiliaryText", SHOW_AUXILIARY_TEXT },
+ { "HideAuxiliaryText", HIDE_AUXILIARY_TEXT },
+ { "ShowLookupTable", SHOW_LOOKUP_TABLE },
+ { "HideLookupTable", HIDE_LOOKUP_TABLE },
+ { "PageUpLookupTable", PAGE_UP_LOOKUP_TABLE },
+ { "PageDownLookupTable", PAGE_DOWN_LOOKUP_TABLE },
+ { "CursorUpLookupTable", CURSOR_UP_LOOKUP_TABLE },
+ { "CursorDownLookupTable", CURSOR_DOWN_LOOKUP_TABLE},
+ { NULL, 0},
+ };
+
+ for (i = 0; ; i++) {
+ if (signals[i].member == NULL)
+ break;
+ if (ibus_message_is_signal (message,
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ signals[i].member)) {
+ g_signal_emit (context, context_signals[signals[i].signal_id], 0);
+ goto handled;
+ }
+ }
+
+ if (ibus_message_is_signal (message,
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ "CommitText")) {
+ IBusText *text;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_INVALID);
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (context, context_signals[COMMIT_TEXT], 0, text);
+ g_object_unref (text);
+ }
+ else if (ibus_message_is_signal (message,
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ "UpdatePreeditText")) {
+ IBusText *text;
+ gint32 cursor_pos;
+ gboolean visible;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_UINT, &cursor_pos,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (context,
+ context_signals[UPDATE_PREEDIT_TEXT],
+ 0,
+ text,
+ cursor_pos,
+ visible);
+ g_object_unref (text);
+ }
+ else if (ibus_message_is_signal (message,
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ "ForwardKeyEvent")) {
+ guint32 keyval;
+ gboolean is_press;
+ guint32 state;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_UINT, &keyval,
+ G_TYPE_BOOLEAN, &is_press,
+ G_TYPE_UINT, &state,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+ g_signal_emit (context,
+ context_signals[FORWARD_KEY_EVENT],
+ 0,
+ keyval,
+ state | IBUS_FORWARD_MASK);
+ }
+ else if (ibus_message_is_signal (message,
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ "UpdateAuxiliaryText")) {
+ IBusText *text;
+ gboolean visible;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_TEXT, &text,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (context,
+ context_signals[UPDATE_AUXILIARY_TEXT],
+ 0,
+ text,
+ visible);
+ g_object_unref (text);
+ }
+ else if (ibus_message_is_signal (message,
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ "UpdateLookupTable")) {
+ IBusLookupTable *table;
+ gboolean visible;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_LOOKUP_TABLE, &table,
+ G_TYPE_BOOLEAN, &visible,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (context,
+ context_signals[UPDATE_LOOKUP_TABLE],
+ 0,
+ table,
+ visible);
+ g_object_unref (table);
+ }
+ else if (ibus_message_is_signal (message,
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ "RegisterProperties")) {
+ IBusPropList *prop_list;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_PROP_LIST, &prop_list,
+ G_TYPE_INVALID);
+
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (context,
+ context_signals[REGISTER_PROPERTIES],
+ 0,
+ prop_list);
+ g_object_unref (prop_list);
+ }
+ else if (ibus_message_is_signal (message,
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ "UpdateProperty")) {
+ IBusProperty *prop;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_PROPERTY, &prop,
+ G_TYPE_INVALID);
+ if (!retval)
+ goto failed;
+
+ g_signal_emit (context, context_signals[UPDATE_PROPERTY], 0, prop);
+ g_object_unref (prop);
+ }
+ else {
+ return FALSE;
+ }
+
+handled:
+ g_signal_stop_emission_by_name (context, "ibus-signal");
+ return TRUE;
+
+failed:
+ if (error) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ }
+ return FALSE;
+}
+
+gboolean
+ibus_input_context_process_key_event (IBusInputContext *context,
+ guint32 keyval,
+ guint32 state)
+{
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+ IBusMessage *reply_message;
+ IBusPendingCall *pending = NULL;
+ IBusError *error = NULL;
+ gboolean retval;
+
+ if (state & IBUS_FORWARD_MASK)
+ return FALSE;
+
+ retval = ibus_proxy_call_with_reply ((IBusProxy *) context,
+ "ProcessKeyEvent",
+ &pending,
+ -1,
+ &error,
+ G_TYPE_UINT, &keyval,
+ G_TYPE_UINT, &state,
+ G_TYPE_INVALID);
+ if (!retval) {
+ g_debug ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ return FALSE;
+ }
+
+ /* wait reply or timeout */
+ ibus_pending_call_wait (pending);
+
+ reply_message = ibus_pending_call_steal_reply (pending);
+ ibus_pending_call_unref (pending);
+
+ if (reply_message == NULL) {
+ g_debug ("%s: Do not recevie reply of ProcessKeyEvent", DBUS_ERROR_NO_REPLY);
+ retval = FALSE;
+ }
+ else if ((error = ibus_error_new_from_message (reply_message)) != NULL) {
+ g_debug ("%s: %s", error->name, error->message);
+ ibus_message_unref (reply_message);
+ ibus_error_free (error);
+ retval = FALSE;
+ }
+ else {
+
+ if (!ibus_message_get_args (reply_message,
+ &error,
+ G_TYPE_BOOLEAN, &retval,
+ G_TYPE_INVALID)) {
+ g_debug ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ retval = FALSE;
+ }
+ ibus_message_unref (reply_message);
+ }
+ return retval;
+}
+
+void
+ibus_input_context_set_cursor_location (IBusInputContext *context,
+ gint32 x,
+ gint32 y,
+ gint32 w,
+ gint32 h)
+{
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+ ibus_proxy_call ((IBusProxy *) context,
+ "SetCursorLocation",
+ G_TYPE_INT, &x,
+ G_TYPE_INT, &y,
+ G_TYPE_INT, &w,
+ G_TYPE_INT, &h,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_input_context_set_capabilities (IBusInputContext *context,
+ guint32 capabilites)
+{
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+ ibus_proxy_call ((IBusProxy *) context,
+ "SetCapabilities",
+ G_TYPE_UINT, &capabilites,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_input_context_property_activate (IBusInputContext *context,
+ const gchar *prop_name,
+ gint32 state)
+{
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+ ibus_proxy_call ((IBusProxy *) context,
+ "PropertyActivate",
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_INT, &state,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_input_context_property_show (IBusInputContext *context,
+ const gchar *prop_name)
+{
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+ ibus_proxy_call ((IBusProxy *) context,
+ "PropertyShow",
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_INVALID);
+}
+
+void
+ibus_input_context_property_hide (IBusInputContext *context,
+ const gchar *prop_name)
+{
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+ ibus_proxy_call ((IBusProxy *) context,
+ "PropertyHide",
+ G_TYPE_STRING, &prop_name,
+ G_TYPE_INVALID);
+}
+
+#define DEFINE_FUNC(name,Name) \
+ void \
+ ibus_input_context_##name (IBusInputContext *context) \
+ { \
+ g_assert (IBUS_IS_INPUT_CONTEXT (context)); \
+ ibus_proxy_call ((IBusProxy *) context, \
+ #Name, \
+ G_TYPE_INVALID); \
+ }
+
+DEFINE_FUNC(focus_in, FocusIn);
+DEFINE_FUNC(focus_out, FocusOut);
+DEFINE_FUNC(reset, Reset);
+DEFINE_FUNC(page_up, PageUp);
+DEFINE_FUNC(page_down, PageDown);
+DEFINE_FUNC(cursor_up, CursorUp);
+DEFINE_FUNC(cursor_down, CursorDown);
+DEFINE_FUNC(enable, Enable);
+DEFINE_FUNC(disable, Disable);
+
+#undef DEFINE_FUNC
+
diff --git a/src/ibusinputcontext.h b/src/ibusinputcontext.h
new file mode 100644
index 0000000..3ec1bf9
--- /dev/null
+++ b/src/ibusinputcontext.h
@@ -0,0 +1,87 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_INPUT_CONTEXT_H_
+#define __IBUS_INPUT_CONTEXT_H_
+
+#include "ibusproxy.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_INPUT_CONTEXT \
+ (ibus_input_context_get_type ())
+#define IBUS_INPUT_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_INPUT_CONTEXT, IBusInputContext))
+#define IBUS_INPUT_CONTEXT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_INPUT_CONTEXT, IBusInputContextClass))
+#define IBUS_IS_INPUT_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_INPUT_CONTEXT))
+#define IBUS_IS_INPUT_CONTEXT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_INPUT_CONTEXT))
+#define IBUS_INPUT_CONTEXT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_INPUT_CONTEXT, IBusInputContextClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusInputContext IBusInputContext;
+typedef struct _IBusInputContextClass IBusInputContextClass;
+
+struct _IBusInputContext {
+ IBusProxy parent;
+ /* instance members */
+};
+
+struct _IBusInputContextClass {
+ IBusProxyClass parent;
+ /* signals */
+
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[24];
+};
+
+GType ibus_input_context_get_type (void);
+IBusInputContext
+ *ibus_input_context_new (const gchar *path,
+ IBusConnection *connection);
+gboolean ibus_input_context_process_key_event
+ (IBusInputContext *context,
+ guint32 keyval,
+ guint32 state);
+void ibus_input_context_set_cursor_location
+ (IBusInputContext *context,
+ gint32 x,
+ gint32 y,
+ gint32 w,
+ gint32 h);
+void ibus_input_context_set_capabilities
+ (IBusInputContext *context,
+ guint32 capabilites);
+void ibus_input_context_focus_in (IBusInputContext *context);
+void ibus_input_context_focus_out (IBusInputContext *context);
+void ibus_input_context_reset (IBusInputContext *context);
+void ibus_input_context_enable (IBusInputContext *context);
+void ibus_input_context_disable (IBusInputContext *context);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusinternal.c b/src/ibusinternal.c
new file mode 100644
index 0000000..3610b52
--- /dev/null
+++ b/src/ibusinternal.c
@@ -0,0 +1,667 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-gmain.c GLib main loop integration
+ *
+ * Copyright (C) 2002, 2003 CodeFactory AB
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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
+ *
+ */
+
+#include "ibusinternal.h"
+
+/**
+ * IBusMessageQueue:
+ * A GSource subclass for dispatching DBusConnection messages.
+ * We need this on top of the IO handlers, because sometimes
+ * there are messages to dispatch queued up but no IO pending.
+ */
+typedef struct
+{
+ GSource source; /**< the parent GSource */
+ DBusConnection *connection; /**< the connection to dispatch */
+} IBusMessageQueue;
+
+static gboolean message_queue_prepare (GSource *source,
+ gint *timeout);
+static gboolean message_queue_check (GSource *source);
+static gboolean message_queue_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data);
+
+static const GSourceFuncs message_queue_funcs = {
+ message_queue_prepare,
+ message_queue_check,
+ message_queue_dispatch,
+ NULL
+};
+
+static gboolean
+message_queue_prepare (GSource *source,
+ gint *timeout)
+{
+ DBusConnection *connection = ((IBusMessageQueue *)source)->connection;
+
+ *timeout = -1;
+
+ return (dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_DATA_REMAINS);
+}
+
+static gboolean
+message_queue_check (GSource *source)
+{
+ return FALSE;
+}
+
+static gboolean
+message_queue_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ DBusConnection *connection = ((IBusMessageQueue *)source)->connection;
+
+ dbus_connection_ref (connection);
+
+ /* Only dispatch once - we don't want to starve other GSource */
+ dbus_connection_dispatch (connection);
+
+ dbus_connection_unref (connection);
+
+ return TRUE;
+}
+
+typedef struct
+{
+ GMainContext *context; /**< the main context */
+ GSList *ios; /**< all IOHandler */
+ GSList *timeouts; /**< all TimeoutHandler */
+ DBusConnection *connection; /**< NULL if this is really for a server not a connection */
+ GSource *message_queue_source; /**< IBusMessageQueue */
+} ConnectionSetup;
+
+
+typedef struct
+{
+ ConnectionSetup *cs;
+ GSource *source;
+ DBusWatch *watch;
+} IOHandler;
+
+typedef struct
+{
+ ConnectionSetup *cs;
+ GSource *source;
+ DBusTimeout *timeout;
+} TimeoutHandler;
+
+dbus_int32_t _dbus_gmain_connection_slot = -1;
+static dbus_int32_t server_slot = -1;
+
+static ConnectionSetup*
+connection_setup_new (GMainContext *context,
+ DBusConnection *connection)
+{
+ ConnectionSetup *cs;
+
+ cs = g_new0 (ConnectionSetup, 1);
+
+ g_assert (context != NULL);
+
+ cs->context = context;
+ g_main_context_ref (cs->context);
+
+ if (connection)
+ {
+ cs->connection = connection;
+
+ cs->message_queue_source = g_source_new ((GSourceFuncs *) &message_queue_funcs,
+ sizeof (IBusMessageQueue));
+ ((IBusMessageQueue*)cs->message_queue_source)->connection = connection;
+ g_source_attach (cs->message_queue_source, cs->context);
+ }
+
+ return cs;
+}
+
+static void
+io_handler_source_finalized (gpointer data)
+{
+ IOHandler *handler;
+
+ handler = data;
+
+ if (handler->watch)
+ dbus_watch_set_data (handler->watch, NULL, NULL);
+
+ g_free (handler);
+}
+
+static void
+io_handler_destroy_source (void *data)
+{
+ IOHandler *handler;
+
+ handler = data;
+
+ if (handler->source)
+ {
+ GSource *source = handler->source;
+ handler->source = NULL;
+ handler->cs->ios = g_slist_remove (handler->cs->ios, handler);
+ g_source_destroy (source);
+ g_source_unref (source);
+ }
+}
+
+static void
+io_handler_watch_freed (void *data)
+{
+ IOHandler *handler;
+
+ handler = data;
+
+ handler->watch = NULL;
+
+ io_handler_destroy_source (handler);
+}
+
+static gboolean
+io_handler_dispatch (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data)
+{
+ IOHandler *handler;
+ guint dbus_condition = 0;
+ DBusConnection *connection;
+
+ handler = data;
+
+ connection = handler->cs->connection;
+
+ if (connection)
+ dbus_connection_ref (connection);
+
+ if (condition & G_IO_IN)
+ dbus_condition |= DBUS_WATCH_READABLE;
+ if (condition & G_IO_OUT)
+ dbus_condition |= DBUS_WATCH_WRITABLE;
+ if (condition & G_IO_ERR)
+ dbus_condition |= DBUS_WATCH_ERROR;
+ if (condition & G_IO_HUP)
+ dbus_condition |= DBUS_WATCH_HANGUP;
+
+ /* Note that we don't touch the handler after this, because
+ * dbus may have disabled the watch and thus killed the
+ * handler.
+ */
+ dbus_watch_handle (handler->watch, dbus_condition);
+ handler = NULL;
+
+ if (connection)
+ dbus_connection_unref (connection);
+
+ return TRUE;
+}
+
+static void
+connection_setup_add_watch (ConnectionSetup *cs,
+ DBusWatch *watch)
+{
+ guint flags;
+ GIOCondition condition;
+ GIOChannel *channel;
+ IOHandler *handler;
+
+ if (!dbus_watch_get_enabled (watch))
+ return;
+
+ g_assert (dbus_watch_get_data (watch) == NULL);
+
+ flags = dbus_watch_get_flags (watch);
+
+ condition = G_IO_ERR | G_IO_HUP;
+ if (flags & DBUS_WATCH_READABLE)
+ condition |= G_IO_IN;
+ if (flags & DBUS_WATCH_WRITABLE)
+ condition |= G_IO_OUT;
+
+ handler = g_new0 (IOHandler, 1);
+ handler->cs = cs;
+ handler->watch = watch;
+
+ channel = g_io_channel_unix_new (dbus_watch_get_unix_fd (watch));
+
+ handler->source = g_io_create_watch (channel, condition);
+ g_source_set_callback (handler->source, (GSourceFunc) io_handler_dispatch, handler,
+ io_handler_source_finalized);
+ g_source_attach (handler->source, cs->context);
+
+ cs->ios = g_slist_prepend (cs->ios, handler);
+
+ dbus_watch_set_data (watch, handler, io_handler_watch_freed);
+ g_io_channel_unref (channel);
+}
+
+static void
+connection_setup_remove_watch (ConnectionSetup *cs,
+ DBusWatch *watch)
+{
+ IOHandler *handler;
+
+ handler = dbus_watch_get_data (watch);
+
+ if (handler == NULL)
+ return;
+
+ io_handler_destroy_source (handler);
+}
+
+static void
+timeout_handler_source_finalized (gpointer data)
+{
+ TimeoutHandler *handler;
+
+ handler = data;
+
+ if (handler->timeout)
+ dbus_timeout_set_data (handler->timeout, NULL, NULL);
+
+ g_free (handler);
+}
+
+static void
+timeout_handler_destroy_source (void *data)
+{
+ TimeoutHandler *handler;
+
+ handler = data;
+
+ if (handler->source)
+ {
+ GSource *source = handler->source;
+ handler->source = NULL;
+ handler->cs->timeouts = g_slist_remove (handler->cs->timeouts, handler);
+ g_source_destroy (source);
+ g_source_unref (source);
+ }
+}
+
+static void
+timeout_handler_timeout_freed (void *data)
+{
+ TimeoutHandler *handler;
+
+ handler = data;
+
+ handler->timeout = NULL;
+
+ timeout_handler_destroy_source (handler);
+}
+
+static gboolean
+timeout_handler_dispatch (gpointer data)
+{
+ TimeoutHandler *handler;
+
+ handler = data;
+
+ dbus_timeout_handle (handler->timeout);
+
+ return TRUE;
+}
+
+static void
+connection_setup_add_timeout (ConnectionSetup *cs,
+ DBusTimeout *timeout)
+{
+ TimeoutHandler *handler;
+
+ if (!dbus_timeout_get_enabled (timeout))
+ return;
+
+ g_assert (dbus_timeout_get_data (timeout) == NULL);
+
+ handler = g_new0 (TimeoutHandler, 1);
+ handler->cs = cs;
+ handler->timeout = timeout;
+
+ handler->source = g_timeout_source_new (dbus_timeout_get_interval (timeout));
+ g_source_set_callback (handler->source, timeout_handler_dispatch, handler,
+ timeout_handler_source_finalized);
+ g_source_attach (handler->source, handler->cs->context);
+
+ cs->timeouts = g_slist_prepend (cs->timeouts, handler);
+
+ dbus_timeout_set_data (timeout, handler, timeout_handler_timeout_freed);
+}
+
+static void
+connection_setup_remove_timeout (ConnectionSetup *cs,
+ DBusTimeout *timeout)
+{
+ TimeoutHandler *handler;
+
+ handler = dbus_timeout_get_data (timeout);
+
+ if (handler == NULL)
+ return;
+
+ timeout_handler_destroy_source (handler);
+}
+
+static void
+connection_setup_free (ConnectionSetup *cs)
+{
+ while (cs->ios)
+ io_handler_destroy_source (cs->ios->data);
+
+ while (cs->timeouts)
+ timeout_handler_destroy_source (cs->timeouts->data);
+
+ if (cs->message_queue_source)
+ {
+ GSource *source;
+
+ source = cs->message_queue_source;
+ cs->message_queue_source = NULL;
+
+ g_source_destroy (source);
+ g_source_unref (source);
+ }
+
+ g_main_context_unref (cs->context);
+ g_free (cs);
+}
+
+static dbus_bool_t
+add_watch (DBusWatch *watch,
+ gpointer data)
+{
+ ConnectionSetup *cs;
+
+ cs = data;
+
+ connection_setup_add_watch (cs, watch);
+
+ return TRUE;
+}
+
+static void
+remove_watch (DBusWatch *watch,
+ gpointer data)
+{
+ ConnectionSetup *cs;
+
+ cs = data;
+
+ connection_setup_remove_watch (cs, watch);
+}
+
+static void
+watch_toggled (DBusWatch *watch,
+ void *data)
+{
+ /* Because we just exit on OOM, enable/disable is
+ * no different from add/remove
+ */
+ if (dbus_watch_get_enabled (watch))
+ add_watch (watch, data);
+ else
+ remove_watch (watch, data);
+}
+
+static dbus_bool_t
+add_timeout (DBusTimeout *timeout,
+ void *data)
+{
+ ConnectionSetup *cs;
+
+ cs = data;
+
+ if (!dbus_timeout_get_enabled (timeout))
+ return TRUE;
+
+ connection_setup_add_timeout (cs, timeout);
+
+ return TRUE;
+}
+
+static void
+remove_timeout (DBusTimeout *timeout,
+ void *data)
+{
+ ConnectionSetup *cs;
+
+ cs = data;
+
+ connection_setup_remove_timeout (cs, timeout);
+}
+
+static void
+timeout_toggled (DBusTimeout *timeout,
+ void *data)
+{
+ /* Because we just exit on OOM, enable/disable is
+ * no different from add/remove
+ */
+ if (dbus_timeout_get_enabled (timeout))
+ add_timeout (timeout, data);
+ else
+ remove_timeout (timeout, data);
+}
+
+static void
+wakeup_main (void *data)
+{
+ ConnectionSetup *cs = data;
+
+ g_main_context_wakeup (cs->context);
+}
+
+
+/* Move to a new context */
+static ConnectionSetup*
+connection_setup_new_from_old (GMainContext *context,
+ ConnectionSetup *old)
+{
+ GSList *tmp;
+ ConnectionSetup *cs;
+
+ g_assert (old->context != context);
+
+ cs = connection_setup_new (context, old->connection);
+
+ tmp = old->ios;
+ while (tmp != NULL)
+ {
+ IOHandler *handler = tmp->data;
+
+ connection_setup_add_watch (cs, handler->watch);
+
+ tmp = tmp->next;
+ }
+
+ tmp = old->timeouts;
+ while (tmp != NULL)
+ {
+ TimeoutHandler *handler = tmp->data;
+
+ connection_setup_add_timeout (cs, handler->timeout);
+
+ tmp = tmp->next;
+ }
+
+ return cs;
+}
+
+/** @} */ /* End of GLib bindings internals */
+
+/** @addtogroup IBusLib
+ * @{
+ */
+
+/**
+ * dbus_connection_setup_with_g_main:
+ * @connection: the connection
+ * @context: the #GMainContext or #NULL for default context
+ *
+ * Sets the watch and timeout functions of a #DBusConnection
+ * to integrate the connection with the GLib main loop.
+ * Pass in #NULL for the #GMainContext unless you're
+ * doing something specialized.
+ *
+ * If called twice for the same context, does nothing the second
+ * time. If called once with context A and once with context B,
+ * context B replaces context A as the context monitoring the
+ * connection.
+ */
+void
+dbus_connection_setup (DBusConnection *connection,
+ GMainContext *context)
+{
+ ConnectionSetup *old_setup;
+ ConnectionSetup *cs;
+
+ /* FIXME we never free the slot, so its refcount just keeps growing,
+ * which is kind of broken.
+ */
+ dbus_connection_allocate_data_slot (&_dbus_gmain_connection_slot);
+ if (_dbus_gmain_connection_slot < 0)
+ goto nomem;
+
+ if (context == NULL)
+ context = g_main_context_default ();
+
+ cs = NULL;
+
+ old_setup = dbus_connection_get_data (connection, _dbus_gmain_connection_slot);
+ if (old_setup != NULL)
+ {
+ if (old_setup->context == context)
+ return; /* nothing to do */
+
+ cs = connection_setup_new_from_old (context, old_setup);
+
+ /* Nuke the old setup */
+ dbus_connection_set_data (connection, _dbus_gmain_connection_slot, NULL, NULL);
+ old_setup = NULL;
+ }
+
+ if (cs == NULL)
+ cs = connection_setup_new (context, connection);
+
+ if (!dbus_connection_set_data (connection, _dbus_gmain_connection_slot, cs,
+ (DBusFreeFunction)connection_setup_free))
+ goto nomem;
+
+ if (!dbus_connection_set_watch_functions (connection,
+ add_watch,
+ remove_watch,
+ watch_toggled,
+ cs, NULL))
+ goto nomem;
+
+ if (!dbus_connection_set_timeout_functions (connection,
+ add_timeout,
+ remove_timeout,
+ timeout_toggled,
+ cs, NULL))
+ goto nomem;
+
+ dbus_connection_set_wakeup_main_function (connection,
+ wakeup_main,
+ cs, NULL);
+
+ return;
+
+ nomem:
+ g_error ("Not enough memory to set up DBusConnection for use with GLib");
+}
+
+/**
+ * dbus_server_setup_with_g_main:
+ * @server: the server
+ * @context: the #GMainContext or #NULL for default
+ *
+ * Sets the watch and timeout functions of a #DBusServer
+ * to integrate the server with the GLib main loop.
+ * In most cases the context argument should be #NULL.
+ *
+ * If called twice for the same context, does nothing the second
+ * time. If called once with context A and once with context B,
+ * context B replaces context A as the context monitoring the
+ * connection.
+ */
+void
+dbus_server_setup (DBusServer *server,
+ GMainContext *context)
+{
+ ConnectionSetup *old_setup;
+ ConnectionSetup *cs;
+
+ /* FIXME we never free the slot, so its refcount just keeps growing,
+ * which is kind of broken.
+ */
+ dbus_server_allocate_data_slot (&server_slot);
+ if (server_slot < 0)
+ goto nomem;
+
+ if (context == NULL)
+ context = g_main_context_default ();
+
+ cs = NULL;
+
+ old_setup = dbus_server_get_data (server, server_slot);
+ if (old_setup != NULL)
+ {
+ if (old_setup->context == context)
+ return; /* nothing to do */
+
+ cs = connection_setup_new_from_old (context, old_setup);
+
+ /* Nuke the old setup */
+ dbus_server_set_data (server, server_slot, NULL, NULL);
+ old_setup = NULL;
+ }
+
+ if (cs == NULL)
+ cs = connection_setup_new (context, NULL);
+
+ if (!dbus_server_set_data (server, server_slot, cs,
+ (DBusFreeFunction)connection_setup_free))
+ goto nomem;
+
+ if (!dbus_server_set_watch_functions (server,
+ add_watch,
+ remove_watch,
+ watch_toggled,
+ cs, NULL))
+ goto nomem;
+
+ if (!dbus_server_set_timeout_functions (server,
+ add_timeout,
+ remove_timeout,
+ timeout_toggled,
+ cs, NULL))
+ goto nomem;
+
+ return;
+
+ nomem:
+ g_error ("Not enough memory to set up DBusServer for use with GLib");
+}
+
diff --git a/src/ibusinternal.h b/src/ibusinternal.h
new file mode 100644
index 0000000..924d96e
--- /dev/null
+++ b/src/ibusinternal.h
@@ -0,0 +1,36 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_INTERNEL_H_
+#define __IBUS_INTERNEL_H_
+
+#include <glib.h>
+#include <dbus/dbus.h>
+
+#define I_(string) g_intern_static_string (string)
+
+void dbus_server_setup (DBusServer *server,
+ GMainContext *context);
+void dbus_connection_setup (DBusConnection *connection,
+ GMainContext *context);
+
+
+
+#endif
+
diff --git a/src/ibuskeynames.c b/src/ibuskeynames.c
new file mode 100644
index 0000000..9a8c1e4
--- /dev/null
+++ b/src/ibuskeynames.c
@@ -0,0 +1,199 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/* Key handling not part of the keymap */
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ibuskeysyms.h"
+#include "keyname-table.h"
+
+#define IBUS_NUM_KEYS G_N_ELEMENTS (gdk_keys_by_keyval)
+
+static int
+gdk_keys_keyval_compare (const void *pkey, const void *pbase)
+{
+ return (*(int *) pkey) - ((gdk_key *) pbase)->keyval;
+}
+
+const gchar*
+ibus_keyval_name (guint keyval)
+{
+ static gchar buf[100];
+ gdk_key *found;
+
+ /* Check for directly encoded 24-bit UCS characters: */
+ if ((keyval & 0xff000000) == 0x01000000)
+ {
+ g_sprintf (buf, "U+%.04X", (keyval & 0x00ffffff));
+ return buf;
+ }
+
+ found = bsearch (&keyval, gdk_keys_by_keyval,
+ IBUS_NUM_KEYS, sizeof (gdk_key),
+ gdk_keys_keyval_compare);
+
+ if (found != NULL)
+ {
+ while ((found > gdk_keys_by_keyval) &&
+ ((found - 1)->keyval == keyval))
+ found--;
+
+ return (gchar *) (keynames + found->offset);
+ }
+ else if (keyval != 0)
+ {
+ g_sprintf (buf, "%#x", keyval);
+ return buf;
+ }
+
+ return NULL;
+}
+
+static int
+gdk_keys_name_compare (const void *pkey, const void *pbase)
+{
+ return strcmp ((const char *) pkey,
+ (const char *) (keynames + ((const gdk_key *) pbase)->offset));
+}
+
+guint
+ibus_keyval_from_name (const gchar *keyval_name)
+{
+ gdk_key *found;
+
+ g_return_val_if_fail (keyval_name != NULL, 0);
+
+ found = bsearch (keyval_name, gdk_keys_by_name,
+ IBUS_NUM_KEYS, sizeof (gdk_key),
+ gdk_keys_name_compare);
+ if (found != NULL)
+ return found->keyval;
+ else
+ return IBUS_VoidSymbol;
+}
+
+static const gchar *
+modifier_name[] = {
+ "Shift",
+ "Lock",
+ "Control",
+ "Alt",
+ "Mod2",
+ "Mod3",
+ "Mod4",
+ "Mod5",
+ "Button1",
+ "Button2",
+ "Button3",
+ "Button4",
+ "Button5",
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ "Supper",
+ "Hyper",
+ "Meta",
+ NULL,
+ "Release",
+ NULL,
+ NULL,
+};
+
+const gchar *
+ibus_key_event_to_string (guint keyval,
+ guint modifiers)
+{
+ guint i;
+ GString *str;
+ const gchar *keyval_name;
+
+ g_return_val_if_fail (keyval != IBUS_VoidSymbol, NULL);
+
+ keyval_name = ibus_keyval_name (keyval);
+ g_return_val_if_fail (keyval_name != NULL, NULL);
+
+ str = g_string_new ("");
+
+ for (i = 0; i < 32; i++) {
+ guint mask = 1 << i;
+
+ if ((modifiers & mask) == 0)
+ continue;
+ if (modifier_name[i] == NULL)
+ continue;
+
+ g_string_append (str, modifier_name[i]);
+ g_string_append_c (str, '+');
+ }
+
+ g_string_append (str, keyval_name);
+
+ return g_string_free (str, FALSE);
+}
+
+gboolean
+ibus_key_event_from_string (const gchar *string,
+ guint *keyval,
+ guint *modifiers)
+{
+ g_return_val_if_fail (string != NULL, FALSE);
+ g_return_val_if_fail (keyval != NULL, FALSE);
+ g_return_val_if_fail (modifiers != NULL, FALSE);
+
+ gchar **tokens = NULL;
+ gchar **p;
+ gboolean retval = FALSE;
+
+ tokens = g_strsplit (string, "+", 0);
+ g_return_val_if_fail (tokens != NULL, FALSE);
+
+ *keyval = 0;
+ *modifiers = 0;
+
+ for (p = tokens; *(p + 1) != NULL; p++) {
+ gint i;
+ for (i = 0; i < 32; i++) {
+ if (g_strcmp0 (modifier_name[i], *p) != 0)
+ continue;
+ *modifiers |= (1 << i);
+ break;
+ }
+ if (i == 32) {
+ goto _out;
+ }
+ }
+
+ *keyval = ibus_keyval_from_name (*p);
+ if (*keyval != IBUS_VoidSymbol)
+ retval = TRUE;
+_out:
+ if (tokens)
+ g_strfreev (tokens);
+ return retval;
+}
+
diff --git a/src/ibuskeysyms-update.pl b/src/ibuskeysyms-update.pl
new file mode 100755
index 0000000..4fd426d
--- /dev/null
+++ b/src/ibuskeysyms-update.pl
@@ -0,0 +1,105 @@
+#!/usr/bin/env perl
+
+# Updates http://svn.gnome.org/viewcvs/gtk%2B/trunk/gdk/gdkkeysyms.h?view=log from upstream (X.org 7.x),
+# from http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=keysymdef.h
+#
+# Author : Simos Xenitellis <simos at gnome dot org>.
+# Version : 1.2
+#
+# Input : http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=keysymdef.h
+# Output : http://svn.gnome.org/svn/gtk+/trunk/gdk/gdkkeysyms.h
+#
+# Notes : It downloads keysymdef.h from the Internet, if not found locally,
+# Notes : and creates an updated gdkkeysyms.h
+# Notes : This version updates the source of gdkkeysyms.h from CVS to the GIT server.
+
+use strict;
+
+# Used for reading the keysymdef symbols.
+my @keysymelements;
+
+if ( ! -f "keysymdef.h" )
+{
+ print "Trying to download keysymdef.h from\n";
+ print "http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=keysymdef.h\n";
+ die "Unable to download keysymdef.h from http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=keysymdef.h\n"
+ unless system("wget -c -O keysymdef.h \"http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=keysymdef.h\"") == 0;
+ print " done.\n\n";
+}
+else
+{
+ print "We are using existing keysymdef.h found in this directory.\n";
+ print "It is assumed that you took care and it is a recent version\n";
+ print "as found at http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob;f=keysymdef.h\n\n";
+}
+
+
+if ( -f "ibuskeysyms.h" )
+{
+ print "There is already a ibuskeysyms.h file in this directory. We are not overwriting it.\n";
+ print "Please move it somewhere else in order to run this script.\n";
+ die "Exiting...\n\n";
+}
+
+# Source: http://cvs.freedesktop.org/xorg/xc/include/keysymdef.h
+die "Could not open file keysymdef.h: $!\n" unless open(IN_KEYSYMDEF, "<:utf8", "keysymdef.h");
+
+# Output: gtk+/gdk/gdkkeysyms.h
+die "Could not open file ibuskeysyms.h: $!\n" unless open(OUT_IBUSKEYSYMS, ">:utf8", "ibuskeysyms.h");
+
+print OUT_IBUSKEYSYMS<<EOF;
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __IBUS_KEYSYMS_H__
+#define __IBUS_KEYSYMS_H__
+
+
+EOF
+
+
+while (<IN_KEYSYMDEF>)
+{
+ next if ( ! /^#define / );
+
+ @keysymelements = split(/\s+/);
+ die "Internal error, no \@keysymelements: $_\n" unless @keysymelements;
+
+ $_ = $keysymelements[1];
+ die "Internal error, was expecting \"XC_*\", found: $_\n" if ( ! /^XK_/ );
+
+ $_ = $keysymelements[2];
+ die "Internal error, was expecting \"0x*\", found: $_\n" if ( ! /^0x/ );
+
+ $keysymelements[1] =~ s/^XK_/IBUS_/g;
+
+ printf OUT_IBUSKEYSYMS "#define %s 0x%03x\n", $keysymelements[1], hex($keysymelements[2]);
+}
+
+#$ibussyms{"0"} = "0000";
+
+close IN_KEYSYMDEF;
+
+
+print OUT_IBUSKEYSYMS<<EOF;
+
+#endif /* __IBUS_KEYSYMS_H__ */
+EOF
+
+printf "We just finished converting keysymdef.h to ibuskeysyms.h\nThank you\n";
diff --git a/src/ibuskeysyms.h b/src/ibuskeysyms.h
new file mode 100644
index 0000000..cfcfe8d
--- /dev/null
+++ b/src/ibuskeysyms.h
@@ -0,0 +1,2014 @@
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __IBUS_KEYSYMS_H__
+#define __IBUS_KEYSYMS_H__
+
+
+#define IBUS_VoidSymbol 0xffffff
+#define IBUS_BackSpace 0xff08
+#define IBUS_Tab 0xff09
+#define IBUS_Linefeed 0xff0a
+#define IBUS_Clear 0xff0b
+#define IBUS_Return 0xff0d
+#define IBUS_Pause 0xff13
+#define IBUS_Scroll_Lock 0xff14
+#define IBUS_Sys_Req 0xff15
+#define IBUS_Escape 0xff1b
+#define IBUS_Delete 0xffff
+#define IBUS_Multi_key 0xff20
+#define IBUS_Codeinput 0xff37
+#define IBUS_SingleCandidate 0xff3c
+#define IBUS_MultipleCandidate 0xff3d
+#define IBUS_PreviousCandidate 0xff3e
+#define IBUS_Kanji 0xff21
+#define IBUS_Muhenkan 0xff22
+#define IBUS_Henkan_Mode 0xff23
+#define IBUS_Henkan 0xff23
+#define IBUS_Romaji 0xff24
+#define IBUS_Hiragana 0xff25
+#define IBUS_Katakana 0xff26
+#define IBUS_Hiragana_Katakana 0xff27
+#define IBUS_Zenkaku 0xff28
+#define IBUS_Hankaku 0xff29
+#define IBUS_Zenkaku_Hankaku 0xff2a
+#define IBUS_Touroku 0xff2b
+#define IBUS_Massyo 0xff2c
+#define IBUS_Kana_Lock 0xff2d
+#define IBUS_Kana_Shift 0xff2e
+#define IBUS_Eisu_Shift 0xff2f
+#define IBUS_Eisu_toggle 0xff30
+#define IBUS_Kanji_Bangou 0xff37
+#define IBUS_Zen_Koho 0xff3d
+#define IBUS_Mae_Koho 0xff3e
+#define IBUS_Home 0xff50
+#define IBUS_Left 0xff51
+#define IBUS_Up 0xff52
+#define IBUS_Right 0xff53
+#define IBUS_Down 0xff54
+#define IBUS_Prior 0xff55
+#define IBUS_Page_Up 0xff55
+#define IBUS_Next 0xff56
+#define IBUS_Page_Down 0xff56
+#define IBUS_End 0xff57
+#define IBUS_Begin 0xff58
+#define IBUS_Select 0xff60
+#define IBUS_Print 0xff61
+#define IBUS_Execute 0xff62
+#define IBUS_Insert 0xff63
+#define IBUS_Undo 0xff65
+#define IBUS_Redo 0xff66
+#define IBUS_Menu 0xff67
+#define IBUS_Find 0xff68
+#define IBUS_Cancel 0xff69
+#define IBUS_Help 0xff6a
+#define IBUS_Break 0xff6b
+#define IBUS_Mode_switch 0xff7e
+#define IBUS_script_switch 0xff7e
+#define IBUS_Num_Lock 0xff7f
+#define IBUS_KP_Space 0xff80
+#define IBUS_KP_Tab 0xff89
+#define IBUS_KP_Enter 0xff8d
+#define IBUS_KP_F1 0xff91
+#define IBUS_KP_F2 0xff92
+#define IBUS_KP_F3 0xff93
+#define IBUS_KP_F4 0xff94
+#define IBUS_KP_Home 0xff95
+#define IBUS_KP_Left 0xff96
+#define IBUS_KP_Up 0xff97
+#define IBUS_KP_Right 0xff98
+#define IBUS_KP_Down 0xff99
+#define IBUS_KP_Prior 0xff9a
+#define IBUS_KP_Page_Up 0xff9a
+#define IBUS_KP_Next 0xff9b
+#define IBUS_KP_Page_Down 0xff9b
+#define IBUS_KP_End 0xff9c
+#define IBUS_KP_Begin 0xff9d
+#define IBUS_KP_Insert 0xff9e
+#define IBUS_KP_Delete 0xff9f
+#define IBUS_KP_Equal 0xffbd
+#define IBUS_KP_Multiply 0xffaa
+#define IBUS_KP_Add 0xffab
+#define IBUS_KP_Separator 0xffac
+#define IBUS_KP_Subtract 0xffad
+#define IBUS_KP_Decimal 0xffae
+#define IBUS_KP_Divide 0xffaf
+#define IBUS_KP_0 0xffb0
+#define IBUS_KP_1 0xffb1
+#define IBUS_KP_2 0xffb2
+#define IBUS_KP_3 0xffb3
+#define IBUS_KP_4 0xffb4
+#define IBUS_KP_5 0xffb5
+#define IBUS_KP_6 0xffb6
+#define IBUS_KP_7 0xffb7
+#define IBUS_KP_8 0xffb8
+#define IBUS_KP_9 0xffb9
+#define IBUS_F1 0xffbe
+#define IBUS_F2 0xffbf
+#define IBUS_F3 0xffc0
+#define IBUS_F4 0xffc1
+#define IBUS_F5 0xffc2
+#define IBUS_F6 0xffc3
+#define IBUS_F7 0xffc4
+#define IBUS_F8 0xffc5
+#define IBUS_F9 0xffc6
+#define IBUS_F10 0xffc7
+#define IBUS_F11 0xffc8
+#define IBUS_L1 0xffc8
+#define IBUS_F12 0xffc9
+#define IBUS_L2 0xffc9
+#define IBUS_F13 0xffca
+#define IBUS_L3 0xffca
+#define IBUS_F14 0xffcb
+#define IBUS_L4 0xffcb
+#define IBUS_F15 0xffcc
+#define IBUS_L5 0xffcc
+#define IBUS_F16 0xffcd
+#define IBUS_L6 0xffcd
+#define IBUS_F17 0xffce
+#define IBUS_L7 0xffce
+#define IBUS_F18 0xffcf
+#define IBUS_L8 0xffcf
+#define IBUS_F19 0xffd0
+#define IBUS_L9 0xffd0
+#define IBUS_F20 0xffd1
+#define IBUS_L10 0xffd1
+#define IBUS_F21 0xffd2
+#define IBUS_R1 0xffd2
+#define IBUS_F22 0xffd3
+#define IBUS_R2 0xffd3
+#define IBUS_F23 0xffd4
+#define IBUS_R3 0xffd4
+#define IBUS_F24 0xffd5
+#define IBUS_R4 0xffd5
+#define IBUS_F25 0xffd6
+#define IBUS_R5 0xffd6
+#define IBUS_F26 0xffd7
+#define IBUS_R6 0xffd7
+#define IBUS_F27 0xffd8
+#define IBUS_R7 0xffd8
+#define IBUS_F28 0xffd9
+#define IBUS_R8 0xffd9
+#define IBUS_F29 0xffda
+#define IBUS_R9 0xffda
+#define IBUS_F30 0xffdb
+#define IBUS_R10 0xffdb
+#define IBUS_F31 0xffdc
+#define IBUS_R11 0xffdc
+#define IBUS_F32 0xffdd
+#define IBUS_R12 0xffdd
+#define IBUS_F33 0xffde
+#define IBUS_R13 0xffde
+#define IBUS_F34 0xffdf
+#define IBUS_R14 0xffdf
+#define IBUS_F35 0xffe0
+#define IBUS_R15 0xffe0
+#define IBUS_Shift_L 0xffe1
+#define IBUS_Shift_R 0xffe2
+#define IBUS_Control_L 0xffe3
+#define IBUS_Control_R 0xffe4
+#define IBUS_Caps_Lock 0xffe5
+#define IBUS_Shift_Lock 0xffe6
+#define IBUS_Meta_L 0xffe7
+#define IBUS_Meta_R 0xffe8
+#define IBUS_Alt_L 0xffe9
+#define IBUS_Alt_R 0xffea
+#define IBUS_Super_L 0xffeb
+#define IBUS_Super_R 0xffec
+#define IBUS_Hyper_L 0xffed
+#define IBUS_Hyper_R 0xffee
+#define IBUS_ISO_Lock 0xfe01
+#define IBUS_ISO_Level2_Latch 0xfe02
+#define IBUS_ISO_Level3_Shift 0xfe03
+#define IBUS_ISO_Level3_Latch 0xfe04
+#define IBUS_ISO_Level3_Lock 0xfe05
+#define IBUS_ISO_Level5_Shift 0xfe11
+#define IBUS_ISO_Level5_Latch 0xfe12
+#define IBUS_ISO_Level5_Lock 0xfe13
+#define IBUS_ISO_Group_Shift 0xff7e
+#define IBUS_ISO_Group_Latch 0xfe06
+#define IBUS_ISO_Group_Lock 0xfe07
+#define IBUS_ISO_Next_Group 0xfe08
+#define IBUS_ISO_Next_Group_Lock 0xfe09
+#define IBUS_ISO_Prev_Group 0xfe0a
+#define IBUS_ISO_Prev_Group_Lock 0xfe0b
+#define IBUS_ISO_First_Group 0xfe0c
+#define IBUS_ISO_First_Group_Lock 0xfe0d
+#define IBUS_ISO_Last_Group 0xfe0e
+#define IBUS_ISO_Last_Group_Lock 0xfe0f
+#define IBUS_ISO_Left_Tab 0xfe20
+#define IBUS_ISO_Move_Line_Up 0xfe21
+#define IBUS_ISO_Move_Line_Down 0xfe22
+#define IBUS_ISO_Partial_Line_Up 0xfe23
+#define IBUS_ISO_Partial_Line_Down 0xfe24
+#define IBUS_ISO_Partial_Space_Left 0xfe25
+#define IBUS_ISO_Partial_Space_Right 0xfe26
+#define IBUS_ISO_Set_Margin_Left 0xfe27
+#define IBUS_ISO_Set_Margin_Right 0xfe28
+#define IBUS_ISO_Release_Margin_Left 0xfe29
+#define IBUS_ISO_Release_Margin_Right 0xfe2a
+#define IBUS_ISO_Release_Both_Margins 0xfe2b
+#define IBUS_ISO_Fast_Cursor_Left 0xfe2c
+#define IBUS_ISO_Fast_Cursor_Right 0xfe2d
+#define IBUS_ISO_Fast_Cursor_Up 0xfe2e
+#define IBUS_ISO_Fast_Cursor_Down 0xfe2f
+#define IBUS_ISO_Continuous_Underline 0xfe30
+#define IBUS_ISO_Discontinuous_Underline 0xfe31
+#define IBUS_ISO_Emphasize 0xfe32
+#define IBUS_ISO_Center_Object 0xfe33
+#define IBUS_ISO_Enter 0xfe34
+#define IBUS_dead_grave 0xfe50
+#define IBUS_dead_acute 0xfe51
+#define IBUS_dead_circumflex 0xfe52
+#define IBUS_dead_tilde 0xfe53
+#define IBUS_dead_perispomeni 0xfe53
+#define IBUS_dead_macron 0xfe54
+#define IBUS_dead_breve 0xfe55
+#define IBUS_dead_abovedot 0xfe56
+#define IBUS_dead_diaeresis 0xfe57
+#define IBUS_dead_abovering 0xfe58
+#define IBUS_dead_doubleacute 0xfe59
+#define IBUS_dead_caron 0xfe5a
+#define IBUS_dead_cedilla 0xfe5b
+#define IBUS_dead_ogonek 0xfe5c
+#define IBUS_dead_iota 0xfe5d
+#define IBUS_dead_voiced_sound 0xfe5e
+#define IBUS_dead_semivoiced_sound 0xfe5f
+#define IBUS_dead_belowdot 0xfe60
+#define IBUS_dead_hook 0xfe61
+#define IBUS_dead_horn 0xfe62
+#define IBUS_dead_stroke 0xfe63
+#define IBUS_dead_abovecomma 0xfe64
+#define IBUS_dead_psili 0xfe64
+#define IBUS_dead_abovereversedcomma 0xfe65
+#define IBUS_dead_dasia 0xfe65
+#define IBUS_dead_belowring 0xfe67
+#define IBUS_dead_belowmacron 0xfe68
+#define IBUS_dead_belowcircumflex 0xfe69
+#define IBUS_dead_belowtilde 0xfe6a
+#define IBUS_dead_belowbreve 0xfe6b
+#define IBUS_dead_belowdiaeresis 0xfe6c
+#define IBUS_First_Virtual_Screen 0xfed0
+#define IBUS_Prev_Virtual_Screen 0xfed1
+#define IBUS_Next_Virtual_Screen 0xfed2
+#define IBUS_Last_Virtual_Screen 0xfed4
+#define IBUS_Terminate_Server 0xfed5
+#define IBUS_AccessX_Enable 0xfe70
+#define IBUS_AccessX_Feedback_Enable 0xfe71
+#define IBUS_RepeatKeys_Enable 0xfe72
+#define IBUS_SlowKeys_Enable 0xfe73
+#define IBUS_BounceKeys_Enable 0xfe74
+#define IBUS_StickyKeys_Enable 0xfe75
+#define IBUS_MouseKeys_Enable 0xfe76
+#define IBUS_MouseKeys_Accel_Enable 0xfe77
+#define IBUS_Overlay1_Enable 0xfe78
+#define IBUS_Overlay2_Enable 0xfe79
+#define IBUS_AudibleBell_Enable 0xfe7a
+#define IBUS_Pointer_Left 0xfee0
+#define IBUS_Pointer_Right 0xfee1
+#define IBUS_Pointer_Up 0xfee2
+#define IBUS_Pointer_Down 0xfee3
+#define IBUS_Pointer_UpLeft 0xfee4
+#define IBUS_Pointer_UpRight 0xfee5
+#define IBUS_Pointer_DownLeft 0xfee6
+#define IBUS_Pointer_DownRight 0xfee7
+#define IBUS_Pointer_Button_Dflt 0xfee8
+#define IBUS_Pointer_Button1 0xfee9
+#define IBUS_Pointer_Button2 0xfeea
+#define IBUS_Pointer_Button3 0xfeeb
+#define IBUS_Pointer_Button4 0xfeec
+#define IBUS_Pointer_Button5 0xfeed
+#define IBUS_Pointer_DblClick_Dflt 0xfeee
+#define IBUS_Pointer_DblClick1 0xfeef
+#define IBUS_Pointer_DblClick2 0xfef0
+#define IBUS_Pointer_DblClick3 0xfef1
+#define IBUS_Pointer_DblClick4 0xfef2
+#define IBUS_Pointer_DblClick5 0xfef3
+#define IBUS_Pointer_Drag_Dflt 0xfef4
+#define IBUS_Pointer_Drag1 0xfef5
+#define IBUS_Pointer_Drag2 0xfef6
+#define IBUS_Pointer_Drag3 0xfef7
+#define IBUS_Pointer_Drag4 0xfef8
+#define IBUS_Pointer_Drag5 0xfefd
+#define IBUS_Pointer_EnableKeys 0xfef9
+#define IBUS_Pointer_Accelerate 0xfefa
+#define IBUS_Pointer_DfltBtnNext 0xfefb
+#define IBUS_Pointer_DfltBtnPrev 0xfefc
+#define IBUS_3270_Duplicate 0xfd01
+#define IBUS_3270_FieldMark 0xfd02
+#define IBUS_3270_Right2 0xfd03
+#define IBUS_3270_Left2 0xfd04
+#define IBUS_3270_BackTab 0xfd05
+#define IBUS_3270_EraseEOF 0xfd06
+#define IBUS_3270_EraseInput 0xfd07
+#define IBUS_3270_Reset 0xfd08
+#define IBUS_3270_Quit 0xfd09
+#define IBUS_3270_PA1 0xfd0a
+#define IBUS_3270_PA2 0xfd0b
+#define IBUS_3270_PA3 0xfd0c
+#define IBUS_3270_Test 0xfd0d
+#define IBUS_3270_Attn 0xfd0e
+#define IBUS_3270_CursorBlink 0xfd0f
+#define IBUS_3270_AltCursor 0xfd10
+#define IBUS_3270_KeyClick 0xfd11
+#define IBUS_3270_Jump 0xfd12
+#define IBUS_3270_Ident 0xfd13
+#define IBUS_3270_Rule 0xfd14
+#define IBUS_3270_Copy 0xfd15
+#define IBUS_3270_Play 0xfd16
+#define IBUS_3270_Setup 0xfd17
+#define IBUS_3270_Record 0xfd18
+#define IBUS_3270_ChangeScreen 0xfd19
+#define IBUS_3270_DeleteWord 0xfd1a
+#define IBUS_3270_ExSelect 0xfd1b
+#define IBUS_3270_CursorSelect 0xfd1c
+#define IBUS_3270_PrintScreen 0xfd1d
+#define IBUS_3270_Enter 0xfd1e
+#define IBUS_space 0x020
+#define IBUS_exclam 0x021
+#define IBUS_quotedbl 0x022
+#define IBUS_numbersign 0x023
+#define IBUS_dollar 0x024
+#define IBUS_percent 0x025
+#define IBUS_ampersand 0x026
+#define IBUS_apostrophe 0x027
+#define IBUS_quoteright 0x027
+#define IBUS_parenleft 0x028
+#define IBUS_parenright 0x029
+#define IBUS_asterisk 0x02a
+#define IBUS_plus 0x02b
+#define IBUS_comma 0x02c
+#define IBUS_minus 0x02d
+#define IBUS_period 0x02e
+#define IBUS_slash 0x02f
+#define IBUS_0 0x030
+#define IBUS_1 0x031
+#define IBUS_2 0x032
+#define IBUS_3 0x033
+#define IBUS_4 0x034
+#define IBUS_5 0x035
+#define IBUS_6 0x036
+#define IBUS_7 0x037
+#define IBUS_8 0x038
+#define IBUS_9 0x039
+#define IBUS_colon 0x03a
+#define IBUS_semicolon 0x03b
+#define IBUS_less 0x03c
+#define IBUS_equal 0x03d
+#define IBUS_greater 0x03e
+#define IBUS_question 0x03f
+#define IBUS_at 0x040
+#define IBUS_A 0x041
+#define IBUS_B 0x042
+#define IBUS_C 0x043
+#define IBUS_D 0x044
+#define IBUS_E 0x045
+#define IBUS_F 0x046
+#define IBUS_G 0x047
+#define IBUS_H 0x048
+#define IBUS_I 0x049
+#define IBUS_J 0x04a
+#define IBUS_K 0x04b
+#define IBUS_L 0x04c
+#define IBUS_M 0x04d
+#define IBUS_N 0x04e
+#define IBUS_O 0x04f
+#define IBUS_P 0x050
+#define IBUS_Q 0x051
+#define IBUS_R 0x052
+#define IBUS_S 0x053
+#define IBUS_T 0x054
+#define IBUS_U 0x055
+#define IBUS_V 0x056
+#define IBUS_W 0x057
+#define IBUS_X 0x058
+#define IBUS_Y 0x059
+#define IBUS_Z 0x05a
+#define IBUS_bracketleft 0x05b
+#define IBUS_backslash 0x05c
+#define IBUS_bracketright 0x05d
+#define IBUS_asciicircum 0x05e
+#define IBUS_underscore 0x05f
+#define IBUS_grave 0x060
+#define IBUS_quoteleft 0x060
+#define IBUS_a 0x061
+#define IBUS_b 0x062
+#define IBUS_c 0x063
+#define IBUS_d 0x064
+#define IBUS_e 0x065
+#define IBUS_f 0x066
+#define IBUS_g 0x067
+#define IBUS_h 0x068
+#define IBUS_i 0x069
+#define IBUS_j 0x06a
+#define IBUS_k 0x06b
+#define IBUS_l 0x06c
+#define IBUS_m 0x06d
+#define IBUS_n 0x06e
+#define IBUS_o 0x06f
+#define IBUS_p 0x070
+#define IBUS_q 0x071
+#define IBUS_r 0x072
+#define IBUS_s 0x073
+#define IBUS_t 0x074
+#define IBUS_u 0x075
+#define IBUS_v 0x076
+#define IBUS_w 0x077
+#define IBUS_x 0x078
+#define IBUS_y 0x079
+#define IBUS_z 0x07a
+#define IBUS_braceleft 0x07b
+#define IBUS_bar 0x07c
+#define IBUS_braceright 0x07d
+#define IBUS_asciitilde 0x07e
+#define IBUS_nobreakspace 0x0a0
+#define IBUS_exclamdown 0x0a1
+#define IBUS_cent 0x0a2
+#define IBUS_sterling 0x0a3
+#define IBUS_currency 0x0a4
+#define IBUS_yen 0x0a5
+#define IBUS_brokenbar 0x0a6
+#define IBUS_section 0x0a7
+#define IBUS_diaeresis 0x0a8
+#define IBUS_copyright 0x0a9
+#define IBUS_ordfeminine 0x0aa
+#define IBUS_guillemotleft 0x0ab
+#define IBUS_notsign 0x0ac
+#define IBUS_hyphen 0x0ad
+#define IBUS_registered 0x0ae
+#define IBUS_macron 0x0af
+#define IBUS_degree 0x0b0
+#define IBUS_plusminus 0x0b1
+#define IBUS_twosuperior 0x0b2
+#define IBUS_threesuperior 0x0b3
+#define IBUS_acute 0x0b4
+#define IBUS_mu 0x0b5
+#define IBUS_paragraph 0x0b6
+#define IBUS_periodcentered 0x0b7
+#define IBUS_cedilla 0x0b8
+#define IBUS_onesuperior 0x0b9
+#define IBUS_masculine 0x0ba
+#define IBUS_guillemotright 0x0bb
+#define IBUS_onequarter 0x0bc
+#define IBUS_onehalf 0x0bd
+#define IBUS_threequarters 0x0be
+#define IBUS_questiondown 0x0bf
+#define IBUS_Agrave 0x0c0
+#define IBUS_Aacute 0x0c1
+#define IBUS_Acircumflex 0x0c2
+#define IBUS_Atilde 0x0c3
+#define IBUS_Adiaeresis 0x0c4
+#define IBUS_Aring 0x0c5
+#define IBUS_AE 0x0c6
+#define IBUS_Ccedilla 0x0c7
+#define IBUS_Egrave 0x0c8
+#define IBUS_Eacute 0x0c9
+#define IBUS_Ecircumflex 0x0ca
+#define IBUS_Ediaeresis 0x0cb
+#define IBUS_Igrave 0x0cc
+#define IBUS_Iacute 0x0cd
+#define IBUS_Icircumflex 0x0ce
+#define IBUS_Idiaeresis 0x0cf
+#define IBUS_ETH 0x0d0
+#define IBUS_Eth 0x0d0
+#define IBUS_Ntilde 0x0d1
+#define IBUS_Ograve 0x0d2
+#define IBUS_Oacute 0x0d3
+#define IBUS_Ocircumflex 0x0d4
+#define IBUS_Otilde 0x0d5
+#define IBUS_Odiaeresis 0x0d6
+#define IBUS_multiply 0x0d7
+#define IBUS_Oslash 0x0d8
+#define IBUS_Ooblique 0x0d8
+#define IBUS_Ugrave 0x0d9
+#define IBUS_Uacute 0x0da
+#define IBUS_Ucircumflex 0x0db
+#define IBUS_Udiaeresis 0x0dc
+#define IBUS_Yacute 0x0dd
+#define IBUS_THORN 0x0de
+#define IBUS_Thorn 0x0de
+#define IBUS_ssharp 0x0df
+#define IBUS_agrave 0x0e0
+#define IBUS_aacute 0x0e1
+#define IBUS_acircumflex 0x0e2
+#define IBUS_atilde 0x0e3
+#define IBUS_adiaeresis 0x0e4
+#define IBUS_aring 0x0e5
+#define IBUS_ae 0x0e6
+#define IBUS_ccedilla 0x0e7
+#define IBUS_egrave 0x0e8
+#define IBUS_eacute 0x0e9
+#define IBUS_ecircumflex 0x0ea
+#define IBUS_ediaeresis 0x0eb
+#define IBUS_igrave 0x0ec
+#define IBUS_iacute 0x0ed
+#define IBUS_icircumflex 0x0ee
+#define IBUS_idiaeresis 0x0ef
+#define IBUS_eth 0x0f0
+#define IBUS_ntilde 0x0f1
+#define IBUS_ograve 0x0f2
+#define IBUS_oacute 0x0f3
+#define IBUS_ocircumflex 0x0f4
+#define IBUS_otilde 0x0f5
+#define IBUS_odiaeresis 0x0f6
+#define IBUS_division 0x0f7
+#define IBUS_oslash 0x0f8
+#define IBUS_ooblique 0x0f8
+#define IBUS_ugrave 0x0f9
+#define IBUS_uacute 0x0fa
+#define IBUS_ucircumflex 0x0fb
+#define IBUS_udiaeresis 0x0fc
+#define IBUS_yacute 0x0fd
+#define IBUS_thorn 0x0fe
+#define IBUS_ydiaeresis 0x0ff
+#define IBUS_Aogonek 0x1a1
+#define IBUS_breve 0x1a2
+#define IBUS_Lstroke 0x1a3
+#define IBUS_Lcaron 0x1a5
+#define IBUS_Sacute 0x1a6
+#define IBUS_Scaron 0x1a9
+#define IBUS_Scedilla 0x1aa
+#define IBUS_Tcaron 0x1ab
+#define IBUS_Zacute 0x1ac
+#define IBUS_Zcaron 0x1ae
+#define IBUS_Zabovedot 0x1af
+#define IBUS_aogonek 0x1b1
+#define IBUS_ogonek 0x1b2
+#define IBUS_lstroke 0x1b3
+#define IBUS_lcaron 0x1b5
+#define IBUS_sacute 0x1b6
+#define IBUS_caron 0x1b7
+#define IBUS_scaron 0x1b9
+#define IBUS_scedilla 0x1ba
+#define IBUS_tcaron 0x1bb
+#define IBUS_zacute 0x1bc
+#define IBUS_doubleacute 0x1bd
+#define IBUS_zcaron 0x1be
+#define IBUS_zabovedot 0x1bf
+#define IBUS_Racute 0x1c0
+#define IBUS_Abreve 0x1c3
+#define IBUS_Lacute 0x1c5
+#define IBUS_Cacute 0x1c6
+#define IBUS_Ccaron 0x1c8
+#define IBUS_Eogonek 0x1ca
+#define IBUS_Ecaron 0x1cc
+#define IBUS_Dcaron 0x1cf
+#define IBUS_Dstroke 0x1d0
+#define IBUS_Nacute 0x1d1
+#define IBUS_Ncaron 0x1d2
+#define IBUS_Odoubleacute 0x1d5
+#define IBUS_Rcaron 0x1d8
+#define IBUS_Uring 0x1d9
+#define IBUS_Udoubleacute 0x1db
+#define IBUS_Tcedilla 0x1de
+#define IBUS_racute 0x1e0
+#define IBUS_abreve 0x1e3
+#define IBUS_lacute 0x1e5
+#define IBUS_cacute 0x1e6
+#define IBUS_ccaron 0x1e8
+#define IBUS_eogonek 0x1ea
+#define IBUS_ecaron 0x1ec
+#define IBUS_dcaron 0x1ef
+#define IBUS_dstroke 0x1f0
+#define IBUS_nacute 0x1f1
+#define IBUS_ncaron 0x1f2
+#define IBUS_odoubleacute 0x1f5
+#define IBUS_udoubleacute 0x1fb
+#define IBUS_rcaron 0x1f8
+#define IBUS_uring 0x1f9
+#define IBUS_tcedilla 0x1fe
+#define IBUS_abovedot 0x1ff
+#define IBUS_Hstroke 0x2a1
+#define IBUS_Hcircumflex 0x2a6
+#define IBUS_Iabovedot 0x2a9
+#define IBUS_Gbreve 0x2ab
+#define IBUS_Jcircumflex 0x2ac
+#define IBUS_hstroke 0x2b1
+#define IBUS_hcircumflex 0x2b6
+#define IBUS_idotless 0x2b9
+#define IBUS_gbreve 0x2bb
+#define IBUS_jcircumflex 0x2bc
+#define IBUS_Cabovedot 0x2c5
+#define IBUS_Ccircumflex 0x2c6
+#define IBUS_Gabovedot 0x2d5
+#define IBUS_Gcircumflex 0x2d8
+#define IBUS_Ubreve 0x2dd
+#define IBUS_Scircumflex 0x2de
+#define IBUS_cabovedot 0x2e5
+#define IBUS_ccircumflex 0x2e6
+#define IBUS_gabovedot 0x2f5
+#define IBUS_gcircumflex 0x2f8
+#define IBUS_ubreve 0x2fd
+#define IBUS_scircumflex 0x2fe
+#define IBUS_kra 0x3a2
+#define IBUS_kappa 0x3a2
+#define IBUS_Rcedilla 0x3a3
+#define IBUS_Itilde 0x3a5
+#define IBUS_Lcedilla 0x3a6
+#define IBUS_Emacron 0x3aa
+#define IBUS_Gcedilla 0x3ab
+#define IBUS_Tslash 0x3ac
+#define IBUS_rcedilla 0x3b3
+#define IBUS_itilde 0x3b5
+#define IBUS_lcedilla 0x3b6
+#define IBUS_emacron 0x3ba
+#define IBUS_gcedilla 0x3bb
+#define IBUS_tslash 0x3bc
+#define IBUS_ENG 0x3bd
+#define IBUS_eng 0x3bf
+#define IBUS_Amacron 0x3c0
+#define IBUS_Iogonek 0x3c7
+#define IBUS_Eabovedot 0x3cc
+#define IBUS_Imacron 0x3cf
+#define IBUS_Ncedilla 0x3d1
+#define IBUS_Omacron 0x3d2
+#define IBUS_Kcedilla 0x3d3
+#define IBUS_Uogonek 0x3d9
+#define IBUS_Utilde 0x3dd
+#define IBUS_Umacron 0x3de
+#define IBUS_amacron 0x3e0
+#define IBUS_iogonek 0x3e7
+#define IBUS_eabovedot 0x3ec
+#define IBUS_imacron 0x3ef
+#define IBUS_ncedilla 0x3f1
+#define IBUS_omacron 0x3f2
+#define IBUS_kcedilla 0x3f3
+#define IBUS_uogonek 0x3f9
+#define IBUS_utilde 0x3fd
+#define IBUS_umacron 0x3fe
+#define IBUS_Babovedot 0x1001e02
+#define IBUS_babovedot 0x1001e03
+#define IBUS_Dabovedot 0x1001e0a
+#define IBUS_Wgrave 0x1001e80
+#define IBUS_Wacute 0x1001e82
+#define IBUS_dabovedot 0x1001e0b
+#define IBUS_Ygrave 0x1001ef2
+#define IBUS_Fabovedot 0x1001e1e
+#define IBUS_fabovedot 0x1001e1f
+#define IBUS_Mabovedot 0x1001e40
+#define IBUS_mabovedot 0x1001e41
+#define IBUS_Pabovedot 0x1001e56
+#define IBUS_wgrave 0x1001e81
+#define IBUS_pabovedot 0x1001e57
+#define IBUS_wacute 0x1001e83
+#define IBUS_Sabovedot 0x1001e60
+#define IBUS_ygrave 0x1001ef3
+#define IBUS_Wdiaeresis 0x1001e84
+#define IBUS_wdiaeresis 0x1001e85
+#define IBUS_sabovedot 0x1001e61
+#define IBUS_Wcircumflex 0x1000174
+#define IBUS_Tabovedot 0x1001e6a
+#define IBUS_Ycircumflex 0x1000176
+#define IBUS_wcircumflex 0x1000175
+#define IBUS_tabovedot 0x1001e6b
+#define IBUS_ycircumflex 0x1000177
+#define IBUS_OE 0x13bc
+#define IBUS_oe 0x13bd
+#define IBUS_Ydiaeresis 0x13be
+#define IBUS_overline 0x47e
+#define IBUS_kana_fullstop 0x4a1
+#define IBUS_kana_openingbracket 0x4a2
+#define IBUS_kana_closingbracket 0x4a3
+#define IBUS_kana_comma 0x4a4
+#define IBUS_kana_conjunctive 0x4a5
+#define IBUS_kana_middledot 0x4a5
+#define IBUS_kana_WO 0x4a6
+#define IBUS_kana_a 0x4a7
+#define IBUS_kana_i 0x4a8
+#define IBUS_kana_u 0x4a9
+#define IBUS_kana_e 0x4aa
+#define IBUS_kana_o 0x4ab
+#define IBUS_kana_ya 0x4ac
+#define IBUS_kana_yu 0x4ad
+#define IBUS_kana_yo 0x4ae
+#define IBUS_kana_tsu 0x4af
+#define IBUS_kana_tu 0x4af
+#define IBUS_prolongedsound 0x4b0
+#define IBUS_kana_A 0x4b1
+#define IBUS_kana_I 0x4b2
+#define IBUS_kana_U 0x4b3
+#define IBUS_kana_E 0x4b4
+#define IBUS_kana_O 0x4b5
+#define IBUS_kana_KA 0x4b6
+#define IBUS_kana_KI 0x4b7
+#define IBUS_kana_KU 0x4b8
+#define IBUS_kana_KE 0x4b9
+#define IBUS_kana_KO 0x4ba
+#define IBUS_kana_SA 0x4bb
+#define IBUS_kana_SHI 0x4bc
+#define IBUS_kana_SU 0x4bd
+#define IBUS_kana_SE 0x4be
+#define IBUS_kana_SO 0x4bf
+#define IBUS_kana_TA 0x4c0
+#define IBUS_kana_CHI 0x4c1
+#define IBUS_kana_TI 0x4c1
+#define IBUS_kana_TSU 0x4c2
+#define IBUS_kana_TU 0x4c2
+#define IBUS_kana_TE 0x4c3
+#define IBUS_kana_TO 0x4c4
+#define IBUS_kana_NA 0x4c5
+#define IBUS_kana_NI 0x4c6
+#define IBUS_kana_NU 0x4c7
+#define IBUS_kana_NE 0x4c8
+#define IBUS_kana_NO 0x4c9
+#define IBUS_kana_HA 0x4ca
+#define IBUS_kana_HI 0x4cb
+#define IBUS_kana_FU 0x4cc
+#define IBUS_kana_HU 0x4cc
+#define IBUS_kana_HE 0x4cd
+#define IBUS_kana_HO 0x4ce
+#define IBUS_kana_MA 0x4cf
+#define IBUS_kana_MI 0x4d0
+#define IBUS_kana_MU 0x4d1
+#define IBUS_kana_ME 0x4d2
+#define IBUS_kana_MO 0x4d3
+#define IBUS_kana_YA 0x4d4
+#define IBUS_kana_YU 0x4d5
+#define IBUS_kana_YO 0x4d6
+#define IBUS_kana_RA 0x4d7
+#define IBUS_kana_RI 0x4d8
+#define IBUS_kana_RU 0x4d9
+#define IBUS_kana_RE 0x4da
+#define IBUS_kana_RO 0x4db
+#define IBUS_kana_WA 0x4dc
+#define IBUS_kana_N 0x4dd
+#define IBUS_voicedsound 0x4de
+#define IBUS_semivoicedsound 0x4df
+#define IBUS_kana_switch 0xff7e
+#define IBUS_Farsi_0 0x10006f0
+#define IBUS_Farsi_1 0x10006f1
+#define IBUS_Farsi_2 0x10006f2
+#define IBUS_Farsi_3 0x10006f3
+#define IBUS_Farsi_4 0x10006f4
+#define IBUS_Farsi_5 0x10006f5
+#define IBUS_Farsi_6 0x10006f6
+#define IBUS_Farsi_7 0x10006f7
+#define IBUS_Farsi_8 0x10006f8
+#define IBUS_Farsi_9 0x10006f9
+#define IBUS_Arabic_percent 0x100066a
+#define IBUS_Arabic_superscript_alef 0x1000670
+#define IBUS_Arabic_tteh 0x1000679
+#define IBUS_Arabic_peh 0x100067e
+#define IBUS_Arabic_tcheh 0x1000686
+#define IBUS_Arabic_ddal 0x1000688
+#define IBUS_Arabic_rreh 0x1000691
+#define IBUS_Arabic_comma 0x5ac
+#define IBUS_Arabic_fullstop 0x10006d4
+#define IBUS_Arabic_0 0x1000660
+#define IBUS_Arabic_1 0x1000661
+#define IBUS_Arabic_2 0x1000662
+#define IBUS_Arabic_3 0x1000663
+#define IBUS_Arabic_4 0x1000664
+#define IBUS_Arabic_5 0x1000665
+#define IBUS_Arabic_6 0x1000666
+#define IBUS_Arabic_7 0x1000667
+#define IBUS_Arabic_8 0x1000668
+#define IBUS_Arabic_9 0x1000669
+#define IBUS_Arabic_semicolon 0x5bb
+#define IBUS_Arabic_question_mark 0x5bf
+#define IBUS_Arabic_hamza 0x5c1
+#define IBUS_Arabic_maddaonalef 0x5c2
+#define IBUS_Arabic_hamzaonalef 0x5c3
+#define IBUS_Arabic_hamzaonwaw 0x5c4
+#define IBUS_Arabic_hamzaunderalef 0x5c5
+#define IBUS_Arabic_hamzaonyeh 0x5c6
+#define IBUS_Arabic_alef 0x5c7
+#define IBUS_Arabic_beh 0x5c8
+#define IBUS_Arabic_tehmarbuta 0x5c9
+#define IBUS_Arabic_teh 0x5ca
+#define IBUS_Arabic_theh 0x5cb
+#define IBUS_Arabic_jeem 0x5cc
+#define IBUS_Arabic_hah 0x5cd
+#define IBUS_Arabic_khah 0x5ce
+#define IBUS_Arabic_dal 0x5cf
+#define IBUS_Arabic_thal 0x5d0
+#define IBUS_Arabic_ra 0x5d1
+#define IBUS_Arabic_zain 0x5d2
+#define IBUS_Arabic_seen 0x5d3
+#define IBUS_Arabic_sheen 0x5d4
+#define IBUS_Arabic_sad 0x5d5
+#define IBUS_Arabic_dad 0x5d6
+#define IBUS_Arabic_tah 0x5d7
+#define IBUS_Arabic_zah 0x5d8
+#define IBUS_Arabic_ain 0x5d9
+#define IBUS_Arabic_ghain 0x5da
+#define IBUS_Arabic_tatweel 0x5e0
+#define IBUS_Arabic_feh 0x5e1
+#define IBUS_Arabic_qaf 0x5e2
+#define IBUS_Arabic_kaf 0x5e3
+#define IBUS_Arabic_lam 0x5e4
+#define IBUS_Arabic_meem 0x5e5
+#define IBUS_Arabic_noon 0x5e6
+#define IBUS_Arabic_ha 0x5e7
+#define IBUS_Arabic_heh 0x5e7
+#define IBUS_Arabic_waw 0x5e8
+#define IBUS_Arabic_alefmaksura 0x5e9
+#define IBUS_Arabic_yeh 0x5ea
+#define IBUS_Arabic_fathatan 0x5eb
+#define IBUS_Arabic_dammatan 0x5ec
+#define IBUS_Arabic_kasratan 0x5ed
+#define IBUS_Arabic_fatha 0x5ee
+#define IBUS_Arabic_damma 0x5ef
+#define IBUS_Arabic_kasra 0x5f0
+#define IBUS_Arabic_shadda 0x5f1
+#define IBUS_Arabic_sukun 0x5f2
+#define IBUS_Arabic_madda_above 0x1000653
+#define IBUS_Arabic_hamza_above 0x1000654
+#define IBUS_Arabic_hamza_below 0x1000655
+#define IBUS_Arabic_jeh 0x1000698
+#define IBUS_Arabic_veh 0x10006a4
+#define IBUS_Arabic_keheh 0x10006a9
+#define IBUS_Arabic_gaf 0x10006af
+#define IBUS_Arabic_noon_ghunna 0x10006ba
+#define IBUS_Arabic_heh_doachashmee 0x10006be
+#define IBUS_Farsi_yeh 0x10006cc
+#define IBUS_Arabic_farsi_yeh 0x10006cc
+#define IBUS_Arabic_yeh_baree 0x10006d2
+#define IBUS_Arabic_heh_goal 0x10006c1
+#define IBUS_Arabic_switch 0xff7e
+#define IBUS_Cyrillic_GHE_bar 0x1000492
+#define IBUS_Cyrillic_ghe_bar 0x1000493
+#define IBUS_Cyrillic_ZHE_descender 0x1000496
+#define IBUS_Cyrillic_zhe_descender 0x1000497
+#define IBUS_Cyrillic_KA_descender 0x100049a
+#define IBUS_Cyrillic_ka_descender 0x100049b
+#define IBUS_Cyrillic_KA_vertstroke 0x100049c
+#define IBUS_Cyrillic_ka_vertstroke 0x100049d
+#define IBUS_Cyrillic_EN_descender 0x10004a2
+#define IBUS_Cyrillic_en_descender 0x10004a3
+#define IBUS_Cyrillic_U_straight 0x10004ae
+#define IBUS_Cyrillic_u_straight 0x10004af
+#define IBUS_Cyrillic_U_straight_bar 0x10004b0
+#define IBUS_Cyrillic_u_straight_bar 0x10004b1
+#define IBUS_Cyrillic_HA_descender 0x10004b2
+#define IBUS_Cyrillic_ha_descender 0x10004b3
+#define IBUS_Cyrillic_CHE_descender 0x10004b6
+#define IBUS_Cyrillic_che_descender 0x10004b7
+#define IBUS_Cyrillic_CHE_vertstroke 0x10004b8
+#define IBUS_Cyrillic_che_vertstroke 0x10004b9
+#define IBUS_Cyrillic_SHHA 0x10004ba
+#define IBUS_Cyrillic_shha 0x10004bb
+#define IBUS_Cyrillic_SCHWA 0x10004d8
+#define IBUS_Cyrillic_schwa 0x10004d9
+#define IBUS_Cyrillic_I_macron 0x10004e2
+#define IBUS_Cyrillic_i_macron 0x10004e3
+#define IBUS_Cyrillic_O_bar 0x10004e8
+#define IBUS_Cyrillic_o_bar 0x10004e9
+#define IBUS_Cyrillic_U_macron 0x10004ee
+#define IBUS_Cyrillic_u_macron 0x10004ef
+#define IBUS_Serbian_dje 0x6a1
+#define IBUS_Macedonia_gje 0x6a2
+#define IBUS_Cyrillic_io 0x6a3
+#define IBUS_Ukrainian_ie 0x6a4
+#define IBUS_Ukranian_je 0x6a4
+#define IBUS_Macedonia_dse 0x6a5
+#define IBUS_Ukrainian_i 0x6a6
+#define IBUS_Ukranian_i 0x6a6
+#define IBUS_Ukrainian_yi 0x6a7
+#define IBUS_Ukranian_yi 0x6a7
+#define IBUS_Cyrillic_je 0x6a8
+#define IBUS_Serbian_je 0x6a8
+#define IBUS_Cyrillic_lje 0x6a9
+#define IBUS_Serbian_lje 0x6a9
+#define IBUS_Cyrillic_nje 0x6aa
+#define IBUS_Serbian_nje 0x6aa
+#define IBUS_Serbian_tshe 0x6ab
+#define IBUS_Macedonia_kje 0x6ac
+#define IBUS_Ukrainian_ghe_with_upturn 0x6ad
+#define IBUS_Byelorussian_shortu 0x6ae
+#define IBUS_Cyrillic_dzhe 0x6af
+#define IBUS_Serbian_dze 0x6af
+#define IBUS_numerosign 0x6b0
+#define IBUS_Serbian_DJE 0x6b1
+#define IBUS_Macedonia_GJE 0x6b2
+#define IBUS_Cyrillic_IO 0x6b3
+#define IBUS_Ukrainian_IE 0x6b4
+#define IBUS_Ukranian_JE 0x6b4
+#define IBUS_Macedonia_DSE 0x6b5
+#define IBUS_Ukrainian_I 0x6b6
+#define IBUS_Ukranian_I 0x6b6
+#define IBUS_Ukrainian_YI 0x6b7
+#define IBUS_Ukranian_YI 0x6b7
+#define IBUS_Cyrillic_JE 0x6b8
+#define IBUS_Serbian_JE 0x6b8
+#define IBUS_Cyrillic_LJE 0x6b9
+#define IBUS_Serbian_LJE 0x6b9
+#define IBUS_Cyrillic_NJE 0x6ba
+#define IBUS_Serbian_NJE 0x6ba
+#define IBUS_Serbian_TSHE 0x6bb
+#define IBUS_Macedonia_KJE 0x6bc
+#define IBUS_Ukrainian_GHE_WITH_UPTURN 0x6bd
+#define IBUS_Byelorussian_SHORTU 0x6be
+#define IBUS_Cyrillic_DZHE 0x6bf
+#define IBUS_Serbian_DZE 0x6bf
+#define IBUS_Cyrillic_yu 0x6c0
+#define IBUS_Cyrillic_a 0x6c1
+#define IBUS_Cyrillic_be 0x6c2
+#define IBUS_Cyrillic_tse 0x6c3
+#define IBUS_Cyrillic_de 0x6c4
+#define IBUS_Cyrillic_ie 0x6c5
+#define IBUS_Cyrillic_ef 0x6c6
+#define IBUS_Cyrillic_ghe 0x6c7
+#define IBUS_Cyrillic_ha 0x6c8
+#define IBUS_Cyrillic_i 0x6c9
+#define IBUS_Cyrillic_shorti 0x6ca
+#define IBUS_Cyrillic_ka 0x6cb
+#define IBUS_Cyrillic_el 0x6cc
+#define IBUS_Cyrillic_em 0x6cd
+#define IBUS_Cyrillic_en 0x6ce
+#define IBUS_Cyrillic_o 0x6cf
+#define IBUS_Cyrillic_pe 0x6d0
+#define IBUS_Cyrillic_ya 0x6d1
+#define IBUS_Cyrillic_er 0x6d2
+#define IBUS_Cyrillic_es 0x6d3
+#define IBUS_Cyrillic_te 0x6d4
+#define IBUS_Cyrillic_u 0x6d5
+#define IBUS_Cyrillic_zhe 0x6d6
+#define IBUS_Cyrillic_ve 0x6d7
+#define IBUS_Cyrillic_softsign 0x6d8
+#define IBUS_Cyrillic_yeru 0x6d9
+#define IBUS_Cyrillic_ze 0x6da
+#define IBUS_Cyrillic_sha 0x6db
+#define IBUS_Cyrillic_e 0x6dc
+#define IBUS_Cyrillic_shcha 0x6dd
+#define IBUS_Cyrillic_che 0x6de
+#define IBUS_Cyrillic_hardsign 0x6df
+#define IBUS_Cyrillic_YU 0x6e0
+#define IBUS_Cyrillic_A 0x6e1
+#define IBUS_Cyrillic_BE 0x6e2
+#define IBUS_Cyrillic_TSE 0x6e3
+#define IBUS_Cyrillic_DE 0x6e4
+#define IBUS_Cyrillic_IE 0x6e5
+#define IBUS_Cyrillic_EF 0x6e6
+#define IBUS_Cyrillic_GHE 0x6e7
+#define IBUS_Cyrillic_HA 0x6e8
+#define IBUS_Cyrillic_I 0x6e9
+#define IBUS_Cyrillic_SHORTI 0x6ea
+#define IBUS_Cyrillic_KA 0x6eb
+#define IBUS_Cyrillic_EL 0x6ec
+#define IBUS_Cyrillic_EM 0x6ed
+#define IBUS_Cyrillic_EN 0x6ee
+#define IBUS_Cyrillic_O 0x6ef
+#define IBUS_Cyrillic_PE 0x6f0
+#define IBUS_Cyrillic_YA 0x6f1
+#define IBUS_Cyrillic_ER 0x6f2
+#define IBUS_Cyrillic_ES 0x6f3
+#define IBUS_Cyrillic_TE 0x6f4
+#define IBUS_Cyrillic_U 0x6f5
+#define IBUS_Cyrillic_ZHE 0x6f6
+#define IBUS_Cyrillic_VE 0x6f7
+#define IBUS_Cyrillic_SOFTSIGN 0x6f8
+#define IBUS_Cyrillic_YERU 0x6f9
+#define IBUS_Cyrillic_ZE 0x6fa
+#define IBUS_Cyrillic_SHA 0x6fb
+#define IBUS_Cyrillic_E 0x6fc
+#define IBUS_Cyrillic_SHCHA 0x6fd
+#define IBUS_Cyrillic_CHE 0x6fe
+#define IBUS_Cyrillic_HARDSIGN 0x6ff
+#define IBUS_Greek_ALPHAaccent 0x7a1
+#define IBUS_Greek_EPSILONaccent 0x7a2
+#define IBUS_Greek_ETAaccent 0x7a3
+#define IBUS_Greek_IOTAaccent 0x7a4
+#define IBUS_Greek_IOTAdieresis 0x7a5
+#define IBUS_Greek_IOTAdiaeresis 0x7a5
+#define IBUS_Greek_OMICRONaccent 0x7a7
+#define IBUS_Greek_UPSILONaccent 0x7a8
+#define IBUS_Greek_UPSILONdieresis 0x7a9
+#define IBUS_Greek_OMEGAaccent 0x7ab
+#define IBUS_Greek_accentdieresis 0x7ae
+#define IBUS_Greek_horizbar 0x7af
+#define IBUS_Greek_alphaaccent 0x7b1
+#define IBUS_Greek_epsilonaccent 0x7b2
+#define IBUS_Greek_etaaccent 0x7b3
+#define IBUS_Greek_iotaaccent 0x7b4
+#define IBUS_Greek_iotadieresis 0x7b5
+#define IBUS_Greek_iotaaccentdieresis 0x7b6
+#define IBUS_Greek_omicronaccent 0x7b7
+#define IBUS_Greek_upsilonaccent 0x7b8
+#define IBUS_Greek_upsilondieresis 0x7b9
+#define IBUS_Greek_upsilonaccentdieresis 0x7ba
+#define IBUS_Greek_omegaaccent 0x7bb
+#define IBUS_Greek_ALPHA 0x7c1
+#define IBUS_Greek_BETA 0x7c2
+#define IBUS_Greek_GAMMA 0x7c3
+#define IBUS_Greek_DELTA 0x7c4
+#define IBUS_Greek_EPSILON 0x7c5
+#define IBUS_Greek_ZETA 0x7c6
+#define IBUS_Greek_ETA 0x7c7
+#define IBUS_Greek_THETA 0x7c8
+#define IBUS_Greek_IOTA 0x7c9
+#define IBUS_Greek_KAPPA 0x7ca
+#define IBUS_Greek_LAMDA 0x7cb
+#define IBUS_Greek_LAMBDA 0x7cb
+#define IBUS_Greek_MU 0x7cc
+#define IBUS_Greek_NU 0x7cd
+#define IBUS_Greek_XI 0x7ce
+#define IBUS_Greek_OMICRON 0x7cf
+#define IBUS_Greek_PI 0x7d0
+#define IBUS_Greek_RHO 0x7d1
+#define IBUS_Greek_SIGMA 0x7d2
+#define IBUS_Greek_TAU 0x7d4
+#define IBUS_Greek_UPSILON 0x7d5
+#define IBUS_Greek_PHI 0x7d6
+#define IBUS_Greek_CHI 0x7d7
+#define IBUS_Greek_PSI 0x7d8
+#define IBUS_Greek_OMEGA 0x7d9
+#define IBUS_Greek_alpha 0x7e1
+#define IBUS_Greek_beta 0x7e2
+#define IBUS_Greek_gamma 0x7e3
+#define IBUS_Greek_delta 0x7e4
+#define IBUS_Greek_epsilon 0x7e5
+#define IBUS_Greek_zeta 0x7e6
+#define IBUS_Greek_eta 0x7e7
+#define IBUS_Greek_theta 0x7e8
+#define IBUS_Greek_iota 0x7e9
+#define IBUS_Greek_kappa 0x7ea
+#define IBUS_Greek_lamda 0x7eb
+#define IBUS_Greek_lambda 0x7eb
+#define IBUS_Greek_mu 0x7ec
+#define IBUS_Greek_nu 0x7ed
+#define IBUS_Greek_xi 0x7ee
+#define IBUS_Greek_omicron 0x7ef
+#define IBUS_Greek_pi 0x7f0
+#define IBUS_Greek_rho 0x7f1
+#define IBUS_Greek_sigma 0x7f2
+#define IBUS_Greek_finalsmallsigma 0x7f3
+#define IBUS_Greek_tau 0x7f4
+#define IBUS_Greek_upsilon 0x7f5
+#define IBUS_Greek_phi 0x7f6
+#define IBUS_Greek_chi 0x7f7
+#define IBUS_Greek_psi 0x7f8
+#define IBUS_Greek_omega 0x7f9
+#define IBUS_Greek_switch 0xff7e
+#define IBUS_leftradical 0x8a1
+#define IBUS_topleftradical 0x8a2
+#define IBUS_horizconnector 0x8a3
+#define IBUS_topintegral 0x8a4
+#define IBUS_botintegral 0x8a5
+#define IBUS_vertconnector 0x8a6
+#define IBUS_topleftsqbracket 0x8a7
+#define IBUS_botleftsqbracket 0x8a8
+#define IBUS_toprightsqbracket 0x8a9
+#define IBUS_botrightsqbracket 0x8aa
+#define IBUS_topleftparens 0x8ab
+#define IBUS_botleftparens 0x8ac
+#define IBUS_toprightparens 0x8ad
+#define IBUS_botrightparens 0x8ae
+#define IBUS_leftmiddlecurlybrace 0x8af
+#define IBUS_rightmiddlecurlybrace 0x8b0
+#define IBUS_topleftsummation 0x8b1
+#define IBUS_botleftsummation 0x8b2
+#define IBUS_topvertsummationconnector 0x8b3
+#define IBUS_botvertsummationconnector 0x8b4
+#define IBUS_toprightsummation 0x8b5
+#define IBUS_botrightsummation 0x8b6
+#define IBUS_rightmiddlesummation 0x8b7
+#define IBUS_lessthanequal 0x8bc
+#define IBUS_notequal 0x8bd
+#define IBUS_greaterthanequal 0x8be
+#define IBUS_integral 0x8bf
+#define IBUS_therefore 0x8c0
+#define IBUS_variation 0x8c1
+#define IBUS_infinity 0x8c2
+#define IBUS_nabla 0x8c5
+#define IBUS_approximate 0x8c8
+#define IBUS_similarequal 0x8c9
+#define IBUS_ifonlyif 0x8cd
+#define IBUS_implies 0x8ce
+#define IBUS_identical 0x8cf
+#define IBUS_radical 0x8d6
+#define IBUS_includedin 0x8da
+#define IBUS_includes 0x8db
+#define IBUS_intersection 0x8dc
+#define IBUS_union 0x8dd
+#define IBUS_logicaland 0x8de
+#define IBUS_logicalor 0x8df
+#define IBUS_partialderivative 0x8ef
+#define IBUS_function 0x8f6
+#define IBUS_leftarrow 0x8fb
+#define IBUS_uparrow 0x8fc
+#define IBUS_rightarrow 0x8fd
+#define IBUS_downarrow 0x8fe
+#define IBUS_blank 0x9df
+#define IBUS_soliddiamond 0x9e0
+#define IBUS_checkerboard 0x9e1
+#define IBUS_ht 0x9e2
+#define IBUS_ff 0x9e3
+#define IBUS_cr 0x9e4
+#define IBUS_lf 0x9e5
+#define IBUS_nl 0x9e8
+#define IBUS_vt 0x9e9
+#define IBUS_lowrightcorner 0x9ea
+#define IBUS_uprightcorner 0x9eb
+#define IBUS_upleftcorner 0x9ec
+#define IBUS_lowleftcorner 0x9ed
+#define IBUS_crossinglines 0x9ee
+#define IBUS_horizlinescan1 0x9ef
+#define IBUS_horizlinescan3 0x9f0
+#define IBUS_horizlinescan5 0x9f1
+#define IBUS_horizlinescan7 0x9f2
+#define IBUS_horizlinescan9 0x9f3
+#define IBUS_leftt 0x9f4
+#define IBUS_rightt 0x9f5
+#define IBUS_bott 0x9f6
+#define IBUS_topt 0x9f7
+#define IBUS_vertbar 0x9f8
+#define IBUS_emspace 0xaa1
+#define IBUS_enspace 0xaa2
+#define IBUS_em3space 0xaa3
+#define IBUS_em4space 0xaa4
+#define IBUS_digitspace 0xaa5
+#define IBUS_punctspace 0xaa6
+#define IBUS_thinspace 0xaa7
+#define IBUS_hairspace 0xaa8
+#define IBUS_emdash 0xaa9
+#define IBUS_endash 0xaaa
+#define IBUS_signifblank 0xaac
+#define IBUS_ellipsis 0xaae
+#define IBUS_doubbaselinedot 0xaaf
+#define IBUS_onethird 0xab0
+#define IBUS_twothirds 0xab1
+#define IBUS_onefifth 0xab2
+#define IBUS_twofifths 0xab3
+#define IBUS_threefifths 0xab4
+#define IBUS_fourfifths 0xab5
+#define IBUS_onesixth 0xab6
+#define IBUS_fivesixths 0xab7
+#define IBUS_careof 0xab8
+#define IBUS_figdash 0xabb
+#define IBUS_leftanglebracket 0xabc
+#define IBUS_decimalpoint 0xabd
+#define IBUS_rightanglebracket 0xabe
+#define IBUS_marker 0xabf
+#define IBUS_oneeighth 0xac3
+#define IBUS_threeeighths 0xac4
+#define IBUS_fiveeighths 0xac5
+#define IBUS_seveneighths 0xac6
+#define IBUS_trademark 0xac9
+#define IBUS_signaturemark 0xaca
+#define IBUS_trademarkincircle 0xacb
+#define IBUS_leftopentriangle 0xacc
+#define IBUS_rightopentriangle 0xacd
+#define IBUS_emopencircle 0xace
+#define IBUS_emopenrectangle 0xacf
+#define IBUS_leftsinglequotemark 0xad0
+#define IBUS_rightsinglequotemark 0xad1
+#define IBUS_leftdoublequotemark 0xad2
+#define IBUS_rightdoublequotemark 0xad3
+#define IBUS_prescription 0xad4
+#define IBUS_minutes 0xad6
+#define IBUS_seconds 0xad7
+#define IBUS_latincross 0xad9
+#define IBUS_hexagram 0xada
+#define IBUS_filledrectbullet 0xadb
+#define IBUS_filledlefttribullet 0xadc
+#define IBUS_filledrighttribullet 0xadd
+#define IBUS_emfilledcircle 0xade
+#define IBUS_emfilledrect 0xadf
+#define IBUS_enopencircbullet 0xae0
+#define IBUS_enopensquarebullet 0xae1
+#define IBUS_openrectbullet 0xae2
+#define IBUS_opentribulletup 0xae3
+#define IBUS_opentribulletdown 0xae4
+#define IBUS_openstar 0xae5
+#define IBUS_enfilledcircbullet 0xae6
+#define IBUS_enfilledsqbullet 0xae7
+#define IBUS_filledtribulletup 0xae8
+#define IBUS_filledtribulletdown 0xae9
+#define IBUS_leftpointer 0xaea
+#define IBUS_rightpointer 0xaeb
+#define IBUS_club 0xaec
+#define IBUS_diamond 0xaed
+#define IBUS_heart 0xaee
+#define IBUS_maltesecross 0xaf0
+#define IBUS_dagger 0xaf1
+#define IBUS_doubledagger 0xaf2
+#define IBUS_checkmark 0xaf3
+#define IBUS_ballotcross 0xaf4
+#define IBUS_musicalsharp 0xaf5
+#define IBUS_musicalflat 0xaf6
+#define IBUS_malesymbol 0xaf7
+#define IBUS_femalesymbol 0xaf8
+#define IBUS_telephone 0xaf9
+#define IBUS_telephonerecorder 0xafa
+#define IBUS_phonographcopyright 0xafb
+#define IBUS_caret 0xafc
+#define IBUS_singlelowquotemark 0xafd
+#define IBUS_doublelowquotemark 0xafe
+#define IBUS_cursor 0xaff
+#define IBUS_leftcaret 0xba3
+#define IBUS_rightcaret 0xba6
+#define IBUS_downcaret 0xba8
+#define IBUS_upcaret 0xba9
+#define IBUS_overbar 0xbc0
+#define IBUS_downtack 0xbc2
+#define IBUS_upshoe 0xbc3
+#define IBUS_downstile 0xbc4
+#define IBUS_underbar 0xbc6
+#define IBUS_jot 0xbca
+#define IBUS_quad 0xbcc
+#define IBUS_uptack 0xbce
+#define IBUS_circle 0xbcf
+#define IBUS_upstile 0xbd3
+#define IBUS_downshoe 0xbd6
+#define IBUS_rightshoe 0xbd8
+#define IBUS_leftshoe 0xbda
+#define IBUS_lefttack 0xbdc
+#define IBUS_righttack 0xbfc
+#define IBUS_hebrew_doublelowline 0xcdf
+#define IBUS_hebrew_aleph 0xce0
+#define IBUS_hebrew_bet 0xce1
+#define IBUS_hebrew_beth 0xce1
+#define IBUS_hebrew_gimel 0xce2
+#define IBUS_hebrew_gimmel 0xce2
+#define IBUS_hebrew_dalet 0xce3
+#define IBUS_hebrew_daleth 0xce3
+#define IBUS_hebrew_he 0xce4
+#define IBUS_hebrew_waw 0xce5
+#define IBUS_hebrew_zain 0xce6
+#define IBUS_hebrew_zayin 0xce6
+#define IBUS_hebrew_chet 0xce7
+#define IBUS_hebrew_het 0xce7
+#define IBUS_hebrew_tet 0xce8
+#define IBUS_hebrew_teth 0xce8
+#define IBUS_hebrew_yod 0xce9
+#define IBUS_hebrew_finalkaph 0xcea
+#define IBUS_hebrew_kaph 0xceb
+#define IBUS_hebrew_lamed 0xcec
+#define IBUS_hebrew_finalmem 0xced
+#define IBUS_hebrew_mem 0xcee
+#define IBUS_hebrew_finalnun 0xcef
+#define IBUS_hebrew_nun 0xcf0
+#define IBUS_hebrew_samech 0xcf1
+#define IBUS_hebrew_samekh 0xcf1
+#define IBUS_hebrew_ayin 0xcf2
+#define IBUS_hebrew_finalpe 0xcf3
+#define IBUS_hebrew_pe 0xcf4
+#define IBUS_hebrew_finalzade 0xcf5
+#define IBUS_hebrew_finalzadi 0xcf5
+#define IBUS_hebrew_zade 0xcf6
+#define IBUS_hebrew_zadi 0xcf6
+#define IBUS_hebrew_qoph 0xcf7
+#define IBUS_hebrew_kuf 0xcf7
+#define IBUS_hebrew_resh 0xcf8
+#define IBUS_hebrew_shin 0xcf9
+#define IBUS_hebrew_taw 0xcfa
+#define IBUS_hebrew_taf 0xcfa
+#define IBUS_Hebrew_switch 0xff7e
+#define IBUS_Thai_kokai 0xda1
+#define IBUS_Thai_khokhai 0xda2
+#define IBUS_Thai_khokhuat 0xda3
+#define IBUS_Thai_khokhwai 0xda4
+#define IBUS_Thai_khokhon 0xda5
+#define IBUS_Thai_khorakhang 0xda6
+#define IBUS_Thai_ngongu 0xda7
+#define IBUS_Thai_chochan 0xda8
+#define IBUS_Thai_choching 0xda9
+#define IBUS_Thai_chochang 0xdaa
+#define IBUS_Thai_soso 0xdab
+#define IBUS_Thai_chochoe 0xdac
+#define IBUS_Thai_yoying 0xdad
+#define IBUS_Thai_dochada 0xdae
+#define IBUS_Thai_topatak 0xdaf
+#define IBUS_Thai_thothan 0xdb0
+#define IBUS_Thai_thonangmontho 0xdb1
+#define IBUS_Thai_thophuthao 0xdb2
+#define IBUS_Thai_nonen 0xdb3
+#define IBUS_Thai_dodek 0xdb4
+#define IBUS_Thai_totao 0xdb5
+#define IBUS_Thai_thothung 0xdb6
+#define IBUS_Thai_thothahan 0xdb7
+#define IBUS_Thai_thothong 0xdb8
+#define IBUS_Thai_nonu 0xdb9
+#define IBUS_Thai_bobaimai 0xdba
+#define IBUS_Thai_popla 0xdbb
+#define IBUS_Thai_phophung 0xdbc
+#define IBUS_Thai_fofa 0xdbd
+#define IBUS_Thai_phophan 0xdbe
+#define IBUS_Thai_fofan 0xdbf
+#define IBUS_Thai_phosamphao 0xdc0
+#define IBUS_Thai_moma 0xdc1
+#define IBUS_Thai_yoyak 0xdc2
+#define IBUS_Thai_rorua 0xdc3
+#define IBUS_Thai_ru 0xdc4
+#define IBUS_Thai_loling 0xdc5
+#define IBUS_Thai_lu 0xdc6
+#define IBUS_Thai_wowaen 0xdc7
+#define IBUS_Thai_sosala 0xdc8
+#define IBUS_Thai_sorusi 0xdc9
+#define IBUS_Thai_sosua 0xdca
+#define IBUS_Thai_hohip 0xdcb
+#define IBUS_Thai_lochula 0xdcc
+#define IBUS_Thai_oang 0xdcd
+#define IBUS_Thai_honokhuk 0xdce
+#define IBUS_Thai_paiyannoi 0xdcf
+#define IBUS_Thai_saraa 0xdd0
+#define IBUS_Thai_maihanakat 0xdd1
+#define IBUS_Thai_saraaa 0xdd2
+#define IBUS_Thai_saraam 0xdd3
+#define IBUS_Thai_sarai 0xdd4
+#define IBUS_Thai_saraii 0xdd5
+#define IBUS_Thai_saraue 0xdd6
+#define IBUS_Thai_sarauee 0xdd7
+#define IBUS_Thai_sarau 0xdd8
+#define IBUS_Thai_sarauu 0xdd9
+#define IBUS_Thai_phinthu 0xdda
+#define IBUS_Thai_maihanakat_maitho 0xdde
+#define IBUS_Thai_baht 0xddf
+#define IBUS_Thai_sarae 0xde0
+#define IBUS_Thai_saraae 0xde1
+#define IBUS_Thai_sarao 0xde2
+#define IBUS_Thai_saraaimaimuan 0xde3
+#define IBUS_Thai_saraaimaimalai 0xde4
+#define IBUS_Thai_lakkhangyao 0xde5
+#define IBUS_Thai_maiyamok 0xde6
+#define IBUS_Thai_maitaikhu 0xde7
+#define IBUS_Thai_maiek 0xde8
+#define IBUS_Thai_maitho 0xde9
+#define IBUS_Thai_maitri 0xdea
+#define IBUS_Thai_maichattawa 0xdeb
+#define IBUS_Thai_thanthakhat 0xdec
+#define IBUS_Thai_nikhahit 0xded
+#define IBUS_Thai_leksun 0xdf0
+#define IBUS_Thai_leknung 0xdf1
+#define IBUS_Thai_leksong 0xdf2
+#define IBUS_Thai_leksam 0xdf3
+#define IBUS_Thai_leksi 0xdf4
+#define IBUS_Thai_lekha 0xdf5
+#define IBUS_Thai_lekhok 0xdf6
+#define IBUS_Thai_lekchet 0xdf7
+#define IBUS_Thai_lekpaet 0xdf8
+#define IBUS_Thai_lekkao 0xdf9
+#define IBUS_Hangul 0xff31
+#define IBUS_Hangul_Start 0xff32
+#define IBUS_Hangul_End 0xff33
+#define IBUS_Hangul_Hanja 0xff34
+#define IBUS_Hangul_Jamo 0xff35
+#define IBUS_Hangul_Romaja 0xff36
+#define IBUS_Hangul_Codeinput 0xff37
+#define IBUS_Hangul_Jeonja 0xff38
+#define IBUS_Hangul_Banja 0xff39
+#define IBUS_Hangul_PreHanja 0xff3a
+#define IBUS_Hangul_PostHanja 0xff3b
+#define IBUS_Hangul_SingleCandidate 0xff3c
+#define IBUS_Hangul_MultipleCandidate 0xff3d
+#define IBUS_Hangul_PreviousCandidate 0xff3e
+#define IBUS_Hangul_Special 0xff3f
+#define IBUS_Hangul_switch 0xff7e
+#define IBUS_Hangul_Kiyeog 0xea1
+#define IBUS_Hangul_SsangKiyeog 0xea2
+#define IBUS_Hangul_KiyeogSios 0xea3
+#define IBUS_Hangul_Nieun 0xea4
+#define IBUS_Hangul_NieunJieuj 0xea5
+#define IBUS_Hangul_NieunHieuh 0xea6
+#define IBUS_Hangul_Dikeud 0xea7
+#define IBUS_Hangul_SsangDikeud 0xea8
+#define IBUS_Hangul_Rieul 0xea9
+#define IBUS_Hangul_RieulKiyeog 0xeaa
+#define IBUS_Hangul_RieulMieum 0xeab
+#define IBUS_Hangul_RieulPieub 0xeac
+#define IBUS_Hangul_RieulSios 0xead
+#define IBUS_Hangul_RieulTieut 0xeae
+#define IBUS_Hangul_RieulPhieuf 0xeaf
+#define IBUS_Hangul_RieulHieuh 0xeb0
+#define IBUS_Hangul_Mieum 0xeb1
+#define IBUS_Hangul_Pieub 0xeb2
+#define IBUS_Hangul_SsangPieub 0xeb3
+#define IBUS_Hangul_PieubSios 0xeb4
+#define IBUS_Hangul_Sios 0xeb5
+#define IBUS_Hangul_SsangSios 0xeb6
+#define IBUS_Hangul_Ieung 0xeb7
+#define IBUS_Hangul_Jieuj 0xeb8
+#define IBUS_Hangul_SsangJieuj 0xeb9
+#define IBUS_Hangul_Cieuc 0xeba
+#define IBUS_Hangul_Khieuq 0xebb
+#define IBUS_Hangul_Tieut 0xebc
+#define IBUS_Hangul_Phieuf 0xebd
+#define IBUS_Hangul_Hieuh 0xebe
+#define IBUS_Hangul_A 0xebf
+#define IBUS_Hangul_AE 0xec0
+#define IBUS_Hangul_YA 0xec1
+#define IBUS_Hangul_YAE 0xec2
+#define IBUS_Hangul_EO 0xec3
+#define IBUS_Hangul_E 0xec4
+#define IBUS_Hangul_YEO 0xec5
+#define IBUS_Hangul_YE 0xec6
+#define IBUS_Hangul_O 0xec7
+#define IBUS_Hangul_WA 0xec8
+#define IBUS_Hangul_WAE 0xec9
+#define IBUS_Hangul_OE 0xeca
+#define IBUS_Hangul_YO 0xecb
+#define IBUS_Hangul_U 0xecc
+#define IBUS_Hangul_WEO 0xecd
+#define IBUS_Hangul_WE 0xece
+#define IBUS_Hangul_WI 0xecf
+#define IBUS_Hangul_YU 0xed0
+#define IBUS_Hangul_EU 0xed1
+#define IBUS_Hangul_YI 0xed2
+#define IBUS_Hangul_I 0xed3
+#define IBUS_Hangul_J_Kiyeog 0xed4
+#define IBUS_Hangul_J_SsangKiyeog 0xed5
+#define IBUS_Hangul_J_KiyeogSios 0xed6
+#define IBUS_Hangul_J_Nieun 0xed7
+#define IBUS_Hangul_J_NieunJieuj 0xed8
+#define IBUS_Hangul_J_NieunHieuh 0xed9
+#define IBUS_Hangul_J_Dikeud 0xeda
+#define IBUS_Hangul_J_Rieul 0xedb
+#define IBUS_Hangul_J_RieulKiyeog 0xedc
+#define IBUS_Hangul_J_RieulMieum 0xedd
+#define IBUS_Hangul_J_RieulPieub 0xede
+#define IBUS_Hangul_J_RieulSios 0xedf
+#define IBUS_Hangul_J_RieulTieut 0xee0
+#define IBUS_Hangul_J_RieulPhieuf 0xee1
+#define IBUS_Hangul_J_RieulHieuh 0xee2
+#define IBUS_Hangul_J_Mieum 0xee3
+#define IBUS_Hangul_J_Pieub 0xee4
+#define IBUS_Hangul_J_PieubSios 0xee5
+#define IBUS_Hangul_J_Sios 0xee6
+#define IBUS_Hangul_J_SsangSios 0xee7
+#define IBUS_Hangul_J_Ieung 0xee8
+#define IBUS_Hangul_J_Jieuj 0xee9
+#define IBUS_Hangul_J_Cieuc 0xeea
+#define IBUS_Hangul_J_Khieuq 0xeeb
+#define IBUS_Hangul_J_Tieut 0xeec
+#define IBUS_Hangul_J_Phieuf 0xeed
+#define IBUS_Hangul_J_Hieuh 0xeee
+#define IBUS_Hangul_RieulYeorinHieuh 0xeef
+#define IBUS_Hangul_SunkyeongeumMieum 0xef0
+#define IBUS_Hangul_SunkyeongeumPieub 0xef1
+#define IBUS_Hangul_PanSios 0xef2
+#define IBUS_Hangul_KkogjiDalrinIeung 0xef3
+#define IBUS_Hangul_SunkyeongeumPhieuf 0xef4
+#define IBUS_Hangul_YeorinHieuh 0xef5
+#define IBUS_Hangul_AraeA 0xef6
+#define IBUS_Hangul_AraeAE 0xef7
+#define IBUS_Hangul_J_PanSios 0xef8
+#define IBUS_Hangul_J_KkogjiDalrinIeung 0xef9
+#define IBUS_Hangul_J_YeorinHieuh 0xefa
+#define IBUS_Korean_Won 0xeff
+#define IBUS_Armenian_ligature_ew 0x1000587
+#define IBUS_Armenian_full_stop 0x1000589
+#define IBUS_Armenian_verjaket 0x1000589
+#define IBUS_Armenian_separation_mark 0x100055d
+#define IBUS_Armenian_but 0x100055d
+#define IBUS_Armenian_hyphen 0x100058a
+#define IBUS_Armenian_yentamna 0x100058a
+#define IBUS_Armenian_exclam 0x100055c
+#define IBUS_Armenian_amanak 0x100055c
+#define IBUS_Armenian_accent 0x100055b
+#define IBUS_Armenian_shesht 0x100055b
+#define IBUS_Armenian_question 0x100055e
+#define IBUS_Armenian_paruyk 0x100055e
+#define IBUS_Armenian_AYB 0x1000531
+#define IBUS_Armenian_ayb 0x1000561
+#define IBUS_Armenian_BEN 0x1000532
+#define IBUS_Armenian_ben 0x1000562
+#define IBUS_Armenian_GIM 0x1000533
+#define IBUS_Armenian_gim 0x1000563
+#define IBUS_Armenian_DA 0x1000534
+#define IBUS_Armenian_da 0x1000564
+#define IBUS_Armenian_YECH 0x1000535
+#define IBUS_Armenian_yech 0x1000565
+#define IBUS_Armenian_ZA 0x1000536
+#define IBUS_Armenian_za 0x1000566
+#define IBUS_Armenian_E 0x1000537
+#define IBUS_Armenian_e 0x1000567
+#define IBUS_Armenian_AT 0x1000538
+#define IBUS_Armenian_at 0x1000568
+#define IBUS_Armenian_TO 0x1000539
+#define IBUS_Armenian_to 0x1000569
+#define IBUS_Armenian_ZHE 0x100053a
+#define IBUS_Armenian_zhe 0x100056a
+#define IBUS_Armenian_INI 0x100053b
+#define IBUS_Armenian_ini 0x100056b
+#define IBUS_Armenian_LYUN 0x100053c
+#define IBUS_Armenian_lyun 0x100056c
+#define IBUS_Armenian_KHE 0x100053d
+#define IBUS_Armenian_khe 0x100056d
+#define IBUS_Armenian_TSA 0x100053e
+#define IBUS_Armenian_tsa 0x100056e
+#define IBUS_Armenian_KEN 0x100053f
+#define IBUS_Armenian_ken 0x100056f
+#define IBUS_Armenian_HO 0x1000540
+#define IBUS_Armenian_ho 0x1000570
+#define IBUS_Armenian_DZA 0x1000541
+#define IBUS_Armenian_dza 0x1000571
+#define IBUS_Armenian_GHAT 0x1000542
+#define IBUS_Armenian_ghat 0x1000572
+#define IBUS_Armenian_TCHE 0x1000543
+#define IBUS_Armenian_tche 0x1000573
+#define IBUS_Armenian_MEN 0x1000544
+#define IBUS_Armenian_men 0x1000574
+#define IBUS_Armenian_HI 0x1000545
+#define IBUS_Armenian_hi 0x1000575
+#define IBUS_Armenian_NU 0x1000546
+#define IBUS_Armenian_nu 0x1000576
+#define IBUS_Armenian_SHA 0x1000547
+#define IBUS_Armenian_sha 0x1000577
+#define IBUS_Armenian_VO 0x1000548
+#define IBUS_Armenian_vo 0x1000578
+#define IBUS_Armenian_CHA 0x1000549
+#define IBUS_Armenian_cha 0x1000579
+#define IBUS_Armenian_PE 0x100054a
+#define IBUS_Armenian_pe 0x100057a
+#define IBUS_Armenian_JE 0x100054b
+#define IBUS_Armenian_je 0x100057b
+#define IBUS_Armenian_RA 0x100054c
+#define IBUS_Armenian_ra 0x100057c
+#define IBUS_Armenian_SE 0x100054d
+#define IBUS_Armenian_se 0x100057d
+#define IBUS_Armenian_VEV 0x100054e
+#define IBUS_Armenian_vev 0x100057e
+#define IBUS_Armenian_TYUN 0x100054f
+#define IBUS_Armenian_tyun 0x100057f
+#define IBUS_Armenian_RE 0x1000550
+#define IBUS_Armenian_re 0x1000580
+#define IBUS_Armenian_TSO 0x1000551
+#define IBUS_Armenian_tso 0x1000581
+#define IBUS_Armenian_VYUN 0x1000552
+#define IBUS_Armenian_vyun 0x1000582
+#define IBUS_Armenian_PYUR 0x1000553
+#define IBUS_Armenian_pyur 0x1000583
+#define IBUS_Armenian_KE 0x1000554
+#define IBUS_Armenian_ke 0x1000584
+#define IBUS_Armenian_O 0x1000555
+#define IBUS_Armenian_o 0x1000585
+#define IBUS_Armenian_FE 0x1000556
+#define IBUS_Armenian_fe 0x1000586
+#define IBUS_Armenian_apostrophe 0x100055a
+#define IBUS_Georgian_an 0x10010d0
+#define IBUS_Georgian_ban 0x10010d1
+#define IBUS_Georgian_gan 0x10010d2
+#define IBUS_Georgian_don 0x10010d3
+#define IBUS_Georgian_en 0x10010d4
+#define IBUS_Georgian_vin 0x10010d5
+#define IBUS_Georgian_zen 0x10010d6
+#define IBUS_Georgian_tan 0x10010d7
+#define IBUS_Georgian_in 0x10010d8
+#define IBUS_Georgian_kan 0x10010d9
+#define IBUS_Georgian_las 0x10010da
+#define IBUS_Georgian_man 0x10010db
+#define IBUS_Georgian_nar 0x10010dc
+#define IBUS_Georgian_on 0x10010dd
+#define IBUS_Georgian_par 0x10010de
+#define IBUS_Georgian_zhar 0x10010df
+#define IBUS_Georgian_rae 0x10010e0
+#define IBUS_Georgian_san 0x10010e1
+#define IBUS_Georgian_tar 0x10010e2
+#define IBUS_Georgian_un 0x10010e3
+#define IBUS_Georgian_phar 0x10010e4
+#define IBUS_Georgian_khar 0x10010e5
+#define IBUS_Georgian_ghan 0x10010e6
+#define IBUS_Georgian_qar 0x10010e7
+#define IBUS_Georgian_shin 0x10010e8
+#define IBUS_Georgian_chin 0x10010e9
+#define IBUS_Georgian_can 0x10010ea
+#define IBUS_Georgian_jil 0x10010eb
+#define IBUS_Georgian_cil 0x10010ec
+#define IBUS_Georgian_char 0x10010ed
+#define IBUS_Georgian_xan 0x10010ee
+#define IBUS_Georgian_jhan 0x10010ef
+#define IBUS_Georgian_hae 0x10010f0
+#define IBUS_Georgian_he 0x10010f1
+#define IBUS_Georgian_hie 0x10010f2
+#define IBUS_Georgian_we 0x10010f3
+#define IBUS_Georgian_har 0x10010f4
+#define IBUS_Georgian_hoe 0x10010f5
+#define IBUS_Georgian_fi 0x10010f6
+#define IBUS_Xabovedot 0x1001e8a
+#define IBUS_Ibreve 0x100012c
+#define IBUS_Zstroke 0x10001b5
+#define IBUS_Gcaron 0x10001e6
+#define IBUS_Ocaron 0x10001d1
+#define IBUS_Obarred 0x100019f
+#define IBUS_xabovedot 0x1001e8b
+#define IBUS_ibreve 0x100012d
+#define IBUS_zstroke 0x10001b6
+#define IBUS_gcaron 0x10001e7
+#define IBUS_ocaron 0x10001d2
+#define IBUS_obarred 0x1000275
+#define IBUS_SCHWA 0x100018f
+#define IBUS_schwa 0x1000259
+#define IBUS_Lbelowdot 0x1001e36
+#define IBUS_lbelowdot 0x1001e37
+#define IBUS_Abelowdot 0x1001ea0
+#define IBUS_abelowdot 0x1001ea1
+#define IBUS_Ahook 0x1001ea2
+#define IBUS_ahook 0x1001ea3
+#define IBUS_Acircumflexacute 0x1001ea4
+#define IBUS_acircumflexacute 0x1001ea5
+#define IBUS_Acircumflexgrave 0x1001ea6
+#define IBUS_acircumflexgrave 0x1001ea7
+#define IBUS_Acircumflexhook 0x1001ea8
+#define IBUS_acircumflexhook 0x1001ea9
+#define IBUS_Acircumflextilde 0x1001eaa
+#define IBUS_acircumflextilde 0x1001eab
+#define IBUS_Acircumflexbelowdot 0x1001eac
+#define IBUS_acircumflexbelowdot 0x1001ead
+#define IBUS_Abreveacute 0x1001eae
+#define IBUS_abreveacute 0x1001eaf
+#define IBUS_Abrevegrave 0x1001eb0
+#define IBUS_abrevegrave 0x1001eb1
+#define IBUS_Abrevehook 0x1001eb2
+#define IBUS_abrevehook 0x1001eb3
+#define IBUS_Abrevetilde 0x1001eb4
+#define IBUS_abrevetilde 0x1001eb5
+#define IBUS_Abrevebelowdot 0x1001eb6
+#define IBUS_abrevebelowdot 0x1001eb7
+#define IBUS_Ebelowdot 0x1001eb8
+#define IBUS_ebelowdot 0x1001eb9
+#define IBUS_Ehook 0x1001eba
+#define IBUS_ehook 0x1001ebb
+#define IBUS_Etilde 0x1001ebc
+#define IBUS_etilde 0x1001ebd
+#define IBUS_Ecircumflexacute 0x1001ebe
+#define IBUS_ecircumflexacute 0x1001ebf
+#define IBUS_Ecircumflexgrave 0x1001ec0
+#define IBUS_ecircumflexgrave 0x1001ec1
+#define IBUS_Ecircumflexhook 0x1001ec2
+#define IBUS_ecircumflexhook 0x1001ec3
+#define IBUS_Ecircumflextilde 0x1001ec4
+#define IBUS_ecircumflextilde 0x1001ec5
+#define IBUS_Ecircumflexbelowdot 0x1001ec6
+#define IBUS_ecircumflexbelowdot 0x1001ec7
+#define IBUS_Ihook 0x1001ec8
+#define IBUS_ihook 0x1001ec9
+#define IBUS_Ibelowdot 0x1001eca
+#define IBUS_ibelowdot 0x1001ecb
+#define IBUS_Obelowdot 0x1001ecc
+#define IBUS_obelowdot 0x1001ecd
+#define IBUS_Ohook 0x1001ece
+#define IBUS_ohook 0x1001ecf
+#define IBUS_Ocircumflexacute 0x1001ed0
+#define IBUS_ocircumflexacute 0x1001ed1
+#define IBUS_Ocircumflexgrave 0x1001ed2
+#define IBUS_ocircumflexgrave 0x1001ed3
+#define IBUS_Ocircumflexhook 0x1001ed4
+#define IBUS_ocircumflexhook 0x1001ed5
+#define IBUS_Ocircumflextilde 0x1001ed6
+#define IBUS_ocircumflextilde 0x1001ed7
+#define IBUS_Ocircumflexbelowdot 0x1001ed8
+#define IBUS_ocircumflexbelowdot 0x1001ed9
+#define IBUS_Ohornacute 0x1001eda
+#define IBUS_ohornacute 0x1001edb
+#define IBUS_Ohorngrave 0x1001edc
+#define IBUS_ohorngrave 0x1001edd
+#define IBUS_Ohornhook 0x1001ede
+#define IBUS_ohornhook 0x1001edf
+#define IBUS_Ohorntilde 0x1001ee0
+#define IBUS_ohorntilde 0x1001ee1
+#define IBUS_Ohornbelowdot 0x1001ee2
+#define IBUS_ohornbelowdot 0x1001ee3
+#define IBUS_Ubelowdot 0x1001ee4
+#define IBUS_ubelowdot 0x1001ee5
+#define IBUS_Uhook 0x1001ee6
+#define IBUS_uhook 0x1001ee7
+#define IBUS_Uhornacute 0x1001ee8
+#define IBUS_uhornacute 0x1001ee9
+#define IBUS_Uhorngrave 0x1001eea
+#define IBUS_uhorngrave 0x1001eeb
+#define IBUS_Uhornhook 0x1001eec
+#define IBUS_uhornhook 0x1001eed
+#define IBUS_Uhorntilde 0x1001eee
+#define IBUS_uhorntilde 0x1001eef
+#define IBUS_Uhornbelowdot 0x1001ef0
+#define IBUS_uhornbelowdot 0x1001ef1
+#define IBUS_Ybelowdot 0x1001ef4
+#define IBUS_ybelowdot 0x1001ef5
+#define IBUS_Yhook 0x1001ef6
+#define IBUS_yhook 0x1001ef7
+#define IBUS_Ytilde 0x1001ef8
+#define IBUS_ytilde 0x1001ef9
+#define IBUS_Ohorn 0x10001a0
+#define IBUS_ohorn 0x10001a1
+#define IBUS_Uhorn 0x10001af
+#define IBUS_uhorn 0x10001b0
+#define IBUS_EcuSign 0x10020a0
+#define IBUS_ColonSign 0x10020a1
+#define IBUS_CruzeiroSign 0x10020a2
+#define IBUS_FFrancSign 0x10020a3
+#define IBUS_LiraSign 0x10020a4
+#define IBUS_MillSign 0x10020a5
+#define IBUS_NairaSign 0x10020a6
+#define IBUS_PesetaSign 0x10020a7
+#define IBUS_RupeeSign 0x10020a8
+#define IBUS_WonSign 0x10020a9
+#define IBUS_NewSheqelSign 0x10020aa
+#define IBUS_DongSign 0x10020ab
+#define IBUS_EuroSign 0x20ac
+#define IBUS_zerosuperior 0x1002070
+#define IBUS_foursuperior 0x1002074
+#define IBUS_fivesuperior 0x1002075
+#define IBUS_sixsuperior 0x1002076
+#define IBUS_sevensuperior 0x1002077
+#define IBUS_eightsuperior 0x1002078
+#define IBUS_ninesuperior 0x1002079
+#define IBUS_zerosubscript 0x1002080
+#define IBUS_onesubscript 0x1002081
+#define IBUS_twosubscript 0x1002082
+#define IBUS_threesubscript 0x1002083
+#define IBUS_foursubscript 0x1002084
+#define IBUS_fivesubscript 0x1002085
+#define IBUS_sixsubscript 0x1002086
+#define IBUS_sevensubscript 0x1002087
+#define IBUS_eightsubscript 0x1002088
+#define IBUS_ninesubscript 0x1002089
+#define IBUS_partdifferential 0x1002202
+#define IBUS_emptyset 0x1002205
+#define IBUS_elementof 0x1002208
+#define IBUS_notelementof 0x1002209
+#define IBUS_containsas 0x100220b
+#define IBUS_squareroot 0x100221a
+#define IBUS_cuberoot 0x100221b
+#define IBUS_fourthroot 0x100221c
+#define IBUS_dintegral 0x100222c
+#define IBUS_tintegral 0x100222d
+#define IBUS_because 0x1002235
+#define IBUS_approxeq 0x1002248
+#define IBUS_notapproxeq 0x1002247
+#define IBUS_notidentical 0x1002262
+#define IBUS_stricteq 0x1002263
+#define IBUS_braille_dot_1 0xfff1
+#define IBUS_braille_dot_2 0xfff2
+#define IBUS_braille_dot_3 0xfff3
+#define IBUS_braille_dot_4 0xfff4
+#define IBUS_braille_dot_5 0xfff5
+#define IBUS_braille_dot_6 0xfff6
+#define IBUS_braille_dot_7 0xfff7
+#define IBUS_braille_dot_8 0xfff8
+#define IBUS_braille_dot_9 0xfff9
+#define IBUS_braille_dot_10 0xfffa
+#define IBUS_braille_blank 0x1002800
+#define IBUS_braille_dots_1 0x1002801
+#define IBUS_braille_dots_2 0x1002802
+#define IBUS_braille_dots_12 0x1002803
+#define IBUS_braille_dots_3 0x1002804
+#define IBUS_braille_dots_13 0x1002805
+#define IBUS_braille_dots_23 0x1002806
+#define IBUS_braille_dots_123 0x1002807
+#define IBUS_braille_dots_4 0x1002808
+#define IBUS_braille_dots_14 0x1002809
+#define IBUS_braille_dots_24 0x100280a
+#define IBUS_braille_dots_124 0x100280b
+#define IBUS_braille_dots_34 0x100280c
+#define IBUS_braille_dots_134 0x100280d
+#define IBUS_braille_dots_234 0x100280e
+#define IBUS_braille_dots_1234 0x100280f
+#define IBUS_braille_dots_5 0x1002810
+#define IBUS_braille_dots_15 0x1002811
+#define IBUS_braille_dots_25 0x1002812
+#define IBUS_braille_dots_125 0x1002813
+#define IBUS_braille_dots_35 0x1002814
+#define IBUS_braille_dots_135 0x1002815
+#define IBUS_braille_dots_235 0x1002816
+#define IBUS_braille_dots_1235 0x1002817
+#define IBUS_braille_dots_45 0x1002818
+#define IBUS_braille_dots_145 0x1002819
+#define IBUS_braille_dots_245 0x100281a
+#define IBUS_braille_dots_1245 0x100281b
+#define IBUS_braille_dots_345 0x100281c
+#define IBUS_braille_dots_1345 0x100281d
+#define IBUS_braille_dots_2345 0x100281e
+#define IBUS_braille_dots_12345 0x100281f
+#define IBUS_braille_dots_6 0x1002820
+#define IBUS_braille_dots_16 0x1002821
+#define IBUS_braille_dots_26 0x1002822
+#define IBUS_braille_dots_126 0x1002823
+#define IBUS_braille_dots_36 0x1002824
+#define IBUS_braille_dots_136 0x1002825
+#define IBUS_braille_dots_236 0x1002826
+#define IBUS_braille_dots_1236 0x1002827
+#define IBUS_braille_dots_46 0x1002828
+#define IBUS_braille_dots_146 0x1002829
+#define IBUS_braille_dots_246 0x100282a
+#define IBUS_braille_dots_1246 0x100282b
+#define IBUS_braille_dots_346 0x100282c
+#define IBUS_braille_dots_1346 0x100282d
+#define IBUS_braille_dots_2346 0x100282e
+#define IBUS_braille_dots_12346 0x100282f
+#define IBUS_braille_dots_56 0x1002830
+#define IBUS_braille_dots_156 0x1002831
+#define IBUS_braille_dots_256 0x1002832
+#define IBUS_braille_dots_1256 0x1002833
+#define IBUS_braille_dots_356 0x1002834
+#define IBUS_braille_dots_1356 0x1002835
+#define IBUS_braille_dots_2356 0x1002836
+#define IBUS_braille_dots_12356 0x1002837
+#define IBUS_braille_dots_456 0x1002838
+#define IBUS_braille_dots_1456 0x1002839
+#define IBUS_braille_dots_2456 0x100283a
+#define IBUS_braille_dots_12456 0x100283b
+#define IBUS_braille_dots_3456 0x100283c
+#define IBUS_braille_dots_13456 0x100283d
+#define IBUS_braille_dots_23456 0x100283e
+#define IBUS_braille_dots_123456 0x100283f
+#define IBUS_braille_dots_7 0x1002840
+#define IBUS_braille_dots_17 0x1002841
+#define IBUS_braille_dots_27 0x1002842
+#define IBUS_braille_dots_127 0x1002843
+#define IBUS_braille_dots_37 0x1002844
+#define IBUS_braille_dots_137 0x1002845
+#define IBUS_braille_dots_237 0x1002846
+#define IBUS_braille_dots_1237 0x1002847
+#define IBUS_braille_dots_47 0x1002848
+#define IBUS_braille_dots_147 0x1002849
+#define IBUS_braille_dots_247 0x100284a
+#define IBUS_braille_dots_1247 0x100284b
+#define IBUS_braille_dots_347 0x100284c
+#define IBUS_braille_dots_1347 0x100284d
+#define IBUS_braille_dots_2347 0x100284e
+#define IBUS_braille_dots_12347 0x100284f
+#define IBUS_braille_dots_57 0x1002850
+#define IBUS_braille_dots_157 0x1002851
+#define IBUS_braille_dots_257 0x1002852
+#define IBUS_braille_dots_1257 0x1002853
+#define IBUS_braille_dots_357 0x1002854
+#define IBUS_braille_dots_1357 0x1002855
+#define IBUS_braille_dots_2357 0x1002856
+#define IBUS_braille_dots_12357 0x1002857
+#define IBUS_braille_dots_457 0x1002858
+#define IBUS_braille_dots_1457 0x1002859
+#define IBUS_braille_dots_2457 0x100285a
+#define IBUS_braille_dots_12457 0x100285b
+#define IBUS_braille_dots_3457 0x100285c
+#define IBUS_braille_dots_13457 0x100285d
+#define IBUS_braille_dots_23457 0x100285e
+#define IBUS_braille_dots_123457 0x100285f
+#define IBUS_braille_dots_67 0x1002860
+#define IBUS_braille_dots_167 0x1002861
+#define IBUS_braille_dots_267 0x1002862
+#define IBUS_braille_dots_1267 0x1002863
+#define IBUS_braille_dots_367 0x1002864
+#define IBUS_braille_dots_1367 0x1002865
+#define IBUS_braille_dots_2367 0x1002866
+#define IBUS_braille_dots_12367 0x1002867
+#define IBUS_braille_dots_467 0x1002868
+#define IBUS_braille_dots_1467 0x1002869
+#define IBUS_braille_dots_2467 0x100286a
+#define IBUS_braille_dots_12467 0x100286b
+#define IBUS_braille_dots_3467 0x100286c
+#define IBUS_braille_dots_13467 0x100286d
+#define IBUS_braille_dots_23467 0x100286e
+#define IBUS_braille_dots_123467 0x100286f
+#define IBUS_braille_dots_567 0x1002870
+#define IBUS_braille_dots_1567 0x1002871
+#define IBUS_braille_dots_2567 0x1002872
+#define IBUS_braille_dots_12567 0x1002873
+#define IBUS_braille_dots_3567 0x1002874
+#define IBUS_braille_dots_13567 0x1002875
+#define IBUS_braille_dots_23567 0x1002876
+#define IBUS_braille_dots_123567 0x1002877
+#define IBUS_braille_dots_4567 0x1002878
+#define IBUS_braille_dots_14567 0x1002879
+#define IBUS_braille_dots_24567 0x100287a
+#define IBUS_braille_dots_124567 0x100287b
+#define IBUS_braille_dots_34567 0x100287c
+#define IBUS_braille_dots_134567 0x100287d
+#define IBUS_braille_dots_234567 0x100287e
+#define IBUS_braille_dots_1234567 0x100287f
+#define IBUS_braille_dots_8 0x1002880
+#define IBUS_braille_dots_18 0x1002881
+#define IBUS_braille_dots_28 0x1002882
+#define IBUS_braille_dots_128 0x1002883
+#define IBUS_braille_dots_38 0x1002884
+#define IBUS_braille_dots_138 0x1002885
+#define IBUS_braille_dots_238 0x1002886
+#define IBUS_braille_dots_1238 0x1002887
+#define IBUS_braille_dots_48 0x1002888
+#define IBUS_braille_dots_148 0x1002889
+#define IBUS_braille_dots_248 0x100288a
+#define IBUS_braille_dots_1248 0x100288b
+#define IBUS_braille_dots_348 0x100288c
+#define IBUS_braille_dots_1348 0x100288d
+#define IBUS_braille_dots_2348 0x100288e
+#define IBUS_braille_dots_12348 0x100288f
+#define IBUS_braille_dots_58 0x1002890
+#define IBUS_braille_dots_158 0x1002891
+#define IBUS_braille_dots_258 0x1002892
+#define IBUS_braille_dots_1258 0x1002893
+#define IBUS_braille_dots_358 0x1002894
+#define IBUS_braille_dots_1358 0x1002895
+#define IBUS_braille_dots_2358 0x1002896
+#define IBUS_braille_dots_12358 0x1002897
+#define IBUS_braille_dots_458 0x1002898
+#define IBUS_braille_dots_1458 0x1002899
+#define IBUS_braille_dots_2458 0x100289a
+#define IBUS_braille_dots_12458 0x100289b
+#define IBUS_braille_dots_3458 0x100289c
+#define IBUS_braille_dots_13458 0x100289d
+#define IBUS_braille_dots_23458 0x100289e
+#define IBUS_braille_dots_123458 0x100289f
+#define IBUS_braille_dots_68 0x10028a0
+#define IBUS_braille_dots_168 0x10028a1
+#define IBUS_braille_dots_268 0x10028a2
+#define IBUS_braille_dots_1268 0x10028a3
+#define IBUS_braille_dots_368 0x10028a4
+#define IBUS_braille_dots_1368 0x10028a5
+#define IBUS_braille_dots_2368 0x10028a6
+#define IBUS_braille_dots_12368 0x10028a7
+#define IBUS_braille_dots_468 0x10028a8
+#define IBUS_braille_dots_1468 0x10028a9
+#define IBUS_braille_dots_2468 0x10028aa
+#define IBUS_braille_dots_12468 0x10028ab
+#define IBUS_braille_dots_3468 0x10028ac
+#define IBUS_braille_dots_13468 0x10028ad
+#define IBUS_braille_dots_23468 0x10028ae
+#define IBUS_braille_dots_123468 0x10028af
+#define IBUS_braille_dots_568 0x10028b0
+#define IBUS_braille_dots_1568 0x10028b1
+#define IBUS_braille_dots_2568 0x10028b2
+#define IBUS_braille_dots_12568 0x10028b3
+#define IBUS_braille_dots_3568 0x10028b4
+#define IBUS_braille_dots_13568 0x10028b5
+#define IBUS_braille_dots_23568 0x10028b6
+#define IBUS_braille_dots_123568 0x10028b7
+#define IBUS_braille_dots_4568 0x10028b8
+#define IBUS_braille_dots_14568 0x10028b9
+#define IBUS_braille_dots_24568 0x10028ba
+#define IBUS_braille_dots_124568 0x10028bb
+#define IBUS_braille_dots_34568 0x10028bc
+#define IBUS_braille_dots_134568 0x10028bd
+#define IBUS_braille_dots_234568 0x10028be
+#define IBUS_braille_dots_1234568 0x10028bf
+#define IBUS_braille_dots_78 0x10028c0
+#define IBUS_braille_dots_178 0x10028c1
+#define IBUS_braille_dots_278 0x10028c2
+#define IBUS_braille_dots_1278 0x10028c3
+#define IBUS_braille_dots_378 0x10028c4
+#define IBUS_braille_dots_1378 0x10028c5
+#define IBUS_braille_dots_2378 0x10028c6
+#define IBUS_braille_dots_12378 0x10028c7
+#define IBUS_braille_dots_478 0x10028c8
+#define IBUS_braille_dots_1478 0x10028c9
+#define IBUS_braille_dots_2478 0x10028ca
+#define IBUS_braille_dots_12478 0x10028cb
+#define IBUS_braille_dots_3478 0x10028cc
+#define IBUS_braille_dots_13478 0x10028cd
+#define IBUS_braille_dots_23478 0x10028ce
+#define IBUS_braille_dots_123478 0x10028cf
+#define IBUS_braille_dots_578 0x10028d0
+#define IBUS_braille_dots_1578 0x10028d1
+#define IBUS_braille_dots_2578 0x10028d2
+#define IBUS_braille_dots_12578 0x10028d3
+#define IBUS_braille_dots_3578 0x10028d4
+#define IBUS_braille_dots_13578 0x10028d5
+#define IBUS_braille_dots_23578 0x10028d6
+#define IBUS_braille_dots_123578 0x10028d7
+#define IBUS_braille_dots_4578 0x10028d8
+#define IBUS_braille_dots_14578 0x10028d9
+#define IBUS_braille_dots_24578 0x10028da
+#define IBUS_braille_dots_124578 0x10028db
+#define IBUS_braille_dots_34578 0x10028dc
+#define IBUS_braille_dots_134578 0x10028dd
+#define IBUS_braille_dots_234578 0x10028de
+#define IBUS_braille_dots_1234578 0x10028df
+#define IBUS_braille_dots_678 0x10028e0
+#define IBUS_braille_dots_1678 0x10028e1
+#define IBUS_braille_dots_2678 0x10028e2
+#define IBUS_braille_dots_12678 0x10028e3
+#define IBUS_braille_dots_3678 0x10028e4
+#define IBUS_braille_dots_13678 0x10028e5
+#define IBUS_braille_dots_23678 0x10028e6
+#define IBUS_braille_dots_123678 0x10028e7
+#define IBUS_braille_dots_4678 0x10028e8
+#define IBUS_braille_dots_14678 0x10028e9
+#define IBUS_braille_dots_24678 0x10028ea
+#define IBUS_braille_dots_124678 0x10028eb
+#define IBUS_braille_dots_34678 0x10028ec
+#define IBUS_braille_dots_134678 0x10028ed
+#define IBUS_braille_dots_234678 0x10028ee
+#define IBUS_braille_dots_1234678 0x10028ef
+#define IBUS_braille_dots_5678 0x10028f0
+#define IBUS_braille_dots_15678 0x10028f1
+#define IBUS_braille_dots_25678 0x10028f2
+#define IBUS_braille_dots_125678 0x10028f3
+#define IBUS_braille_dots_35678 0x10028f4
+#define IBUS_braille_dots_135678 0x10028f5
+#define IBUS_braille_dots_235678 0x10028f6
+#define IBUS_braille_dots_1235678 0x10028f7
+#define IBUS_braille_dots_45678 0x10028f8
+#define IBUS_braille_dots_145678 0x10028f9
+#define IBUS_braille_dots_245678 0x10028fa
+#define IBUS_braille_dots_1245678 0x10028fb
+#define IBUS_braille_dots_345678 0x10028fc
+#define IBUS_braille_dots_1345678 0x10028fd
+#define IBUS_braille_dots_2345678 0x10028fe
+#define IBUS_braille_dots_12345678 0x10028ff
+
+#endif /* __IBUS_KEYSYMS_H__ */
diff --git a/src/ibuslookuptable.c b/src/ibuslookuptable.c
new file mode 100644
index 0000000..aab3ecd
--- /dev/null
+++ b/src/ibuslookuptable.c
@@ -0,0 +1,283 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibuslookuptable.h"
+
+/* functions prototype */
+static void ibus_lookup_table_class_init (IBusLookupTableClass *klass);
+static void ibus_lookup_table_init (IBusLookupTable *table);
+static void ibus_lookup_table_destroy (IBusLookupTable *table);
+static gboolean ibus_lookup_table_serialize (IBusLookupTable *table,
+ IBusMessageIter *iter);
+static gboolean ibus_lookup_table_deserialize (IBusLookupTable *table,
+ IBusMessageIter *iter);
+static gboolean ibus_lookup_table_copy (IBusLookupTable *dest,
+ IBusLookupTable *src);
+
+static IBusSerializableClass *parent_class = NULL;
+
+GType
+ibus_lookup_table_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusLookupTableClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_lookup_table_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusLookupTable),
+ 0,
+ (GInstanceInitFunc) ibus_lookup_table_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusLookupTable",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_lookup_table_class_init (IBusLookupTableClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_lookup_table_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_lookup_table_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_lookup_table_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_lookup_table_copy;
+
+ g_string_append (serializable_class->signature, "uubav");
+}
+
+static void
+ibus_lookup_table_init (IBusLookupTable *table)
+{
+ table->candidates = g_array_new (TRUE, TRUE, sizeof (IBusText *));
+}
+
+static void
+ibus_lookup_table_destroy (IBusLookupTable *table)
+{
+ IBusText **sp, **p;
+
+ if (table->candidates != NULL) {
+ p = sp = (IBusText **) g_array_free (table->candidates, FALSE);
+ table->candidates = NULL;
+ while (*p != NULL) {
+ g_object_unref (*p);
+ p ++;
+ }
+ g_free (sp);
+ }
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *) table);
+}
+
+static gboolean
+ibus_lookup_table_serialize (IBusLookupTable *table,
+ IBusMessageIter *iter)
+{
+ IBusMessageIter array_iter;
+ gboolean retval;
+ guint i;
+
+ retval = parent_class->serialize ((IBusSerializable *)table, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (table), FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &table->page_size);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &table->cursor_pos);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_BOOLEAN, &table->cursor_visible);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_open_container (iter,
+ IBUS_TYPE_ARRAY,
+ "v",
+ &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ for (i = 0;; i++) {
+ IBusText *text;
+
+ text = ibus_lookup_table_get_candidate (table, i);
+ if (text == NULL)
+ break;
+
+ retval = ibus_message_iter_append (&array_iter, IBUS_TYPE_TEXT, &text);
+ g_return_val_if_fail (retval, FALSE);
+ }
+
+ retval = ibus_message_iter_close_container (iter, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_lookup_table_deserialize (IBusLookupTable *table,
+ IBusMessageIter *iter)
+{
+ DBusMessageIter array_iter;
+ gboolean retval;
+
+ retval = parent_class->deserialize ((IBusSerializable *)table, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (table), FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &table->page_size);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &table->cursor_pos);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_BOOLEAN, &table->cursor_visible);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_recurse (iter, IBUS_TYPE_ARRAY, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ while (ibus_message_iter_get_arg_type (&array_iter) != G_TYPE_INVALID) {
+ IBusText *text;
+ retval = ibus_message_iter_get (&array_iter, IBUS_TYPE_TEXT, &text);
+ g_return_val_if_fail (retval, FALSE);
+
+ ibus_lookup_table_append_candidate (table, text);
+ }
+
+ ibus_message_iter_next (iter);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_lookup_table_copy (IBusLookupTable *dest,
+ IBusLookupTable *src)
+{
+ gboolean retval;
+ guint i;
+
+ retval = parent_class->copy ((IBusSerializable *)dest, (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (src), FALSE);
+
+ for (i = 0;; i++) {
+ IBusText *text;
+
+ text = ibus_lookup_table_get_candidate (src, i);
+ if (text == NULL)
+ break;
+
+ text = (IBusText *) ibus_serializable_copy ((IBusSerializable *) text);
+
+ ibus_lookup_table_append_candidate (dest, text);
+ g_object_unref (text);
+ }
+
+ return TRUE;
+}
+
+IBusLookupTable *
+ibus_lookup_table_new (guint page_size,
+ gboolean cursor_visible)
+{
+ IBusLookupTable *table;
+
+ table= g_object_new (IBUS_TYPE_LOOKUP_TABLE, NULL);
+
+ table->cursor_pos = 0;
+ table->page_size = page_size;
+ table->cursor_visible = cursor_visible;
+
+ return table;
+}
+
+void
+ibus_lookup_table_append_candidate (IBusLookupTable *table,
+ IBusText *text)
+{
+ g_return_if_fail (IBUS_IS_LOOKUP_TABLE (table));
+ g_return_if_fail (IBUS_IS_TEXT (text));
+
+ g_object_ref (text);
+ g_array_append_val (table->candidates, text);
+}
+
+IBusText *
+ibus_lookup_table_get_candidate (IBusLookupTable *table,
+ guint index)
+{
+ g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (table), NULL);
+
+ if (index >= table->candidates->len)
+ return NULL;
+
+ return g_array_index (table->candidates, IBusText *, index);
+}
+
+
+void
+ibus_lookup_table_clear (IBusLookupTable *table)
+{
+ g_return_if_fail (IBUS_IS_LOOKUP_TABLE (table));
+
+ gint index;
+
+ for (index = 0; index < table->candidates->len; index ++) {
+ g_object_unref (g_array_index (table->candidates, IBusText *, index));
+ }
+
+ g_array_set_size (table->candidates, 0);
+}
+
+void
+ibus_lookup_table_set_cursor_pos (IBusLookupTable *table,
+ guint cursor_pos)
+{
+ g_assert (IBUS_IS_LOOKUP_TABLE (table));
+
+ table->cursor_pos = cursor_pos;
+}
+void
+ibus_lookup_table_set_page_size (IBusLookupTable *table,
+ guint page_size)
+{
+ g_assert (IBUS_IS_LOOKUP_TABLE (table));
+
+ table->page_size = page_size;
+}
+
diff --git a/src/ibuslookuptable.h b/src/ibuslookuptable.h
new file mode 100644
index 0000000..2b29138
--- /dev/null
+++ b/src/ibuslookuptable.h
@@ -0,0 +1,82 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_LOOKUP_TABLE_H_
+#define __IBUS_LOOKUP_TABLE_H_
+
+#include "ibusserializable.h"
+#include "ibustext.h"
+
+/*
+ * Type macros.
+ */
+/* define IBusLookupTable macros */
+#define IBUS_TYPE_LOOKUP_TABLE \
+ (ibus_lookup_table_get_type ())
+#define IBUS_LOOKUP_TABLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_LOOKUP_TABLE, IBusLookupTable))
+#define IBUS_LOOKUP_TABLE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_LOOKUP_TABLE, IBusLookupTableClass))
+#define IBUS_IS_LOOKUP_TABLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_LOOKUP_TABLE))
+#define IBUS_IS_LOOKUP_TABLE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_LOOKUP_TABLE))
+#define IBUS_LOOKUP_TABLE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_LOOKUP_TABLE, IBusLookupTableClass))
+
+
+G_BEGIN_DECLS
+
+typedef struct _IBusLookupTable IBusLookupTable;
+typedef struct _IBusLookupTableClass IBusLookupTableClass;
+
+struct _IBusLookupTable {
+ IBusSerializable parent;
+
+ guint page_size;
+ guint cursor_pos;
+ gboolean cursor_visible;
+
+ GArray *candidates;
+};
+
+struct _IBusLookupTableClass {
+ IBusSerializableClass parent;
+};
+
+
+GType ibus_lookup_table_get_type (void);
+IBusLookupTable *ibus_lookup_table_new (guint page_size,
+ gboolean cursor_visible);
+void ibus_lookup_table_append_candidate
+ (IBusLookupTable *table,
+ IBusText *text);
+IBusText *ibus_lookup_table_get_candidate
+ (IBusLookupTable *table,
+ guint index);
+void ibus_lookup_table_set_cursor_pos
+ (IBusLookupTable *table,
+ guint cursor_pos);
+void ibus_lookup_table_set_page_size
+ (IBusLookupTable *table,
+ guint page_size);
+void ibus_lookup_table_clear (IBusLookupTable *table);
+G_END_DECLS
+#endif
+
diff --git a/src/ibusmarshalers.list b/src/ibusmarshalers.list
new file mode 100644
index 0000000..14def28
--- /dev/null
+++ b/src/ibusmarshalers.list
@@ -0,0 +1,18 @@
+VOID:NONE
+VOID:OBJECT
+VOID:POINTER
+VOID:STRING
+VOID:STRING,INT
+BOOL:POINTER
+BOOL:POINTER,POINTER
+BOOL:UINT,UINT
+VOID:INT,INT,INT,INT
+VOID:UINT,UINT
+VOID:OBJECT,UINT,BOOL
+VOID:OBJECT,BOOL
+VOID:BOXED,BOOL
+VOID:BOXED
+VOID:STRING,STRING,BOXED
+VOID:STRING,STRING,STRING
+VOID:UINT
+VOID:UINT,POINTER
diff --git a/src/ibusmessage.c b/src/ibusmessage.c
new file mode 100644
index 0000000..08457a3
--- /dev/null
+++ b/src/ibusmessage.c
@@ -0,0 +1,872 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibusmessage.h"
+#include "ibusserializable.h"
+#include "ibusconfigprivate.h"
+
+GType
+ibus_type_get_object_path (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_type_register_static_simple (
+ G_TYPE_STRING,
+ "IBusObjectPath",
+ 0,
+ NULL,
+ 0,
+ NULL,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+ return type;
+}
+
+GType
+ibus_type_get_array (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_type_register_static_simple (
+ G_TYPE_BOXED,
+ "IBusArray",
+ 0,
+ NULL,
+ 0,
+ NULL,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+ return type;
+}
+
+GType
+ibus_type_get_struct (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_type_register_static_simple (
+ G_TYPE_BOXED,
+ "IBusStruct",
+ 0,
+ NULL,
+ 0,
+ NULL,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+ return type;
+}
+
+GType
+ibus_type_get_dict_entry (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_type_register_static_simple (
+ G_TYPE_BOXED,
+ "IBusDictEntry",
+ 0,
+ NULL,
+ 0,
+ NULL,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+ return type;
+}
+
+GType
+ibus_type_get_variant (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_type_register_static_simple (G_TYPE_BOXED,
+ "IBusVariant",
+ 0,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ }
+ return type;
+}
+
+IBusMessage *
+ibus_message_new (gint message_type)
+{
+ return dbus_message_new (message_type);
+}
+
+IBusMessage *
+ibus_message_ref (IBusMessage *message)
+{
+ return dbus_message_ref (message);
+}
+
+void
+ibus_message_unref (IBusMessage *message)
+{
+ dbus_message_unref (message);
+}
+
+IBusMessage *
+ibus_message_new_method_call (const gchar *destination,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *method)
+{
+ return dbus_message_new_method_call (destination,
+ path,
+ interface,
+ method);
+}
+
+IBusMessage *
+ibus_message_new_method_return (IBusMessage *reply_to)
+{
+ return dbus_message_new_method_return (reply_to);
+}
+
+IBusMessage *
+ibus_message_new_error (IBusMessage *reply_to,
+ const gchar *error_name,
+ const gchar *error_message)
+{
+ return dbus_message_new_error (reply_to,
+ error_name,
+ error_message);
+}
+
+IBusMessage *
+ibus_message_new_error_printf (IBusMessage *reply_to,
+ const gchar *error_name,
+ const gchar *error_format,
+ ...)
+{
+ va_list va_args;
+ gchar *error_message;
+ IBusMessage *message;
+
+ va_start (va_args, error_format);
+ error_message = g_strdup_vprintf (error_format, va_args);
+ va_end (va_args);
+
+ message = ibus_message_new_error (reply_to,
+ error_name,
+ error_message);
+ g_free (error_message);
+
+ return message;
+}
+
+IBusMessage *
+ibus_message_new_signal (const gchar *path,
+ const gchar *interface,
+ const gchar *name)
+{
+ return dbus_message_new_signal (path,
+ interface,
+ name);
+}
+
+gboolean
+ibus_message_is_method_call (IBusMessage *message,
+ const gchar *interface,
+ const gchar *method)
+{
+ return dbus_message_is_method_call (message,
+ interface,
+ method);
+}
+
+gboolean
+ibus_message_is_error (IBusMessage *message,
+ const gchar *error_name)
+{
+ return dbus_message_is_error (message, error_name);
+}
+
+gboolean
+ibus_message_is_signal (IBusMessage *message,
+ const gchar *interface,
+ const gchar *signal_name)
+{
+ return dbus_message_is_signal (message,
+ interface,
+ signal_name);
+}
+
+gboolean
+ibus_message_set_destination (IBusMessage *message,
+ const gchar *destination)
+{
+ return dbus_message_set_destination (message, destination);
+}
+
+gboolean
+ibus_message_set_sender (IBusMessage *message,
+ const gchar *sender)
+{
+ return dbus_message_set_sender (message, sender);
+}
+
+gboolean
+ibus_message_set_error_name (IBusMessage *message,
+ const gchar *error_name)
+{
+ return dbus_message_set_error_name (message, error_name);
+}
+
+gboolean
+ibus_message_set_interface (IBusMessage *message,
+ const gchar *interface)
+{
+ return dbus_message_set_interface (message, interface);
+}
+
+gboolean
+ibus_message_set_member (IBusMessage *message,
+ const gchar *member)
+{
+ return dbus_message_set_member (message, member);
+}
+
+gboolean
+ibus_message_set_path (IBusMessage *message,
+ const gchar *path)
+{
+ return dbus_message_set_path (message, path);
+}
+
+void
+ibus_message_set_no_reply (IBusMessage *message,
+ gboolean no_reply)
+{
+ return dbus_message_set_no_reply (message, no_reply);
+}
+
+gboolean
+ibus_message_set_reply_serial (IBusMessage *message,
+ guint32 reply_serial)
+{
+ return dbus_message_set_reply_serial (message, reply_serial);
+}
+
+gint
+ibus_message_get_type (IBusMessage *message)
+{
+ return dbus_message_get_type (message);
+}
+
+const gchar *
+ibus_message_get_destination (IBusMessage *message)
+{
+ return dbus_message_get_destination (message);
+}
+
+const gchar *
+ibus_message_get_sender (IBusMessage *message)
+{
+ return dbus_message_get_sender (message);
+}
+
+const gchar *
+ibus_message_get_error_name (IBusMessage *message)
+{
+ return dbus_message_get_error_name (message);
+}
+
+const gchar *
+ibus_message_get_error_message (IBusMessage *message)
+{
+ gchar *error_message;
+ gboolean retval;
+
+ retval = ibus_message_get_args (message, NULL, G_TYPE_STRING, &error_message, G_TYPE_INVALID);
+
+ if (retval)
+ return error_message;
+ return NULL;
+}
+
+const gchar *
+ibus_message_get_interface (IBusMessage *message)
+{
+ return dbus_message_get_interface (message);
+}
+
+const gchar *
+ibus_message_get_member (IBusMessage *message)
+{
+ return dbus_message_get_member (message);
+}
+
+const gchar *
+ibus_message_get_path (IBusMessage *message)
+{
+ return dbus_message_get_path (message);
+}
+
+gboolean
+ibus_message_get_no_reply (IBusMessage *message)
+{
+ return dbus_message_get_no_reply (message);
+}
+
+guint32
+ibus_message_get_reply_serial (IBusMessage *message)
+{
+ return dbus_message_get_reply_serial (message);
+}
+
+guint32
+ibus_message_get_serial (IBusMessage *message)
+{
+ return dbus_message_get_serial (message);
+}
+
+gboolean
+ibus_message_append_args (IBusMessage *message,
+ GType first_arg_type,
+ ...)
+{
+ gboolean retval;
+ va_list va_args;
+
+ va_start (va_args, first_arg_type);
+ retval = ibus_message_append_args_valist (message,
+ first_arg_type,
+ va_args);
+ va_end (va_args);
+
+ return retval;
+}
+
+gboolean
+ibus_message_append_args_valist (IBusMessage *message,
+ GType first_arg_type,
+ va_list va_args)
+{
+ GType type;
+ gboolean retval;
+ IBusMessageIter iter;
+
+ ibus_message_iter_init_append (message, &iter);
+
+ type = first_arg_type;
+ while (type != G_TYPE_INVALID) {
+ gpointer value = va_arg (va_args, gpointer);
+ retval = ibus_message_iter_append (&iter, type, value);
+ type = va_arg (va_args, GType);
+
+ g_return_val_if_fail (retval, FALSE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+ibus_message_get_args (IBusMessage *message,
+ IBusError **error,
+ GType first_arg_type,
+ ...)
+{
+ gboolean retval;
+ va_list va_args;
+
+ va_start (va_args, first_arg_type);
+ retval = ibus_message_get_args_valist (message,
+ error,
+ first_arg_type,
+ va_args);
+ va_end (va_args);
+
+ return retval;
+
+}
+
+gboolean
+ibus_message_get_args_valist (IBusMessage *message,
+ IBusError **error,
+ GType first_arg_type,
+ va_list va_args)
+{
+ g_assert (message != NULL);
+
+ gboolean retval;
+ IBusMessageIter iter;
+ GType type;
+ gpointer value;
+ va_list backup_args;
+ gint i;
+
+ retval = ibus_message_iter_init (message, &iter);
+
+ if (!retval) {
+ if (error) {
+ *error = ibus_error_new_from_printf (DBUS_ERROR_INVALID_ARGS,
+ "Message does not have arguments!");
+ }
+ return FALSE;
+ }
+
+ va_copy (backup_args, va_args);
+
+ i = 0;
+ type = first_arg_type;
+ while (type != G_TYPE_INVALID) {
+ value = va_arg (va_args, gpointer);
+ retval = ibus_message_iter_get (&iter, type, value);
+ if (!retval)
+ goto _failed;
+ i ++;
+ type = va_arg (va_args, GType);
+ }
+ va_end (backup_args);
+
+ return TRUE;
+
+_failed:
+ *error = ibus_error_new_from_printf (DBUS_ERROR_INVALID_ARGS,
+ "The argument %d is not %s",
+ i,
+ g_type_name (type));
+ /* release resources */
+ type = first_arg_type;
+ while (i > 0) {
+ gpointer *value = va_arg (backup_args, gpointer *);
+ if (g_type_is_a (type, G_TYPE_BOXED)) {
+ g_boxed_free (type, *value);
+ }
+ else if (g_type_is_a (type, G_TYPE_OBJECT)) {
+ g_object_unref (*value);
+ }
+ i --;
+ type = va_arg (backup_args, GType);
+ }
+ va_end (backup_args);
+
+ return FALSE;
+}
+
+void
+ibus_message_iter_init_append (IBusMessage *message,
+ IBusMessageIter *iter)
+{
+ dbus_message_iter_init_append (message, iter);
+}
+
+gboolean
+ibus_message_iter_append (IBusMessageIter *iter,
+ GType type,
+ gconstpointer value)
+{
+ g_assert (iter != NULL);
+ g_assert (type != G_TYPE_INVALID);
+ g_assert (value != NULL);
+
+ switch (type) {
+ case G_TYPE_CHAR:
+ {
+ char v;
+ v = * (gchar *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &v);
+ }
+ case G_TYPE_INT:
+ {
+ dbus_int32_t v;
+ v = * (gint *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &v);
+ }
+ case G_TYPE_UINT:
+ {
+ dbus_uint32_t v;
+ v = * (guint *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &v);
+ }
+ case G_TYPE_ULONG:
+ {
+ dbus_uint64_t v;
+ v = * (gulong *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &v);
+ }
+ case G_TYPE_LONG:
+ {
+ dbus_int64_t v;
+ v = * (glong *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &v);
+ }
+ case G_TYPE_BOOLEAN:
+ {
+ dbus_bool_t v;
+ v = * (gboolean *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &v);
+ }
+ case G_TYPE_STRING:
+ {
+ const gchar *v;
+ v = * (gchar **)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &v);
+ }
+ case G_TYPE_INT64:
+ {
+ dbus_int64_t v;
+ v = * (gint64 *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &v);
+ }
+ case G_TYPE_UINT64:
+ {
+ dbus_uint64_t v;
+ v = * (guint64 *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &v);
+ }
+ case G_TYPE_FLOAT:
+ {
+ double v;
+ v = * (gfloat *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &v);
+ }
+
+ case G_TYPE_DOUBLE:
+ {
+ double v;
+ v = * (gdouble *)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &v);
+ }
+ default:
+ if (type == G_TYPE_VALUE) {
+ _to_dbus_value (iter, (GValue *)value);
+ return TRUE;
+ }
+ if (type == IBUS_TYPE_OBJECT_PATH) {
+ const gchar *v;
+ v = * (gchar **)value;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_OBJECT_PATH, &v);
+ }
+
+ if (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE)) {
+ return ibus_serializable_serialize (*(IBusSerializable **)value, iter);
+ }
+ }
+
+ return FALSE;
+}
+
+gboolean
+ibus_message_iter_init (IBusMessage *message,
+ IBusMessageIter *iter)
+{
+ return dbus_message_iter_init (message, iter);
+}
+
+void
+ibus_message_iter_get_basic (IBusMessageIter *iter,
+ gpointer value)
+{
+ dbus_message_iter_get_basic (iter, value);
+ dbus_message_iter_next (iter);
+}
+
+gboolean
+ibus_message_iter_get (IBusMessageIter *iter,
+ GType type,
+ gpointer value)
+{
+ gboolean retval;
+
+ retval = ibus_message_iter_peek (iter, type, value);
+ ibus_message_iter_next (iter);
+
+ return retval;
+}
+
+gboolean
+ibus_message_iter_peek (IBusMessageIter *iter,
+ GType type,
+ gpointer value)
+{
+ g_assert (iter != NULL);
+ g_assert (type != G_TYPE_INVALID);
+ g_assert (value != NULL);
+
+ switch (type) {
+ case G_TYPE_CHAR:
+ {
+ char v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_BYTE)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(gchar *) value = (gchar) v;
+ return TRUE;
+ }
+ case G_TYPE_INT:
+ {
+ dbus_int32_t v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_INT32)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(gint *) value = (gint) v;
+ return TRUE;
+ }
+ case G_TYPE_UINT:
+ {
+ dbus_uint32_t v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_UINT32)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(guint *) value = (guint) v;
+ return TRUE;
+ }
+ case G_TYPE_BOOLEAN:
+ {
+ dbus_bool_t v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_BOOLEAN)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(gboolean *) value = (gboolean) v;
+ return TRUE;
+ }
+ case G_TYPE_STRING:
+ {
+ gchar *v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRING)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(gchar **) value = (gchar *) v;
+ return TRUE;
+ }
+ case G_TYPE_INT64:
+ {
+ dbus_int64_t v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_INT64)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(gint64 *) value = (gint64) v;
+ return TRUE;
+ }
+ case G_TYPE_UINT64:
+ {
+ dbus_uint64_t v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_UINT64)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(guint64 *) value = (guint64) v;
+ return TRUE;
+ }
+ case G_TYPE_FLOAT:
+ {
+ double v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_DOUBLE)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(gfloat *) value = (gfloat) v;
+ return TRUE;
+ }
+
+ case G_TYPE_DOUBLE:
+ {
+ double v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_DOUBLE)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(gdouble *) value = (gdouble) v;
+ return TRUE;
+ }
+ default:
+ if (type == G_TYPE_VALUE) {
+ _from_dbus_value (iter, (GValue *) value);
+ return TRUE;
+ }
+ if (type == IBUS_TYPE_OBJECT_PATH) {
+ gchar *v;
+ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_OBJECT_PATH)
+ return FALSE;
+ dbus_message_iter_get_basic (iter, &v);
+ *(gchar **) value = (gchar *) v;
+ return TRUE;
+ }
+
+ if (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE)) {
+ IBusSerializable *v;
+ v = ibus_serializable_deserialize (iter);
+
+ if (v == NULL)
+ return FALSE;
+ if (!g_type_is_a (G_OBJECT_TYPE (v), type)) {
+ g_object_unref (v);
+ return FALSE;
+ }
+ *(gpointer *) value = v;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+gboolean
+ibus_message_iter_next (IBusMessageIter *iter)
+{
+ return dbus_message_iter_next (iter);
+}
+
+gboolean
+ibus_message_iter_has_next (IBusMessageIter *iter)
+{
+ return dbus_message_iter_has_next (iter);
+}
+
+gboolean
+ibus_message_iter_open_container (IBusMessageIter *iter,
+ GType type,
+ const gchar *contained_signature,
+ IBusMessageIter *sub)
+{
+ gint dbus_type;
+
+ if (type == IBUS_TYPE_ARRAY) {
+ dbus_type = DBUS_TYPE_ARRAY;
+ }
+ else if (type == IBUS_TYPE_STRUCT) {
+ dbus_type = DBUS_TYPE_STRUCT;
+ }
+ else if (type == IBUS_TYPE_DICT_ENTRY) {
+ dbus_type = DBUS_TYPE_DICT_ENTRY;
+ }
+ else if (type == IBUS_TYPE_VARIANT) {
+ dbus_type = DBUS_TYPE_VARIANT;
+ }
+ else
+ g_return_val_if_reached (FALSE);
+
+ return dbus_message_iter_open_container (iter,
+ dbus_type,
+ contained_signature,
+ sub);
+}
+
+gboolean
+ibus_message_iter_close_container (IBusMessageIter *iter,
+ IBusMessageIter *sub)
+{
+ return dbus_message_iter_close_container (iter, sub);
+}
+
+
+static GType
+dbus_type_to_gtype (gint type)
+{
+ switch (type) {
+#define TYPE_TABLE(a, b) case a: return (b);
+ TYPE_TABLE (DBUS_TYPE_BYTE, G_TYPE_CHAR);
+ TYPE_TABLE (DBUS_TYPE_INT32, G_TYPE_INT);
+ TYPE_TABLE (DBUS_TYPE_INT64, G_TYPE_INT64);
+ TYPE_TABLE (DBUS_TYPE_UINT32, G_TYPE_UINT);
+ TYPE_TABLE (DBUS_TYPE_UINT64, G_TYPE_UINT64);
+ TYPE_TABLE (DBUS_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+ TYPE_TABLE (DBUS_TYPE_DOUBLE, G_TYPE_DOUBLE);
+ TYPE_TABLE (DBUS_TYPE_STRING, G_TYPE_STRING);
+ TYPE_TABLE (DBUS_TYPE_OBJECT_PATH, IBUS_TYPE_OBJECT_PATH);
+ TYPE_TABLE (DBUS_TYPE_ARRAY, IBUS_TYPE_ARRAY);
+ TYPE_TABLE (DBUS_TYPE_STRUCT, IBUS_TYPE_STRUCT);
+ TYPE_TABLE (DBUS_TYPE_DICT_ENTRY, IBUS_TYPE_DICT_ENTRY);
+ TYPE_TABLE (DBUS_TYPE_VARIANT, IBUS_TYPE_VARIANT);
+#undef TYPE_TABLE
+ }
+ return G_TYPE_INVALID;
+}
+
+
+gboolean
+ibus_message_iter_recurse (IBusMessageIter *iter,
+ GType type,
+ IBusMessageIter *sub)
+{
+ g_assert (iter != NULL);
+ g_assert (sub != NULL);
+ g_assert (type == IBUS_TYPE_ARRAY ||
+ type == IBUS_TYPE_STRUCT ||
+ type == IBUS_TYPE_DICT_ENTRY ||
+ type == IBUS_TYPE_VARIANT);
+ GType gtype;
+
+ gtype = ibus_message_iter_get_arg_type (iter);
+
+ g_return_val_if_fail (gtype == type, FALSE);
+
+ dbus_message_iter_recurse (iter, sub);
+
+ return TRUE;
+}
+
+GType
+ibus_message_iter_get_arg_type (IBusMessageIter *iter)
+{
+ gint type;
+
+ type = dbus_message_iter_get_arg_type (iter);
+
+ return dbus_type_to_gtype (type);
+}
+
+
+GType
+ibus_message_iter_get_element_type (IBusMessageIter *iter)
+{
+ gint type;
+
+ type = dbus_message_iter_get_element_type (iter);
+
+ return dbus_type_to_gtype (type);
+}
+
+gchar *
+ibus_message_to_string (IBusMessage *message)
+{
+ g_assert (message != NULL);
+
+ GString *string = g_string_new ("");
+
+ IBusMessageIter iter;
+ GType type;
+ gint i = 0;
+
+ g_string_append_printf (string,
+ "message: %d\n"
+ "\tdestination = %s\n"
+ "\tpath = %s\n"
+ "\tinterface = %s\n"
+ "\tmember = %s\n",
+ ibus_message_get_type (message),
+ ibus_message_get_destination (message),
+ ibus_message_get_path (message),
+ ibus_message_get_interface (message),
+ ibus_message_get_member (message));
+
+ ibus_message_iter_init (message, &iter);
+ while ((type = ibus_message_iter_get_arg_type (&iter)) != G_TYPE_INVALID) {
+ g_string_append_printf (string, "\t\targ%d is %s\n", i++, g_type_name (type));
+ ibus_message_iter_next (&iter);
+ }
+
+ return g_string_free (string, FALSE);
+}
+
diff --git a/src/ibusmessage.h b/src/ibusmessage.h
new file mode 100644
index 0000000..36f4066
--- /dev/null
+++ b/src/ibusmessage.h
@@ -0,0 +1,146 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_MESSAGE_H_
+#define __IBUS_MESSAGE_H_
+
+#include <glib.h>
+#include <glib-object.h>
+#include <dbus/dbus.h>
+#include "ibuserror.h"
+
+#define IBUS_TYPE_OBJECT_PATH (ibus_type_get_object_path ())
+#define IBUS_TYPE_ARRAY (ibus_type_get_array ())
+#define IBUS_TYPE_STRUCT (ibus_type_get_struct ())
+#define IBUS_TYPE_DICT_ENTRY (ibus_type_get_dict_entry ())
+#define IBUS_TYPE_VARIANT (ibus_type_get_variant ())
+
+G_BEGIN_DECLS
+
+typedef DBusMessage IBusMessage;
+typedef DBusMessageIter IBusMessageIter;
+
+GType ibus_type_get_object_path (void);
+GType ibus_type_get_array (void);
+GType ibus_type_get_struct (void);
+GType ibus_type_get_dict_entry (void);
+GType ibus_type_get_variant (void);
+
+IBusMessage *ibus_message_new (gint message_type);
+IBusMessage *ibus_message_ref (IBusMessage *message);
+void ibus_message_unref (IBusMessage *message);
+IBusMessage *ibus_message_new_method_call (const gchar *destination,
+ const gchar *path,
+ const gchar *interface,
+ const gchar *method);
+IBusMessage *ibus_message_new_method_return (IBusMessage *reply_to);
+IBusMessage *ibus_message_new_error (IBusMessage *reply_to,
+ const gchar *error_name,
+ const gchar *error_message);
+IBusMessage *ibus_message_new_error_printf (IBusMessage *reply_to,
+ const gchar *error_name,
+ const gchar *error_format,
+ ...);
+IBusMessage *ibus_message_new_signal (const gchar *path,
+ const gchar *interface,
+ const gchar *method);
+gboolean ibus_message_is_method_call (IBusMessage *message,
+ const gchar *interface,
+ const gchar *method);
+gboolean ibus_message_is_error (IBusMessage *message,
+ const gchar *error_name);
+gboolean ibus_message_is_signal (IBusMessage *message,
+ const gchar *interface,
+ const gchar *signal_name);
+gboolean ibus_message_set_destination (IBusMessage *message,
+ const gchar *destination);
+gboolean ibus_message_set_sender (IBusMessage *message,
+ const gchar *sender);
+gboolean ibus_message_set_error_name (IBusMessage *message,
+ const gchar *error_name);
+gboolean ibus_message_set_interface (IBusMessage *message,
+ const gchar *interface);
+gboolean ibus_message_set_member (IBusMessage *message,
+ const gchar *member);
+gboolean ibus_message_set_path (IBusMessage *message,
+ const gchar *path);
+void ibus_message_set_no_reply (IBusMessage *message,
+ gboolean no_reply);
+gboolean ibus_message_set_reply_serial (IBusMessage *message,
+ guint32 reply_serial);
+gint ibus_message_get_type (IBusMessage *message);
+const gchar *ibus_message_get_destination (IBusMessage *message);
+const gchar *ibus_message_get_sender (IBusMessage *message);
+const gchar *ibus_message_get_error_name (IBusMessage *message);
+const gchar *ibus_message_get_error_message (IBusMessage *message);
+const gchar *ibus_message_get_interface (IBusMessage *message);
+const gchar *ibus_message_get_member (IBusMessage *message);
+const gchar *ibus_message_get_path (IBusMessage *message);
+gboolean ibus_message_get_no_reply (IBusMessage *message);
+guint32 ibus_message_get_reply_serial (IBusMessage *message);
+guint32 ibus_message_get_serial (IBusMessage *message);
+gboolean ibus_message_append_args (IBusMessage *message,
+ GType first_arg_type,
+ ...);
+gboolean ibus_message_append_args_valist(IBusMessage *message,
+ GType first_arg_type,
+ va_list va_args);
+gboolean ibus_message_get_args (IBusMessage *message,
+ IBusError **error,
+ GType first_arg_type,
+ ...);
+gboolean ibus_message_get_args_valist (IBusMessage *message,
+ IBusError **error,
+ GType first_arg_type,
+ va_list va_args);
+void ibus_message_iter_init_append (IBusMessage *message,
+ IBusMessageIter *iter);
+gboolean ibus_message_iter_append (IBusMessageIter *iter,
+ GType type,
+ gconstpointer value);
+gboolean ibus_message_iter_init (IBusMessage *message,
+ IBusMessageIter *iter);
+gboolean ibus_message_iter_peek (IBusMessageIter *iter,
+ GType type,
+ gpointer value);
+void ibus_message_iter_get_basic (IBusMessageIter *iter,
+ gpointer value);
+gboolean ibus_message_iter_get (IBusMessageIter *iter,
+ GType type,
+ gpointer value);
+gboolean ibus_message_iter_next (IBusMessageIter *iter);
+gboolean ibus_message_iter_has_next (IBusMessageIter *iter);
+gboolean ibus_message_iter_open_container
+ (IBusMessageIter *iter,
+ GType type,
+ const gchar *contained_signature,
+ IBusMessageIter *sub);
+gboolean ibus_message_iter_close_container
+ (IBusMessageIter *iter,
+ IBusMessageIter *sub);
+gboolean ibus_message_iter_recurse (IBusMessageIter *iter,
+ GType type,
+ IBusMessageIter *sub);
+GType ibus_message_iter_get_arg_type (IBusMessageIter *iter);
+GType ibus_message_iter_get_element_type
+ (IBusMessageIter *iter);
+gchar *ibus_message_to_string (IBusMessage *message);
+
+G_END_DECLS
+#endif
diff --git a/src/ibusobject.c b/src/ibusobject.c
new file mode 100644
index 0000000..2c2c25a
--- /dev/null
+++ b/src/ibusobject.c
@@ -0,0 +1,189 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusobject.h"
+#include "ibusinternal.h"
+
+#define IBUS_OBJECT_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_OBJECT, IBusObjectPrivate))
+
+enum {
+ DESTROY,
+ LAST_SIGNAL,
+};
+
+typedef struct _IBusObjectPrivate IBusObjectPrivate;
+struct _IBusObjectPrivate {
+ gpointer pad;
+};
+
+static guint object_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_object_class_init (IBusObjectClass *klass);
+static void ibus_object_init (IBusObject *obj);
+static GObject *ibus_object_constructor (GType type,
+ guint n,
+ GObjectConstructParam
+ *args);
+static void ibus_object_dispose (IBusObject *obj);
+static void ibus_object_finalize (IBusObject *obj);
+static void ibus_object_real_destroy (IBusObject *obj);
+
+static GObjectClass *parent_class = NULL;
+
+
+GType
+ibus_object_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusObjectClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_object_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusObject),
+ 0,
+ (GInstanceInitFunc) ibus_object_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "IBusObject",
+ &type_info,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+/**
+ * ibus_object_new:
+ *
+ * Creates a new instance of an #IBusObject.
+ *
+ * Returns: a new instance of #IBusObject.
+ */
+IBusObject *
+ibus_object_new (void)
+{
+ return IBUS_OBJECT (g_object_new (IBUS_TYPE_OBJECT, NULL));
+}
+
+static void
+ibus_object_class_init (IBusObjectClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusObjectPrivate));
+
+ gobject_class->constructor = ibus_object_constructor;
+ gobject_class->dispose = (GObjectFinalizeFunc) ibus_object_dispose;
+ gobject_class->finalize = (GObjectFinalizeFunc) ibus_object_finalize;
+
+ klass->destroy = ibus_object_real_destroy;
+
+ /* install signals */
+ object_signals[DESTROY] =
+ g_signal_new (I_("destroy"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusObjectClass, destroy),
+ NULL, NULL,
+ ibus_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+ibus_object_init (IBusObject *obj)
+{
+ IBusObjectPrivate *priv;
+ priv = IBUS_OBJECT_GET_PRIVATE (obj);
+
+ obj->flags = 0;
+}
+
+
+static GObject *
+ibus_object_constructor (GType type,
+ guint n,
+ GObjectConstructParam *args)
+{
+ GObject *object;
+
+ object = parent_class->constructor (type, n ,args);
+
+ return object;
+}
+
+
+static void
+ibus_object_dispose (IBusObject *obj)
+{
+ if (! (IBUS_OBJECT_FLAGS (obj) & IBUS_IN_DESTRUCTION)) {
+ IBUS_OBJECT_SET_FLAGS (obj, IBUS_IN_DESTRUCTION);
+ if (! (IBUS_OBJECT_FLAGS (obj) & IBUS_DESTROYED)) {
+ g_signal_emit (obj, object_signals[DESTROY], 0);
+ IBUS_OBJECT_SET_FLAGS (obj, IBUS_DESTROYED);
+ }
+ IBUS_OBJECT_UNSET_FLAGS (obj, IBUS_IN_DESTRUCTION);
+ }
+
+ G_OBJECT_CLASS(parent_class)->dispose (G_OBJECT (obj));
+}
+
+static void
+ibus_object_finalize (IBusObject *obj)
+{
+ G_OBJECT_CLASS(parent_class)->finalize (G_OBJECT (obj));
+}
+
+static void
+ibus_object_real_destroy (IBusObject *obj)
+{
+ g_signal_handlers_destroy (obj);
+}
+
+/**
+ * ibus_object_destroy:
+ * @object: an #IBusObject to destroy.
+ *
+ * Emit the "destory" signal notifying all reference holders that they should
+ * release the #IBusObject.
+ *
+ * The memory for the object itself won't be deleted until its reference count
+ * actually drops to 0; ibus_object_destroy merely asks reference holders to
+ * release their references. it does not free the object.
+ */
+void
+ibus_object_destroy (IBusObject *obj)
+{
+ IBusObjectPrivate *priv;
+ priv = IBUS_OBJECT_GET_PRIVATE (obj);
+
+ if (! (IBUS_OBJECT_FLAGS (obj) & IBUS_IN_DESTRUCTION)) {
+ g_object_run_dispose (G_OBJECT (obj));
+ }
+}
diff --git a/src/ibusobject.h b/src/ibusobject.h
new file mode 100644
index 0000000..2c09882
--- /dev/null
+++ b/src/ibusobject.h
@@ -0,0 +1,92 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_OBJECT_H_
+#define __IBUS_OBJECT_H_
+
+#include <glib-object.h>
+#include "ibusmarshalers.h"
+#include "ibustypes.h"
+#include "ibusdebug.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_OBJECT \
+ (ibus_object_get_type ())
+#define IBUS_OBJECT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_OBJECT, IBusObject))
+#define IBUS_OBJECT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_OBJECT, IBusObjectClass))
+#define IBUS_IS_OBJECT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_OBJECT))
+#define IBUS_IS_OBJECT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_OBJECT))
+#define IBUS_OBJECT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_OBJECT, IBusObjectClass))
+
+typedef enum {
+ IBUS_IN_DESTRUCTION = (1 << 0),
+ IBUS_DESTROYED = (1 << 1),
+ IBUS_RESERVED_1 = (1 << 2),
+ IBUS_RESERVED_2 = (1 << 3),
+} IBusObjectFlags;
+
+#define IBUS_OBJECT_FLAGS(obj) (IBUS_OBJECT (obj)->flags)
+#define IBUS_OBJECT_SET_FLAGS(obj,flag) G_STMT_START{ (IBUS_OBJECT_FLAGS (obj) |= (flag)); }G_STMT_END
+#define IBUS_OBJECT_UNSET_FLAGS(obj,flag) G_STMT_START{ (IBUS_OBJECT_FLAGS (obj) &= ~(flag)); }G_STMT_END
+
+G_BEGIN_DECLS
+
+typedef struct _IBusObject IBusObject;
+typedef struct _IBusObjectClass IBusObjectClass;
+/**
+ * IBusObject:
+ *
+ * All the fields in the <structname>IBusObject</structname> structure are
+ * prtivate to the #IBusObject and should never be accessed directly.
+ */
+struct _IBusObject {
+ GObject parent;
+ /* instance members */
+ guint32 flags;
+};
+
+typedef void ( *IBusObjectDestroyFunc) (IBusObject *);
+
+struct _IBusObjectClass {
+ GObjectClass parent;
+
+ /* signals */
+ void (* destroy) (IBusObject *object);
+
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[7];
+};
+
+GType ibus_object_get_type (void);
+IBusObject *ibus_object_new (void);
+void ibus_object_destroy (IBusObject *object);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusobservedpath.c b/src/ibusobservedpath.c
new file mode 100644
index 0000000..4dea00b
--- /dev/null
+++ b/src/ibusobservedpath.c
@@ -0,0 +1,335 @@
+/* vim:set et sts=4: */
+/* ibus - The Input IBus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <glib/gstdio.h>
+#include <stdlib.h>
+#include "ibusobservedpath.h"
+
+
+enum {
+ LAST_SIGNAL,
+};
+
+
+/* IBusObservedPathPriv */
+struct _IBusObservedPathPrivate {
+ gpointer pad;
+};
+typedef struct _IBusObservedPathPrivate IBusObservedPathPrivate;
+
+#define IBUS_OBSERVED_PATH_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_OBSERVED_PATH, IBusObservedPathPrivate))
+
+// static guint _signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_observed_path_class_init (IBusObservedPathClass *klass);
+static void ibus_observed_path_init (IBusObservedPath *path);
+static void ibus_observed_path_destroy (IBusObservedPath *path);
+static gboolean ibus_observed_path_serialize (IBusObservedPath *path,
+ IBusMessageIter *iter);
+static gboolean ibus_observed_path_deserialize (IBusObservedPath *path,
+ IBusMessageIter *iter);
+static gboolean ibus_observed_path_copy (IBusObservedPath *dest,
+ const IBusObservedPath *src);
+static gboolean ibus_observed_path_parse_xml_node (IBusObservedPath *path,
+ XMLNode *node);
+
+static IBusSerializableClass *parent_class = NULL;
+
+GType
+ibus_observed_path_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusObservedPathClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_observed_path_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusObservedPath),
+ 0,
+ (GInstanceInitFunc) ibus_observed_path_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusObservedPath",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+
+static void
+ibus_observed_path_class_init (IBusObservedPathClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ // g_type_class_add_private (klass, sizeof (IBusObservedPathPrivate));
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_observed_path_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_observed_path_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_observed_path_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_observed_path_copy;
+
+ g_string_append (serializable_class->signature, "sx");
+}
+
+
+static void
+ibus_observed_path_init (IBusObservedPath *path)
+{
+ path->path = NULL;
+}
+
+static void
+ibus_observed_path_destroy (IBusObservedPath *path)
+{
+ g_free (path->path);
+ IBUS_OBJECT_CLASS (parent_class)->destroy (IBUS_OBJECT (path));
+}
+
+static gboolean
+ibus_observed_path_serialize (IBusObservedPath *path,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = parent_class->serialize ((IBusSerializable *)path, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &(path->path));
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_LONG, &(path->mtime));
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_observed_path_deserialize (IBusObservedPath *path,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ gchar *str;
+
+ retval = parent_class->deserialize ((IBusSerializable *)path, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+ path->path = g_strdup (str);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_LONG, &(path->mtime));
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_observed_path_copy (IBusObservedPath *dest,
+ const IBusObservedPath *src)
+{
+ gboolean retval;
+
+ retval = parent_class->copy ((IBusSerializable *)dest, (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+ dest->path = g_strdup (src->path);
+ dest->mtime = src->mtime;
+
+ return TRUE;
+}
+
+#define g_string_append_indent(string, indent) \
+ { \
+ gint i; \
+ for (i = 0; i < (indent); i++) { \
+ g_string_append (string, " "); \
+ } \
+ }
+
+void
+ibus_observed_path_output (IBusObservedPath *path,
+ GString *output,
+ gint indent)
+{
+ g_assert (IBUS_IS_OBSERVED_PATH (path));
+ g_assert (output);
+
+ g_string_append_indent (output, indent);
+ g_string_append_printf (output, "<path mtime=\"%ld\" >%s</path>\n",
+ path->mtime,
+ path->path);
+}
+
+gboolean
+ibus_observed_path_check_modification (IBusObservedPath *path)
+{
+ g_assert (IBUS_IS_OBSERVED_PATH (path));
+ struct stat buf;
+
+ if (g_stat (path->path, &buf) != 0) {
+ buf.st_mtime = 0;
+ }
+
+ if (path->mtime == buf.st_mtime)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+ibus_observed_path_fill_stat (IBusObservedPath *path)
+{
+ g_assert (IBUS_IS_OBSERVED_PATH (path));
+
+ struct stat buf;
+
+ if (g_stat (path->path, &buf) == 0) {
+ path->is_exist = 1;
+ if (S_ISDIR (buf.st_mode)) {
+ path->is_dir = 1;
+ }
+ path->mtime = buf.st_mtime;
+ }
+ else {
+ path->is_dir = 0;
+ path->is_exist = 0;
+ path->mtime = 0;
+ }
+}
+
+GList *
+ibus_observed_path_traverse (IBusObservedPath *path)
+{
+ g_assert (IBUS_IS_OBSERVED_PATH (path));
+
+ GDir *dir;
+ const gchar *name;
+ GList *paths = NULL;
+
+ dir = g_dir_open (path->path, 0, NULL);
+
+ if (dir == NULL)
+ return NULL;
+
+ while ((name = g_dir_read_name (dir)) != NULL) {
+ IBusObservedPath *sub;
+
+ sub = g_object_new (IBUS_TYPE_OBSERVED_PATH, NULL);
+ sub->path = g_build_filename (path->path, name, NULL);
+
+ ibus_observed_path_fill_stat (sub);
+ paths = g_list_append (paths, sub);
+
+ if (sub->is_exist && sub->is_dir)
+ paths = g_list_concat (paths, ibus_observed_path_traverse (sub));
+ }
+ g_dir_close (dir);
+
+ return paths;
+}
+
+static gboolean
+ibus_observed_path_parse_xml_node (IBusObservedPath *path,
+ XMLNode *node)
+{
+ g_assert (IBUS_IS_OBSERVED_PATH (path));
+ g_assert (node);
+
+ if (G_UNLIKELY (g_strcmp0 (node->name, "path") != 0)) {
+ return FALSE;
+ }
+
+ if (node->text[0] == '~' && node->text[1] != G_DIR_SEPARATOR) {
+ g_warning ("invalide path \"%s\"", node->text);
+ return FALSE;
+ }
+
+ if (node->text[0] == '~') {
+ const gchar *homedir = g_getenv ("HOME");
+ if (homedir == NULL)
+ homedir = g_get_home_dir ();
+ path->path = g_build_filename (homedir, node->text + 2, NULL);
+ }
+ else {
+ path->path = g_strdup (node->text);
+ }
+
+ gchar **attr;
+ for (attr = node->attributes; attr[0]; attr += 2) {
+ if (g_strcmp0 (*attr, "mtime") == 0) {
+ path->mtime = atol (attr[1]);
+ continue;
+ }
+ g_warning ("Unkonwn attribute %s", attr[0]);
+ }
+
+ return TRUE;
+}
+
+IBusObservedPath *
+ibus_observed_path_new_from_xml_node (XMLNode *node,
+ gboolean fill_stat)
+{
+ g_assert (node);
+
+ IBusObservedPath *path;
+
+ path = (IBusObservedPath *) g_object_new (IBUS_TYPE_OBSERVED_PATH, NULL);
+
+ if (!ibus_observed_path_parse_xml_node (path, node)) {
+ g_object_unref (path);
+ path = NULL;
+ }
+ else if (fill_stat) {
+ ibus_observed_path_fill_stat (path);
+ }
+
+ return path;
+}
+
+IBusObservedPath *
+ibus_observed_path_new (const gchar *path,
+ gboolean fill_stat)
+{
+ g_assert (path);
+
+ IBusObservedPath *op;
+
+ op = (IBusObservedPath *) g_object_new (IBUS_TYPE_OBSERVED_PATH, NULL);
+ op->path = g_strdup (path);
+
+ if (fill_stat) {
+ ibus_observed_path_fill_stat (op);
+ }
+
+ return op;
+}
+
diff --git a/src/ibusobservedpath.h b/src/ibusobservedpath.h
new file mode 100644
index 0000000..4ebd625
--- /dev/null
+++ b/src/ibusobservedpath.h
@@ -0,0 +1,79 @@
+/* vim:set et sts=4: */
+/* ibus - The Input IBus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_OBSERVED_PATH_H_
+#define __IBUS_OBSERVED_PATH_H_
+
+#include "ibusserializable.h"
+#include "ibusxml.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_OBSERVED_PATH \
+ (ibus_observed_path_get_type ())
+#define IBUS_OBSERVED_PATH(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_OBSERVED_PATH, IBusObservedPath))
+#define IBUS_OBSERVED_PATH_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_OBSERVED_PATH, IBusObservedPathClass))
+#define IBUS_IS_OBSERVED_PATH(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_OBSERVED_PATH))
+#define IBUS_IS_OBSERVED_PATH_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_OBSERVED_PATH))
+#define IBUS_OBSERVED_PATH_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_OBSERVED_PATH, IBusObservedPathClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusObservedPath IBusObservedPath;
+typedef struct _IBusObservedPathClass IBusObservedPathClass;
+
+struct _IBusObservedPath {
+ IBusSerializable parent;
+ /* instance members */
+
+ gchar *path;
+ glong mtime;
+ gboolean is_dir;
+ gboolean is_exist;
+
+};
+
+struct _IBusObservedPathClass {
+ IBusSerializableClass parent;
+
+ /* class members */
+};
+
+GType ibus_observed_path_get_type (void);
+IBusObservedPath *ibus_observed_path_new_from_xml_node (XMLNode *node,
+ gboolean fill_stat);
+IBusObservedPath *ibus_observed_path_new (const gchar *path,
+ gboolean fill_stat);
+GList *ibus_observed_path_traverse (IBusObservedPath *path);
+gboolean ibus_observed_path_check_modification (IBusObservedPath *path);
+void ibus_observed_path_output (IBusObservedPath *path,
+ GString *output,
+ gint indent);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibuspendingcall.c b/src/ibuspendingcall.c
new file mode 100644
index 0000000..2812dbf
--- /dev/null
+++ b/src/ibuspendingcall.c
@@ -0,0 +1,103 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibuspendingcall.h"
+
+IBusPendingCall*
+ibus_pending_call_ref (IBusPendingCall *pending)
+{
+ return dbus_pending_call_ref (pending);
+}
+
+void
+ibus_pending_call_unref (IBusPendingCall *pending)
+{
+ dbus_pending_call_unref (pending);
+}
+
+gboolean
+ibus_pending_call_set_notify (IBusPendingCall *pending,
+ IBusPendingCallNotifyFunction function,
+ gpointer user_data,
+ GDestroyNotify free_user_data)
+{
+ return dbus_pending_call_set_notify (pending, function, user_data, free_user_data);
+}
+
+void
+ibus_pending_call_cancel (IBusPendingCall *pending)
+{
+ dbus_pending_call_cancel (pending);
+}
+
+gboolean
+ibus_pending_call_get_completed (IBusPendingCall *pending)
+{
+ return dbus_pending_call_get_completed (pending);
+}
+
+IBusMessage*
+ibus_pending_call_steal_reply (IBusPendingCall *pending)
+{
+ return dbus_pending_call_steal_reply (pending);
+}
+
+void
+ibus_pending_call_block (IBusPendingCall *pending)
+{
+ return dbus_pending_call_block (pending);
+}
+
+void
+ibus_pending_call_wait (IBusPendingCall *pending)
+{
+ g_assert (pending);
+
+ while (!ibus_pending_call_get_completed (pending)) {
+ g_main_context_iteration (NULL, TRUE);
+ }
+}
+
+gboolean
+ibus_pending_call_allocate_data_slot (gint *slot_p)
+{
+ return dbus_pending_call_allocate_data_slot (slot_p);
+}
+
+void
+ibus_pending_call_free_data_slot (gint *slot_p)
+{
+ dbus_pending_call_free_data_slot (slot_p);
+}
+
+gboolean
+ibus_pending_call_set_data (IBusPendingCall *pending,
+ gint slot,
+ gpointer data,
+ GDestroyNotify free_data_func)
+{
+ return dbus_pending_call_set_data (pending, slot, data, free_data_func);
+}
+
+gpointer
+ibus_pending_call_get_data (IBusPendingCall *pending,
+ gint slot)
+{
+ return dbus_pending_call_get_data (pending, slot);
+}
diff --git a/src/ibuspendingcall.h b/src/ibuspendingcall.h
new file mode 100644
index 0000000..ff76df6
--- /dev/null
+++ b/src/ibuspendingcall.h
@@ -0,0 +1,56 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_PENDING_CALL_H_
+#define __IBUS_PENDING_CALL_H_
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include "ibusmessage.h"
+
+G_BEGIN_DECLS
+
+typedef DBusPendingCall IBusPendingCall;
+typedef void (* IBusPendingCallNotifyFunction)(IBusPendingCall *pending, gpointer user_data);
+
+
+IBusPendingCall* ibus_pending_call_ref (IBusPendingCall *pending);
+void ibus_pending_call_unref (IBusPendingCall *pending);
+gboolean ibus_pending_call_set_notify (IBusPendingCall *pending,
+ IBusPendingCallNotifyFunction function,
+ gpointer user_data,
+ GDestroyNotify free_user_data);
+void ibus_pending_call_cancel (IBusPendingCall *pending);
+gboolean ibus_pending_call_get_completed (IBusPendingCall *pending);
+IBusMessage* ibus_pending_call_steal_reply (IBusPendingCall *pending);
+void ibus_pending_call_block (IBusPendingCall *pending);
+void ibus_pending_call_wait (IBusPendingCall *pending);
+gboolean ibus_pending_call_allocate_data_slot
+ (gint *slot_p);
+void ibus_pending_call_free_data_slot
+ (gint *slot_p);
+gboolean ibus_pending_call_set_data (IBusPendingCall *pending,
+ gint slot,
+ gpointer data,
+ GDestroyNotify free_data_func);
+gpointer ibus_pending_call_get_data (IBusPendingCall *pending,
+ gint slot);
+
+G_END_DECLS
+#endif
diff --git a/src/ibusproperty.c b/src/ibusproperty.c
new file mode 100644
index 0000000..712bf1f
--- /dev/null
+++ b/src/ibusproperty.c
@@ -0,0 +1,531 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibusproperty.h"
+
+/* functions prototype */
+static void ibus_property_class_init (IBusPropertyClass *klass);
+static void ibus_property_init (IBusProperty *prop);
+static void ibus_property_destroy (IBusProperty *prop);
+static gboolean ibus_property_serialize (IBusProperty *prop,
+ IBusMessageIter *iter);
+static gboolean ibus_property_deserialize (IBusProperty *prop,
+ IBusMessageIter *iter);
+static gboolean ibus_property_copy (IBusProperty *dest,
+ const IBusProperty *src);
+
+static void ibus_prop_list_class_init (IBusPropListClass *klass);
+static void ibus_prop_list_init (IBusPropList *prop_list);
+static void ibus_prop_list_destroy (IBusPropList *prop_list);
+static gboolean ibus_prop_list_serialize (IBusPropList *prop_list,
+ IBusMessageIter *iter);
+static gboolean ibus_prop_list_deserialize (IBusPropList *prop_list,
+ IBusMessageIter *iter);
+static gboolean ibus_prop_list_copy (IBusPropList *dest,
+ const IBusPropList *src);
+
+static IBusSerializableClass *parent_class = NULL;
+
+GType
+ibus_property_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusPropertyClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_property_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusProperty),
+ 0,
+ (GInstanceInitFunc) ibus_property_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusProperty",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_property_class_init (IBusPropertyClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_property_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_property_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_property_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_property_copy;
+
+ g_string_append (serializable_class->signature, "suvsvbbuv");
+}
+
+static void
+ibus_property_init (IBusProperty *prop)
+{
+ prop->key = NULL;
+ prop->type = 0;
+ prop->label = NULL;
+ prop->icon = NULL;
+ prop->tooltip = NULL;
+ prop->sensitive = FALSE;
+ prop->visible = FALSE;
+ prop->state = 0;
+}
+
+static void
+ibus_property_destroy (IBusProperty *prop)
+{
+ g_free (prop->key);
+ g_free (prop->icon);
+
+ prop->key = NULL;
+ prop->icon = NULL;
+
+ if (prop->label) {
+ g_object_unref (prop->label);
+ prop->label = NULL;
+ }
+
+ if (prop->tooltip) {
+ g_object_unref (prop->tooltip);
+ prop->tooltip = NULL;
+ }
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)prop);
+}
+
+gboolean
+ibus_property_serialize (IBusProperty *prop,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = parent_class->serialize ((IBusSerializable *) prop, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_PROPERTY (prop), FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &prop->key);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &prop->type);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, IBUS_TYPE_TEXT, &prop->label);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &prop->icon);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, IBUS_TYPE_TEXT, &prop->tooltip);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_BOOLEAN, &prop->sensitive);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_BOOLEAN, &prop->visible);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_UINT, &prop->state);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, IBUS_TYPE_PROP_LIST, &prop->sub_props);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_property_deserialize (IBusProperty *prop,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ gchar *p;
+
+ retval = parent_class->deserialize ((IBusSerializable *) prop, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &p);
+ g_return_val_if_fail (retval, FALSE);
+ prop->key = g_strdup (p);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &prop->type);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, IBUS_TYPE_TEXT, &prop->label);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &p);
+ g_return_val_if_fail (retval, FALSE);
+ prop->icon = g_strdup (p);
+
+ retval = ibus_message_iter_get (iter, IBUS_TYPE_TEXT, &prop->tooltip);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_BOOLEAN, &prop->sensitive);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_BOOLEAN, &prop->visible);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_UINT, &prop->state);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, IBUS_TYPE_PROP_LIST, &prop->sub_props);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_property_copy (IBusProperty *dest,
+ const IBusProperty *src)
+{
+ gboolean retval;
+
+ retval = parent_class->copy ((IBusSerializable *) dest, (IBusSerializable *) src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_PROPERTY (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_PROPERTY (src), FALSE);
+
+ dest->key = g_strdup (src->key);
+ dest->icon = g_strdup (src->icon);
+ if (src->label) {
+ dest->label = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->label);
+ }
+ else
+ dest->label = ibus_text_new_from_static_string ("");
+ if (src->tooltip) {
+ dest->tooltip = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->tooltip);
+ }
+ else
+ dest->tooltip = ibus_text_new_from_static_string ("");
+
+ dest->sensitive = src->sensitive;
+ dest->visible = src->visible;
+ dest->type = src->type;
+ dest->state = src->state;
+
+ dest->sub_props = (IBusPropList *) ibus_serializable_copy ((IBusSerializable *) src->sub_props);
+
+ return TRUE;
+}
+
+IBusProperty *
+ibus_property_new (const gchar *key,
+ IBusPropType type,
+ IBusText *label,
+ const gchar *icon,
+ IBusText *tooltip,
+ gboolean sensitive,
+ gboolean visible,
+ IBusPropState state,
+ IBusPropList *prop_list)
+{
+ g_return_val_if_fail (key != NULL, NULL);
+ g_return_val_if_fail (type >= PROP_TYPE_NORMAL &&
+ type <= PROP_TYPE_SEPARATOR,
+ NULL);
+ g_return_val_if_fail (label == NULL || IBUS_IS_TEXT (label), NULL);
+ g_return_val_if_fail (tooltip == NULL || IBUS_IS_TEXT (tooltip), NULL);
+ g_return_val_if_fail (state == PROP_STATE_UNCHECKED ||
+ state == PROP_STATE_CHECKED ||
+ state == PROP_STATE_INCONSISTENT,
+ NULL);
+
+ IBusProperty *prop;
+
+ prop = (IBusProperty *)g_object_new (IBUS_TYPE_PROPERTY, 0);
+
+ prop->key = g_strdup (key);
+ prop->icon = g_strdup (icon != NULL ? icon : "");
+ prop->type = type;
+
+ if (label)
+ prop->label = (IBusText *) g_object_ref (label);
+ else
+ prop->label = ibus_text_new_from_static_string ("");
+
+ if (tooltip)
+ prop->tooltip = (IBusText *) g_object_ref (tooltip);
+ else
+ prop->tooltip = ibus_text_new_from_static_string ("");
+
+ prop->sensitive = sensitive;
+ prop->visible = visible;
+ prop->state = state;
+
+ if (prop_list)
+ prop->sub_props = g_object_ref (prop_list);
+ else
+ prop->sub_props = ibus_prop_list_new ();
+
+ return prop;
+}
+
+void
+ibus_property_set_label (IBusProperty *prop,
+ IBusText *label)
+{
+ g_assert (IBUS_IS_PROPERTY (prop));
+
+ if (prop->label) {
+ g_object_unref (prop->label);
+ }
+
+ if (label == NULL) {
+ label = ibus_text_new_from_static_string ("");
+ }
+
+ prop->label = g_object_ref (label);
+}
+
+void
+ibus_property_set_visible (IBusProperty *prop,
+ gboolean visible)
+{
+ g_assert (IBUS_IS_PROPERTY (prop));
+ prop->visible = visible;
+}
+
+void
+ibus_property_set_sub_props (IBusProperty *prop,
+ IBusPropList *prop_list)
+{
+ g_return_if_fail (IBUS_IS_PROPERTY (prop));
+ g_return_if_fail (IBUS_IS_PROP_LIST (prop_list) || prop_list == NULL);
+
+ if (prop->sub_props) {
+ g_object_unref (prop->sub_props);
+ }
+
+ if (prop_list) {
+ g_object_ref (prop_list);
+ prop->sub_props = prop_list;
+ }
+ else
+ prop->sub_props = ibus_prop_list_new ();
+}
+
+GType
+ibus_prop_list_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusPropListClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_prop_list_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusProperty),
+ 0,
+ (GInstanceInitFunc) ibus_prop_list_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusPropList",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_prop_list_class_init (IBusPropListClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_prop_list_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_prop_list_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_prop_list_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_prop_list_copy;
+
+ g_string_append (serializable_class->signature, "av");
+}
+
+static void
+ibus_prop_list_init (IBusPropList *prop_list)
+{
+ prop_list->properties = g_array_new (TRUE, TRUE, sizeof (IBusProperty *));
+}
+
+static void
+ibus_prop_list_destroy (IBusPropList *prop_list)
+{
+ IBusProperty **ps, **p;
+ p = ps = (IBusProperty **) g_array_free (prop_list->properties, FALSE);
+
+ while (*p != NULL) {
+ g_object_unref (*p);
+ p ++;
+ }
+ g_free (ps);
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *) prop_list);
+}
+
+static gboolean
+ibus_prop_list_serialize (IBusPropList *prop_list,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ IBusMessageIter array_iter;
+ IBusProperty *prop;
+ guint i;
+
+ retval = parent_class->serialize ((IBusSerializable *) prop_list, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_open_container (iter, IBUS_TYPE_ARRAY, "v", &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ i = 0;
+
+ while ((prop = ibus_prop_list_get (prop_list, i)) != NULL) {
+ retval = ibus_message_iter_append (&array_iter, IBUS_TYPE_PROPERTY, &prop);
+ g_return_val_if_fail (retval, FALSE);
+ i ++;
+ }
+
+ retval = ibus_message_iter_close_container (iter, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+gboolean
+ibus_prop_list_deserialize (IBusPropList *prop_list,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ IBusMessageIter array_iter;
+ IBusSerializable *object;
+
+ retval = parent_class->deserialize ((IBusSerializable *) prop_list, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_PROP_LIST (prop_list), FALSE);
+
+ retval = ibus_message_iter_recurse (iter, IBUS_TYPE_ARRAY, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ while (ibus_message_iter_get_arg_type (&array_iter) != G_TYPE_INVALID) {
+ retval = ibus_message_iter_get (&array_iter, IBUS_TYPE_PROPERTY, &object);
+ g_return_val_if_fail (retval, FALSE);
+
+ ibus_prop_list_append (prop_list, (IBusProperty *)object);
+ g_object_unref (object);
+ }
+
+ ibus_message_iter_next (iter);
+
+ return TRUE;
+}
+
+
+
+static gboolean
+ibus_prop_list_copy (IBusPropList *dest,
+ const IBusPropList *src)
+{
+ gboolean retval;
+ IBusProperty *prop;
+ guint i;
+
+ retval = parent_class->copy ((IBusSerializable *) dest,
+ (const IBusSerializable *) src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_PROP_LIST (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_PROP_LIST (src), FALSE);
+
+ i = 0;
+ while ((prop = ibus_prop_list_get ((IBusPropList *)src, i)) != NULL) {
+ prop = (IBusProperty *) ibus_serializable_copy ((IBusSerializable *) prop);
+ ibus_prop_list_append (dest, prop);
+ g_object_unref (prop);
+ i ++;
+ }
+ return TRUE;
+}
+
+
+IBusPropList *
+ibus_prop_list_new ()
+{
+ IBusPropList *prop_list;
+
+ prop_list = g_object_new (IBUS_TYPE_PROP_LIST, NULL);
+
+ return prop_list;
+}
+
+void
+ibus_prop_list_append (IBusPropList *prop_list,
+ IBusProperty *prop)
+{
+ g_return_if_fail (IBUS_IS_PROP_LIST (prop_list));
+ g_return_if_fail (IBUS_IS_PROPERTY (prop));
+
+ g_object_ref (prop);
+
+ g_array_append_val (prop_list->properties, prop);
+}
+
+IBusProperty *
+ibus_prop_list_get (IBusPropList *prop_list,
+ guint index)
+{
+ g_return_val_if_fail (IBUS_IS_PROP_LIST (prop_list), NULL);
+
+
+ if (index >= prop_list->properties->len)
+ return NULL;
+
+ return g_array_index (prop_list->properties, IBusProperty *, index);
+}
+
+
+
+gboolean
+ibus_prop_list_update_property (IBusPropList *prop_list,
+ IBusProperty *prop)
+{
+ return FALSE;
+}
diff --git a/src/ibusproperty.h b/src/ibusproperty.h
new file mode 100644
index 0000000..7cd90c9
--- /dev/null
+++ b/src/ibusproperty.h
@@ -0,0 +1,140 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_PROPERTY_H_
+#define __IBUS_PROPERTY_H_
+
+#include "ibusserializable.h"
+#include "ibustext.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type macros.
+ */
+#define IBUS_TYPE_PROPERTY (ibus_property_get_type ())
+#define IBUS_TYPE_PROP_LIST (ibus_prop_list_get_type ())
+
+/* define IBusProperty macros */
+#define IBUS_TYPE_PROPERTY \
+ (ibus_property_get_type ())
+#define IBUS_PROPERTY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_PROPERTY, IBusProperty))
+#define IBUS_PROPERTY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_PROPERTY, IBusPropertyClass))
+#define IBUS_IS_PROPERTY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_PROPERTY))
+#define IBUS_IS_PROPERTY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_PROPERTY))
+#define IBUS_PROPERTY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_PROPERTY, IBusPropertyClass))
+
+/* define IBusPropList macros */
+#define IBUS_TYPE_PROP_LIST \
+ (ibus_prop_list_get_type ())
+#define IBUS_PROP_LIST(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_PROP_LIST, IBusPropList))
+#define IBUS_PROP_LIST_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_PROP_LIST, IBusPropListClass))
+#define IBUS_IS_PROP_LIST(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_PROP_LIST))
+#define IBUS_IS_PROP_LIST_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_PROP_LIST))
+#define IBUS_PROP_LIST_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_PROP_LIST, IBusPropListClass))
+
+
+typedef enum {
+ PROP_TYPE_NORMAL = 0,
+ PROP_TYPE_TOGGLE = 1,
+ PROP_TYPE_RADIO = 2,
+ PROP_TYPE_MENU = 3,
+ PROP_TYPE_SEPARATOR = 4,
+} IBusPropType;
+
+typedef enum {
+ PROP_STATE_UNCHECKED = 0,
+ PROP_STATE_CHECKED = 1,
+ PROP_STATE_INCONSISTENT = 2,
+} IBusPropState;
+
+
+typedef struct _IBusProperty IBusProperty;
+typedef struct _IBusPropertyClass IBusPropertyClass;
+typedef struct _IBusPropList IBusPropList;
+typedef struct _IBusPropListClass IBusPropListClass;
+
+struct _IBusProperty {
+ IBusSerializable parent;
+
+ gchar *key;
+ gchar *icon;
+ IBusText *label;
+ IBusText *tooltip;
+
+ gboolean sensitive;
+ gboolean visible;
+ guint type;
+ guint state;
+
+ IBusPropList *sub_props;
+};
+
+struct _IBusPropertyClass {
+ IBusSerializableClass parent;
+};
+
+struct _IBusPropList {
+ IBusSerializable parent;
+
+ GArray *properties;
+};
+
+struct _IBusPropListClass {
+ IBusSerializableClass parent;
+};
+
+GType ibus_property_get_type ();
+IBusProperty *ibus_property_new (const gchar *key,
+ IBusPropType type,
+ IBusText *label,
+ const gchar *icon,
+ IBusText *tooltip,
+ gboolean sensitive,
+ gboolean visible,
+ IBusPropState state,
+ IBusPropList *prop_list);
+void ibus_property_set_label (IBusProperty *prop,
+ IBusText *label);
+void ibus_property_set_visible (IBusProperty *prop,
+ gboolean visible);
+void ibus_property_set_sub_props(IBusProperty *prop,
+ IBusPropList *prop_list);
+
+GType ibus_prop_list_get_type ();
+IBusPropList *ibus_prop_list_new ();
+void ibus_prop_list_append (IBusPropList *prop_list,
+ IBusProperty *prop);
+IBusProperty *ibus_prop_list_get (IBusPropList *prop_list,
+ guint index);
+gboolean ibus_prop_list_update_property
+ (IBusPropList *prop_list,
+ IBusProperty *prop);
+G_END_DECLS
+#endif
diff --git a/src/ibusproxy.c b/src/ibusproxy.c
new file mode 100644
index 0000000..5ef3b40
--- /dev/null
+++ b/src/ibusproxy.c
@@ -0,0 +1,638 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdarg.h>
+#include "ibusmessage.h"
+#include "ibusproxy.h"
+#include "ibusinternal.h"
+
+#define IBUS_PROXY_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_PROXY, IBusProxyPrivate))
+
+enum {
+ IBUS_SIGNAL,
+ LAST_SIGNAL,
+};
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ PROP_PATH,
+ PROP_INTERFACE,
+ PROP_CONNECTION,
+};
+
+
+/* IBusProxyPriv */
+struct _IBusProxyPrivate {
+ gchar *name;
+ gchar *path;
+ gchar *interface;
+ IBusConnection *connection;
+};
+typedef struct _IBusProxyPrivate IBusProxyPrivate;
+
+static guint proxy_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_proxy_class_init (IBusProxyClass *klass);
+static void ibus_proxy_init (IBusProxy *proxy);
+static GObject *ibus_proxy_constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params);
+static void ibus_proxy_destroy (IBusProxy *proxy);
+static void ibus_proxy_set_property(IBusProxy *proxy,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ibus_proxy_get_property(IBusProxy *proxy,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static gboolean ibus_proxy_ibus_signal (IBusProxy *proxy,
+ IBusMessage *message);
+
+static IBusObjectClass *parent_class = NULL;
+
+GType
+ibus_proxy_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusProxyClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_proxy_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusProxy),
+ 0,
+ (GInstanceInitFunc) ibus_proxy_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_OBJECT,
+ "IBusProxy",
+ &type_info,
+ (GTypeFlags)0);
+ }
+ return type;
+}
+
+IBusProxy *
+ibus_proxy_new (const gchar *name,
+ const gchar *path,
+ IBusConnection *connection)
+{
+ g_assert (name != NULL);
+ g_assert (path != NULL);
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ IBusProxy *proxy;
+
+ proxy = IBUS_PROXY (g_object_new (IBUS_TYPE_PROXY,
+ "name", name,
+ "path", path,
+ "connection", connection,
+ NULL));
+
+ return proxy;
+}
+
+static void
+ibus_proxy_class_init (IBusProxyClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusProxyPrivate));
+
+ gobject_class->constructor = ibus_proxy_constructor;
+ gobject_class->set_property = (GObjectSetPropertyFunc) ibus_proxy_set_property;
+ gobject_class->get_property = (GObjectGetPropertyFunc) ibus_proxy_get_property;
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_proxy_destroy;
+
+ klass->ibus_signal = ibus_proxy_ibus_signal;
+
+ /* install properties */
+ g_object_class_install_property (gobject_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ "service name",
+ "The service name of proxy object",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class,
+ PROP_PATH,
+ g_param_spec_string ("path",
+ "object path",
+ "The path of proxy object",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class,
+ PROP_INTERFACE,
+ g_param_spec_string ("interface",
+ "interface",
+ "The interface of proxy object",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class,
+ PROP_CONNECTION,
+ g_param_spec_object ("connection",
+ "object path",
+ "The path of proxy object",
+ IBUS_TYPE_CONNECTION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /* install signals */
+ proxy_signals[IBUS_SIGNAL] =
+ g_signal_new (I_("ibus-signal"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusProxyClass, ibus_signal),
+ NULL, NULL,
+ ibus_marshal_BOOLEAN__POINTER,
+ G_TYPE_BOOLEAN,
+ 1, G_TYPE_POINTER);
+
+}
+
+static gboolean
+_connection_ibus_signal_cb (IBusConnection *connection,
+ IBusMessage *message,
+ IBusProxy *proxy)
+{
+ if (ibus_proxy_handle_signal (proxy, message)) {
+ g_signal_stop_emission_by_name (connection, "ibus-signal");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+_connection_destroy_cb (IBusConnection *connection,
+ IBusProxy *proxy)
+{
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ g_assert (priv->connection == connection);
+
+ g_object_unref (connection);
+ priv->connection = NULL;
+
+ ibus_object_destroy ((IBusObject *) proxy);
+}
+
+static GObject *
+ibus_proxy_constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *obj;
+ IBusProxy *proxy;
+ IBusProxyPrivate *priv;
+
+ obj = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_params, construct_params);
+
+ proxy = IBUS_PROXY (obj);
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ if (priv->connection != NULL) {
+ if (priv->name != NULL) {
+
+ IBusError *error;
+ gchar *rule;
+
+ rule = g_strdup_printf ("type='signal',"
+ "sender='" DBUS_SERVICE_DBUS "',"
+ "path='" DBUS_PATH_DBUS "',"
+ "interface='" DBUS_INTERFACE_DBUS "',"
+ "member='NameOwnerChanged',"
+ "arg0='%s'",
+ priv->name);
+
+ if (!ibus_connection_call (priv->connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "AddMatch",
+ &error,
+ G_TYPE_STRING, &rule,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ }
+ g_free (rule);
+ }
+ g_signal_connect (priv->connection,
+ "ibus-signal",
+ (GCallback) _connection_ibus_signal_cb,
+ proxy);
+
+ g_signal_connect (priv->connection,
+ "destroy",
+ (GCallback) _connection_destroy_cb,
+ proxy);
+ }
+
+ return obj;
+}
+
+static void
+ibus_proxy_init (IBusProxy *proxy)
+{
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ priv->name = NULL;
+ priv->path = NULL;
+ priv->interface = NULL;
+ priv->connection = NULL;
+}
+
+static void
+ibus_proxy_destroy (IBusProxy *proxy)
+{
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ if (priv->connection) {
+
+ g_signal_handlers_disconnect_by_func (priv->connection,
+ (GCallback) _connection_ibus_signal_cb,
+ proxy);
+ g_signal_handlers_disconnect_by_func (priv->connection,
+ (GCallback) _connection_destroy_cb,
+ proxy);
+
+ if (priv->name != NULL) {
+
+ IBusError *error;
+ gchar *rule;
+
+ rule = g_strdup_printf ("type='signal',"
+ "sender='" DBUS_SERVICE_DBUS "',"
+ "path='" DBUS_PATH_DBUS "',"
+ "interface='" DBUS_INTERFACE_DBUS "',"
+ "member='NameOwnerChanged',"
+ "arg0='%s'",
+ priv->name);
+
+ if (!ibus_connection_call (priv->connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "RemoveMatch",
+ &error,
+ G_TYPE_STRING, &rule,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID)) {
+
+ g_warning ("%s: %s", error->name, error->message);
+ ibus_error_free (error);
+ }
+ g_free (rule);
+ }
+ }
+
+ g_free (priv->name);
+ g_free (priv->path);
+ g_free (priv->interface);
+
+ priv->name = NULL;
+ priv->path = NULL;
+ priv->interface = NULL;
+
+ if (priv->connection) {
+ g_object_unref (priv->connection);
+ priv->connection = NULL;
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (proxy));
+}
+
+static void
+ibus_proxy_set_property (IBusProxy *proxy,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_assert (priv->name == NULL);
+ priv->name = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_PATH:
+ g_assert (priv->path == NULL);
+ priv->path = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_INTERFACE:
+ g_assert (priv->interface == NULL);
+ priv->interface = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_CONNECTION:
+ g_assert (priv->connection == NULL);
+ priv->connection = IBUS_CONNECTION (g_value_get_object (value));
+ g_object_ref (priv->connection);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (proxy, prop_id, pspec);
+ }
+}
+
+static void
+ibus_proxy_get_property (IBusProxy *proxy,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, ibus_proxy_get_name (proxy));
+ break;
+ case PROP_PATH:
+ g_value_set_string (value, ibus_proxy_get_path (proxy));
+ break;
+ case PROP_INTERFACE:
+ g_value_set_string (value, ibus_proxy_get_interface (proxy));
+ break;
+ case PROP_CONNECTION:
+ g_value_set_object (value, ibus_proxy_get_connection (proxy));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (proxy, prop_id, pspec);
+ }
+}
+
+
+gboolean
+ibus_proxy_handle_signal (IBusProxy *proxy,
+ DBusMessage *message)
+{
+ g_assert (IBUS_IS_PROXY (proxy));
+ g_assert (message != NULL);
+
+ gboolean retval = FALSE;
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ if (ibus_message_is_signal (message, DBUS_SERVICE_DBUS, "NameOwnerChanged")) {
+ gchar *name, *old_name, *new_name;
+ IBusError *error;
+
+ if (!ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &name,
+ G_TYPE_STRING, &old_name,
+ G_TYPE_STRING, &new_name,
+ G_TYPE_INVALID)) {
+ g_warning ("%s :%s", error->name, error->message);
+ ibus_error_free (error);
+ }
+
+ if (g_strcmp0 (priv->name, old_name) == 0) {
+ ibus_object_destroy (IBUS_OBJECT (proxy));
+ return FALSE;
+ }
+ }
+
+ if (g_strcmp0 (ibus_message_get_path (message), priv->path) == 0) {
+ g_signal_emit (proxy, proxy_signals[IBUS_SIGNAL], 0, message, &retval);
+ }
+
+ return retval;
+}
+
+static gboolean
+ibus_proxy_ibus_signal (IBusProxy *proxy,
+ DBusMessage *message)
+{
+ return FALSE;
+}
+
+
+const gchar *
+ibus_proxy_get_name (IBusProxy *proxy)
+{
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ return priv->name;
+}
+
+const gchar *
+ibus_proxy_get_path (IBusProxy *proxy)
+{
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ return priv->path;
+}
+
+const gchar *
+ibus_proxy_get_interface (IBusProxy *proxy)
+{
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ return priv->interface;
+}
+
+IBusConnection *
+ibus_proxy_get_connection (IBusProxy *proxy)
+{
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ return priv->connection;
+}
+
+gboolean
+ibus_proxy_send (IBusProxy *proxy,
+ DBusMessage *message)
+{
+ g_assert (IBUS_IS_PROXY (proxy));
+ g_assert (message != NULL);
+
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ g_return_val_if_fail (priv->connection, FALSE);
+ g_return_val_if_fail (ibus_connection_is_connected (priv->connection), FALSE);
+
+ return ibus_connection_send (priv->connection, message);
+}
+
+gboolean
+ibus_proxy_call (IBusProxy *proxy,
+ const gchar *method,
+ GType first_arg_type,
+ ...)
+{
+ g_assert (IBUS_IS_PROXY (proxy));
+ g_assert (method != NULL);
+
+ va_list args;
+ gboolean retval;
+ DBusMessage *message;
+
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ g_return_val_if_fail (priv->connection, FALSE);
+ g_return_val_if_fail (ibus_connection_is_connected (priv->connection), FALSE);
+
+ message = ibus_message_new_method_call (priv->name,
+ priv->path,
+ priv->interface,
+ method);
+ va_start (args, first_arg_type);
+ retval = ibus_message_append_args_valist (message,
+ first_arg_type,
+ args);
+ if (!retval) {
+ ibus_message_unref (message);
+ g_return_val_if_reached (FALSE);
+ }
+
+ va_end (args);
+
+ retval = ibus_connection_send (priv->connection, message);
+
+ ibus_message_unref (message);
+
+ return retval;
+}
+
+gboolean
+ibus_proxy_call_with_reply (IBusProxy *proxy,
+ const gchar *method,
+ IBusPendingCall **pending,
+ gint timeout_milliseconds,
+ IBusError **error,
+ GType first_arg_type,
+ ...)
+{
+ g_assert (IBUS_IS_PROXY (proxy));
+ g_assert (pending != NULL);
+ g_assert (method != NULL);
+
+ va_list args;
+ gboolean retval;
+ DBusMessage *message;
+
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ if (priv->connection == NULL || !ibus_connection_is_connected (priv->connection)) {
+ if (error) {
+ *error = ibus_error_new_from_printf (DBUS_ERROR_DISCONNECTED,
+ "Connection of %s was disconnected.",
+ G_OBJECT_TYPE_NAME (proxy));
+ }
+ return FALSE;
+ }
+
+ message = ibus_message_new_method_call (priv->name,
+ priv->path,
+ priv->interface,
+ method);
+ va_start (args, first_arg_type);
+ retval = ibus_message_append_args_valist (message,
+ first_arg_type,
+ args);
+ va_end (args);
+
+ *pending = NULL;
+ retval = ibus_connection_send_with_reply (priv->connection,
+ message,
+ pending,
+ timeout_milliseconds);
+ ibus_message_unref (message);
+
+ if (!retval && error != NULL) {
+ *error = ibus_error_new_from_printf (DBUS_ERROR_NO_MEMORY, "");
+ }
+
+ return retval;
+}
+
+
+IBusMessage *
+ibus_proxy_call_with_reply_and_block (IBusProxy *proxy,
+ const gchar *method,
+ gint timeout_milliseconds,
+ IBusError **error,
+ GType first_arg_type,
+ ...)
+{
+ g_assert (IBUS_IS_PROXY (proxy));
+ g_assert (method != NULL);
+
+ va_list args;
+ gboolean retval;
+ DBusMessage *message;
+ DBusMessage *reply_message;
+
+ IBusProxyPrivate *priv;
+ priv = IBUS_PROXY_GET_PRIVATE (proxy);
+
+ if (priv->connection == NULL || !ibus_connection_is_connected (priv->connection)) {
+ if (error) {
+ *error = ibus_error_new_from_printf (DBUS_ERROR_DISCONNECTED,
+ "Connection of %s was disconnected.",
+ G_OBJECT_TYPE_NAME (proxy));
+ }
+ return NULL;
+ }
+
+ message = ibus_message_new_method_call (priv->name,
+ priv->path,
+ priv->interface,
+ method);
+ va_start (args, first_arg_type);
+ retval = ibus_message_append_args_valist (message,
+ first_arg_type,
+ args);
+ va_end (args);
+
+ reply_message = ibus_connection_send_with_reply_and_block (
+ priv->connection,
+ message,
+ timeout_milliseconds,
+ error);
+ ibus_message_unref (message);
+
+ return reply_message;
+}
diff --git a/src/ibusproxy.h b/src/ibusproxy.h
new file mode 100644
index 0000000..0cc22d4
--- /dev/null
+++ b/src/ibusproxy.h
@@ -0,0 +1,107 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_PROXY_H_
+#define __IBUS_PROXY_H_
+
+#include <dbus/dbus.h>
+#include "ibusobject.h"
+#include "ibusconnection.h"
+#include "ibusmessage.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_PROXY \
+ (ibus_proxy_get_type ())
+#define IBUS_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_PROXY, IBusProxy))
+#define IBUS_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_PROXY, IBusProxyClass))
+#define IBUS_IS_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_PROXY))
+#define IBUS_IS_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_PROXY))
+#define IBUS_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_PROXY, IBusProxyClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusProxy IBusProxy;
+typedef struct _IBusProxyClass IBusProxyClass;
+
+struct _IBusProxy {
+ IBusObject parent;
+ /* instance members */
+};
+
+struct _IBusProxyClass {
+ IBusObjectClass parent;
+
+ /* class members */
+ gboolean (* ibus_signal) (IBusProxy *proxy,
+ IBusMessage *message);
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[7];
+};
+
+GType ibus_proxy_get_type (void);
+IBusProxy *ibus_proxy_new (const gchar *name,
+ const gchar *path,
+ IBusConnection *connection);
+gboolean ibus_proxy_send (IBusProxy *proxy,
+ IBusMessage *message);
+gboolean ibus_proxy_call (IBusProxy *proxy,
+ const gchar *method,
+ GType first_agr_type,
+ ...);
+gboolean ibus_proxy_call_with_reply (IBusProxy *proxy,
+ const gchar *method,
+ IBusPendingCall **pending,
+ gint timeout_milliseconds,
+ IBusError **error,
+ GType first_arg_type,
+ ...);
+IBusMessage *ibus_proxy_call_with_reply_and_block
+ (IBusProxy *proxy,
+ const gchar *method,
+ gint timeout_milliseconds,
+ IBusError **error,
+ GType first_arg_type,
+ ...);
+gboolean ibus_proxy_send_with_reply (IBusProxy *proxy,
+ IBusMessage *message,
+ IBusPendingCall **pending,
+ gint timeout_milliseconds);
+IBusMessage *ibus_proxy_send_with_reply_and_block
+ (IBusProxy *proxy,
+ IBusMessage *message);
+gboolean ibus_proxy_handle_signal (IBusProxy *proxy,
+ IBusMessage *message);
+const gchar *ibus_proxy_get_name (IBusProxy *proxy);
+const gchar *ibus_proxy_get_path (IBusProxy *proxy);
+const gchar *ibus_proxy_get_interface (IBusProxy *proxy);
+IBusConnection *ibus_proxy_get_connection (IBusProxy *proxy);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusserializable.c b/src/ibusserializable.c
new file mode 100644
index 0000000..82a49bc
--- /dev/null
+++ b/src/ibusserializable.c
@@ -0,0 +1,578 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusinternal.h"
+#include "ibusserializable.h"
+
+#define IBUS_SERIALIZABLE_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_SERIALIZABLE, IBusSerializablePrivate))
+
+enum {
+ LAST_SIGNAL,
+};
+
+typedef struct _IBusSerializablePrivate IBusSerializablePrivate;
+struct _IBusSerializablePrivate {
+ GData *attachments;
+};
+
+// static guint object_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_serializable_base_init (IBusSerializableClass *klass);
+static void ibus_serializable_base_fini (IBusSerializableClass *klass);
+static void ibus_serializable_class_init (IBusSerializableClass *klass);
+static void ibus_serializable_init (IBusSerializable *object);
+static void ibus_serializable_destroy (IBusSerializable *object);
+static gboolean ibus_serializable_real_serialize (IBusSerializable *object,
+ IBusMessageIter *iter);
+static gboolean ibus_serializable_real_deserialize (IBusSerializable *object,
+ IBusMessageIter *iter);
+static gboolean ibus_serializable_real_copy (IBusSerializable *dest,
+ const IBusSerializable *src);
+
+static IBusObjectClass *parent_class = NULL;
+
+
+GType
+ibus_serializable_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusSerializableClass),
+ (GBaseInitFunc) ibus_serializable_base_init,
+ (GBaseFinalizeFunc) ibus_serializable_base_fini,
+ (GClassInitFunc) ibus_serializable_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusSerializable),
+ 0,
+ (GInstanceInitFunc) ibus_serializable_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_OBJECT,
+ "IBusSerializable",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+/**
+ * ibus_serializable_new:
+ *
+ * Creates a new instance of an #IBusSerializable.
+ *
+ * Returns: a new instance of #IBusSerializable.
+ */
+IBusSerializable *
+ibus_serializable_new (void)
+{
+ return IBUS_SERIALIZABLE (g_object_new (IBUS_TYPE_SERIALIZABLE, NULL));
+}
+
+static void
+ibus_serializable_base_init (IBusSerializableClass *klass)
+{
+ /* init signature */
+ klass->signature = g_string_new ("a{sv}");
+}
+
+static void
+ibus_serializable_base_fini (IBusSerializableClass *klass)
+{
+ /* init signature */
+ g_string_free (klass->signature, TRUE);
+ klass->signature = NULL;
+}
+
+static void
+ibus_serializable_class_init (IBusSerializableClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusSerializablePrivate));
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_serializable_destroy;
+
+ klass->serialize = ibus_serializable_real_serialize;
+ klass->deserialize = ibus_serializable_real_deserialize;
+ klass->copy = ibus_serializable_real_copy;
+}
+
+static void
+ibus_serializable_init (IBusSerializable *object)
+{
+ IBusSerializablePrivate *priv;
+ priv = IBUS_SERIALIZABLE_GET_PRIVATE (object);
+
+ priv->attachments = NULL;
+ g_datalist_init (&priv->attachments);
+}
+
+static void
+ibus_serializable_destroy (IBusSerializable *object)
+{
+ IBusSerializablePrivate *priv;
+ priv = IBUS_SERIALIZABLE_GET_PRIVATE (object);
+
+ g_datalist_clear (&priv->attachments);
+
+ parent_class->destroy (IBUS_OBJECT (object));
+}
+
+static GValue *
+ibus_g_value_dup (const GValue *value)
+{
+ GValue *new_value;
+
+ new_value = g_slice_new0 (GValue);
+ g_value_init (new_value, G_VALUE_TYPE (value));
+ g_value_copy (value, new_value);
+
+ return new_value;
+}
+
+static void
+ibus_g_value_free (GValue *value)
+{
+ g_value_unset (value);
+ g_slice_free (GValue, value);
+}
+
+static gboolean
+_g_value_serialize (GValue *value,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ GType type;
+
+ type = G_VALUE_TYPE (value);
+ g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
+
+
+ if (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE)) {
+ IBusSerializable *object;
+ object = IBUS_SERIALIZABLE (g_value_get_object (value));
+ retval = ibus_message_iter_append (iter,
+ type,
+ &object);
+ g_return_val_if_fail (retval, FALSE);
+ return TRUE;
+ }
+
+ typedef const gchar *gstring;
+ switch (type) {
+#define CASE_ENTRY(TYPE, _type, signature) \
+ case G_TYPE_##TYPE: \
+ { \
+ g##_type v; \
+ IBusMessageIter variant_iter; \
+ \
+ retval = ibus_message_iter_open_container (iter, \
+ IBUS_TYPE_VARIANT, \
+ signature, \
+ &variant_iter); \
+ g_return_val_if_fail (retval, FALSE); \
+ \
+ v = g_value_get_##_type (value); \
+ retval = ibus_message_iter_append (&variant_iter, \
+ G_TYPE_##TYPE, \
+ &v); \
+ g_return_val_if_fail (retval, FALSE); \
+ \
+ retval = ibus_message_iter_close_container (iter, &variant_iter); \
+ g_return_val_if_fail (retval, FALSE); \
+ \
+ return TRUE; \
+ }
+ CASE_ENTRY(CHAR, char, "y");
+ CASE_ENTRY(BOOLEAN, boolean, "b");
+ CASE_ENTRY(INT, int, "i");
+ CASE_ENTRY(UINT, uint, "u");
+ CASE_ENTRY(INT64, int64, "x");
+ CASE_ENTRY(UINT64, uint64, "t");
+ CASE_ENTRY(FLOAT, float, "d");
+ CASE_ENTRY(DOUBLE, double, "d");
+ CASE_ENTRY(STRING, string, "s");
+#undef CASE_ENTRY
+ }
+
+ g_return_val_if_reached (FALSE);
+}
+
+static GValue *
+_g_value_deserialize (IBusMessageIter *iter)
+{
+ IBusMessageIter variant_iter;
+ gboolean retval;
+ GValue *value = NULL;
+ GType type;
+
+ retval = ibus_message_iter_recurse (iter, IBUS_TYPE_VARIANT, &variant_iter);
+ g_return_val_if_fail (retval, NULL);
+
+ type = ibus_message_iter_get_arg_type (&variant_iter);
+
+ if (type == IBUS_TYPE_STRUCT) {
+ IBusSerializable *object;
+ retval = ibus_message_iter_get (iter, IBUS_TYPE_SERIALIZABLE, &object);
+ g_return_val_if_fail (retval, NULL);
+
+ value = g_slice_new0 (GValue);
+ g_value_init (value, G_OBJECT_TYPE (object));
+ g_value_take_object (value, object);
+ return value;
+ }
+
+ typedef gchar *gstring;
+ switch (type) {
+#define CASE_ENTRY(TYPE, _type) \
+ case G_TYPE_##TYPE: \
+ { \
+ g##_type v; \
+ ibus_message_iter_get_basic (&variant_iter, &v); \
+ value = g_slice_new0 (GValue); \
+ g_value_init (value, G_TYPE_##TYPE); \
+ g_value_set_##_type (value, v); \
+ ibus_message_iter_next (iter); \
+ return value; \
+ }
+ CASE_ENTRY(CHAR, char);
+ CASE_ENTRY(BOOLEAN, boolean);
+ CASE_ENTRY(INT, int);
+ CASE_ENTRY(UINT, uint);
+ CASE_ENTRY(INT64, int64);
+ CASE_ENTRY(UINT64, uint64);
+ CASE_ENTRY(FLOAT, float);
+ CASE_ENTRY(DOUBLE, double);
+ CASE_ENTRY(STRING, string);
+ }
+ g_return_val_if_reached (NULL);
+}
+
+static void
+_serialize_cb (GQuark key,
+ GValue *value,
+ IBusMessageIter *iter)
+{
+ IBusMessageIter dict_entry;
+ gboolean retval;
+ const gchar *name;
+
+ retval = ibus_message_iter_open_container (iter,
+ IBUS_TYPE_DICT_ENTRY,
+ NULL,
+ &dict_entry);
+ g_return_if_fail (retval);
+ name = g_quark_to_string (key);
+ retval = ibus_message_iter_append (&dict_entry,
+ G_TYPE_STRING,
+ &name);
+ g_return_if_fail (retval);
+
+ retval = _g_value_serialize (value, &dict_entry);
+ g_return_if_fail (retval);
+
+ retval = ibus_message_iter_close_container (iter, &dict_entry);
+ g_return_if_fail (retval);
+}
+
+static gboolean
+ibus_serializable_real_serialize (IBusSerializable *object,
+ IBusMessageIter *iter)
+{
+ IBusSerializablePrivate *priv;
+ IBusMessageIter array_iter;
+ gboolean retval;
+
+ priv = IBUS_SERIALIZABLE_GET_PRIVATE (object);
+
+ retval = ibus_message_iter_open_container (iter,
+ IBUS_TYPE_ARRAY,
+ "{sv}",
+ &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_datalist_foreach (&priv->attachments,
+ (GDataForeachFunc) _serialize_cb,
+ &array_iter);
+
+ retval = ibus_message_iter_close_container (iter, &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_serializable_real_deserialize (IBusSerializable *object,
+ IBusMessageIter *iter)
+{
+ IBusMessageIter array_iter;
+ gboolean retval;
+
+ retval = ibus_message_iter_recurse (iter,
+ IBUS_TYPE_ARRAY,
+ &array_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ while (ibus_message_iter_get_arg_type (&array_iter) != G_TYPE_INVALID) {
+ gchar *name;
+ GValue *value;
+ IBusMessageIter dict_entry;
+
+ retval = ibus_message_iter_recurse (&array_iter,
+ IBUS_TYPE_DICT_ENTRY,
+ &dict_entry);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (&dict_entry,
+ G_TYPE_STRING,
+ &name);
+ g_return_val_if_fail (retval, FALSE);
+
+ value = _g_value_deserialize (&dict_entry);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ ibus_serializable_set_attachment (object, name, value);
+
+ ibus_message_iter_next (&array_iter);
+ }
+
+ ibus_message_iter_next (iter);
+
+ return TRUE;
+}
+
+static void
+_copy_cb (GQuark key,
+ GValue *value,
+ GData **datalist)
+{
+ g_datalist_id_set_data_full (datalist,
+ key,
+ ibus_g_value_dup (value),
+ (GDestroyNotify) ibus_g_value_free);
+}
+
+static gboolean
+ibus_serializable_real_copy (IBusSerializable *dest,
+ const IBusSerializable *src)
+{
+ IBusSerializablePrivate *src_priv;
+ IBusSerializablePrivate *dest_priv;
+ src_priv = IBUS_SERIALIZABLE_GET_PRIVATE (src);
+ dest_priv = IBUS_SERIALIZABLE_GET_PRIVATE (dest);
+
+ g_datalist_foreach (&src_priv->attachments,
+ (GDataForeachFunc) _copy_cb,
+ &dest_priv->attachments);
+ return TRUE;
+}
+
+gboolean
+ibus_serializable_set_qattachment (IBusSerializable *object,
+ GQuark key,
+ const GValue *value)
+{
+ g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), FALSE);
+ g_return_val_if_fail (key != 0, FALSE);
+ g_return_val_if_fail (G_IS_VALUE (value), FALSE);
+
+ IBusSerializablePrivate *priv;
+ priv = IBUS_SERIALIZABLE_GET_PRIVATE (object);
+
+ GType type = G_VALUE_TYPE (value);
+
+ switch (type) {
+ case G_TYPE_CHAR:
+ case G_TYPE_INT:
+ case G_TYPE_INT64:
+ case G_TYPE_UINT:
+ case G_TYPE_UINT64:
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_DOUBLE:
+ case G_TYPE_FLOAT:
+ case G_TYPE_STRING:
+ g_datalist_id_set_data_full (&priv->attachments,
+ key,
+ ibus_g_value_dup (value),
+ (GDestroyNotify) ibus_g_value_free);
+ return TRUE;
+ }
+
+ if (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE)) {
+ g_datalist_id_set_data_full (&priv->attachments,
+ key,
+ ibus_g_value_dup (value),
+ (GDestroyNotify) ibus_g_value_free);
+ return TRUE;
+ }
+
+ g_warning ("The value of %s is not support serializing", g_type_name (type));
+ return FALSE;
+}
+
+const GValue *
+ibus_serializable_get_qattachment (IBusSerializable *object,
+ GQuark key)
+{
+
+ g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), NULL);
+ g_return_val_if_fail (key != 0, NULL);
+
+ IBusSerializablePrivate *priv;
+ priv = IBUS_SERIALIZABLE_GET_PRIVATE (object);
+
+ return (const GValue *) g_datalist_id_get_data (&priv->attachments, key);
+}
+
+void
+ibus_serializable_remove_qattachment (IBusSerializable *object,
+ GQuark key)
+{
+
+ g_return_if_fail (IBUS_IS_SERIALIZABLE (object));
+ g_return_if_fail (key != 0);
+
+ IBusSerializablePrivate *priv;
+ priv = IBUS_SERIALIZABLE_GET_PRIVATE (object);
+
+ g_datalist_id_remove_no_notify (&priv->attachments, key);
+}
+
+IBusSerializable *
+ibus_serializable_copy (IBusSerializable *object)
+{
+ g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), NULL);
+
+ GType type;
+ IBusSerializable *new_object;
+
+ type = G_OBJECT_TYPE (object);
+
+ new_object = g_object_new (type, 0);
+ g_return_val_if_fail (new_object != NULL, NULL);
+
+ if (IBUS_SERIALIZABLE_GET_CLASS (new_object)->copy (new_object, object)) {
+ return new_object;
+ }
+
+ g_object_unref (new_object);
+ g_return_val_if_reached (NULL);
+}
+
+gboolean
+ibus_serializable_serialize (IBusSerializable *object,
+ IBusMessageIter *iter)
+{
+ g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ IBusMessageIter variant_iter;
+ IBusMessageIter sub_iter;
+ gboolean retval;
+
+ gchar *signature;
+
+ signature = g_strdup_printf ("(s%s)", IBUS_SERIALIZABLE_GET_CLASS (object)->signature->str);
+ retval = ibus_message_iter_open_container (iter,
+ IBUS_TYPE_VARIANT,
+ signature,
+ &variant_iter);
+ g_free (signature);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_open_container (&variant_iter,
+ IBUS_TYPE_STRUCT,
+ NULL,
+ &sub_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ const gchar *type_name = g_type_name (G_OBJECT_TYPE (object));
+ g_return_val_if_fail (type_name != NULL, FALSE);
+
+ retval = ibus_message_iter_append (&sub_iter,
+ G_TYPE_STRING,
+ &type_name);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = IBUS_SERIALIZABLE_GET_CLASS (object)->serialize (object, &sub_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_close_container (&variant_iter, &sub_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_close_container (iter, &variant_iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+IBusSerializable *
+ibus_serializable_deserialize (IBusMessageIter *iter)
+{
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ gboolean retval;
+ IBusMessageIter variant_iter;
+ IBusMessageIter sub_iter;
+ gchar *type_name;
+ GType type;
+ IBusSerializable *object;
+
+ type = ibus_message_iter_get_arg_type (iter);
+
+ if (type == IBUS_TYPE_VARIANT) {
+ retval = ibus_message_iter_recurse (iter, IBUS_TYPE_VARIANT, &variant_iter);
+ g_return_val_if_fail (retval, NULL);
+
+ retval = ibus_message_iter_recurse (&variant_iter, IBUS_TYPE_STRUCT, &sub_iter);
+ g_return_val_if_fail (retval, NULL);
+ }
+ else if (type == IBUS_TYPE_STRUCT) {
+ retval = ibus_message_iter_recurse (iter, IBUS_TYPE_STRUCT, &sub_iter);
+ g_return_val_if_fail (retval, NULL);
+ }
+ else
+ g_return_val_if_reached (NULL);
+
+ retval = ibus_message_iter_get (&sub_iter, G_TYPE_STRING, &type_name);
+ g_return_val_if_fail (retval, NULL);
+
+ type = g_type_from_name (type_name);
+
+ g_return_val_if_fail (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE), NULL);
+
+ object = g_object_new (type, 0);
+
+ retval = IBUS_SERIALIZABLE_GET_CLASS (object)->deserialize (object, &sub_iter);
+ if (retval)
+ return object;
+
+ g_object_unref (object);
+ g_return_val_if_reached (NULL);
+}
+
diff --git a/src/ibusserializable.h b/src/ibusserializable.h
new file mode 100644
index 0000000..a99f123
--- /dev/null
+++ b/src/ibusserializable.h
@@ -0,0 +1,108 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_SERIALIZABLE_H_
+#define __IBUS_SERIALIZABLE_H_
+
+#include "ibusobject.h"
+#include "ibusmessage.h"
+
+/*
+ * Type macros.
+ */
+
+/* define IBusSerializable macros */
+#define IBUS_TYPE_SERIALIZABLE \
+ (ibus_serializable_get_type ())
+#define IBUS_SERIALIZABLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_SERIALIZABLE, IBusSerializable))
+#define IBUS_SERIALIZABLE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_SERIALIZABLE, IBusSerializableClass))
+#define IBUS_IS_SERIALIZABLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_SERIALIZABLE))
+#define IBUS_IS_SERIALIZABLE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_SERIALIZABLE))
+#define IBUS_SERIALIZABLE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_SERIALIZABLE, IBusSerializableClass))
+
+#define ibus_serializable_set_attachment(o, k, v) \
+ ibus_serializable_set_qattachment (o, g_quark_from_string (k), v)
+#define ibus_serializable_get_attachment(o, k, v) \
+ ibus_serializable_get_qattachment (o, g_quark_from_string (k))
+#define ibus_serializable_remove_attachment(o, k) \
+ ibus_serializable_remove_qattachment (o, g_quark_from_string (k))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusSerializable IBusSerializable;
+typedef struct _IBusSerializableClass IBusSerializableClass;
+/**
+ * IBusSerializable:
+ *
+ * All the fields in the <structname>IBusSerializable</structname> structure are
+ * prtivate to the #IBusSerializable and should never be accessed directly.
+ */
+struct _IBusSerializable {
+ GObject parent;
+ /* instance members */
+ guint32 flags;
+};
+
+typedef gboolean (* IBusSerializableSerializeFunc) (IBusSerializable *object,
+ IBusMessageIter *iter);
+typedef gboolean (* IBusSerializableDeserializeFunc) (IBusSerializable *object,
+ IBusMessageIter *iter);
+typedef gboolean (* IBusSerializableCopyFunc) (IBusSerializable *dest,
+ const IBusSerializable *src);
+struct _IBusSerializableClass {
+ IBusObjectClass parent;
+
+ /* signature */
+ GString *signature;
+
+ /* virtual table */
+ gboolean (* serialize) (IBusSerializable *object,
+ IBusMessageIter *iter);
+ gboolean (* deserialize) (IBusSerializable *object,
+ IBusMessageIter *iter);
+ gboolean (* copy) (IBusSerializable *dest,
+ const IBusSerializable *src);
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[5];
+};
+
+GType ibus_serializable_get_type (void);
+IBusSerializable * ibus_serializable_new (void);
+gboolean ibus_serializable_set_qattachment (IBusSerializable *object,
+ GQuark key,
+ const GValue *value);
+const GValue *ibus_serializable_get_qattachment (IBusSerializable *object,
+ GQuark key);
+void ibus_serializable_remove_qattachment
+ (IBusSerializable *object,
+ GQuark key);
+IBusSerializable *ibus_serializable_copy (IBusSerializable *object);
+gboolean ibus_serializable_serialize (IBusSerializable *object,
+ IBusMessageIter *iter);
+IBusSerializable *ibus_serializable_deserialize (IBusMessageIter *iter);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusserver.c b/src/ibusserver.c
new file mode 100644
index 0000000..cda80af
--- /dev/null
+++ b/src/ibusserver.c
@@ -0,0 +1,327 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusserver.h"
+#include "ibusinternal.h"
+
+#define IBUS_SERVER_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_SERVER, IBusServerPrivate))
+#define DECLARE_PRIV IBusServerPrivate *priv = IBUS_SERVER_GET_PRIVATE(server)
+
+enum {
+ NEW_CONNECTION,
+ LAST_SIGNAL,
+};
+
+enum {
+ PROP_0,
+ PROP_CONNECTION_TYPE,
+};
+
+/* IBusServerPriv */
+struct _IBusServerPrivate {
+ DBusServer *server;
+ GType connection_type;
+};
+typedef struct _IBusServerPrivate IBusServerPrivate;
+
+static guint server_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_server_class_init (IBusServerClass *klass);
+static void ibus_server_init (IBusServer *server);
+static void ibus_server_destroy (IBusServer *server);
+static void ibus_server_set_property(IBusServer *server,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ibus_server_get_property(IBusServer *server,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void ibus_server_listen_internal
+ (IBusServer *server,
+ const gchar *address);
+static void ibus_server_new_connection
+ (IBusServer *server,
+ IBusConnection *connection);
+
+static IBusObjectClass *parent_class = NULL;
+
+GType
+ibus_server_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusServerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_server_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusServer),
+ 0,
+ (GInstanceInitFunc) ibus_server_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_OBJECT,
+ "IBusServer",
+ &type_info,
+ (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+IBusServer *
+ibus_server_new (void)
+{
+ IBusServer *server;
+
+ server = IBUS_SERVER (g_object_new (IBUS_TYPE_SERVER, NULL));
+ return server;
+}
+
+gboolean
+ibus_server_listen (IBusServer *server,
+ const gchar *address)
+{
+ g_assert (IBUS_IS_SERVER (server));
+ g_assert (address != NULL);
+ ibus_server_listen_internal (server, address);
+
+ return TRUE;
+}
+
+static void
+ibus_server_class_init (IBusServerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusServerPrivate));
+
+ gobject_class->set_property = (GObjectSetPropertyFunc) ibus_server_set_property;
+ gobject_class->get_property = (GObjectGetPropertyFunc) ibus_server_get_property;
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_server_destroy;
+
+ klass->new_connection = ibus_server_new_connection;
+
+ /* install properties */
+ g_object_class_install_property (gobject_class,
+ PROP_CONNECTION_TYPE,
+ g_param_spec_gtype ("connection-type",
+ "connection type",
+ "The connection type of server object",
+ IBUS_TYPE_CONNECTION,
+ G_PARAM_READWRITE));
+
+ /* install signals */
+ server_signals[NEW_CONNECTION] =
+ g_signal_new (I_("new-connection"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusServerClass, new_connection),
+ NULL, NULL,
+ ibus_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+}
+
+static void
+ibus_server_init (IBusServer *server)
+{
+ IBusServerPrivate *priv;
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+ priv->server = NULL;
+ priv->connection_type = IBUS_TYPE_CONNECTION;
+}
+
+static void
+ibus_server_destroy (IBusServer *server)
+{
+ IBusServerPrivate *priv;
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+
+ if (priv->server) {
+ dbus_server_unref (priv->server);
+ priv->server = NULL;
+ }
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (server));
+}
+
+static void
+ibus_server_set_property (IBusServer *server,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IBusServerPrivate *priv;
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+
+ switch (prop_id) {
+ case PROP_CONNECTION_TYPE:
+ {
+ GType type;
+ type = g_value_get_gtype (value);
+ g_assert (g_type_is_a (type, IBUS_TYPE_CONNECTION));
+ priv->connection_type = type;
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (server, prop_id, pspec);
+ }
+}
+
+static void
+ibus_server_get_property (IBusServer *server,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IBusServerPrivate *priv;
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+
+ switch (prop_id) {
+ case PROP_CONNECTION_TYPE:
+ g_value_set_gtype (value, priv->connection_type);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (server, prop_id, pspec);
+ }
+}
+
+static void
+ibus_server_new_connection (IBusServer *server,
+ IBusConnection *connection)
+{
+}
+
+static void
+_new_connection_cb (DBusServer *dbus_server,
+ DBusConnection *new_connection,
+ IBusServer *server)
+{
+ IBusServerPrivate *priv;
+ IBusConnection *connection;
+
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+ connection = IBUS_CONNECTION (g_object_new (priv->connection_type, NULL));
+ ibus_connection_set_connection (connection, new_connection, FALSE);
+
+ g_signal_emit (server, server_signals[NEW_CONNECTION], 0, connection);
+ g_object_unref (connection);
+}
+
+static void
+ibus_server_listen_internal (IBusServer *server,
+ const gchar *address)
+{
+ g_assert (IBUS_IS_SERVER (server));
+ g_assert (address != NULL);
+
+ IBusServerPrivate *priv;
+ DBusError error;
+
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+
+ g_assert (priv->server == NULL);
+
+ dbus_error_init (&error);
+ priv->server = dbus_server_listen (address, &error);
+
+ if (priv->server == NULL) {
+ g_error ("Can not listen on '%s':\n"
+ " %s:%s",
+ address, error.name, error.message);
+ }
+
+ dbus_server_set_new_connection_function (priv->server,
+ (DBusNewConnectionFunction) _new_connection_cb,
+ server, NULL);
+
+ dbus_server_set_auth_mechanisms (priv->server, NULL);
+
+ dbus_server_setup (priv->server, NULL);
+}
+
+void ibus_server_disconnect (IBusServer *server)
+{
+ g_assert (IBUS_IS_SERVER (server));
+
+ IBusServerPrivate *priv;
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+
+ g_assert (priv->server != NULL);
+ dbus_server_disconnect (priv->server);
+}
+
+const gchar *ibus_server_get_address (IBusServer *server)
+{
+ g_assert (IBUS_IS_SERVER (server));
+
+ gchar *address, *tmp;
+ IBusServerPrivate *priv;
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+
+ g_assert (priv->server != NULL);
+
+ tmp = dbus_server_get_address (priv->server);
+ address = g_strdup (tmp);
+ dbus_free (tmp);
+ return address;
+}
+
+const gchar *ibus_server_get_id (IBusServer *server)
+{
+ g_assert (IBUS_IS_SERVER (server));
+
+ gchar *id, *tmp;
+ IBusServerPrivate *priv;
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+
+ g_assert (priv->server != NULL);
+
+ tmp = dbus_server_get_id (priv->server);
+ id = g_strdup (tmp);
+ dbus_free (tmp);
+ return id;
+}
+
+gboolean
+ibus_server_is_connected (IBusServer *server)
+{
+ g_assert (IBUS_IS_SERVER (server));
+
+ IBusServerPrivate *priv;
+ priv = IBUS_SERVER_GET_PRIVATE (server);
+
+ g_assert (priv->server != NULL);
+
+ return dbus_server_get_is_connected (priv->server);
+}
+
+
diff --git a/src/ibusserver.h b/src/ibusserver.h
new file mode 100644
index 0000000..cf3547f
--- /dev/null
+++ b/src/ibusserver.h
@@ -0,0 +1,79 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_SERVER_H_
+#define __IBUS_SERVER_H_
+
+#include <dbus/dbus.h>
+#include "ibusobject.h"
+#include "ibusconnection.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_SERVER \
+ (ibus_server_get_type ())
+#define IBUS_SERVER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_SERVER, IBusServer))
+#define IBUS_SERVER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_SERVER, IBusServerClass))
+#define IBUS_IS_SERVER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_SERVER))
+#define IBUS_IS_SERVER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_SERVER))
+#define IBUS_SERVER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_SERVER, IBusServerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusServer IBusServer;
+typedef struct _IBusServerClass IBusServerClass;
+
+typedef void (* IBusNewConnectionFunc) (IBusServer *server, IBusConnection *connection);
+
+struct _IBusServer {
+ IBusObject parent;
+ /* instance members */
+};
+
+struct _IBusServerClass {
+ IBusObjectClass parent;
+
+ /* signals */
+ void (* new_connection) (IBusServer *server,
+ IBusConnection *connectin);
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[7];
+};
+
+GType ibus_server_get_type (void);
+IBusServer *ibus_server_new (void);
+gboolean ibus_server_listen (IBusServer *server,
+ const gchar *address);
+void ibus_server_disconnect (IBusServer *server);
+const gchar *ibus_server_get_address (IBusServer *server);
+const gchar *ibus_server_get_id (IBusServer *server);
+gboolean ibus_server_is_connected (IBusServer *server);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibusservice.c b/src/ibusservice.c
new file mode 100644
index 0000000..380e3ee
--- /dev/null
+++ b/src/ibusservice.c
@@ -0,0 +1,406 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusservice.h"
+#include "ibusinternal.h"
+
+#define IBUS_SERVICE_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_SERVICE, IBusServicePrivate))
+
+enum {
+ IBUS_MESSAGE,
+ IBUS_SIGNAL,
+ LAST_SIGNAL,
+};
+
+enum {
+ PROP_0,
+ PROP_PATH
+};
+
+/* IBusServicePriv */
+struct _IBusServicePrivate {
+ gchar *path;
+ GList *connections;
+};
+typedef struct _IBusServicePrivate IBusServicePrivate;
+
+static guint service_signals[LAST_SIGNAL] = { 0 };
+
+/* functions prototype */
+static void ibus_service_class_init (IBusServiceClass *klass);
+static void ibus_service_init (IBusService *service);
+static void ibus_service_destroy (IBusService *service);
+static void ibus_service_set_property (IBusService *service,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ibus_service_get_property (IBusService *service,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static gboolean ibus_service_ibus_message (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message);
+static gboolean ibus_service_ibus_signal (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message);
+
+static IBusObjectClass *parent_class = NULL;
+
+GType
+ibus_service_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusServiceClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_service_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusService),
+ 0,
+ (GInstanceInitFunc) ibus_service_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_OBJECT,
+ "IBusService",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+ return type;
+}
+
+IBusService *
+ibus_service_new (const gchar *path)
+{
+ GObject *obj;
+ obj = g_object_new (IBUS_TYPE_SERVICE,
+ "path", path,
+ NULL);
+ return IBUS_SERVICE (obj);
+}
+
+static void
+ibus_service_class_init (IBusServiceClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ parent_class = (IBusObjectClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusServicePrivate));
+
+ gobject_class->set_property = (GObjectSetPropertyFunc) ibus_service_set_property;
+ gobject_class->get_property = (GObjectGetPropertyFunc) ibus_service_get_property;
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_service_destroy;
+
+ klass->ibus_message = ibus_service_ibus_message;
+ klass->ibus_signal = ibus_service_ibus_signal;
+
+ /* install properties */
+ g_object_class_install_property (
+ gobject_class,
+ PROP_PATH,
+ g_param_spec_string (
+ "path",
+ "object path",
+ "The path of service object",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)
+ );
+
+ /* Install signals */
+ service_signals[IBUS_MESSAGE] =
+ g_signal_new (I_("ibus-message"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusServiceClass, ibus_message),
+ NULL, NULL,
+ ibus_marshal_BOOLEAN__POINTER_POINTER,
+ G_TYPE_BOOLEAN,
+ 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ service_signals[IBUS_SIGNAL] =
+ g_signal_new (I_("ibus-signal"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusServiceClass, ibus_signal),
+ NULL, NULL,
+ ibus_marshal_BOOLEAN__POINTER_POINTER,
+ G_TYPE_BOOLEAN,
+ 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+}
+
+static void
+ibus_service_init (IBusService *service)
+{
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ priv->path = NULL;
+ priv->connections = NULL;
+}
+
+static void
+ibus_service_destroy (IBusService *service)
+{
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ ibus_service_remove_from_all_connections (service);
+
+ g_free (priv->path);
+ priv->path = NULL;
+
+ IBUS_OBJECT_CLASS(parent_class)->destroy (IBUS_OBJECT (service));
+}
+
+static void
+ibus_service_set_property (IBusService *service,
+ guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ switch (prop_id) {
+ case PROP_PATH:
+ priv->path = g_strdup (g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (service, prop_id, pspec);
+ }
+}
+
+static void
+ibus_service_get_property (IBusService *service,
+ guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_PATH:
+ g_value_set_string (value, ibus_service_get_path (service));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (service, prop_id, pspec);
+ }
+}
+
+const gchar *
+ibus_service_get_path (IBusService *service)
+{
+ g_assert (IBUS_IS_SERVICE (service));
+
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ return priv->path;
+}
+
+gboolean
+ibus_service_handle_message (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message)
+{
+ gboolean retval = FALSE;
+ g_return_val_if_fail (message != NULL, FALSE);
+
+ g_signal_emit (service, service_signals[IBUS_MESSAGE], 0, connection, message, &retval);
+ return retval;
+}
+
+static gboolean
+ibus_service_ibus_message (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message)
+{
+ if (ibus_message_is_method_call (message, "", "Destroy")) {
+ IBusMessage *reply;
+ reply = ibus_message_new_method_return (message);
+ ibus_connection_send (connection, reply);
+ ibus_message_unref (reply);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+ibus_service_ibus_signal (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message)
+{
+ return FALSE;
+}
+
+
+gboolean
+_service_message_function (IBusConnection *connection,
+ IBusMessage *message,
+ IBusService *service)
+{
+ return ibus_service_handle_message (service, connection, message);
+}
+
+static void
+_connection_destroy_cb (IBusConnection *connection, IBusService *service)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (IBUS_IS_SERVICE (service));
+
+ ibus_service_remove_from_connection (service, connection);
+}
+
+gboolean
+ibus_service_add_to_connection (IBusService *service, IBusConnection *connection)
+{
+ g_assert (IBUS_IS_SERVICE (service));
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ gboolean retval;
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ g_return_val_if_fail (priv->path != NULL, FALSE);
+ g_return_val_if_fail (g_list_find (priv->connections, connection) == NULL, FALSE);
+
+ g_object_ref (connection);
+
+ retval = ibus_connection_register_object_path (connection, priv->path,
+ (IBusMessageFunc) _service_message_function, service);
+ if (!retval) {
+ g_object_unref (connection);
+ return FALSE;
+ }
+
+ priv->connections = g_list_append (priv->connections, connection);
+ g_signal_connect (connection,
+ "destroy",
+ (GCallback) _connection_destroy_cb,
+ service);
+
+ return retval;
+}
+
+GList *
+ibus_service_get_connections (IBusService *service)
+{
+ g_assert (IBUS_IS_SERVICE (service));
+
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ GList *l;
+
+ l = g_list_copy (priv->connections);
+ g_list_foreach (l, (GFunc) g_object_ref, NULL);
+ return l;
+}
+
+gboolean
+ibus_service_remove_from_connection (IBusService *service, IBusConnection *connection)
+{
+ g_return_val_if_fail (IBUS_IS_SERVICE (service), FALSE);
+ g_return_val_if_fail (IBUS_IS_CONNECTION (connection), FALSE);
+
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ g_assert (priv->path != NULL);
+ g_assert (g_list_find (priv->connections, connection) != NULL);
+
+ gboolean retval;
+ retval = ibus_connection_unregister_object_path (connection, priv->path);
+
+ if (!retval) {
+ return FALSE;
+ }
+
+ g_signal_handlers_disconnect_by_func (connection,
+ (GCallback) _connection_destroy_cb,
+ service);
+ priv->connections = g_list_remove (priv->connections, connection);
+ g_object_unref (connection);
+
+ return TRUE;
+}
+
+gboolean
+ibus_service_remove_from_all_connections (IBusService *service)
+{
+ g_return_val_if_fail (IBUS_IS_SERVICE (service), FALSE);
+
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ GList *element = priv->connections;
+ while (element != NULL) {
+ IBusConnection *connection = IBUS_CONNECTION (element->data);
+
+ gboolean retval;
+ retval = ibus_connection_unregister_object_path (connection, priv->path);
+
+ g_signal_handlers_disconnect_by_func (connection,
+ (GCallback) _connection_destroy_cb,
+ service);
+ g_object_unref (connection);
+ element = element->next;
+ }
+
+ g_list_free (priv->connections);
+ priv->connections = NULL;
+ return TRUE;
+}
+
+gboolean
+ibus_service_send_signal (IBusService *service,
+ const gchar *interface,
+ const gchar *name,
+ GType first_arg_type,
+ ...)
+{
+ g_assert (IBUS_IS_SERVICE (service));
+ g_assert (name != NULL);
+
+ gboolean retval;
+ va_list args;
+ GList *p;
+
+ IBusServicePrivate *priv;
+ priv = IBUS_SERVICE_GET_PRIVATE (service);
+
+ for (p = priv->connections; p != NULL; p = p->next) {
+ va_start (args, first_arg_type);
+ retval = ibus_connection_send_signal_valist ((IBusConnection *) p->data,
+ priv->path,
+ interface,
+ name,
+ first_arg_type,
+ args);
+ va_end (args);
+ }
+ return retval;
+}
diff --git a/src/ibusservice.h b/src/ibusservice.h
new file mode 100644
index 0000000..9d90a85
--- /dev/null
+++ b/src/ibusservice.h
@@ -0,0 +1,99 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_SERVICE_H_
+#define __IBUS_SERVICE_H_
+
+#include <dbus/dbus.h>
+#include "ibusobject.h"
+#include "ibusconnection.h"
+
+/*
+ * Type macros.
+ */
+
+/* define GOBJECT macros */
+#define IBUS_TYPE_SERVICE \
+ (ibus_service_get_type ())
+#define IBUS_SERVICE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_SERVICE, IBusService))
+#define IBUS_SERVICE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_SERVICE, IBusServiceClass))
+#define IBUS_IS_SERVICE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_SERVICE))
+#define IBUS_IS_SERVICE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_SERVICE))
+#define IBUS_SERVICE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_SERVICE, IBusServiceClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusService IBusService;
+typedef struct _IBusServiceClass IBusServiceClass;
+
+struct _IBusService {
+ IBusObject parent;
+ /* instance members */
+};
+
+typedef gboolean (* ServiceIBusMessageFunc) (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message);
+typedef gboolean (* ServiceIBusSignalFunc) (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message);
+
+struct _IBusServiceClass {
+ IBusObjectClass parent;
+
+ /* signals */
+ gboolean (* ibus_message) (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message);
+ gboolean (* ibus_signal) (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message);
+ /*< private >*/
+ /* padding */
+ gpointer pdummy[6];
+};
+
+
+GType ibus_service_get_type (void);
+IBusService *ibus_service_new (const gchar *path);
+const gchar *ibus_service_get_path (IBusService *service);
+gboolean ibus_service_handle_message (IBusService *service,
+ IBusConnection *connection,
+ IBusMessage *message);
+gboolean ibus_service_add_to_connection (IBusService *service,
+ IBusConnection *connection);
+GList *ibus_service_get_connections (IBusService *service);
+gboolean ibus_service_remove_from_connection
+ (IBusService *service,
+ IBusConnection *connection);
+gboolean ibus_service_remove_from_all_connections
+ (IBusService *service);
+gboolean ibus_service_send_signal (IBusService *service,
+ const gchar *interface,
+ const gchar *name,
+ GType first_arg_type,
+ ...);
+G_END_DECLS
+#endif
+
diff --git a/src/ibusshare.c b/src/ibusshare.c
new file mode 100644
index 0000000..26a6480
--- /dev/null
+++ b/src/ibusshare.c
@@ -0,0 +1,164 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib-object.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include "ibusshare.h"
+
+const gchar *
+ibus_get_user_name (void)
+{
+ static gchar *username = NULL;
+ if (username == NULL) {
+ username = g_strdup (getlogin());
+ if (username == NULL)
+ username = g_strdup (g_getenv("SUDO_USER"));
+ if (username == NULL) {
+ const gchar *uid = g_getenv ("USERHELPER_UID");
+ if (uid != NULL) {
+ gchar *end;
+ uid_t id = (uid_t)strtol(uid, &end, 10);
+ if (uid != end) {
+ struct passwd *pw = getpwuid (id);
+ if (pw != NULL) {
+ username = g_strdup (pw->pw_name);
+ }
+ }
+ }
+ }
+ if (username == NULL)
+ username = g_strdup (g_getenv("USERNAME"));
+ if (username == NULL)
+ username = g_strdup (g_getenv("LOGNAME"));
+ if (username == NULL)
+ username = g_strdup (g_getenv("USER"));
+ if (username == NULL)
+ username = g_strdup (g_getenv("LNAME"));
+
+ }
+ return username;
+}
+
+const gchar *
+ibus_get_socket_path (void)
+{
+ static gchar *path = NULL;
+
+ if (path == NULL) {
+ gchar *display;
+ gchar *hostname = "";
+ gchar *displaynumber = "0";
+ gchar *screennumber = "0";
+ const 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;
+ }
+ }
+
+ username = ibus_get_user_name ();
+
+ path = g_strdup_printf (
+ "/tmp/ibus-%s/ibus-%s-%s.%s",
+ username, hostname, displaynumber, screennumber);
+
+ g_free (display);
+ }
+ return path;
+
+}
+
+const gchar *
+ibus_get_address (void)
+{
+ static gchar *address = NULL;
+
+ if (address == NULL) {
+ address = g_strdup_printf (
+ "unix:path=%s",
+ ibus_get_socket_path ());
+ }
+ return address;
+}
+
+void
+ibus_free_strv (gchar **strv)
+{
+ gchar **p;
+
+ if (strv == NULL)
+ return;
+
+ for (p = strv; *p != NULL; p++) {
+ g_free (*p);
+ }
+
+ g_free (strv);
+}
+
+
+void
+ibus_init (void)
+{
+ g_type_init ();
+}
+
+static GMainLoop *main_loop = NULL;
+
+void
+ibus_main (void)
+{
+ main_loop = g_main_loop_new (NULL, FALSE);
+
+ g_main_loop_run (main_loop);
+
+ g_main_loop_unref (main_loop);
+ main_loop = NULL;
+}
+
+void
+ibus_quit (void)
+{
+ if (main_loop) {
+ g_main_loop_quit (main_loop);
+ }
+}
diff --git a/src/ibusshare.h b/src/ibusshare.h
new file mode 100644
index 0000000..142bd47
--- /dev/null
+++ b/src/ibusshare.h
@@ -0,0 +1,68 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_SHARE_H_
+#define __IBUS_SHARE_H_
+
+#include <glib.h>
+
+#define IBUS_SERVICE_IBUS "org.freedesktop.IBus"
+#define IBUS_SERVICE_PANEL "org.freedesktop.IBus.Panel"
+#define IBUS_SERVICE_CONFIG "org.freedesktop.IBus.Config"
+#define IBUS_SERVICE_NOTIFICATIONS "org.freedesktop.IBus.Notifications"
+
+#define IBUS_PATH_IBUS "/org/freedesktop/IBus"
+#define IBUS_PATH_FACTORY "/org/freedesktop/IBus/Factory"
+#define IBUS_PATH_PANEL "/org/freedesktop/IBus/Panel"
+#define IBUS_PATH_CONFIG "/org/freedesktop/IBus/Config"
+#define IBUS_PATH_NOTIFICATIONS "/org/freedesktop/IBus/Notifications"
+#define IBUS_PATH_INPUT_CONTEXT "/org/freedesktop/IBus/InputContext_%d"
+
+#define IBUS_INTERFACE_IBUS "org.freedesktop.IBus"
+#define IBUS_INTERFACE_INPUT_CONTEXT \
+ "org.freedesktop.IBus.InputContext"
+#define IBUS_INTERFACE_FACTORY "org.freedesktop.IBus.Factory"
+#define IBUS_INTERFACE_ENGINE "org.freedesktop.IBus.Engine"
+#define IBUS_INTERFACE_PANEL "org.freedesktop.IBus.Panel"
+#define IBUS_INTERFACE_CONFIG "org.freedesktop.IBus.Config"
+#define IBUS_INTERFACE_NOTIFICATIONS "org.freedesktop.IBus.Notifications"
+
+G_BEGIN_DECLS
+
+const gchar *ibus_get_address (void);
+const gchar *ibus_get_user_name (void);
+const gchar *ibus_get_socket_path (void);
+
+const gchar *ibus_keyval_name (guint keyval);
+guint ibus_keyval_from_name (const gchar *keyval_name);
+void ibus_free_strv (gchar **strv);
+const gchar *ibus_key_event_to_string
+ (guint keyval,
+ guint modifiers);
+
+gboolean ibus_key_event_from_string
+ (const gchar *string,
+ guint *keyval,
+ guint *modifiers);
+void ibus_init (void);
+void ibus_main (void);
+void ibus_quit (void);
+
+G_END_DECLS
+#endif
diff --git a/src/ibustext.c b/src/ibustext.c
new file mode 100644
index 0000000..9b87701
--- /dev/null
+++ b/src/ibustext.c
@@ -0,0 +1,283 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "ibustext.h"
+
+/* functions prototype */
+static void ibus_text_class_init (IBusTextClass *klass);
+static void ibus_text_init (IBusText *text);
+static void ibus_text_destroy (IBusText *text);
+static gboolean ibus_text_serialize (IBusText *text,
+ IBusMessageIter *iter);
+static gboolean ibus_text_deserialize (IBusText *text,
+ IBusMessageIter *iter);
+static gboolean ibus_text_copy (IBusText *dest,
+ const IBusText *src);
+
+static IBusSerializableClass *parent_class = NULL;
+
+GType
+ibus_text_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusTextClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_text_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusText),
+ 0,
+ (GInstanceInitFunc) ibus_text_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusText",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_text_class_init (IBusTextClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_text_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_text_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_text_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_text_copy;
+
+ g_string_append (serializable_class->signature, "sv");
+}
+
+static void
+ibus_text_init (IBusText *text)
+{
+ text->is_static = TRUE;
+ text->text = "";
+ text->attrs = NULL;
+}
+
+static void
+ibus_text_destroy (IBusText *text)
+{
+ if (text->text != NULL && text->is_static == FALSE) {
+ g_free (text->text);
+ text->text = NULL;
+ }
+
+ if (text->attrs) {
+ g_object_unref (text->attrs);
+ text->attrs = NULL;
+ }
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)text);
+}
+
+static gboolean
+ibus_text_serialize (IBusText *text,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = parent_class->serialize ((IBusSerializable *)text, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &text->text);
+ g_return_val_if_fail (retval, FALSE);
+
+ if (text->attrs == NULL)
+ text->attrs = ibus_attr_list_new ();
+
+ retval = ibus_message_iter_append (iter, IBUS_TYPE_ATTR_LIST, &text->attrs);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_text_deserialize (IBusText *text,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+ gchar *str;
+
+ retval = parent_class->deserialize ((IBusSerializable *)text, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &str);
+ g_return_val_if_fail (retval, FALSE);
+
+ text->is_static = FALSE;
+ text->text = g_strdup (str);
+
+ if (text->attrs) {
+ g_object_unref (text->attrs);
+ text->attrs = NULL;
+ }
+
+ retval = ibus_message_iter_get (iter, IBUS_TYPE_ATTR_LIST, &text->attrs);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_text_copy (IBusText *dest,
+ const IBusText *src)
+{
+ gboolean retval;
+
+ retval = parent_class->copy ((IBusSerializable *)dest,
+ (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_TEXT (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_TEXT (src), FALSE);
+
+ dest->text = g_strdup (src->text);
+ dest->is_static = FALSE;
+ if (src->attrs)
+ dest->attrs = (IBusAttrList *)ibus_serializable_copy ((IBusSerializable *)src->attrs);
+
+ return TRUE;
+}
+
+IBusText *
+ibus_text_new_from_string (const gchar *str)
+{
+ g_return_val_if_fail (str != NULL, NULL);
+
+ IBusText *text;
+
+ text= g_object_new (IBUS_TYPE_TEXT, 0);
+
+ text->is_static = FALSE;
+ text->text = g_strdup (str);
+
+ return text;
+}
+
+IBusText *
+ibus_text_new_from_ucs4 (const gunichar *str)
+{
+ g_return_val_if_fail (str != NULL, NULL);
+
+ IBusText *text;
+
+ text= g_object_new (IBUS_TYPE_TEXT, 0);
+
+ text->is_static = FALSE;
+ text->text = g_ucs4_to_utf8 (str, -1, NULL, NULL, NULL);
+
+ return text;
+}
+
+IBusText *
+ibus_text_new_from_static_string (const gchar *str)
+{
+ g_return_val_if_fail (str != NULL, NULL);
+
+ IBusText *text;
+
+ text= g_object_new (IBUS_TYPE_TEXT, 0);
+
+ text->is_static = TRUE;
+ text->text = (gchar *)str;
+
+ return text;
+}
+
+IBusText *
+ibus_text_new_from_printf (const gchar *format,
+ ...)
+{
+ g_return_val_if_fail (format != NULL, NULL);
+
+ gchar *str;
+ IBusText *text;
+ va_list args;
+
+ va_start (args, format);
+ str = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ if (str == NULL)
+ return NULL;
+
+ text= g_object_new (IBUS_TYPE_TEXT, 0);
+
+ text->text = (gchar *)str;
+
+ return text;
+}
+
+IBusText *
+ibus_text_new_from_unichar (gunichar c)
+{
+ IBusText *text;
+ gint len;
+
+ text= g_object_new (IBUS_TYPE_TEXT, 0);
+
+ text->text = (gchar *)g_malloc (12);
+ len = g_unichar_to_utf8 (c, text->text);
+ text->text[len] = 0;
+
+ return text;
+
+}
+
+void
+ibus_text_append_attribute (IBusText *text,
+ guint type,
+ guint value,
+ guint start_index,
+ gint end_index)
+{
+ g_assert (IBUS_IS_TEXT (text));
+
+ if (end_index < 0) {
+ end_index += g_utf8_strlen(text->text, -1) + 1;
+ }
+
+ if (end_index <= 0)
+ return;
+
+ if (text->attrs == NULL)
+ text->attrs = ibus_attr_list_new ();
+
+ ibus_attr_list_append (text->attrs, ibus_attribute_new (type, value, start_index, end_index));
+}
+
+guint
+ibus_text_get_length (IBusText *text)
+{
+ return g_utf8_strlen (text->text, -1);
+}
diff --git a/src/ibustext.h b/src/ibustext.h
new file mode 100644
index 0000000..9696f80
--- /dev/null
+++ b/src/ibustext.h
@@ -0,0 +1,77 @@
+/* vim:set et sts=4: */
+/* IBus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_TEXT_H_
+#define __IBUS_TEXT_H_
+
+#include "ibusserializable.h"
+#include "ibusattribute.h"
+
+/*
+ * Type macros.
+ */
+/* define IBusText macros */
+#define IBUS_TYPE_TEXT \
+ (ibus_text_get_type ())
+#define IBUS_TEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_TEXT, IBusText))
+#define IBUS_TEXT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_TEXT, IBusTextClass))
+#define IBUS_IS_TEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_TEXT))
+#define IBUS_IS_TEXT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_TEXT))
+#define IBUS_TEXT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_TEXT, IBusTextClass))
+
+G_BEGIN_DECLS
+
+typedef struct _IBusText IBusText;
+typedef struct _IBusTextClass IBusTextClass;
+
+struct _IBusText {
+ IBusSerializable parent;
+
+ /* members */
+ gboolean is_static;
+ gchar *text;
+ IBusAttrList *attrs;
+};
+
+struct _IBusTextClass {
+ IBusSerializableClass parent;
+};
+
+GType ibus_text_get_type (void);
+IBusText *ibus_text_new_from_string (const gchar *str);
+IBusText *ibus_text_new_from_ucs4 (const gunichar *str);
+IBusText *ibus_text_new_from_static_string (const gchar *str);
+IBusText *ibus_text_new_from_printf (const gchar *fmt,
+ ...);
+IBusText *ibus_text_new_from_unichar (gunichar c);
+void ibus_text_append_attribute (IBusText *text,
+ guint type,
+ guint value,
+ guint start_index,
+ gint end_index);
+guint ibus_text_get_length (IBusText *text);
+
+G_END_DECLS
+#endif
+
diff --git a/src/ibustypes.h b/src/ibustypes.h
new file mode 100644
index 0000000..a977db4
--- /dev/null
+++ b/src/ibustypes.h
@@ -0,0 +1,74 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_TYPES_H_
+#define __IBUS_TYPES_H_
+
+typedef enum
+{
+ IBUS_SHIFT_MASK = 1 << 0,
+ IBUS_LOCK_MASK = 1 << 1,
+ IBUS_CONTROL_MASK = 1 << 2,
+ IBUS_MOD1_MASK = 1 << 3,
+ IBUS_MOD2_MASK = 1 << 4,
+ IBUS_MOD3_MASK = 1 << 5,
+ IBUS_MOD4_MASK = 1 << 6,
+ IBUS_MOD5_MASK = 1 << 7,
+ IBUS_BUTTON1_MASK = 1 << 8,
+ IBUS_BUTTON2_MASK = 1 << 9,
+ IBUS_BUTTON3_MASK = 1 << 10,
+ IBUS_BUTTON4_MASK = 1 << 11,
+ IBUS_BUTTON5_MASK = 1 << 12,
+
+ /* The next few modifiers are used by XKB, so we skip to the end.
+ * Bits 15 - 25 are currently unused. Bit 29 is used internally.
+ */
+
+ /* forard mask */
+ IBUS_FORWARD_MASK = 1 << 25,
+
+ IBUS_SUPER_MASK = 1 << 26,
+ IBUS_HYPER_MASK = 1 << 27,
+ IBUS_META_MASK = 1 << 28,
+
+ IBUS_RELEASE_MASK = 1 << 30,
+
+ IBUS_MODIFIER_MASK = 0x5c001fff
+} IBusModifierType;
+
+typedef enum {
+ IBUS_CAP_PREEDIT_TEXT = 1 << 0,
+ IBUS_CAP_AUXILIARY_TEXT = 1 << 1,
+ IBUS_CAP_LOOKUP_TABLE = 1 << 2,
+ IBUS_CAP_FOCUS = 1 << 3,
+ IBUS_CAP_PROPERTY = 1 << 4,
+} IBusCapabilite;
+
+typedef struct _IBusRectangle IBusRectangle;
+struct _IBusRectangle {
+ gint x;
+ gint y;
+ gint width;
+ gint height;
+};
+
+typedef void (* IBusFreeFunc) (gpointer );
+
+#endif
+
diff --git a/src/ibusxml.c b/src/ibusxml.c
new file mode 100644
index 0000000..6a1e0bf
--- /dev/null
+++ b/src/ibusxml.c
@@ -0,0 +1,317 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <stdio.h>
+#include <string.h>
+#include "ibusxml.h"
+
+static GMarkupParser parser;
+
+void
+ibus_xml_free (XMLNode *node)
+{
+ g_free (node->name);
+
+ g_free (node->text);
+
+ g_strfreev (node->attributes);
+
+ g_list_foreach (node->sub_nodes, (GFunc) ibus_xml_free, NULL);
+ g_list_free (node->sub_nodes);
+
+ g_slice_free (XMLNode, node);
+}
+
+static void
+_start_root_element_cb (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ XMLNode **node = (XMLNode **) user_data;
+ g_assert (node != NULL);
+
+ XMLNode *p = g_slice_new0 (XMLNode);
+
+
+ p->name = g_strdup (element_name);
+
+ GArray *attributes = g_array_new (TRUE, TRUE, sizeof (gchar *));
+ while (*attribute_names != NULL && *attribute_values != NULL) {
+ gchar *p;
+ p = g_strdup (*attribute_names++);
+ g_array_append_val (attributes, p);
+ p = g_strdup (*attribute_values++);
+ g_array_append_val (attributes, p);
+ }
+
+ p->attributes = (gchar **) g_array_free (attributes, FALSE);
+
+ g_markup_parse_context_push (context, &parser, p);
+ *node = p;
+}
+
+
+static void
+_start_element_cb (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ XMLNode *node = (XMLNode *) user_data;
+
+ if (node->text) {
+ g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, " ");
+ return;
+ }
+
+ XMLNode *p = g_slice_new0 (XMLNode);
+
+ node->sub_nodes = g_list_append (node->sub_nodes, p);
+ g_markup_parse_context_push (context, &parser, p);
+
+ p->name = g_strdup (element_name);
+
+ GArray *attributes = g_array_new (TRUE, TRUE, sizeof (gchar *));
+ while (*attribute_names != NULL && *attribute_values != NULL) {
+ gchar *p;
+ p = g_strdup (*attribute_names++);
+ g_array_append_val (attributes, p);
+ p = g_strdup (*attribute_values++);
+ g_array_append_val (attributes, p);
+ }
+
+ p->attributes = (gchar **)g_array_free (attributes, FALSE);
+}
+
+static void
+_end_element_cb (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ XMLNode *p = (XMLNode *) g_markup_parse_context_pop (context);
+
+ if (p->text && p->sub_nodes) {
+ g_debug ("Error");
+ }
+
+ if (p->text == NULL && p->sub_nodes == NULL) {
+ p->text = g_strdup ("");
+ }
+}
+
+static gboolean
+_is_space (const gchar *text,
+ gsize text_len)
+{
+ gsize i = 0;
+
+ for (i = 0; text[i] != '\0' && i < text_len; i++) {
+ switch (text[i]) {
+ case '\t':
+ case ' ':
+ case '\n':
+ case '\r':
+ continue;
+ default:
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+_text_cb (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ XMLNode *p = (XMLNode *)user_data;
+
+ if (_is_space (text, text_len)) {
+ return;
+ }
+
+ if (p->sub_nodes || p->text) {
+ g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, " ");
+ return;
+ }
+
+ p->text = g_strndup (text, text_len);
+}
+
+static GMarkupParser parser = {
+ _start_element_cb,
+ _end_element_cb,
+ _text_cb,
+ 0,
+ 0,
+};
+
+XMLNode *
+ibus_xml_parse_file (const gchar *filename)
+{
+ gboolean retval;
+ GError *error = NULL;
+ FILE *pf = fopen (filename, "r");
+
+ if (pf == NULL) {
+ return NULL;
+ }
+
+ GMarkupParseContext *context;
+ XMLNode *node;
+
+ const static GMarkupParser root_parser = {
+ _start_root_element_cb,
+ _end_element_cb,
+ _text_cb,
+ 0,
+ 0,
+ };
+
+ context = g_markup_parse_context_new (&root_parser, 0, &node, 0);
+
+ while (!feof (pf)) {
+ gchar buf[1024];
+ gssize len = 0;
+
+ len = fread (buf, 1, sizeof (buf), pf);
+ retval = g_markup_parse_context_parse (context, buf, len, &error);
+
+ if (!retval)
+ goto _failed_out;
+ }
+
+ fclose (pf);
+
+ retval = g_markup_parse_context_end_parse (context, &error);
+ if (!retval)
+ goto _failed_out;
+
+ g_markup_parse_context_free (context);
+
+ return node;
+
+_failed_out:
+ g_warning ("Parse %s failed: %s", filename, error->message);
+ g_error_free (error);
+ g_markup_parse_context_free (context);
+ return NULL;
+}
+
+XMLNode *
+ibus_xml_parse_buffer (const gchar *buffer)
+{
+ gboolean retval;
+ GError *error = NULL;
+
+ GMarkupParseContext *context;
+ XMLNode *node;
+
+ const static GMarkupParser root_parser = {
+ _start_root_element_cb,
+ _end_element_cb,
+ _text_cb,
+ 0,
+ 0,
+ };
+
+ context = g_markup_parse_context_new (&root_parser, 0, &node, 0);
+
+ retval = g_markup_parse_context_parse (context, buffer, strlen (buffer), &error);
+
+ if (!retval)
+ goto _failed_out;
+
+ retval = g_markup_parse_context_end_parse (context, &error);
+ if (!retval)
+ goto _failed_out;
+
+ g_markup_parse_context_free (context);
+
+ return node;
+
+_failed_out:
+ g_warning ("Parse buffer failed: %s", error->message);
+ g_error_free (error);
+ g_markup_parse_context_free (context);
+ return NULL;
+
+}
+
+
+void ibus_xml_free (XMLNode *node);
+static void
+output_indent (int level, GString *output)
+{
+ gint i;
+ for (i = 0; i < level; i++) {
+ g_string_append (output, " ");
+ }
+}
+
+static void
+xml_output_indent (const XMLNode *node, int level, GString *output)
+{
+ gchar **attrs;
+
+ output_indent (level, output);
+ g_string_append_printf (output, "<%s", node->name);
+
+ attrs = node->attributes;
+
+ while (attrs != NULL && *attrs != NULL) {
+ g_string_append_printf (output, " %s", *(attrs++));
+ g_string_append_printf (output, "=\"%s\"", *(attrs++));
+ }
+
+ if (node->sub_nodes != NULL){
+ g_string_append (output, ">\n");
+ GList *sub_node;
+
+ for (sub_node = node->sub_nodes; sub_node != NULL; sub_node = sub_node->next) {
+ xml_output_indent (sub_node->data, level + 1, output);
+ }
+ output_indent (level, output);
+ g_string_append_printf (output, "</%s>\n",node->name);
+ }
+ else if (node->text != NULL) {
+ gchar *text = g_markup_escape_text (node->text, -1);
+ g_string_append_printf (output, ">%s</%s>\n", text, node->name);
+ g_free (text);
+ }
+ else {
+ g_string_append (output, "/>\n");
+ }
+}
+
+void
+xml_output (const XMLNode *node, GString *output)
+{
+ xml_output_indent (node, 0, output);
+}
+
diff --git a/src/ibusxml.h b/src/ibusxml.h
new file mode 100644
index 0000000..f6aeb25
--- /dev/null
+++ b/src/ibusxml.h
@@ -0,0 +1,37 @@
+/* vim:set et sts=4: */
+/* bus - The Input Bus
+ * Copyright (C) 2008-2009 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __IBUS_XML_H__
+#define __IBUS_XML_H__
+
+#include <glib.h>
+
+typedef struct {
+ gchar *name;
+ gchar *text;
+ gchar **attributes;
+ GList *sub_nodes;
+} XMLNode;
+
+XMLNode *ibus_xml_parse_file (const gchar *name);
+XMLNode *ibus_xml_parse_buffer (const gchar *buffer);
+void ibus_xml_free (XMLNode *node);
+void ibus_xml_output (const XMLNode *node,
+ GString *output);
+#endif
diff --git a/src/keyname-table.h b/src/keyname-table.h
new file mode 100644
index 0000000..6c51cc8
--- /dev/null
+++ b/src/keyname-table.h
@@ -0,0 +1,3978 @@
+/* keyname-table.h: Generated by gen-keyname-table.pl from keynames.txt
+ *
+ * Date: Thu Nov 2 17:26:30 2006
+ *
+ * Do not edit.
+ */
+static const char keynames[] =
+ "space\0"
+ "exclam\0"
+ "quotedbl\0"
+ "numbersign\0"
+ "dollar\0"
+ "percent\0"
+ "ampersand\0"
+ "apostrophe\0"
+ "quoteright\0"
+ "parenleft\0"
+ "parenright\0"
+ "asterisk\0"
+ "plus\0"
+ "comma\0"
+ "minus\0"
+ "period\0"
+ "slash\0"
+ "0\0"
+ "1\0"
+ "2\0"
+ "3\0"
+ "4\0"
+ "5\0"
+ "6\0"
+ "7\0"
+ "8\0"
+ "9\0"
+ "colon\0"
+ "semicolon\0"
+ "less\0"
+ "equal\0"
+ "greater\0"
+ "question\0"
+ "at\0"
+ "A\0"
+ "B\0"
+ "C\0"
+ "D\0"
+ "E\0"
+ "F\0"
+ "G\0"
+ "H\0"
+ "I\0"
+ "J\0"
+ "K\0"
+ "L\0"
+ "M\0"
+ "N\0"
+ "O\0"
+ "P\0"
+ "Q\0"
+ "R\0"
+ "S\0"
+ "T\0"
+ "U\0"
+ "V\0"
+ "W\0"
+ "X\0"
+ "Y\0"
+ "Z\0"
+ "bracketleft\0"
+ "backslash\0"
+ "bracketright\0"
+ "asciicircum\0"
+ "underscore\0"
+ "grave\0"
+ "quoteleft\0"
+ "a\0"
+ "b\0"
+ "c\0"
+ "d\0"
+ "e\0"
+ "f\0"
+ "g\0"
+ "h\0"
+ "i\0"
+ "j\0"
+ "k\0"
+ "l\0"
+ "m\0"
+ "n\0"
+ "o\0"
+ "p\0"
+ "q\0"
+ "r\0"
+ "s\0"
+ "t\0"
+ "u\0"
+ "v\0"
+ "w\0"
+ "x\0"
+ "y\0"
+ "z\0"
+ "braceleft\0"
+ "bar\0"
+ "braceright\0"
+ "asciitilde\0"
+ "nobreakspace\0"
+ "exclamdown\0"
+ "cent\0"
+ "sterling\0"
+ "currency\0"
+ "yen\0"
+ "brokenbar\0"
+ "section\0"
+ "diaeresis\0"
+ "copyright\0"
+ "ordfeminine\0"
+ "guillemotleft\0"
+ "notsign\0"
+ "hyphen\0"
+ "registered\0"
+ "macron\0"
+ "degree\0"
+ "plusminus\0"
+ "twosuperior\0"
+ "threesuperior\0"
+ "acute\0"
+ "mu\0"
+ "paragraph\0"
+ "periodcentered\0"
+ "cedilla\0"
+ "onesuperior\0"
+ "masculine\0"
+ "guillemotright\0"
+ "onequarter\0"
+ "onehalf\0"
+ "threequarters\0"
+ "questiondown\0"
+ "Agrave\0"
+ "Aacute\0"
+ "Acircumflex\0"
+ "Atilde\0"
+ "Adiaeresis\0"
+ "Aring\0"
+ "AE\0"
+ "Ccedilla\0"
+ "Egrave\0"
+ "Eacute\0"
+ "Ecircumflex\0"
+ "Ediaeresis\0"
+ "Igrave\0"
+ "Iacute\0"
+ "Icircumflex\0"
+ "Idiaeresis\0"
+ "ETH\0"
+ "Eth\0"
+ "Ntilde\0"
+ "Ograve\0"
+ "Oacute\0"
+ "Ocircumflex\0"
+ "Otilde\0"
+ "Odiaeresis\0"
+ "multiply\0"
+ "Ooblique\0"
+ "Ugrave\0"
+ "Uacute\0"
+ "Ucircumflex\0"
+ "Udiaeresis\0"
+ "Yacute\0"
+ "THORN\0"
+ "Thorn\0"
+ "ssharp\0"
+ "agrave\0"
+ "aacute\0"
+ "acircumflex\0"
+ "atilde\0"
+ "adiaeresis\0"
+ "aring\0"
+ "ae\0"
+ "ccedilla\0"
+ "egrave\0"
+ "eacute\0"
+ "ecircumflex\0"
+ "ediaeresis\0"
+ "igrave\0"
+ "iacute\0"
+ "icircumflex\0"
+ "idiaeresis\0"
+ "eth\0"
+ "ntilde\0"
+ "ograve\0"
+ "oacute\0"
+ "ocircumflex\0"
+ "otilde\0"
+ "odiaeresis\0"
+ "division\0"
+ "oslash\0"
+ "ugrave\0"
+ "uacute\0"
+ "ucircumflex\0"
+ "udiaeresis\0"
+ "yacute\0"
+ "thorn\0"
+ "ydiaeresis\0"
+ "Aogonek\0"
+ "breve\0"
+ "Lstroke\0"
+ "Lcaron\0"
+ "Sacute\0"
+ "Scaron\0"
+ "Scedilla\0"
+ "Tcaron\0"
+ "Zacute\0"
+ "Zcaron\0"
+ "Zabovedot\0"
+ "aogonek\0"
+ "ogonek\0"
+ "lstroke\0"
+ "lcaron\0"
+ "sacute\0"
+ "caron\0"
+ "scaron\0"
+ "scedilla\0"
+ "tcaron\0"
+ "zacute\0"
+ "doubleacute\0"
+ "zcaron\0"
+ "zabovedot\0"
+ "Racute\0"
+ "Abreve\0"
+ "Lacute\0"
+ "Cacute\0"
+ "Ccaron\0"
+ "Eogonek\0"
+ "Ecaron\0"
+ "Dcaron\0"
+ "Dstroke\0"
+ "Nacute\0"
+ "Ncaron\0"
+ "Odoubleacute\0"
+ "Rcaron\0"
+ "Uring\0"
+ "Udoubleacute\0"
+ "Tcedilla\0"
+ "racute\0"
+ "abreve\0"
+ "lacute\0"
+ "cacute\0"
+ "ccaron\0"
+ "eogonek\0"
+ "ecaron\0"
+ "dcaron\0"
+ "dstroke\0"
+ "nacute\0"
+ "ncaron\0"
+ "odoubleacute\0"
+ "rcaron\0"
+ "uring\0"
+ "udoubleacute\0"
+ "tcedilla\0"
+ "abovedot\0"
+ "Hstroke\0"
+ "Hcircumflex\0"
+ "Iabovedot\0"
+ "Gbreve\0"
+ "Jcircumflex\0"
+ "hstroke\0"
+ "hcircumflex\0"
+ "idotless\0"
+ "gbreve\0"
+ "jcircumflex\0"
+ "Cabovedot\0"
+ "Ccircumflex\0"
+ "Gabovedot\0"
+ "Gcircumflex\0"
+ "Ubreve\0"
+ "Scircumflex\0"
+ "cabovedot\0"
+ "ccircumflex\0"
+ "gabovedot\0"
+ "gcircumflex\0"
+ "ubreve\0"
+ "scircumflex\0"
+ "kappa\0"
+ "kra\0"
+ "Rcedilla\0"
+ "Itilde\0"
+ "Lcedilla\0"
+ "Emacron\0"
+ "Gcedilla\0"
+ "Tslash\0"
+ "rcedilla\0"
+ "itilde\0"
+ "lcedilla\0"
+ "emacron\0"
+ "gcedilla\0"
+ "tslash\0"
+ "ENG\0"
+ "eng\0"
+ "Amacron\0"
+ "Iogonek\0"
+ "Eabovedot\0"
+ "Imacron\0"
+ "Ncedilla\0"
+ "Omacron\0"
+ "Kcedilla\0"
+ "Uogonek\0"
+ "Utilde\0"
+ "Umacron\0"
+ "amacron\0"
+ "iogonek\0"
+ "eabovedot\0"
+ "imacron\0"
+ "ncedilla\0"
+ "omacron\0"
+ "kcedilla\0"
+ "uogonek\0"
+ "utilde\0"
+ "umacron\0"
+ "overline\0"
+ "kana_fullstop\0"
+ "kana_openingbracket\0"
+ "kana_closingbracket\0"
+ "kana_comma\0"
+ "kana_conjunctive\0"
+ "kana_middledot\0"
+ "kana_WO\0"
+ "kana_a\0"
+ "kana_i\0"
+ "kana_u\0"
+ "kana_e\0"
+ "kana_o\0"
+ "kana_ya\0"
+ "kana_yu\0"
+ "kana_yo\0"
+ "kana_tsu\0"
+ "kana_tu\0"
+ "prolongedsound\0"
+ "kana_A\0"
+ "kana_I\0"
+ "kana_U\0"
+ "kana_E\0"
+ "kana_O\0"
+ "kana_KA\0"
+ "kana_KI\0"
+ "kana_KU\0"
+ "kana_KE\0"
+ "kana_KO\0"
+ "kana_SA\0"
+ "kana_SHI\0"
+ "kana_SU\0"
+ "kana_SE\0"
+ "kana_SO\0"
+ "kana_TA\0"
+ "kana_CHI\0"
+ "kana_TI\0"
+ "kana_TSU\0"
+ "kana_TU\0"
+ "kana_TE\0"
+ "kana_TO\0"
+ "kana_NA\0"
+ "kana_NI\0"
+ "kana_NU\0"
+ "kana_NE\0"
+ "kana_NO\0"
+ "kana_HA\0"
+ "kana_HI\0"
+ "kana_FU\0"
+ "kana_HU\0"
+ "kana_HE\0"
+ "kana_HO\0"
+ "kana_MA\0"
+ "kana_MI\0"
+ "kana_MU\0"
+ "kana_ME\0"
+ "kana_MO\0"
+ "kana_YA\0"
+ "kana_YU\0"
+ "kana_YO\0"
+ "kana_RA\0"
+ "kana_RI\0"
+ "kana_RU\0"
+ "kana_RE\0"
+ "kana_RO\0"
+ "kana_WA\0"
+ "kana_N\0"
+ "voicedsound\0"
+ "semivoicedsound\0"
+ "Arabic_comma\0"
+ "Arabic_semicolon\0"
+ "Arabic_question_mark\0"
+ "Arabic_hamza\0"
+ "Arabic_maddaonalef\0"
+ "Arabic_hamzaonalef\0"
+ "Arabic_hamzaonwaw\0"
+ "Arabic_hamzaunderalef\0"
+ "Arabic_hamzaonyeh\0"
+ "Arabic_alef\0"
+ "Arabic_beh\0"
+ "Arabic_tehmarbuta\0"
+ "Arabic_teh\0"
+ "Arabic_theh\0"
+ "Arabic_jeem\0"
+ "Arabic_hah\0"
+ "Arabic_khah\0"
+ "Arabic_dal\0"
+ "Arabic_thal\0"
+ "Arabic_ra\0"
+ "Arabic_zain\0"
+ "Arabic_seen\0"
+ "Arabic_sheen\0"
+ "Arabic_sad\0"
+ "Arabic_dad\0"
+ "Arabic_tah\0"
+ "Arabic_zah\0"
+ "Arabic_ain\0"
+ "Arabic_ghain\0"
+ "Arabic_tatweel\0"
+ "Arabic_feh\0"
+ "Arabic_qaf\0"
+ "Arabic_kaf\0"
+ "Arabic_lam\0"
+ "Arabic_meem\0"
+ "Arabic_noon\0"
+ "Arabic_ha\0"
+ "Arabic_heh\0"
+ "Arabic_waw\0"
+ "Arabic_alefmaksura\0"
+ "Arabic_yeh\0"
+ "Arabic_fathatan\0"
+ "Arabic_dammatan\0"
+ "Arabic_kasratan\0"
+ "Arabic_fatha\0"
+ "Arabic_damma\0"
+ "Arabic_kasra\0"
+ "Arabic_shadda\0"
+ "Arabic_sukun\0"
+ "Serbian_dje\0"
+ "Macedonia_gje\0"
+ "Cyrillic_io\0"
+ "Ukrainian_ie\0"
+ "Ukranian_je\0"
+ "Macedonia_dse\0"
+ "Ukrainian_i\0"
+ "Ukranian_i\0"
+ "Ukrainian_yi\0"
+ "Ukranian_yi\0"
+ "Cyrillic_je\0"
+ "Serbian_je\0"
+ "Cyrillic_lje\0"
+ "Serbian_lje\0"
+ "Cyrillic_nje\0"
+ "Serbian_nje\0"
+ "Serbian_tshe\0"
+ "Macedonia_kje\0"
+ "Byelorussian_shortu\0"
+ "Cyrillic_dzhe\0"
+ "Serbian_dze\0"
+ "numerosign\0"
+ "Serbian_DJE\0"
+ "Macedonia_GJE\0"
+ "Cyrillic_IO\0"
+ "Ukrainian_IE\0"
+ "Ukranian_JE\0"
+ "Macedonia_DSE\0"
+ "Ukrainian_I\0"
+ "Ukranian_I\0"
+ "Ukrainian_YI\0"
+ "Ukranian_YI\0"
+ "Cyrillic_JE\0"
+ "Serbian_JE\0"
+ "Cyrillic_LJE\0"
+ "Serbian_LJE\0"
+ "Cyrillic_NJE\0"
+ "Serbian_NJE\0"
+ "Serbian_TSHE\0"
+ "Macedonia_KJE\0"
+ "Byelorussian_SHORTU\0"
+ "Cyrillic_DZHE\0"
+ "Serbian_DZE\0"
+ "Cyrillic_yu\0"
+ "Cyrillic_a\0"
+ "Cyrillic_be\0"
+ "Cyrillic_tse\0"
+ "Cyrillic_de\0"
+ "Cyrillic_ie\0"
+ "Cyrillic_ef\0"
+ "Cyrillic_ghe\0"
+ "Cyrillic_ha\0"
+ "Cyrillic_i\0"
+ "Cyrillic_shorti\0"
+ "Cyrillic_ka\0"
+ "Cyrillic_el\0"
+ "Cyrillic_em\0"
+ "Cyrillic_en\0"
+ "Cyrillic_o\0"
+ "Cyrillic_pe\0"
+ "Cyrillic_ya\0"
+ "Cyrillic_er\0"
+ "Cyrillic_es\0"
+ "Cyrillic_te\0"
+ "Cyrillic_u\0"
+ "Cyrillic_zhe\0"
+ "Cyrillic_ve\0"
+ "Cyrillic_softsign\0"
+ "Cyrillic_yeru\0"
+ "Cyrillic_ze\0"
+ "Cyrillic_sha\0"
+ "Cyrillic_e\0"
+ "Cyrillic_shcha\0"
+ "Cyrillic_che\0"
+ "Cyrillic_hardsign\0"
+ "Cyrillic_YU\0"
+ "Cyrillic_A\0"
+ "Cyrillic_BE\0"
+ "Cyrillic_TSE\0"
+ "Cyrillic_DE\0"
+ "Cyrillic_IE\0"
+ "Cyrillic_EF\0"
+ "Cyrillic_GHE\0"
+ "Cyrillic_HA\0"
+ "Cyrillic_I\0"
+ "Cyrillic_SHORTI\0"
+ "Cyrillic_KA\0"
+ "Cyrillic_EL\0"
+ "Cyrillic_EM\0"
+ "Cyrillic_EN\0"
+ "Cyrillic_O\0"
+ "Cyrillic_PE\0"
+ "Cyrillic_YA\0"
+ "Cyrillic_ER\0"
+ "Cyrillic_ES\0"
+ "Cyrillic_TE\0"
+ "Cyrillic_U\0"
+ "Cyrillic_ZHE\0"
+ "Cyrillic_VE\0"
+ "Cyrillic_SOFTSIGN\0"
+ "Cyrillic_YERU\0"
+ "Cyrillic_ZE\0"
+ "Cyrillic_SHA\0"
+ "Cyrillic_E\0"
+ "Cyrillic_SHCHA\0"
+ "Cyrillic_CHE\0"
+ "Cyrillic_HARDSIGN\0"
+ "Greek_ALPHAaccent\0"
+ "Greek_EPSILONaccent\0"
+ "Greek_ETAaccent\0"
+ "Greek_IOTAaccent\0"
+ "Greek_IOTAdieresis\0"
+ "Greek_IOTAdiaeresis\0"
+ "Greek_OMICRONaccent\0"
+ "Greek_UPSILONaccent\0"
+ "Greek_UPSILONdieresis\0"
+ "Greek_OMEGAaccent\0"
+ "Greek_accentdieresis\0"
+ "Greek_horizbar\0"
+ "Greek_alphaaccent\0"
+ "Greek_epsilonaccent\0"
+ "Greek_etaaccent\0"
+ "Greek_iotaaccent\0"
+ "Greek_iotadieresis\0"
+ "Greek_iotaaccentdieresis\0"
+ "Greek_omicronaccent\0"
+ "Greek_upsilonaccent\0"
+ "Greek_upsilondieresis\0"
+ "Greek_upsilonaccentdieresis\0"
+ "Greek_omegaaccent\0"
+ "Greek_ALPHA\0"
+ "Greek_BETA\0"
+ "Greek_GAMMA\0"
+ "Greek_DELTA\0"
+ "Greek_EPSILON\0"
+ "Greek_ZETA\0"
+ "Greek_ETA\0"
+ "Greek_THETA\0"
+ "Greek_IOTA\0"
+ "Greek_KAPPA\0"
+ "Greek_LAMBDA\0"
+ "Greek_LAMDA\0"
+ "Greek_MU\0"
+ "Greek_NU\0"
+ "Greek_XI\0"
+ "Greek_OMICRON\0"
+ "Greek_PI\0"
+ "Greek_RHO\0"
+ "Greek_SIGMA\0"
+ "Greek_TAU\0"
+ "Greek_UPSILON\0"
+ "Greek_PHI\0"
+ "Greek_CHI\0"
+ "Greek_PSI\0"
+ "Greek_OMEGA\0"
+ "Greek_alpha\0"
+ "Greek_beta\0"
+ "Greek_gamma\0"
+ "Greek_delta\0"
+ "Greek_epsilon\0"
+ "Greek_zeta\0"
+ "Greek_eta\0"
+ "Greek_theta\0"
+ "Greek_iota\0"
+ "Greek_kappa\0"
+ "Greek_lambda\0"
+ "Greek_lamda\0"
+ "Greek_mu\0"
+ "Greek_nu\0"
+ "Greek_xi\0"
+ "Greek_omicron\0"
+ "Greek_pi\0"
+ "Greek_rho\0"
+ "Greek_sigma\0"
+ "Greek_finalsmallsigma\0"
+ "Greek_tau\0"
+ "Greek_upsilon\0"
+ "Greek_phi\0"
+ "Greek_chi\0"
+ "Greek_psi\0"
+ "Greek_omega\0"
+ "leftradical\0"
+ "topleftradical\0"
+ "horizconnector\0"
+ "topintegral\0"
+ "botintegral\0"
+ "vertconnector\0"
+ "topleftsqbracket\0"
+ "botleftsqbracket\0"
+ "toprightsqbracket\0"
+ "botrightsqbracket\0"
+ "topleftparens\0"
+ "botleftparens\0"
+ "toprightparens\0"
+ "botrightparens\0"
+ "leftmiddlecurlybrace\0"
+ "rightmiddlecurlybrace\0"
+ "topleftsummation\0"
+ "botleftsummation\0"
+ "topvertsummationconnector\0"
+ "botvertsummationconnector\0"
+ "toprightsummation\0"
+ "botrightsummation\0"
+ "rightmiddlesummation\0"
+ "lessthanequal\0"
+ "notequal\0"
+ "greaterthanequal\0"
+ "integral\0"
+ "therefore\0"
+ "variation\0"
+ "infinity\0"
+ "nabla\0"
+ "approximate\0"
+ "similarequal\0"
+ "ifonlyif\0"
+ "implies\0"
+ "identical\0"
+ "radical\0"
+ "includedin\0"
+ "includes\0"
+ "intersection\0"
+ "union\0"
+ "logicaland\0"
+ "logicalor\0"
+ "partialderivative\0"
+ "function\0"
+ "leftarrow\0"
+ "uparrow\0"
+ "rightarrow\0"
+ "downarrow\0"
+ "blank\0"
+ "soliddiamond\0"
+ "checkerboard\0"
+ "ht\0"
+ "ff\0"
+ "cr\0"
+ "lf\0"
+ "nl\0"
+ "vt\0"
+ "lowrightcorner\0"
+ "uprightcorner\0"
+ "upleftcorner\0"
+ "lowleftcorner\0"
+ "crossinglines\0"
+ "horizlinescan1\0"
+ "horizlinescan3\0"
+ "horizlinescan5\0"
+ "horizlinescan7\0"
+ "horizlinescan9\0"
+ "leftt\0"
+ "rightt\0"
+ "bott\0"
+ "topt\0"
+ "vertbar\0"
+ "emspace\0"
+ "enspace\0"
+ "em3space\0"
+ "em4space\0"
+ "digitspace\0"
+ "punctspace\0"
+ "thinspace\0"
+ "hairspace\0"
+ "emdash\0"
+ "endash\0"
+ "signifblank\0"
+ "ellipsis\0"
+ "doubbaselinedot\0"
+ "onethird\0"
+ "twothirds\0"
+ "onefifth\0"
+ "twofifths\0"
+ "threefifths\0"
+ "fourfifths\0"
+ "onesixth\0"
+ "fivesixths\0"
+ "careof\0"
+ "figdash\0"
+ "leftanglebracket\0"
+ "decimalpoint\0"
+ "rightanglebracket\0"
+ "marker\0"
+ "oneeighth\0"
+ "threeeighths\0"
+ "fiveeighths\0"
+ "seveneighths\0"
+ "trademark\0"
+ "signaturemark\0"
+ "trademarkincircle\0"
+ "leftopentriangle\0"
+ "rightopentriangle\0"
+ "emopencircle\0"
+ "emopenrectangle\0"
+ "leftsinglequotemark\0"
+ "rightsinglequotemark\0"
+ "leftdoublequotemark\0"
+ "rightdoublequotemark\0"
+ "prescription\0"
+ "minutes\0"
+ "seconds\0"
+ "latincross\0"
+ "hexagram\0"
+ "filledrectbullet\0"
+ "filledlefttribullet\0"
+ "filledrighttribullet\0"
+ "emfilledcircle\0"
+ "emfilledrect\0"
+ "enopencircbullet\0"
+ "enopensquarebullet\0"
+ "openrectbullet\0"
+ "opentribulletup\0"
+ "opentribulletdown\0"
+ "openstar\0"
+ "enfilledcircbullet\0"
+ "enfilledsqbullet\0"
+ "filledtribulletup\0"
+ "filledtribulletdown\0"
+ "leftpointer\0"
+ "rightpointer\0"
+ "club\0"
+ "diamond\0"
+ "heart\0"
+ "maltesecross\0"
+ "dagger\0"
+ "doubledagger\0"
+ "checkmark\0"
+ "ballotcross\0"
+ "musicalsharp\0"
+ "musicalflat\0"
+ "malesymbol\0"
+ "femalesymbol\0"
+ "telephone\0"
+ "telephonerecorder\0"
+ "phonographcopyright\0"
+ "caret\0"
+ "singlelowquotemark\0"
+ "doublelowquotemark\0"
+ "cursor\0"
+ "leftcaret\0"
+ "rightcaret\0"
+ "downcaret\0"
+ "upcaret\0"
+ "overbar\0"
+ "downtack\0"
+ "upshoe\0"
+ "downstile\0"
+ "underbar\0"
+ "jot\0"
+ "quad\0"
+ "uptack\0"
+ "circle\0"
+ "upstile\0"
+ "downshoe\0"
+ "rightshoe\0"
+ "leftshoe\0"
+ "lefttack\0"
+ "righttack\0"
+ "hebrew_doublelowline\0"
+ "hebrew_aleph\0"
+ "hebrew_bet\0"
+ "hebrew_beth\0"
+ "hebrew_gimel\0"
+ "hebrew_gimmel\0"
+ "hebrew_dalet\0"
+ "hebrew_daleth\0"
+ "hebrew_he\0"
+ "hebrew_waw\0"
+ "hebrew_zain\0"
+ "hebrew_zayin\0"
+ "hebrew_chet\0"
+ "hebrew_het\0"
+ "hebrew_tet\0"
+ "hebrew_teth\0"
+ "hebrew_yod\0"
+ "hebrew_finalkaph\0"
+ "hebrew_kaph\0"
+ "hebrew_lamed\0"
+ "hebrew_finalmem\0"
+ "hebrew_mem\0"
+ "hebrew_finalnun\0"
+ "hebrew_nun\0"
+ "hebrew_samech\0"
+ "hebrew_samekh\0"
+ "hebrew_ayin\0"
+ "hebrew_finalpe\0"
+ "hebrew_pe\0"
+ "hebrew_finalzade\0"
+ "hebrew_finalzadi\0"
+ "hebrew_zade\0"
+ "hebrew_zadi\0"
+ "hebrew_kuf\0"
+ "hebrew_qoph\0"
+ "hebrew_resh\0"
+ "hebrew_shin\0"
+ "hebrew_taf\0"
+ "hebrew_taw\0"
+ "Thai_kokai\0"
+ "Thai_khokhai\0"
+ "Thai_khokhuat\0"
+ "Thai_khokhwai\0"
+ "Thai_khokhon\0"
+ "Thai_khorakhang\0"
+ "Thai_ngongu\0"
+ "Thai_chochan\0"
+ "Thai_choching\0"
+ "Thai_chochang\0"
+ "Thai_soso\0"
+ "Thai_chochoe\0"
+ "Thai_yoying\0"
+ "Thai_dochada\0"
+ "Thai_topatak\0"
+ "Thai_thothan\0"
+ "Thai_thonangmontho\0"
+ "Thai_thophuthao\0"
+ "Thai_nonen\0"
+ "Thai_dodek\0"
+ "Thai_totao\0"
+ "Thai_thothung\0"
+ "Thai_thothahan\0"
+ "Thai_thothong\0"
+ "Thai_nonu\0"
+ "Thai_bobaimai\0"
+ "Thai_popla\0"
+ "Thai_phophung\0"
+ "Thai_fofa\0"
+ "Thai_phophan\0"
+ "Thai_fofan\0"
+ "Thai_phosamphao\0"
+ "Thai_moma\0"
+ "Thai_yoyak\0"
+ "Thai_rorua\0"
+ "Thai_ru\0"
+ "Thai_loling\0"
+ "Thai_lu\0"
+ "Thai_wowaen\0"
+ "Thai_sosala\0"
+ "Thai_sorusi\0"
+ "Thai_sosua\0"
+ "Thai_hohip\0"
+ "Thai_lochula\0"
+ "Thai_oang\0"
+ "Thai_honokhuk\0"
+ "Thai_paiyannoi\0"
+ "Thai_saraa\0"
+ "Thai_maihanakat\0"
+ "Thai_saraaa\0"
+ "Thai_saraam\0"
+ "Thai_sarai\0"
+ "Thai_saraii\0"
+ "Thai_saraue\0"
+ "Thai_sarauee\0"
+ "Thai_sarau\0"
+ "Thai_sarauu\0"
+ "Thai_phinthu\0"
+ "Thai_maihanakat_maitho\0"
+ "Thai_baht\0"
+ "Thai_sarae\0"
+ "Thai_saraae\0"
+ "Thai_sarao\0"
+ "Thai_saraaimaimuan\0"
+ "Thai_saraaimaimalai\0"
+ "Thai_lakkhangyao\0"
+ "Thai_maiyamok\0"
+ "Thai_maitaikhu\0"
+ "Thai_maiek\0"
+ "Thai_maitho\0"
+ "Thai_maitri\0"
+ "Thai_maichattawa\0"
+ "Thai_thanthakhat\0"
+ "Thai_nikhahit\0"
+ "Thai_leksun\0"
+ "Thai_leknung\0"
+ "Thai_leksong\0"
+ "Thai_leksam\0"
+ "Thai_leksi\0"
+ "Thai_lekha\0"
+ "Thai_lekhok\0"
+ "Thai_lekchet\0"
+ "Thai_lekpaet\0"
+ "Thai_lekkao\0"
+ "Hangul_Kiyeog\0"
+ "Hangul_SsangKiyeog\0"
+ "Hangul_KiyeogSios\0"
+ "Hangul_Nieun\0"
+ "Hangul_NieunJieuj\0"
+ "Hangul_NieunHieuh\0"
+ "Hangul_Dikeud\0"
+ "Hangul_SsangDikeud\0"
+ "Hangul_Rieul\0"
+ "Hangul_RieulKiyeog\0"
+ "Hangul_RieulMieum\0"
+ "Hangul_RieulPieub\0"
+ "Hangul_RieulSios\0"
+ "Hangul_RieulTieut\0"
+ "Hangul_RieulPhieuf\0"
+ "Hangul_RieulHieuh\0"
+ "Hangul_Mieum\0"
+ "Hangul_Pieub\0"
+ "Hangul_SsangPieub\0"
+ "Hangul_PieubSios\0"
+ "Hangul_Sios\0"
+ "Hangul_SsangSios\0"
+ "Hangul_Ieung\0"
+ "Hangul_Jieuj\0"
+ "Hangul_SsangJieuj\0"
+ "Hangul_Cieuc\0"
+ "Hangul_Khieuq\0"
+ "Hangul_Tieut\0"
+ "Hangul_Phieuf\0"
+ "Hangul_Hieuh\0"
+ "Hangul_A\0"
+ "Hangul_AE\0"
+ "Hangul_YA\0"
+ "Hangul_YAE\0"
+ "Hangul_EO\0"
+ "Hangul_E\0"
+ "Hangul_YEO\0"
+ "Hangul_YE\0"
+ "Hangul_O\0"
+ "Hangul_WA\0"
+ "Hangul_WAE\0"
+ "Hangul_OE\0"
+ "Hangul_YO\0"
+ "Hangul_U\0"
+ "Hangul_WEO\0"
+ "Hangul_WE\0"
+ "Hangul_WI\0"
+ "Hangul_YU\0"
+ "Hangul_EU\0"
+ "Hangul_YI\0"
+ "Hangul_I\0"
+ "Hangul_J_Kiyeog\0"
+ "Hangul_J_SsangKiyeog\0"
+ "Hangul_J_KiyeogSios\0"
+ "Hangul_J_Nieun\0"
+ "Hangul_J_NieunJieuj\0"
+ "Hangul_J_NieunHieuh\0"
+ "Hangul_J_Dikeud\0"
+ "Hangul_J_Rieul\0"
+ "Hangul_J_RieulKiyeog\0"
+ "Hangul_J_RieulMieum\0"
+ "Hangul_J_RieulPieub\0"
+ "Hangul_J_RieulSios\0"
+ "Hangul_J_RieulTieut\0"
+ "Hangul_J_RieulPhieuf\0"
+ "Hangul_J_RieulHieuh\0"
+ "Hangul_J_Mieum\0"
+ "Hangul_J_Pieub\0"
+ "Hangul_J_PieubSios\0"
+ "Hangul_J_Sios\0"
+ "Hangul_J_SsangSios\0"
+ "Hangul_J_Ieung\0"
+ "Hangul_J_Jieuj\0"
+ "Hangul_J_Cieuc\0"
+ "Hangul_J_Khieuq\0"
+ "Hangul_J_Tieut\0"
+ "Hangul_J_Phieuf\0"
+ "Hangul_J_Hieuh\0"
+ "Hangul_RieulYeorinHieuh\0"
+ "Hangul_SunkyeongeumMieum\0"
+ "Hangul_SunkyeongeumPieub\0"
+ "Hangul_PanSios\0"
+ "Hangul_KkogjiDalrinIeung\0"
+ "Hangul_SunkyeongeumPhieuf\0"
+ "Hangul_YeorinHieuh\0"
+ "Hangul_AraeA\0"
+ "Hangul_AraeAE\0"
+ "Hangul_J_PanSios\0"
+ "Hangul_J_KkogjiDalrinIeung\0"
+ "Hangul_J_YeorinHieuh\0"
+ "Korean_Won\0"
+ "OE\0"
+ "oe\0"
+ "Ydiaeresis\0"
+ "EcuSign\0"
+ "ColonSign\0"
+ "CruzeiroSign\0"
+ "FFrancSign\0"
+ "LiraSign\0"
+ "MillSign\0"
+ "NairaSign\0"
+ "PesetaSign\0"
+ "RupeeSign\0"
+ "WonSign\0"
+ "NewSheqelSign\0"
+ "DongSign\0"
+ "EuroSign\0"
+ "3270_Duplicate\0"
+ "3270_FieldMark\0"
+ "3270_Right2\0"
+ "3270_Left2\0"
+ "3270_BackTab\0"
+ "3270_EraseEOF\0"
+ "3270_EraseInput\0"
+ "3270_Reset\0"
+ "3270_Quit\0"
+ "3270_PA1\0"
+ "3270_PA2\0"
+ "3270_PA3\0"
+ "3270_Test\0"
+ "3270_Attn\0"
+ "3270_CursorBlink\0"
+ "3270_AltCursor\0"
+ "3270_KeyClick\0"
+ "3270_Jump\0"
+ "3270_Ident\0"
+ "3270_Rule\0"
+ "3270_Copy\0"
+ "3270_Play\0"
+ "3270_Setup\0"
+ "3270_Record\0"
+ "3270_ChangeScreen\0"
+ "3270_DeleteWord\0"
+ "3270_ExSelect\0"
+ "3270_CursorSelect\0"
+ "3270_PrintScreen\0"
+ "3270_Enter\0"
+ "ISO_Lock\0"
+ "ISO_Level2_Latch\0"
+ "ISO_Level3_Shift\0"
+ "ISO_Level3_Latch\0"
+ "ISO_Level3_Lock\0"
+ "ISO_Group_Latch\0"
+ "ISO_Group_Lock\0"
+ "ISO_Next_Group\0"
+ "ISO_Next_Group_Lock\0"
+ "ISO_Prev_Group\0"
+ "ISO_Prev_Group_Lock\0"
+ "ISO_First_Group\0"
+ "ISO_First_Group_Lock\0"
+ "ISO_Last_Group\0"
+ "ISO_Last_Group_Lock\0"
+ "ISO_Left_Tab\0"
+ "ISO_Move_Line_Up\0"
+ "ISO_Move_Line_Down\0"
+ "ISO_Partial_Line_Up\0"
+ "ISO_Partial_Line_Down\0"
+ "ISO_Partial_Space_Left\0"
+ "ISO_Partial_Space_Right\0"
+ "ISO_Set_Margin_Left\0"
+ "ISO_Set_Margin_Right\0"
+ "ISO_Release_Margin_Left\0"
+ "ISO_Release_Margin_Right\0"
+ "ISO_Release_Both_Margins\0"
+ "ISO_Fast_Cursor_Left\0"
+ "ISO_Fast_Cursor_Right\0"
+ "ISO_Fast_Cursor_Up\0"
+ "ISO_Fast_Cursor_Down\0"
+ "ISO_Continuous_Underline\0"
+ "ISO_Discontinuous_Underline\0"
+ "ISO_Emphasize\0"
+ "ISO_Center_Object\0"
+ "ISO_Enter\0"
+ "dead_grave\0"
+ "dead_acute\0"
+ "dead_circumflex\0"
+ "dead_tilde\0"
+ "dead_macron\0"
+ "dead_breve\0"
+ "dead_abovedot\0"
+ "dead_diaeresis\0"
+ "dead_abovering\0"
+ "dead_doubleacute\0"
+ "dead_caron\0"
+ "dead_cedilla\0"
+ "dead_ogonek\0"
+ "dead_iota\0"
+ "dead_voiced_sound\0"
+ "dead_semivoiced_sound\0"
+ "dead_belowdot\0"
+ "dead_hook\0"
+ "dead_horn\0"
+ "AccessX_Enable\0"
+ "AccessX_Feedback_Enable\0"
+ "RepeatKeys_Enable\0"
+ "SlowKeys_Enable\0"
+ "BounceKeys_Enable\0"
+ "StickyKeys_Enable\0"
+ "MouseKeys_Enable\0"
+ "MouseKeys_Accel_Enable\0"
+ "Overlay1_Enable\0"
+ "Overlay2_Enable\0"
+ "AudibleBell_Enable\0"
+ "First_Virtual_Screen\0"
+ "Prev_Virtual_Screen\0"
+ "Next_Virtual_Screen\0"
+ "Last_Virtual_Screen\0"
+ "Terminate_Server\0"
+ "Pointer_Left\0"
+ "Pointer_Right\0"
+ "Pointer_Up\0"
+ "Pointer_Down\0"
+ "Pointer_UpLeft\0"
+ "Pointer_UpRight\0"
+ "Pointer_DownLeft\0"
+ "Pointer_DownRight\0"
+ "Pointer_Button_Dflt\0"
+ "Pointer_Button1\0"
+ "Pointer_Button2\0"
+ "Pointer_Button3\0"
+ "Pointer_Button4\0"
+ "Pointer_Button5\0"
+ "Pointer_DblClick_Dflt\0"
+ "Pointer_DblClick1\0"
+ "Pointer_DblClick2\0"
+ "Pointer_DblClick3\0"
+ "Pointer_DblClick4\0"
+ "Pointer_DblClick5\0"
+ "Pointer_Drag_Dflt\0"
+ "Pointer_Drag1\0"
+ "Pointer_Drag2\0"
+ "Pointer_Drag3\0"
+ "Pointer_Drag4\0"
+ "Pointer_EnableKeys\0"
+ "Pointer_Accelerate\0"
+ "Pointer_DfltBtnNext\0"
+ "Pointer_DfltBtnPrev\0"
+ "Pointer_Drag5\0"
+ "BackSpace\0"
+ "Tab\0"
+ "Linefeed\0"
+ "Clear\0"
+ "Return\0"
+ "Pause\0"
+ "Scroll_Lock\0"
+ "Sys_Req\0"
+ "Escape\0"
+ "Multi_key\0"
+ "Kanji\0"
+ "Muhenkan\0"
+ "Henkan\0"
+ "Henkan_Mode\0"
+ "Romaji\0"
+ "Hiragana\0"
+ "Katakana\0"
+ "Hiragana_Katakana\0"
+ "Zenkaku\0"
+ "Hankaku\0"
+ "Zenkaku_Hankaku\0"
+ "Touroku\0"
+ "Massyo\0"
+ "Kana_Lock\0"
+ "Kana_Shift\0"
+ "Eisu_Shift\0"
+ "Eisu_toggle\0"
+ "Hangul\0"
+ "Hangul_Start\0"
+ "Hangul_End\0"
+ "Hangul_Hanja\0"
+ "Hangul_Jamo\0"
+ "Hangul_Romaja\0"
+ "Codeinput\0"
+ "Hangul_Jeonja\0"
+ "Hangul_Banja\0"
+ "Hangul_PreHanja\0"
+ "Hangul_PostHanja\0"
+ "SingleCandidate\0"
+ "MultipleCandidate\0"
+ "PreviousCandidate\0"
+ "Hangul_Special\0"
+ "Home\0"
+ "Left\0"
+ "Up\0"
+ "Right\0"
+ "Down\0"
+ "Page_Up\0"
+ "Prior\0"
+ "Page_Down\0"
+ "Next\0"
+ "End\0"
+ "Begin\0"
+ "Select\0"
+ "Print\0"
+ "Execute\0"
+ "Insert\0"
+ "Undo\0"
+ "Redo\0"
+ "Menu\0"
+ "Find\0"
+ "Cancel\0"
+ "Help\0"
+ "Break\0"
+ "Arabic_switch\0"
+ "Greek_switch\0"
+ "Hangul_switch\0"
+ "Hebrew_switch\0"
+ "ISO_Group_Shift\0"
+ "Mode_switch\0"
+ "kana_switch\0"
+ "script_switch\0"
+ "Num_Lock\0"
+ "KP_Space\0"
+ "KP_Tab\0"
+ "KP_Enter\0"
+ "KP_F1\0"
+ "KP_F2\0"
+ "KP_F3\0"
+ "KP_F4\0"
+ "KP_Home\0"
+ "KP_Left\0"
+ "KP_Up\0"
+ "KP_Right\0"
+ "KP_Down\0"
+ "KP_Page_Up\0"
+ "KP_Prior\0"
+ "KP_Page_Down\0"
+ "KP_Next\0"
+ "KP_End\0"
+ "KP_Begin\0"
+ "KP_Insert\0"
+ "KP_Delete\0"
+ "KP_Multiply\0"
+ "KP_Add\0"
+ "KP_Separator\0"
+ "KP_Subtract\0"
+ "KP_Decimal\0"
+ "KP_Divide\0"
+ "KP_0\0"
+ "KP_1\0"
+ "KP_2\0"
+ "KP_3\0"
+ "KP_4\0"
+ "KP_5\0"
+ "KP_6\0"
+ "KP_7\0"
+ "KP_8\0"
+ "KP_9\0"
+ "KP_Equal\0"
+ "F1\0"
+ "F2\0"
+ "F3\0"
+ "F4\0"
+ "F5\0"
+ "F6\0"
+ "F7\0"
+ "F8\0"
+ "F9\0"
+ "F10\0"
+ "F11\0"
+ "F12\0"
+ "F13\0"
+ "F14\0"
+ "F15\0"
+ "F16\0"
+ "F17\0"
+ "F18\0"
+ "F19\0"
+ "F20\0"
+ "F21\0"
+ "F22\0"
+ "F23\0"
+ "F24\0"
+ "F25\0"
+ "F26\0"
+ "F27\0"
+ "F28\0"
+ "F29\0"
+ "F30\0"
+ "F31\0"
+ "F32\0"
+ "F33\0"
+ "F34\0"
+ "F35\0"
+ "Shift_L\0"
+ "Shift_R\0"
+ "Control_L\0"
+ "Control_R\0"
+ "Caps_Lock\0"
+ "Shift_Lock\0"
+ "Meta_L\0"
+ "Meta_R\0"
+ "Alt_L\0"
+ "Alt_R\0"
+ "Super_L\0"
+ "Super_R\0"
+ "Hyper_L\0"
+ "Hyper_R\0"
+ "Delete\0"
+ "VoidSymbol\0";
+
+typedef struct {
+ guint keyval;
+ guint offset;
+} gdk_key;
+
+static const gdk_key gdk_keys_by_keyval[] = {
+ { 0x000020, 0 },
+ { 0x000021, 6 },
+ { 0x000022, 13 },
+ { 0x000023, 22 },
+ { 0x000024, 33 },
+ { 0x000025, 40 },
+ { 0x000026, 48 },
+ { 0x000027, 58 },
+ { 0x000027, 69 },
+ { 0x000028, 80 },
+ { 0x000029, 90 },
+ { 0x00002a, 101 },
+ { 0x00002b, 110 },
+ { 0x00002c, 115 },
+ { 0x00002d, 121 },
+ { 0x00002e, 127 },
+ { 0x00002f, 134 },
+ { 0x000030, 140 },
+ { 0x000031, 142 },
+ { 0x000032, 144 },
+ { 0x000033, 146 },
+ { 0x000034, 148 },
+ { 0x000035, 150 },
+ { 0x000036, 152 },
+ { 0x000037, 154 },
+ { 0x000038, 156 },
+ { 0x000039, 158 },
+ { 0x00003a, 160 },
+ { 0x00003b, 166 },
+ { 0x00003c, 176 },
+ { 0x00003d, 181 },
+ { 0x00003e, 187 },
+ { 0x00003f, 195 },
+ { 0x000040, 204 },
+ { 0x000041, 207 },
+ { 0x000042, 209 },
+ { 0x000043, 211 },
+ { 0x000044, 213 },
+ { 0x000045, 215 },
+ { 0x000046, 217 },
+ { 0x000047, 219 },
+ { 0x000048, 221 },
+ { 0x000049, 223 },
+ { 0x00004a, 225 },
+ { 0x00004b, 227 },
+ { 0x00004c, 229 },
+ { 0x00004d, 231 },
+ { 0x00004e, 233 },
+ { 0x00004f, 235 },
+ { 0x000050, 237 },
+ { 0x000051, 239 },
+ { 0x000052, 241 },
+ { 0x000053, 243 },
+ { 0x000054, 245 },
+ { 0x000055, 247 },
+ { 0x000056, 249 },
+ { 0x000057, 251 },
+ { 0x000058, 253 },
+ { 0x000059, 255 },
+ { 0x00005a, 257 },
+ { 0x00005b, 259 },
+ { 0x00005c, 271 },
+ { 0x00005d, 281 },
+ { 0x00005e, 294 },
+ { 0x00005f, 306 },
+ { 0x000060, 317 },
+ { 0x000060, 323 },
+ { 0x000061, 333 },
+ { 0x000062, 335 },
+ { 0x000063, 337 },
+ { 0x000064, 339 },
+ { 0x000065, 341 },
+ { 0x000066, 343 },
+ { 0x000067, 345 },
+ { 0x000068, 347 },
+ { 0x000069, 349 },
+ { 0x00006a, 351 },
+ { 0x00006b, 353 },
+ { 0x00006c, 355 },
+ { 0x00006d, 357 },
+ { 0x00006e, 359 },
+ { 0x00006f, 361 },
+ { 0x000070, 363 },
+ { 0x000071, 365 },
+ { 0x000072, 367 },
+ { 0x000073, 369 },
+ { 0x000074, 371 },
+ { 0x000075, 373 },
+ { 0x000076, 375 },
+ { 0x000077, 377 },
+ { 0x000078, 379 },
+ { 0x000079, 381 },
+ { 0x00007a, 383 },
+ { 0x00007b, 385 },
+ { 0x00007c, 395 },
+ { 0x00007d, 399 },
+ { 0x00007e, 410 },
+ { 0x0000a0, 421 },
+ { 0x0000a1, 434 },
+ { 0x0000a2, 445 },
+ { 0x0000a3, 450 },
+ { 0x0000a4, 459 },
+ { 0x0000a5, 468 },
+ { 0x0000a6, 472 },
+ { 0x0000a7, 482 },
+ { 0x0000a8, 490 },
+ { 0x0000a9, 500 },
+ { 0x0000aa, 510 },
+ { 0x0000ab, 522 },
+ { 0x0000ac, 536 },
+ { 0x0000ad, 544 },
+ { 0x0000ae, 551 },
+ { 0x0000af, 562 },
+ { 0x0000b0, 569 },
+ { 0x0000b1, 576 },
+ { 0x0000b2, 586 },
+ { 0x0000b3, 598 },
+ { 0x0000b4, 612 },
+ { 0x0000b5, 618 },
+ { 0x0000b6, 621 },
+ { 0x0000b7, 631 },
+ { 0x0000b8, 646 },
+ { 0x0000b9, 654 },
+ { 0x0000ba, 666 },
+ { 0x0000bb, 676 },
+ { 0x0000bc, 691 },
+ { 0x0000bd, 702 },
+ { 0x0000be, 710 },
+ { 0x0000bf, 724 },
+ { 0x0000c0, 737 },
+ { 0x0000c1, 744 },
+ { 0x0000c2, 751 },
+ { 0x0000c3, 763 },
+ { 0x0000c4, 770 },
+ { 0x0000c5, 781 },
+ { 0x0000c6, 787 },
+ { 0x0000c7, 790 },
+ { 0x0000c8, 799 },
+ { 0x0000c9, 806 },
+ { 0x0000ca, 813 },
+ { 0x0000cb, 825 },
+ { 0x0000cc, 836 },
+ { 0x0000cd, 843 },
+ { 0x0000ce, 850 },
+ { 0x0000cf, 862 },
+ { 0x0000d0, 873 },
+ { 0x0000d0, 877 },
+ { 0x0000d1, 881 },
+ { 0x0000d2, 888 },
+ { 0x0000d3, 895 },
+ { 0x0000d4, 902 },
+ { 0x0000d5, 914 },
+ { 0x0000d6, 921 },
+ { 0x0000d7, 932 },
+ { 0x0000d8, 941 },
+ { 0x0000d9, 950 },
+ { 0x0000da, 957 },
+ { 0x0000db, 964 },
+ { 0x0000dc, 976 },
+ { 0x0000dd, 987 },
+ { 0x0000de, 994 },
+ { 0x0000de, 1000 },
+ { 0x0000df, 1006 },
+ { 0x0000e0, 1013 },
+ { 0x0000e1, 1020 },
+ { 0x0000e2, 1027 },
+ { 0x0000e3, 1039 },
+ { 0x0000e4, 1046 },
+ { 0x0000e5, 1057 },
+ { 0x0000e6, 1063 },
+ { 0x0000e7, 1066 },
+ { 0x0000e8, 1075 },
+ { 0x0000e9, 1082 },
+ { 0x0000ea, 1089 },
+ { 0x0000eb, 1101 },
+ { 0x0000ec, 1112 },
+ { 0x0000ed, 1119 },
+ { 0x0000ee, 1126 },
+ { 0x0000ef, 1138 },
+ { 0x0000f0, 1149 },
+ { 0x0000f1, 1153 },
+ { 0x0000f2, 1160 },
+ { 0x0000f3, 1167 },
+ { 0x0000f4, 1174 },
+ { 0x0000f5, 1186 },
+ { 0x0000f6, 1193 },
+ { 0x0000f7, 1204 },
+ { 0x0000f8, 1213 },
+ { 0x0000f9, 1220 },
+ { 0x0000fa, 1227 },
+ { 0x0000fb, 1234 },
+ { 0x0000fc, 1246 },
+ { 0x0000fd, 1257 },
+ { 0x0000fe, 1264 },
+ { 0x0000ff, 1270 },
+ { 0x0001a1, 1281 },
+ { 0x0001a2, 1289 },
+ { 0x0001a3, 1295 },
+ { 0x0001a5, 1303 },
+ { 0x0001a6, 1310 },
+ { 0x0001a9, 1317 },
+ { 0x0001aa, 1324 },
+ { 0x0001ab, 1333 },
+ { 0x0001ac, 1340 },
+ { 0x0001ae, 1347 },
+ { 0x0001af, 1354 },
+ { 0x0001b1, 1364 },
+ { 0x0001b2, 1372 },
+ { 0x0001b3, 1379 },
+ { 0x0001b5, 1387 },
+ { 0x0001b6, 1394 },
+ { 0x0001b7, 1401 },
+ { 0x0001b9, 1407 },
+ { 0x0001ba, 1414 },
+ { 0x0001bb, 1423 },
+ { 0x0001bc, 1430 },
+ { 0x0001bd, 1437 },
+ { 0x0001be, 1449 },
+ { 0x0001bf, 1456 },
+ { 0x0001c0, 1466 },
+ { 0x0001c3, 1473 },
+ { 0x0001c5, 1480 },
+ { 0x0001c6, 1487 },
+ { 0x0001c8, 1494 },
+ { 0x0001ca, 1501 },
+ { 0x0001cc, 1509 },
+ { 0x0001cf, 1516 },
+ { 0x0001d0, 1523 },
+ { 0x0001d1, 1531 },
+ { 0x0001d2, 1538 },
+ { 0x0001d5, 1545 },
+ { 0x0001d8, 1558 },
+ { 0x0001d9, 1565 },
+ { 0x0001db, 1571 },
+ { 0x0001de, 1584 },
+ { 0x0001e0, 1593 },
+ { 0x0001e3, 1600 },
+ { 0x0001e5, 1607 },
+ { 0x0001e6, 1614 },
+ { 0x0001e8, 1621 },
+ { 0x0001ea, 1628 },
+ { 0x0001ec, 1636 },
+ { 0x0001ef, 1643 },
+ { 0x0001f0, 1650 },
+ { 0x0001f1, 1658 },
+ { 0x0001f2, 1665 },
+ { 0x0001f5, 1672 },
+ { 0x0001f8, 1685 },
+ { 0x0001f9, 1692 },
+ { 0x0001fb, 1698 },
+ { 0x0001fe, 1711 },
+ { 0x0001ff, 1720 },
+ { 0x0002a1, 1729 },
+ { 0x0002a6, 1737 },
+ { 0x0002a9, 1749 },
+ { 0x0002ab, 1759 },
+ { 0x0002ac, 1766 },
+ { 0x0002b1, 1778 },
+ { 0x0002b6, 1786 },
+ { 0x0002b9, 1798 },
+ { 0x0002bb, 1807 },
+ { 0x0002bc, 1814 },
+ { 0x0002c5, 1826 },
+ { 0x0002c6, 1836 },
+ { 0x0002d5, 1848 },
+ { 0x0002d8, 1858 },
+ { 0x0002dd, 1870 },
+ { 0x0002de, 1877 },
+ { 0x0002e5, 1889 },
+ { 0x0002e6, 1899 },
+ { 0x0002f5, 1911 },
+ { 0x0002f8, 1921 },
+ { 0x0002fd, 1933 },
+ { 0x0002fe, 1940 },
+ { 0x0003a2, 1952 },
+ { 0x0003a2, 1958 },
+ { 0x0003a3, 1962 },
+ { 0x0003a5, 1971 },
+ { 0x0003a6, 1978 },
+ { 0x0003aa, 1987 },
+ { 0x0003ab, 1995 },
+ { 0x0003ac, 2004 },
+ { 0x0003b3, 2011 },
+ { 0x0003b5, 2020 },
+ { 0x0003b6, 2027 },
+ { 0x0003ba, 2036 },
+ { 0x0003bb, 2044 },
+ { 0x0003bc, 2053 },
+ { 0x0003bd, 2060 },
+ { 0x0003bf, 2064 },
+ { 0x0003c0, 2068 },
+ { 0x0003c7, 2076 },
+ { 0x0003cc, 2084 },
+ { 0x0003cf, 2094 },
+ { 0x0003d1, 2102 },
+ { 0x0003d2, 2111 },
+ { 0x0003d3, 2119 },
+ { 0x0003d9, 2128 },
+ { 0x0003dd, 2136 },
+ { 0x0003de, 2143 },
+ { 0x0003e0, 2151 },
+ { 0x0003e7, 2159 },
+ { 0x0003ec, 2167 },
+ { 0x0003ef, 2177 },
+ { 0x0003f1, 2185 },
+ { 0x0003f2, 2194 },
+ { 0x0003f3, 2202 },
+ { 0x0003f9, 2211 },
+ { 0x0003fd, 2219 },
+ { 0x0003fe, 2226 },
+ { 0x00047e, 2234 },
+ { 0x0004a1, 2243 },
+ { 0x0004a2, 2257 },
+ { 0x0004a3, 2277 },
+ { 0x0004a4, 2297 },
+ { 0x0004a5, 2308 },
+ { 0x0004a5, 2325 },
+ { 0x0004a6, 2340 },
+ { 0x0004a7, 2348 },
+ { 0x0004a8, 2355 },
+ { 0x0004a9, 2362 },
+ { 0x0004aa, 2369 },
+ { 0x0004ab, 2376 },
+ { 0x0004ac, 2383 },
+ { 0x0004ad, 2391 },
+ { 0x0004ae, 2399 },
+ { 0x0004af, 2407 },
+ { 0x0004af, 2416 },
+ { 0x0004b0, 2424 },
+ { 0x0004b1, 2439 },
+ { 0x0004b2, 2446 },
+ { 0x0004b3, 2453 },
+ { 0x0004b4, 2460 },
+ { 0x0004b5, 2467 },
+ { 0x0004b6, 2474 },
+ { 0x0004b7, 2482 },
+ { 0x0004b8, 2490 },
+ { 0x0004b9, 2498 },
+ { 0x0004ba, 2506 },
+ { 0x0004bb, 2514 },
+ { 0x0004bc, 2522 },
+ { 0x0004bd, 2531 },
+ { 0x0004be, 2539 },
+ { 0x0004bf, 2547 },
+ { 0x0004c0, 2555 },
+ { 0x0004c1, 2563 },
+ { 0x0004c1, 2572 },
+ { 0x0004c2, 2580 },
+ { 0x0004c2, 2589 },
+ { 0x0004c3, 2597 },
+ { 0x0004c4, 2605 },
+ { 0x0004c5, 2613 },
+ { 0x0004c6, 2621 },
+ { 0x0004c7, 2629 },
+ { 0x0004c8, 2637 },
+ { 0x0004c9, 2645 },
+ { 0x0004ca, 2653 },
+ { 0x0004cb, 2661 },
+ { 0x0004cc, 2669 },
+ { 0x0004cc, 2677 },
+ { 0x0004cd, 2685 },
+ { 0x0004ce, 2693 },
+ { 0x0004cf, 2701 },
+ { 0x0004d0, 2709 },
+ { 0x0004d1, 2717 },
+ { 0x0004d2, 2725 },
+ { 0x0004d3, 2733 },
+ { 0x0004d4, 2741 },
+ { 0x0004d5, 2749 },
+ { 0x0004d6, 2757 },
+ { 0x0004d7, 2765 },
+ { 0x0004d8, 2773 },
+ { 0x0004d9, 2781 },
+ { 0x0004da, 2789 },
+ { 0x0004db, 2797 },
+ { 0x0004dc, 2805 },
+ { 0x0004dd, 2813 },
+ { 0x0004de, 2820 },
+ { 0x0004df, 2832 },
+ { 0x0005ac, 2848 },
+ { 0x0005bb, 2861 },
+ { 0x0005bf, 2878 },
+ { 0x0005c1, 2899 },
+ { 0x0005c2, 2912 },
+ { 0x0005c3, 2931 },
+ { 0x0005c4, 2950 },
+ { 0x0005c5, 2968 },
+ { 0x0005c6, 2990 },
+ { 0x0005c7, 3008 },
+ { 0x0005c8, 3020 },
+ { 0x0005c9, 3031 },
+ { 0x0005ca, 3049 },
+ { 0x0005cb, 3060 },
+ { 0x0005cc, 3072 },
+ { 0x0005cd, 3084 },
+ { 0x0005ce, 3095 },
+ { 0x0005cf, 3107 },
+ { 0x0005d0, 3118 },
+ { 0x0005d1, 3130 },
+ { 0x0005d2, 3140 },
+ { 0x0005d3, 3152 },
+ { 0x0005d4, 3164 },
+ { 0x0005d5, 3177 },
+ { 0x0005d6, 3188 },
+ { 0x0005d7, 3199 },
+ { 0x0005d8, 3210 },
+ { 0x0005d9, 3221 },
+ { 0x0005da, 3232 },
+ { 0x0005e0, 3245 },
+ { 0x0005e1, 3260 },
+ { 0x0005e2, 3271 },
+ { 0x0005e3, 3282 },
+ { 0x0005e4, 3293 },
+ { 0x0005e5, 3304 },
+ { 0x0005e6, 3316 },
+ { 0x0005e7, 3328 },
+ { 0x0005e7, 3338 },
+ { 0x0005e8, 3349 },
+ { 0x0005e9, 3360 },
+ { 0x0005ea, 3379 },
+ { 0x0005eb, 3390 },
+ { 0x0005ec, 3406 },
+ { 0x0005ed, 3422 },
+ { 0x0005ee, 3438 },
+ { 0x0005ef, 3451 },
+ { 0x0005f0, 3464 },
+ { 0x0005f1, 3477 },
+ { 0x0005f2, 3491 },
+ { 0x0006a1, 3504 },
+ { 0x0006a2, 3516 },
+ { 0x0006a3, 3530 },
+ { 0x0006a4, 3542 },
+ { 0x0006a4, 3555 },
+ { 0x0006a5, 3567 },
+ { 0x0006a6, 3581 },
+ { 0x0006a6, 3593 },
+ { 0x0006a7, 3604 },
+ { 0x0006a7, 3617 },
+ { 0x0006a8, 3629 },
+ { 0x0006a8, 3641 },
+ { 0x0006a9, 3652 },
+ { 0x0006a9, 3665 },
+ { 0x0006aa, 3677 },
+ { 0x0006aa, 3690 },
+ { 0x0006ab, 3702 },
+ { 0x0006ac, 3715 },
+ { 0x0006ae, 3729 },
+ { 0x0006af, 3749 },
+ { 0x0006af, 3763 },
+ { 0x0006b0, 3775 },
+ { 0x0006b1, 3786 },
+ { 0x0006b2, 3798 },
+ { 0x0006b3, 3812 },
+ { 0x0006b4, 3824 },
+ { 0x0006b4, 3837 },
+ { 0x0006b5, 3849 },
+ { 0x0006b6, 3863 },
+ { 0x0006b6, 3875 },
+ { 0x0006b7, 3886 },
+ { 0x0006b7, 3899 },
+ { 0x0006b8, 3911 },
+ { 0x0006b8, 3923 },
+ { 0x0006b9, 3934 },
+ { 0x0006b9, 3947 },
+ { 0x0006ba, 3959 },
+ { 0x0006ba, 3972 },
+ { 0x0006bb, 3984 },
+ { 0x0006bc, 3997 },
+ { 0x0006be, 4011 },
+ { 0x0006bf, 4031 },
+ { 0x0006bf, 4045 },
+ { 0x0006c0, 4057 },
+ { 0x0006c1, 4069 },
+ { 0x0006c2, 4080 },
+ { 0x0006c3, 4092 },
+ { 0x0006c4, 4105 },
+ { 0x0006c5, 4117 },
+ { 0x0006c6, 4129 },
+ { 0x0006c7, 4141 },
+ { 0x0006c8, 4154 },
+ { 0x0006c9, 4166 },
+ { 0x0006ca, 4177 },
+ { 0x0006cb, 4193 },
+ { 0x0006cc, 4205 },
+ { 0x0006cd, 4217 },
+ { 0x0006ce, 4229 },
+ { 0x0006cf, 4241 },
+ { 0x0006d0, 4252 },
+ { 0x0006d1, 4264 },
+ { 0x0006d2, 4276 },
+ { 0x0006d3, 4288 },
+ { 0x0006d4, 4300 },
+ { 0x0006d5, 4312 },
+ { 0x0006d6, 4323 },
+ { 0x0006d7, 4336 },
+ { 0x0006d8, 4348 },
+ { 0x0006d9, 4366 },
+ { 0x0006da, 4380 },
+ { 0x0006db, 4392 },
+ { 0x0006dc, 4405 },
+ { 0x0006dd, 4416 },
+ { 0x0006de, 4431 },
+ { 0x0006df, 4444 },
+ { 0x0006e0, 4462 },
+ { 0x0006e1, 4474 },
+ { 0x0006e2, 4485 },
+ { 0x0006e3, 4497 },
+ { 0x0006e4, 4510 },
+ { 0x0006e5, 4522 },
+ { 0x0006e6, 4534 },
+ { 0x0006e7, 4546 },
+ { 0x0006e8, 4559 },
+ { 0x0006e9, 4571 },
+ { 0x0006ea, 4582 },
+ { 0x0006eb, 4598 },
+ { 0x0006ec, 4610 },
+ { 0x0006ed, 4622 },
+ { 0x0006ee, 4634 },
+ { 0x0006ef, 4646 },
+ { 0x0006f0, 4657 },
+ { 0x0006f1, 4669 },
+ { 0x0006f2, 4681 },
+ { 0x0006f3, 4693 },
+ { 0x0006f4, 4705 },
+ { 0x0006f5, 4717 },
+ { 0x0006f6, 4728 },
+ { 0x0006f7, 4741 },
+ { 0x0006f8, 4753 },
+ { 0x0006f9, 4771 },
+ { 0x0006fa, 4785 },
+ { 0x0006fb, 4797 },
+ { 0x0006fc, 4810 },
+ { 0x0006fd, 4821 },
+ { 0x0006fe, 4836 },
+ { 0x0006ff, 4849 },
+ { 0x0007a1, 4867 },
+ { 0x0007a2, 4885 },
+ { 0x0007a3, 4905 },
+ { 0x0007a4, 4921 },
+ { 0x0007a5, 4938 },
+ { 0x0007a5, 4957 },
+ { 0x0007a7, 4977 },
+ { 0x0007a8, 4997 },
+ { 0x0007a9, 5017 },
+ { 0x0007ab, 5039 },
+ { 0x0007ae, 5057 },
+ { 0x0007af, 5078 },
+ { 0x0007b1, 5093 },
+ { 0x0007b2, 5111 },
+ { 0x0007b3, 5131 },
+ { 0x0007b4, 5147 },
+ { 0x0007b5, 5164 },
+ { 0x0007b6, 5183 },
+ { 0x0007b7, 5208 },
+ { 0x0007b8, 5228 },
+ { 0x0007b9, 5248 },
+ { 0x0007ba, 5270 },
+ { 0x0007bb, 5298 },
+ { 0x0007c1, 5316 },
+ { 0x0007c2, 5328 },
+ { 0x0007c3, 5339 },
+ { 0x0007c4, 5351 },
+ { 0x0007c5, 5363 },
+ { 0x0007c6, 5377 },
+ { 0x0007c7, 5388 },
+ { 0x0007c8, 5398 },
+ { 0x0007c9, 5410 },
+ { 0x0007ca, 5421 },
+ { 0x0007cb, 5433 },
+ { 0x0007cb, 5446 },
+ { 0x0007cc, 5458 },
+ { 0x0007cd, 5467 },
+ { 0x0007ce, 5476 },
+ { 0x0007cf, 5485 },
+ { 0x0007d0, 5499 },
+ { 0x0007d1, 5508 },
+ { 0x0007d2, 5518 },
+ { 0x0007d4, 5530 },
+ { 0x0007d5, 5540 },
+ { 0x0007d6, 5554 },
+ { 0x0007d7, 5564 },
+ { 0x0007d8, 5574 },
+ { 0x0007d9, 5584 },
+ { 0x0007e1, 5596 },
+ { 0x0007e2, 5608 },
+ { 0x0007e3, 5619 },
+ { 0x0007e4, 5631 },
+ { 0x0007e5, 5643 },
+ { 0x0007e6, 5657 },
+ { 0x0007e7, 5668 },
+ { 0x0007e8, 5678 },
+ { 0x0007e9, 5690 },
+ { 0x0007ea, 5701 },
+ { 0x0007eb, 5713 },
+ { 0x0007eb, 5726 },
+ { 0x0007ec, 5738 },
+ { 0x0007ed, 5747 },
+ { 0x0007ee, 5756 },
+ { 0x0007ef, 5765 },
+ { 0x0007f0, 5779 },
+ { 0x0007f1, 5788 },
+ { 0x0007f2, 5798 },
+ { 0x0007f3, 5810 },
+ { 0x0007f4, 5832 },
+ { 0x0007f5, 5842 },
+ { 0x0007f6, 5856 },
+ { 0x0007f7, 5866 },
+ { 0x0007f8, 5876 },
+ { 0x0007f9, 5886 },
+ { 0x0008a1, 5898 },
+ { 0x0008a2, 5910 },
+ { 0x0008a3, 5925 },
+ { 0x0008a4, 5940 },
+ { 0x0008a5, 5952 },
+ { 0x0008a6, 5964 },
+ { 0x0008a7, 5978 },
+ { 0x0008a8, 5995 },
+ { 0x0008a9, 6012 },
+ { 0x0008aa, 6030 },
+ { 0x0008ab, 6048 },
+ { 0x0008ac, 6062 },
+ { 0x0008ad, 6076 },
+ { 0x0008ae, 6091 },
+ { 0x0008af, 6106 },
+ { 0x0008b0, 6127 },
+ { 0x0008b1, 6149 },
+ { 0x0008b2, 6166 },
+ { 0x0008b3, 6183 },
+ { 0x0008b4, 6209 },
+ { 0x0008b5, 6235 },
+ { 0x0008b6, 6253 },
+ { 0x0008b7, 6271 },
+ { 0x0008bc, 6292 },
+ { 0x0008bd, 6306 },
+ { 0x0008be, 6315 },
+ { 0x0008bf, 6332 },
+ { 0x0008c0, 6341 },
+ { 0x0008c1, 6351 },
+ { 0x0008c2, 6361 },
+ { 0x0008c5, 6370 },
+ { 0x0008c8, 6376 },
+ { 0x0008c9, 6388 },
+ { 0x0008cd, 6401 },
+ { 0x0008ce, 6410 },
+ { 0x0008cf, 6418 },
+ { 0x0008d6, 6428 },
+ { 0x0008da, 6436 },
+ { 0x0008db, 6447 },
+ { 0x0008dc, 6456 },
+ { 0x0008dd, 6469 },
+ { 0x0008de, 6475 },
+ { 0x0008df, 6486 },
+ { 0x0008ef, 6496 },
+ { 0x0008f6, 6514 },
+ { 0x0008fb, 6523 },
+ { 0x0008fc, 6533 },
+ { 0x0008fd, 6541 },
+ { 0x0008fe, 6552 },
+ { 0x0009df, 6562 },
+ { 0x0009e0, 6568 },
+ { 0x0009e1, 6581 },
+ { 0x0009e2, 6594 },
+ { 0x0009e3, 6597 },
+ { 0x0009e4, 6600 },
+ { 0x0009e5, 6603 },
+ { 0x0009e8, 6606 },
+ { 0x0009e9, 6609 },
+ { 0x0009ea, 6612 },
+ { 0x0009eb, 6627 },
+ { 0x0009ec, 6641 },
+ { 0x0009ed, 6654 },
+ { 0x0009ee, 6668 },
+ { 0x0009ef, 6682 },
+ { 0x0009f0, 6697 },
+ { 0x0009f1, 6712 },
+ { 0x0009f2, 6727 },
+ { 0x0009f3, 6742 },
+ { 0x0009f4, 6757 },
+ { 0x0009f5, 6763 },
+ { 0x0009f6, 6770 },
+ { 0x0009f7, 6775 },
+ { 0x0009f8, 6780 },
+ { 0x000aa1, 6788 },
+ { 0x000aa2, 6796 },
+ { 0x000aa3, 6804 },
+ { 0x000aa4, 6813 },
+ { 0x000aa5, 6822 },
+ { 0x000aa6, 6833 },
+ { 0x000aa7, 6844 },
+ { 0x000aa8, 6854 },
+ { 0x000aa9, 6864 },
+ { 0x000aaa, 6871 },
+ { 0x000aac, 6878 },
+ { 0x000aae, 6890 },
+ { 0x000aaf, 6899 },
+ { 0x000ab0, 6915 },
+ { 0x000ab1, 6924 },
+ { 0x000ab2, 6934 },
+ { 0x000ab3, 6943 },
+ { 0x000ab4, 6953 },
+ { 0x000ab5, 6965 },
+ { 0x000ab6, 6976 },
+ { 0x000ab7, 6985 },
+ { 0x000ab8, 6996 },
+ { 0x000abb, 7003 },
+ { 0x000abc, 7011 },
+ { 0x000abd, 7028 },
+ { 0x000abe, 7041 },
+ { 0x000abf, 7059 },
+ { 0x000ac3, 7066 },
+ { 0x000ac4, 7076 },
+ { 0x000ac5, 7089 },
+ { 0x000ac6, 7101 },
+ { 0x000ac9, 7114 },
+ { 0x000aca, 7124 },
+ { 0x000acb, 7138 },
+ { 0x000acc, 7156 },
+ { 0x000acd, 7173 },
+ { 0x000ace, 7191 },
+ { 0x000acf, 7204 },
+ { 0x000ad0, 7220 },
+ { 0x000ad1, 7240 },
+ { 0x000ad2, 7261 },
+ { 0x000ad3, 7281 },
+ { 0x000ad4, 7302 },
+ { 0x000ad6, 7315 },
+ { 0x000ad7, 7323 },
+ { 0x000ad9, 7331 },
+ { 0x000ada, 7342 },
+ { 0x000adb, 7351 },
+ { 0x000adc, 7368 },
+ { 0x000add, 7388 },
+ { 0x000ade, 7409 },
+ { 0x000adf, 7424 },
+ { 0x000ae0, 7437 },
+ { 0x000ae1, 7454 },
+ { 0x000ae2, 7473 },
+ { 0x000ae3, 7488 },
+ { 0x000ae4, 7504 },
+ { 0x000ae5, 7522 },
+ { 0x000ae6, 7531 },
+ { 0x000ae7, 7550 },
+ { 0x000ae8, 7567 },
+ { 0x000ae9, 7585 },
+ { 0x000aea, 7605 },
+ { 0x000aeb, 7617 },
+ { 0x000aec, 7630 },
+ { 0x000aed, 7635 },
+ { 0x000aee, 7643 },
+ { 0x000af0, 7649 },
+ { 0x000af1, 7662 },
+ { 0x000af2, 7669 },
+ { 0x000af3, 7682 },
+ { 0x000af4, 7692 },
+ { 0x000af5, 7704 },
+ { 0x000af6, 7717 },
+ { 0x000af7, 7729 },
+ { 0x000af8, 7740 },
+ { 0x000af9, 7753 },
+ { 0x000afa, 7763 },
+ { 0x000afb, 7781 },
+ { 0x000afc, 7801 },
+ { 0x000afd, 7807 },
+ { 0x000afe, 7826 },
+ { 0x000aff, 7845 },
+ { 0x000ba3, 7852 },
+ { 0x000ba6, 7862 },
+ { 0x000ba8, 7873 },
+ { 0x000ba9, 7883 },
+ { 0x000bc0, 7891 },
+ { 0x000bc2, 7899 },
+ { 0x000bc3, 7908 },
+ { 0x000bc4, 7915 },
+ { 0x000bc6, 7925 },
+ { 0x000bca, 7934 },
+ { 0x000bcc, 7938 },
+ { 0x000bce, 7943 },
+ { 0x000bcf, 7950 },
+ { 0x000bd3, 7957 },
+ { 0x000bd6, 7965 },
+ { 0x000bd8, 7974 },
+ { 0x000bda, 7984 },
+ { 0x000bdc, 7993 },
+ { 0x000bfc, 8002 },
+ { 0x000cdf, 8012 },
+ { 0x000ce0, 8033 },
+ { 0x000ce1, 8046 },
+ { 0x000ce1, 8057 },
+ { 0x000ce2, 8069 },
+ { 0x000ce2, 8082 },
+ { 0x000ce3, 8096 },
+ { 0x000ce3, 8109 },
+ { 0x000ce4, 8123 },
+ { 0x000ce5, 8133 },
+ { 0x000ce6, 8144 },
+ { 0x000ce6, 8156 },
+ { 0x000ce7, 8169 },
+ { 0x000ce7, 8181 },
+ { 0x000ce8, 8192 },
+ { 0x000ce8, 8203 },
+ { 0x000ce9, 8215 },
+ { 0x000cea, 8226 },
+ { 0x000ceb, 8243 },
+ { 0x000cec, 8255 },
+ { 0x000ced, 8268 },
+ { 0x000cee, 8284 },
+ { 0x000cef, 8295 },
+ { 0x000cf0, 8311 },
+ { 0x000cf1, 8322 },
+ { 0x000cf1, 8336 },
+ { 0x000cf2, 8350 },
+ { 0x000cf3, 8362 },
+ { 0x000cf4, 8377 },
+ { 0x000cf5, 8387 },
+ { 0x000cf5, 8404 },
+ { 0x000cf6, 8421 },
+ { 0x000cf6, 8433 },
+ { 0x000cf7, 8445 },
+ { 0x000cf7, 8456 },
+ { 0x000cf8, 8468 },
+ { 0x000cf9, 8480 },
+ { 0x000cfa, 8492 },
+ { 0x000cfa, 8503 },
+ { 0x000da1, 8514 },
+ { 0x000da2, 8525 },
+ { 0x000da3, 8538 },
+ { 0x000da4, 8552 },
+ { 0x000da5, 8566 },
+ { 0x000da6, 8579 },
+ { 0x000da7, 8595 },
+ { 0x000da8, 8607 },
+ { 0x000da9, 8620 },
+ { 0x000daa, 8634 },
+ { 0x000dab, 8648 },
+ { 0x000dac, 8658 },
+ { 0x000dad, 8671 },
+ { 0x000dae, 8683 },
+ { 0x000daf, 8696 },
+ { 0x000db0, 8709 },
+ { 0x000db1, 8722 },
+ { 0x000db2, 8741 },
+ { 0x000db3, 8757 },
+ { 0x000db4, 8768 },
+ { 0x000db5, 8779 },
+ { 0x000db6, 8790 },
+ { 0x000db7, 8804 },
+ { 0x000db8, 8819 },
+ { 0x000db9, 8833 },
+ { 0x000dba, 8843 },
+ { 0x000dbb, 8857 },
+ { 0x000dbc, 8868 },
+ { 0x000dbd, 8882 },
+ { 0x000dbe, 8892 },
+ { 0x000dbf, 8905 },
+ { 0x000dc0, 8916 },
+ { 0x000dc1, 8932 },
+ { 0x000dc2, 8942 },
+ { 0x000dc3, 8953 },
+ { 0x000dc4, 8964 },
+ { 0x000dc5, 8972 },
+ { 0x000dc6, 8984 },
+ { 0x000dc7, 8992 },
+ { 0x000dc8, 9004 },
+ { 0x000dc9, 9016 },
+ { 0x000dca, 9028 },
+ { 0x000dcb, 9039 },
+ { 0x000dcc, 9050 },
+ { 0x000dcd, 9063 },
+ { 0x000dce, 9073 },
+ { 0x000dcf, 9087 },
+ { 0x000dd0, 9102 },
+ { 0x000dd1, 9113 },
+ { 0x000dd2, 9129 },
+ { 0x000dd3, 9141 },
+ { 0x000dd4, 9153 },
+ { 0x000dd5, 9164 },
+ { 0x000dd6, 9176 },
+ { 0x000dd7, 9188 },
+ { 0x000dd8, 9201 },
+ { 0x000dd9, 9212 },
+ { 0x000dda, 9224 },
+ { 0x000dde, 9237 },
+ { 0x000ddf, 9260 },
+ { 0x000de0, 9270 },
+ { 0x000de1, 9281 },
+ { 0x000de2, 9293 },
+ { 0x000de3, 9304 },
+ { 0x000de4, 9323 },
+ { 0x000de5, 9343 },
+ { 0x000de6, 9360 },
+ { 0x000de7, 9374 },
+ { 0x000de8, 9389 },
+ { 0x000de9, 9400 },
+ { 0x000dea, 9412 },
+ { 0x000deb, 9424 },
+ { 0x000dec, 9441 },
+ { 0x000ded, 9458 },
+ { 0x000df0, 9472 },
+ { 0x000df1, 9484 },
+ { 0x000df2, 9497 },
+ { 0x000df3, 9510 },
+ { 0x000df4, 9522 },
+ { 0x000df5, 9533 },
+ { 0x000df6, 9544 },
+ { 0x000df7, 9556 },
+ { 0x000df8, 9569 },
+ { 0x000df9, 9582 },
+ { 0x000ea1, 9594 },
+ { 0x000ea2, 9608 },
+ { 0x000ea3, 9627 },
+ { 0x000ea4, 9645 },
+ { 0x000ea5, 9658 },
+ { 0x000ea6, 9676 },
+ { 0x000ea7, 9694 },
+ { 0x000ea8, 9708 },
+ { 0x000ea9, 9727 },
+ { 0x000eaa, 9740 },
+ { 0x000eab, 9759 },
+ { 0x000eac, 9777 },
+ { 0x000ead, 9795 },
+ { 0x000eae, 9812 },
+ { 0x000eaf, 9830 },
+ { 0x000eb0, 9849 },
+ { 0x000eb1, 9867 },
+ { 0x000eb2, 9880 },
+ { 0x000eb3, 9893 },
+ { 0x000eb4, 9911 },
+ { 0x000eb5, 9928 },
+ { 0x000eb6, 9940 },
+ { 0x000eb7, 9957 },
+ { 0x000eb8, 9970 },
+ { 0x000eb9, 9983 },
+ { 0x000eba, 10001 },
+ { 0x000ebb, 10014 },
+ { 0x000ebc, 10028 },
+ { 0x000ebd, 10041 },
+ { 0x000ebe, 10055 },
+ { 0x000ebf, 10068 },
+ { 0x000ec0, 10077 },
+ { 0x000ec1, 10087 },
+ { 0x000ec2, 10097 },
+ { 0x000ec3, 10108 },
+ { 0x000ec4, 10118 },
+ { 0x000ec5, 10127 },
+ { 0x000ec6, 10138 },
+ { 0x000ec7, 10148 },
+ { 0x000ec8, 10157 },
+ { 0x000ec9, 10167 },
+ { 0x000eca, 10178 },
+ { 0x000ecb, 10188 },
+ { 0x000ecc, 10198 },
+ { 0x000ecd, 10207 },
+ { 0x000ece, 10218 },
+ { 0x000ecf, 10228 },
+ { 0x000ed0, 10238 },
+ { 0x000ed1, 10248 },
+ { 0x000ed2, 10258 },
+ { 0x000ed3, 10268 },
+ { 0x000ed4, 10277 },
+ { 0x000ed5, 10293 },
+ { 0x000ed6, 10314 },
+ { 0x000ed7, 10334 },
+ { 0x000ed8, 10349 },
+ { 0x000ed9, 10369 },
+ { 0x000eda, 10389 },
+ { 0x000edb, 10405 },
+ { 0x000edc, 10420 },
+ { 0x000edd, 10441 },
+ { 0x000ede, 10461 },
+ { 0x000edf, 10481 },
+ { 0x000ee0, 10500 },
+ { 0x000ee1, 10520 },
+ { 0x000ee2, 10541 },
+ { 0x000ee3, 10561 },
+ { 0x000ee4, 10576 },
+ { 0x000ee5, 10591 },
+ { 0x000ee6, 10610 },
+ { 0x000ee7, 10624 },
+ { 0x000ee8, 10643 },
+ { 0x000ee9, 10658 },
+ { 0x000eea, 10673 },
+ { 0x000eeb, 10688 },
+ { 0x000eec, 10704 },
+ { 0x000eed, 10719 },
+ { 0x000eee, 10735 },
+ { 0x000eef, 10750 },
+ { 0x000ef0, 10774 },
+ { 0x000ef1, 10799 },
+ { 0x000ef2, 10824 },
+ { 0x000ef3, 10839 },
+ { 0x000ef4, 10864 },
+ { 0x000ef5, 10890 },
+ { 0x000ef6, 10909 },
+ { 0x000ef7, 10922 },
+ { 0x000ef8, 10936 },
+ { 0x000ef9, 10953 },
+ { 0x000efa, 10980 },
+ { 0x000eff, 11001 },
+ { 0x0013bc, 11012 },
+ { 0x0013bd, 11015 },
+ { 0x0013be, 11018 },
+ { 0x0020a0, 11029 },
+ { 0x0020a1, 11037 },
+ { 0x0020a2, 11047 },
+ { 0x0020a3, 11060 },
+ { 0x0020a4, 11071 },
+ { 0x0020a5, 11080 },
+ { 0x0020a6, 11089 },
+ { 0x0020a7, 11099 },
+ { 0x0020a8, 11110 },
+ { 0x0020a9, 11120 },
+ { 0x0020aa, 11128 },
+ { 0x0020ab, 11142 },
+ { 0x0020ac, 11151 },
+ { 0x00fd01, 11160 },
+ { 0x00fd02, 11175 },
+ { 0x00fd03, 11190 },
+ { 0x00fd04, 11202 },
+ { 0x00fd05, 11213 },
+ { 0x00fd06, 11226 },
+ { 0x00fd07, 11240 },
+ { 0x00fd08, 11256 },
+ { 0x00fd09, 11267 },
+ { 0x00fd0a, 11277 },
+ { 0x00fd0b, 11286 },
+ { 0x00fd0c, 11295 },
+ { 0x00fd0d, 11304 },
+ { 0x00fd0e, 11314 },
+ { 0x00fd0f, 11324 },
+ { 0x00fd10, 11341 },
+ { 0x00fd11, 11356 },
+ { 0x00fd12, 11370 },
+ { 0x00fd13, 11380 },
+ { 0x00fd14, 11391 },
+ { 0x00fd15, 11401 },
+ { 0x00fd16, 11411 },
+ { 0x00fd17, 11421 },
+ { 0x00fd18, 11432 },
+ { 0x00fd19, 11444 },
+ { 0x00fd1a, 11462 },
+ { 0x00fd1b, 11478 },
+ { 0x00fd1c, 11492 },
+ { 0x00fd1d, 11510 },
+ { 0x00fd1e, 11527 },
+ { 0x00fe01, 11538 },
+ { 0x00fe02, 11547 },
+ { 0x00fe03, 11564 },
+ { 0x00fe04, 11581 },
+ { 0x00fe05, 11598 },
+ { 0x00fe06, 11614 },
+ { 0x00fe07, 11630 },
+ { 0x00fe08, 11645 },
+ { 0x00fe09, 11660 },
+ { 0x00fe0a, 11680 },
+ { 0x00fe0b, 11695 },
+ { 0x00fe0c, 11715 },
+ { 0x00fe0d, 11731 },
+ { 0x00fe0e, 11752 },
+ { 0x00fe0f, 11767 },
+ { 0x00fe20, 11787 },
+ { 0x00fe21, 11800 },
+ { 0x00fe22, 11817 },
+ { 0x00fe23, 11836 },
+ { 0x00fe24, 11856 },
+ { 0x00fe25, 11878 },
+ { 0x00fe26, 11901 },
+ { 0x00fe27, 11925 },
+ { 0x00fe28, 11945 },
+ { 0x00fe29, 11966 },
+ { 0x00fe2a, 11990 },
+ { 0x00fe2b, 12015 },
+ { 0x00fe2c, 12040 },
+ { 0x00fe2d, 12061 },
+ { 0x00fe2e, 12083 },
+ { 0x00fe2f, 12102 },
+ { 0x00fe30, 12123 },
+ { 0x00fe31, 12148 },
+ { 0x00fe32, 12176 },
+ { 0x00fe33, 12190 },
+ { 0x00fe34, 12208 },
+ { 0x00fe50, 12218 },
+ { 0x00fe51, 12229 },
+ { 0x00fe52, 12240 },
+ { 0x00fe53, 12256 },
+ { 0x00fe54, 12267 },
+ { 0x00fe55, 12279 },
+ { 0x00fe56, 12290 },
+ { 0x00fe57, 12304 },
+ { 0x00fe58, 12319 },
+ { 0x00fe59, 12334 },
+ { 0x00fe5a, 12351 },
+ { 0x00fe5b, 12362 },
+ { 0x00fe5c, 12375 },
+ { 0x00fe5d, 12387 },
+ { 0x00fe5e, 12397 },
+ { 0x00fe5f, 12415 },
+ { 0x00fe60, 12437 },
+ { 0x00fe61, 12451 },
+ { 0x00fe62, 12461 },
+ { 0x00fe70, 12471 },
+ { 0x00fe71, 12486 },
+ { 0x00fe72, 12510 },
+ { 0x00fe73, 12528 },
+ { 0x00fe74, 12544 },
+ { 0x00fe75, 12562 },
+ { 0x00fe76, 12580 },
+ { 0x00fe77, 12597 },
+ { 0x00fe78, 12620 },
+ { 0x00fe79, 12636 },
+ { 0x00fe7a, 12652 },
+ { 0x00fed0, 12671 },
+ { 0x00fed1, 12692 },
+ { 0x00fed2, 12712 },
+ { 0x00fed4, 12732 },
+ { 0x00fed5, 12752 },
+ { 0x00fee0, 12769 },
+ { 0x00fee1, 12782 },
+ { 0x00fee2, 12796 },
+ { 0x00fee3, 12807 },
+ { 0x00fee4, 12820 },
+ { 0x00fee5, 12835 },
+ { 0x00fee6, 12851 },
+ { 0x00fee7, 12868 },
+ { 0x00fee8, 12886 },
+ { 0x00fee9, 12906 },
+ { 0x00feea, 12922 },
+ { 0x00feeb, 12938 },
+ { 0x00feec, 12954 },
+ { 0x00feed, 12970 },
+ { 0x00feee, 12986 },
+ { 0x00feef, 13008 },
+ { 0x00fef0, 13026 },
+ { 0x00fef1, 13044 },
+ { 0x00fef2, 13062 },
+ { 0x00fef3, 13080 },
+ { 0x00fef4, 13098 },
+ { 0x00fef5, 13116 },
+ { 0x00fef6, 13130 },
+ { 0x00fef7, 13144 },
+ { 0x00fef8, 13158 },
+ { 0x00fef9, 13172 },
+ { 0x00fefa, 13191 },
+ { 0x00fefb, 13210 },
+ { 0x00fefc, 13230 },
+ { 0x00fefd, 13250 },
+ { 0x00ff08, 13264 },
+ { 0x00ff09, 13274 },
+ { 0x00ff0a, 13278 },
+ { 0x00ff0b, 13287 },
+ { 0x00ff0d, 13293 },
+ { 0x00ff13, 13300 },
+ { 0x00ff14, 13306 },
+ { 0x00ff15, 13318 },
+ { 0x00ff1b, 13326 },
+ { 0x00ff20, 13333 },
+ { 0x00ff21, 13343 },
+ { 0x00ff22, 13349 },
+ { 0x00ff23, 13358 },
+ { 0x00ff23, 13365 },
+ { 0x00ff24, 13377 },
+ { 0x00ff25, 13384 },
+ { 0x00ff26, 13393 },
+ { 0x00ff27, 13402 },
+ { 0x00ff28, 13420 },
+ { 0x00ff29, 13428 },
+ { 0x00ff2a, 13436 },
+ { 0x00ff2b, 13452 },
+ { 0x00ff2c, 13460 },
+ { 0x00ff2d, 13467 },
+ { 0x00ff2e, 13477 },
+ { 0x00ff2f, 13488 },
+ { 0x00ff30, 13499 },
+ { 0x00ff31, 13511 },
+ { 0x00ff32, 13518 },
+ { 0x00ff33, 13531 },
+ { 0x00ff34, 13542 },
+ { 0x00ff35, 13555 },
+ { 0x00ff36, 13567 },
+ { 0x00ff37, 13581 },
+ { 0x00ff38, 13591 },
+ { 0x00ff39, 13605 },
+ { 0x00ff3a, 13618 },
+ { 0x00ff3b, 13634 },
+ { 0x00ff3c, 13651 },
+ { 0x00ff3d, 13667 },
+ { 0x00ff3e, 13685 },
+ { 0x00ff3f, 13703 },
+ { 0x00ff50, 13718 },
+ { 0x00ff51, 13723 },
+ { 0x00ff52, 13728 },
+ { 0x00ff53, 13731 },
+ { 0x00ff54, 13737 },
+ { 0x00ff55, 13742 },
+ { 0x00ff55, 13750 },
+ { 0x00ff56, 13756 },
+ { 0x00ff56, 13766 },
+ { 0x00ff57, 13771 },
+ { 0x00ff58, 13775 },
+ { 0x00ff60, 13781 },
+ { 0x00ff61, 13788 },
+ { 0x00ff62, 13794 },
+ { 0x00ff63, 13802 },
+ { 0x00ff65, 13809 },
+ { 0x00ff66, 13814 },
+ { 0x00ff67, 13819 },
+ { 0x00ff68, 13824 },
+ { 0x00ff69, 13829 },
+ { 0x00ff6a, 13836 },
+ { 0x00ff6b, 13841 },
+ { 0x00ff7e, 13847 },
+ { 0x00ff7e, 13861 },
+ { 0x00ff7e, 13874 },
+ { 0x00ff7e, 13888 },
+ { 0x00ff7e, 13902 },
+ { 0x00ff7e, 13918 },
+ { 0x00ff7e, 13930 },
+ { 0x00ff7e, 13942 },
+ { 0x00ff7f, 13956 },
+ { 0x00ff80, 13965 },
+ { 0x00ff89, 13974 },
+ { 0x00ff8d, 13981 },
+ { 0x00ff91, 13990 },
+ { 0x00ff92, 13996 },
+ { 0x00ff93, 14002 },
+ { 0x00ff94, 14008 },
+ { 0x00ff95, 14014 },
+ { 0x00ff96, 14022 },
+ { 0x00ff97, 14030 },
+ { 0x00ff98, 14036 },
+ { 0x00ff99, 14045 },
+ { 0x00ff9a, 14053 },
+ { 0x00ff9a, 14064 },
+ { 0x00ff9b, 14073 },
+ { 0x00ff9b, 14086 },
+ { 0x00ff9c, 14094 },
+ { 0x00ff9d, 14101 },
+ { 0x00ff9e, 14110 },
+ { 0x00ff9f, 14120 },
+ { 0x00ffaa, 14130 },
+ { 0x00ffab, 14142 },
+ { 0x00ffac, 14149 },
+ { 0x00ffad, 14162 },
+ { 0x00ffae, 14174 },
+ { 0x00ffaf, 14185 },
+ { 0x00ffb0, 14195 },
+ { 0x00ffb1, 14200 },
+ { 0x00ffb2, 14205 },
+ { 0x00ffb3, 14210 },
+ { 0x00ffb4, 14215 },
+ { 0x00ffb5, 14220 },
+ { 0x00ffb6, 14225 },
+ { 0x00ffb7, 14230 },
+ { 0x00ffb8, 14235 },
+ { 0x00ffb9, 14240 },
+ { 0x00ffbd, 14245 },
+ { 0x00ffbe, 14254 },
+ { 0x00ffbf, 14257 },
+ { 0x00ffc0, 14260 },
+ { 0x00ffc1, 14263 },
+ { 0x00ffc2, 14266 },
+ { 0x00ffc3, 14269 },
+ { 0x00ffc4, 14272 },
+ { 0x00ffc5, 14275 },
+ { 0x00ffc6, 14278 },
+ { 0x00ffc7, 14281 },
+ { 0x00ffc8, 14285 },
+ { 0x00ffc9, 14289 },
+ { 0x00ffca, 14293 },
+ { 0x00ffcb, 14297 },
+ { 0x00ffcc, 14301 },
+ { 0x00ffcd, 14305 },
+ { 0x00ffce, 14309 },
+ { 0x00ffcf, 14313 },
+ { 0x00ffd0, 14317 },
+ { 0x00ffd1, 14321 },
+ { 0x00ffd2, 14325 },
+ { 0x00ffd3, 14329 },
+ { 0x00ffd4, 14333 },
+ { 0x00ffd5, 14337 },
+ { 0x00ffd6, 14341 },
+ { 0x00ffd7, 14345 },
+ { 0x00ffd8, 14349 },
+ { 0x00ffd9, 14353 },
+ { 0x00ffda, 14357 },
+ { 0x00ffdb, 14361 },
+ { 0x00ffdc, 14365 },
+ { 0x00ffdd, 14369 },
+ { 0x00ffde, 14373 },
+ { 0x00ffdf, 14377 },
+ { 0x00ffe0, 14381 },
+ { 0x00ffe1, 14385 },
+ { 0x00ffe2, 14393 },
+ { 0x00ffe3, 14401 },
+ { 0x00ffe4, 14411 },
+ { 0x00ffe5, 14421 },
+ { 0x00ffe6, 14431 },
+ { 0x00ffe7, 14442 },
+ { 0x00ffe8, 14449 },
+ { 0x00ffe9, 14456 },
+ { 0x00ffea, 14462 },
+ { 0x00ffeb, 14468 },
+ { 0x00ffec, 14476 },
+ { 0x00ffed, 14484 },
+ { 0x00ffee, 14492 },
+ { 0x00ffff, 14500 },
+ { 0xffffff, 14507 }
+};
+
+static const gdk_key gdk_keys_by_name[] = {
+ { 0x000030, 140 },
+ { 0x000031, 142 },
+ { 0x000032, 144 },
+ { 0x000033, 146 },
+ { 0x00fd10, 11341 },
+ { 0x00fd0e, 11314 },
+ { 0x00fd05, 11213 },
+ { 0x00fd19, 11444 },
+ { 0x00fd15, 11401 },
+ { 0x00fd0f, 11324 },
+ { 0x00fd1c, 11492 },
+ { 0x00fd1a, 11462 },
+ { 0x00fd01, 11160 },
+ { 0x00fd1e, 11527 },
+ { 0x00fd06, 11226 },
+ { 0x00fd07, 11240 },
+ { 0x00fd1b, 11478 },
+ { 0x00fd02, 11175 },
+ { 0x00fd13, 11380 },
+ { 0x00fd12, 11370 },
+ { 0x00fd11, 11356 },
+ { 0x00fd04, 11202 },
+ { 0x00fd0a, 11277 },
+ { 0x00fd0b, 11286 },
+ { 0x00fd0c, 11295 },
+ { 0x00fd16, 11411 },
+ { 0x00fd1d, 11510 },
+ { 0x00fd09, 11267 },
+ { 0x00fd18, 11432 },
+ { 0x00fd08, 11256 },
+ { 0x00fd03, 11190 },
+ { 0x00fd14, 11391 },
+ { 0x00fd17, 11421 },
+ { 0x00fd0d, 11304 },
+ { 0x000034, 148 },
+ { 0x000035, 150 },
+ { 0x000036, 152 },
+ { 0x000037, 154 },
+ { 0x000038, 156 },
+ { 0x000039, 158 },
+ { 0x000041, 207 },
+ { 0x0000c6, 787 },
+ { 0x0000c1, 744 },
+ { 0x0001c3, 1473 },
+ { 0x00fe70, 12471 },
+ { 0x00fe71, 12486 },
+ { 0x0000c2, 751 },
+ { 0x0000c4, 770 },
+ { 0x0000c0, 737 },
+ { 0x00ffe9, 14456 },
+ { 0x00ffea, 14462 },
+ { 0x0003c0, 2068 },
+ { 0x0001a1, 1281 },
+ { 0x0005d9, 3221 },
+ { 0x0005c7, 3008 },
+ { 0x0005e9, 3360 },
+ { 0x0005c8, 3020 },
+ { 0x0005ac, 2848 },
+ { 0x0005d6, 3188 },
+ { 0x0005cf, 3107 },
+ { 0x0005ef, 3451 },
+ { 0x0005ec, 3406 },
+ { 0x0005ee, 3438 },
+ { 0x0005eb, 3390 },
+ { 0x0005e1, 3260 },
+ { 0x0005da, 3232 },
+ { 0x0005e7, 3328 },
+ { 0x0005cd, 3084 },
+ { 0x0005c1, 2899 },
+ { 0x0005c3, 2931 },
+ { 0x0005c4, 2950 },
+ { 0x0005c6, 2990 },
+ { 0x0005c5, 2968 },
+ { 0x0005e7, 3338 },
+ { 0x0005cc, 3072 },
+ { 0x0005e3, 3282 },
+ { 0x0005f0, 3464 },
+ { 0x0005ed, 3422 },
+ { 0x0005ce, 3095 },
+ { 0x0005e4, 3293 },
+ { 0x0005c2, 2912 },
+ { 0x0005e5, 3304 },
+ { 0x0005e6, 3316 },
+ { 0x0005e2, 3271 },
+ { 0x0005bf, 2878 },
+ { 0x0005d1, 3130 },
+ { 0x0005d5, 3177 },
+ { 0x0005d3, 3152 },
+ { 0x0005bb, 2861 },
+ { 0x0005f1, 3477 },
+ { 0x0005d4, 3164 },
+ { 0x0005f2, 3491 },
+ { 0x00ff7e, 13847 },
+ { 0x0005d7, 3199 },
+ { 0x0005e0, 3245 },
+ { 0x0005ca, 3049 },
+ { 0x0005c9, 3031 },
+ { 0x0005d0, 3118 },
+ { 0x0005cb, 3060 },
+ { 0x0005e8, 3349 },
+ { 0x0005ea, 3379 },
+ { 0x0005d8, 3210 },
+ { 0x0005d2, 3140 },
+ { 0x0000c5, 781 },
+ { 0x0000c3, 763 },
+ { 0x00fe7a, 12652 },
+ { 0x000042, 209 },
+ { 0x00ff08, 13264 },
+ { 0x00ff58, 13775 },
+ { 0x00fe74, 12544 },
+ { 0x00ff6b, 13841 },
+ { 0x0006be, 4011 },
+ { 0x0006ae, 3729 },
+ { 0x000043, 211 },
+ { 0x0002c5, 1826 },
+ { 0x0001c6, 1487 },
+ { 0x00ff69, 13829 },
+ { 0x00ffe5, 14421 },
+ { 0x0001c8, 1494 },
+ { 0x0000c7, 790 },
+ { 0x0002c6, 1836 },
+ { 0x00ff0b, 13287 },
+ { 0x00ff37, 13581 },
+ { 0x0020a1, 11037 },
+ { 0x00ffe3, 14401 },
+ { 0x00ffe4, 14411 },
+ { 0x0020a2, 11047 },
+ { 0x0006e1, 4474 },
+ { 0x0006e2, 4485 },
+ { 0x0006fe, 4836 },
+ { 0x0006e4, 4510 },
+ { 0x0006bf, 4031 },
+ { 0x0006fc, 4810 },
+ { 0x0006e6, 4534 },
+ { 0x0006ec, 4610 },
+ { 0x0006ed, 4622 },
+ { 0x0006ee, 4634 },
+ { 0x0006f2, 4681 },
+ { 0x0006f3, 4693 },
+ { 0x0006e7, 4546 },
+ { 0x0006e8, 4559 },
+ { 0x0006ff, 4849 },
+ { 0x0006e9, 4571 },
+ { 0x0006e5, 4522 },
+ { 0x0006b3, 3812 },
+ { 0x0006b8, 3911 },
+ { 0x0006eb, 4598 },
+ { 0x0006b9, 3934 },
+ { 0x0006ba, 3959 },
+ { 0x0006ef, 4646 },
+ { 0x0006f0, 4657 },
+ { 0x0006fb, 4797 },
+ { 0x0006fd, 4821 },
+ { 0x0006ea, 4582 },
+ { 0x0006f8, 4753 },
+ { 0x0006f4, 4705 },
+ { 0x0006e3, 4497 },
+ { 0x0006f5, 4717 },
+ { 0x0006f7, 4741 },
+ { 0x0006f1, 4669 },
+ { 0x0006f9, 4771 },
+ { 0x0006e0, 4462 },
+ { 0x0006fa, 4785 },
+ { 0x0006f6, 4728 },
+ { 0x0006c1, 4069 },
+ { 0x0006c2, 4080 },
+ { 0x0006de, 4431 },
+ { 0x0006c4, 4105 },
+ { 0x0006af, 3749 },
+ { 0x0006dc, 4405 },
+ { 0x0006c6, 4129 },
+ { 0x0006cc, 4205 },
+ { 0x0006cd, 4217 },
+ { 0x0006ce, 4229 },
+ { 0x0006d2, 4276 },
+ { 0x0006d3, 4288 },
+ { 0x0006c7, 4141 },
+ { 0x0006c8, 4154 },
+ { 0x0006df, 4444 },
+ { 0x0006c9, 4166 },
+ { 0x0006c5, 4117 },
+ { 0x0006a3, 3530 },
+ { 0x0006a8, 3629 },
+ { 0x0006cb, 4193 },
+ { 0x0006a9, 3652 },
+ { 0x0006aa, 3677 },
+ { 0x0006cf, 4241 },
+ { 0x0006d0, 4252 },
+ { 0x0006db, 4392 },
+ { 0x0006dd, 4416 },
+ { 0x0006ca, 4177 },
+ { 0x0006d8, 4348 },
+ { 0x0006d4, 4300 },
+ { 0x0006c3, 4092 },
+ { 0x0006d5, 4312 },
+ { 0x0006d7, 4336 },
+ { 0x0006d1, 4264 },
+ { 0x0006d9, 4366 },
+ { 0x0006c0, 4057 },
+ { 0x0006da, 4380 },
+ { 0x0006d6, 4323 },
+ { 0x000044, 213 },
+ { 0x0001cf, 1516 },
+ { 0x00ffff, 14500 },
+ { 0x0020ab, 11142 },
+ { 0x00ff54, 13737 },
+ { 0x0001d0, 1523 },
+ { 0x000045, 215 },
+ { 0x0003bd, 2060 },
+ { 0x0000d0, 873 },
+ { 0x0003cc, 2084 },
+ { 0x0000c9, 806 },
+ { 0x0001cc, 1509 },
+ { 0x0000ca, 813 },
+ { 0x0020a0, 11029 },
+ { 0x0000cb, 825 },
+ { 0x0000c8, 799 },
+ { 0x00ff2f, 13488 },
+ { 0x00ff30, 13499 },
+ { 0x0003aa, 1987 },
+ { 0x00ff57, 13771 },
+ { 0x0001ca, 1501 },
+ { 0x00ff1b, 13326 },
+ { 0x0000d0, 877 },
+ { 0x0020ac, 11151 },
+ { 0x00ff62, 13794 },
+ { 0x000046, 217 },
+ { 0x00ffbe, 14254 },
+ { 0x00ffc7, 14281 },
+ { 0x00ffc8, 14285 },
+ { 0x00ffc9, 14289 },
+ { 0x00ffca, 14293 },
+ { 0x00ffcb, 14297 },
+ { 0x00ffcc, 14301 },
+ { 0x00ffcd, 14305 },
+ { 0x00ffce, 14309 },
+ { 0x00ffcf, 14313 },
+ { 0x00ffd0, 14317 },
+ { 0x00ffbf, 14257 },
+ { 0x00ffd1, 14321 },
+ { 0x00ffd2, 14325 },
+ { 0x00ffd3, 14329 },
+ { 0x00ffd4, 14333 },
+ { 0x00ffd5, 14337 },
+ { 0x00ffd6, 14341 },
+ { 0x00ffd7, 14345 },
+ { 0x00ffd8, 14349 },
+ { 0x00ffd9, 14353 },
+ { 0x00ffda, 14357 },
+ { 0x00ffc0, 14260 },
+ { 0x00ffdb, 14361 },
+ { 0x00ffdc, 14365 },
+ { 0x00ffdd, 14369 },
+ { 0x00ffde, 14373 },
+ { 0x00ffdf, 14377 },
+ { 0x00ffe0, 14381 },
+ { 0x00ffc1, 14263 },
+ { 0x00ffc2, 14266 },
+ { 0x00ffc3, 14269 },
+ { 0x00ffc4, 14272 },
+ { 0x00ffc5, 14275 },
+ { 0x00ffc6, 14278 },
+ { 0x0020a3, 11060 },
+ { 0x00ff68, 13824 },
+ { 0x00fed0, 12671 },
+ { 0x000047, 219 },
+ { 0x0002d5, 1848 },
+ { 0x0002ab, 1759 },
+ { 0x0003ab, 1995 },
+ { 0x0002d8, 1858 },
+ { 0x0007c1, 5316 },
+ { 0x0007a1, 4867 },
+ { 0x0007c2, 5328 },
+ { 0x0007d7, 5564 },
+ { 0x0007c4, 5351 },
+ { 0x0007c5, 5363 },
+ { 0x0007a2, 4885 },
+ { 0x0007c7, 5388 },
+ { 0x0007a3, 4905 },
+ { 0x0007c3, 5339 },
+ { 0x0007c9, 5410 },
+ { 0x0007a4, 4921 },
+ { 0x0007a5, 4957 },
+ { 0x0007a5, 4938 },
+ { 0x0007ca, 5421 },
+ { 0x0007cb, 5433 },
+ { 0x0007cb, 5446 },
+ { 0x0007cc, 5458 },
+ { 0x0007cd, 5467 },
+ { 0x0007d9, 5584 },
+ { 0x0007ab, 5039 },
+ { 0x0007cf, 5485 },
+ { 0x0007a7, 4977 },
+ { 0x0007d6, 5554 },
+ { 0x0007d0, 5499 },
+ { 0x0007d8, 5574 },
+ { 0x0007d1, 5508 },
+ { 0x0007d2, 5518 },
+ { 0x0007d4, 5530 },
+ { 0x0007c8, 5398 },
+ { 0x0007d5, 5540 },
+ { 0x0007a8, 4997 },
+ { 0x0007a9, 5017 },
+ { 0x0007ce, 5476 },
+ { 0x0007c6, 5377 },
+ { 0x0007ae, 5057 },
+ { 0x0007e1, 5596 },
+ { 0x0007b1, 5093 },
+ { 0x0007e2, 5608 },
+ { 0x0007f7, 5866 },
+ { 0x0007e4, 5631 },
+ { 0x0007e5, 5643 },
+ { 0x0007b2, 5111 },
+ { 0x0007e7, 5668 },
+ { 0x0007b3, 5131 },
+ { 0x0007f3, 5810 },
+ { 0x0007e3, 5619 },
+ { 0x0007af, 5078 },
+ { 0x0007e9, 5690 },
+ { 0x0007b4, 5147 },
+ { 0x0007b6, 5183 },
+ { 0x0007b5, 5164 },
+ { 0x0007ea, 5701 },
+ { 0x0007eb, 5713 },
+ { 0x0007eb, 5726 },
+ { 0x0007ec, 5738 },
+ { 0x0007ed, 5747 },
+ { 0x0007f9, 5886 },
+ { 0x0007bb, 5298 },
+ { 0x0007ef, 5765 },
+ { 0x0007b7, 5208 },
+ { 0x0007f6, 5856 },
+ { 0x0007f0, 5779 },
+ { 0x0007f8, 5876 },
+ { 0x0007f1, 5788 },
+ { 0x0007f2, 5798 },
+ { 0x00ff7e, 13861 },
+ { 0x0007f4, 5832 },
+ { 0x0007e8, 5678 },
+ { 0x0007f5, 5842 },
+ { 0x0007b8, 5228 },
+ { 0x0007ba, 5270 },
+ { 0x0007b9, 5248 },
+ { 0x0007ee, 5756 },
+ { 0x0007e6, 5657 },
+ { 0x000048, 221 },
+ { 0x00ff31, 13511 },
+ { 0x000ebf, 10068 },
+ { 0x000ec0, 10077 },
+ { 0x000ef6, 10909 },
+ { 0x000ef7, 10922 },
+ { 0x00ff39, 13605 },
+ { 0x000eba, 10001 },
+ { 0x000ea7, 9694 },
+ { 0x000ec4, 10118 },
+ { 0x000ec3, 10108 },
+ { 0x000ed1, 10248 },
+ { 0x00ff33, 13531 },
+ { 0x00ff34, 13542 },
+ { 0x000ebe, 10055 },
+ { 0x000ed3, 10268 },
+ { 0x000eb7, 9957 },
+ { 0x000eea, 10673 },
+ { 0x000eda, 10389 },
+ { 0x000eee, 10735 },
+ { 0x000ee8, 10643 },
+ { 0x000ee9, 10658 },
+ { 0x000eeb, 10688 },
+ { 0x000ed4, 10277 },
+ { 0x000ed6, 10314 },
+ { 0x000ef9, 10953 },
+ { 0x000ee3, 10561 },
+ { 0x000ed7, 10334 },
+ { 0x000ed9, 10369 },
+ { 0x000ed8, 10349 },
+ { 0x000ef8, 10936 },
+ { 0x000eed, 10719 },
+ { 0x000ee4, 10576 },
+ { 0x000ee5, 10591 },
+ { 0x000edb, 10405 },
+ { 0x000ee2, 10541 },
+ { 0x000edc, 10420 },
+ { 0x000edd, 10441 },
+ { 0x000ee1, 10520 },
+ { 0x000ede, 10461 },
+ { 0x000edf, 10481 },
+ { 0x000ee0, 10500 },
+ { 0x000ee6, 10610 },
+ { 0x000ed5, 10293 },
+ { 0x000ee7, 10624 },
+ { 0x000eec, 10704 },
+ { 0x000efa, 10980 },
+ { 0x00ff35, 13555 },
+ { 0x00ff38, 13591 },
+ { 0x000eb8, 9970 },
+ { 0x000ebb, 10014 },
+ { 0x000ea1, 9594 },
+ { 0x000ea3, 9627 },
+ { 0x000ef3, 10839 },
+ { 0x000eb1, 9867 },
+ { 0x000ea4, 9645 },
+ { 0x000ea6, 9676 },
+ { 0x000ea5, 9658 },
+ { 0x000ec7, 10148 },
+ { 0x000eca, 10178 },
+ { 0x000ef2, 10824 },
+ { 0x000ebd, 10041 },
+ { 0x000eb2, 9880 },
+ { 0x000eb4, 9911 },
+ { 0x00ff3b, 13634 },
+ { 0x00ff3a, 13618 },
+ { 0x000ea9, 9727 },
+ { 0x000eb0, 9849 },
+ { 0x000eaa, 9740 },
+ { 0x000eab, 9759 },
+ { 0x000eaf, 9830 },
+ { 0x000eac, 9777 },
+ { 0x000ead, 9795 },
+ { 0x000eae, 9812 },
+ { 0x000eef, 10750 },
+ { 0x00ff36, 13567 },
+ { 0x000eb5, 9928 },
+ { 0x00ff3f, 13703 },
+ { 0x000ea8, 9708 },
+ { 0x000eb9, 9983 },
+ { 0x000ea2, 9608 },
+ { 0x000eb3, 9893 },
+ { 0x000eb6, 9940 },
+ { 0x00ff32, 13518 },
+ { 0x000ef0, 10774 },
+ { 0x000ef4, 10864 },
+ { 0x000ef1, 10799 },
+ { 0x000ebc, 10028 },
+ { 0x000ecc, 10198 },
+ { 0x000ec8, 10157 },
+ { 0x000ec9, 10167 },
+ { 0x000ece, 10218 },
+ { 0x000ecd, 10207 },
+ { 0x000ecf, 10228 },
+ { 0x000ec1, 10087 },
+ { 0x000ec2, 10097 },
+ { 0x000ec6, 10138 },
+ { 0x000ec5, 10127 },
+ { 0x000ed2, 10258 },
+ { 0x000ecb, 10188 },
+ { 0x000ed0, 10238 },
+ { 0x000ef5, 10890 },
+ { 0x00ff7e, 13874 },
+ { 0x00ff29, 13428 },
+ { 0x0002a6, 1737 },
+ { 0x00ff7e, 13888 },
+ { 0x00ff6a, 13836 },
+ { 0x00ff23, 13358 },
+ { 0x00ff23, 13365 },
+ { 0x00ff25, 13384 },
+ { 0x00ff27, 13402 },
+ { 0x00ff50, 13718 },
+ { 0x0002a1, 1729 },
+ { 0x00ffed, 14484 },
+ { 0x00ffee, 14492 },
+ { 0x000049, 223 },
+ { 0x00fe33, 12190 },
+ { 0x00fe30, 12123 },
+ { 0x00fe31, 12148 },
+ { 0x00fe32, 12176 },
+ { 0x00fe34, 12208 },
+ { 0x00fe2f, 12102 },
+ { 0x00fe2c, 12040 },
+ { 0x00fe2d, 12061 },
+ { 0x00fe2e, 12083 },
+ { 0x00fe0c, 11715 },
+ { 0x00fe0d, 11731 },
+ { 0x00fe06, 11614 },
+ { 0x00fe07, 11630 },
+ { 0x00ff7e, 13902 },
+ { 0x00fe0e, 11752 },
+ { 0x00fe0f, 11767 },
+ { 0x00fe20, 11787 },
+ { 0x00fe02, 11547 },
+ { 0x00fe04, 11581 },
+ { 0x00fe05, 11598 },
+ { 0x00fe03, 11564 },
+ { 0x00fe01, 11538 },
+ { 0x00fe22, 11817 },
+ { 0x00fe21, 11800 },
+ { 0x00fe08, 11645 },
+ { 0x00fe09, 11660 },
+ { 0x00fe24, 11856 },
+ { 0x00fe23, 11836 },
+ { 0x00fe25, 11878 },
+ { 0x00fe26, 11901 },
+ { 0x00fe0a, 11680 },
+ { 0x00fe0b, 11695 },
+ { 0x00fe2b, 12015 },
+ { 0x00fe29, 11966 },
+ { 0x00fe2a, 11990 },
+ { 0x00fe27, 11925 },
+ { 0x00fe28, 11945 },
+ { 0x0002a9, 1749 },
+ { 0x0000cd, 843 },
+ { 0x0000ce, 850 },
+ { 0x0000cf, 862 },
+ { 0x0000cc, 836 },
+ { 0x0003cf, 2094 },
+ { 0x00ff63, 13802 },
+ { 0x0003c7, 2076 },
+ { 0x0003a5, 1971 },
+ { 0x00004a, 225 },
+ { 0x0002ac, 1766 },
+ { 0x00004b, 227 },
+ { 0x00ffb0, 14195 },
+ { 0x00ffb1, 14200 },
+ { 0x00ffb2, 14205 },
+ { 0x00ffb3, 14210 },
+ { 0x00ffb4, 14215 },
+ { 0x00ffb5, 14220 },
+ { 0x00ffb6, 14225 },
+ { 0x00ffb7, 14230 },
+ { 0x00ffb8, 14235 },
+ { 0x00ffb9, 14240 },
+ { 0x00ffab, 14142 },
+ { 0x00ff9d, 14101 },
+ { 0x00ffae, 14174 },
+ { 0x00ff9f, 14120 },
+ { 0x00ffaf, 14185 },
+ { 0x00ff99, 14045 },
+ { 0x00ff9c, 14094 },
+ { 0x00ff8d, 13981 },
+ { 0x00ffbd, 14245 },
+ { 0x00ff91, 13990 },
+ { 0x00ff92, 13996 },
+ { 0x00ff93, 14002 },
+ { 0x00ff94, 14008 },
+ { 0x00ff95, 14014 },
+ { 0x00ff9e, 14110 },
+ { 0x00ff96, 14022 },
+ { 0x00ffaa, 14130 },
+ { 0x00ff9b, 14086 },
+ { 0x00ff9b, 14073 },
+ { 0x00ff9a, 14053 },
+ { 0x00ff9a, 14064 },
+ { 0x00ff98, 14036 },
+ { 0x00ffac, 14149 },
+ { 0x00ff80, 13965 },
+ { 0x00ffad, 14162 },
+ { 0x00ff89, 13974 },
+ { 0x00ff97, 14030 },
+ { 0x00ff2d, 13467 },
+ { 0x00ff2e, 13477 },
+ { 0x00ff21, 13343 },
+ { 0x00ff26, 13393 },
+ { 0x0003d3, 2119 },
+ { 0x000eff, 11001 },
+ { 0x00004c, 229 },
+ { 0x0001c5, 1480 },
+ { 0x00fed4, 12732 },
+ { 0x0001a5, 1303 },
+ { 0x0003a6, 1978 },
+ { 0x00ff51, 13723 },
+ { 0x00ff0a, 13278 },
+ { 0x0020a4, 11071 },
+ { 0x0001a3, 1295 },
+ { 0x00004d, 231 },
+ { 0x0006b5, 3849 },
+ { 0x0006b2, 3798 },
+ { 0x0006bc, 3997 },
+ { 0x0006a5, 3567 },
+ { 0x0006a2, 3516 },
+ { 0x0006ac, 3715 },
+ { 0x00ff2c, 13460 },
+ { 0x00ff67, 13819 },
+ { 0x00ffe7, 14442 },
+ { 0x00ffe8, 14449 },
+ { 0x0020a5, 11080 },
+ { 0x00ff7e, 13918 },
+ { 0x00fe77, 12597 },
+ { 0x00fe76, 12580 },
+ { 0x00ff22, 13349 },
+ { 0x00ff20, 13333 },
+ { 0x00ff3d, 13667 },
+ { 0x00004e, 233 },
+ { 0x0001d1, 1531 },
+ { 0x0020a6, 11089 },
+ { 0x0001d2, 1538 },
+ { 0x0003d1, 2102 },
+ { 0x0020aa, 11128 },
+ { 0x00ff56, 13766 },
+ { 0x00fed2, 12712 },
+ { 0x0000d1, 881 },
+ { 0x00ff7f, 13956 },
+ { 0x00004f, 235 },
+ { 0x0013bc, 11012 },
+ { 0x0000d3, 895 },
+ { 0x0000d4, 902 },
+ { 0x0000d6, 921 },
+ { 0x0001d5, 1545 },
+ { 0x0000d2, 888 },
+ { 0x0003d2, 2111 },
+ { 0x0000d8, 941 },
+ { 0x0000d5, 914 },
+ { 0x00fe78, 12620 },
+ { 0x00fe79, 12636 },
+ { 0x000050, 237 },
+ { 0x00ff56, 13756 },
+ { 0x00ff55, 13742 },
+ { 0x00ff13, 13300 },
+ { 0x0020a7, 11099 },
+ { 0x00fefa, 13191 },
+ { 0x00fee9, 12906 },
+ { 0x00feea, 12922 },
+ { 0x00feeb, 12938 },
+ { 0x00feec, 12954 },
+ { 0x00feed, 12970 },
+ { 0x00fee8, 12886 },
+ { 0x00feef, 13008 },
+ { 0x00fef0, 13026 },
+ { 0x00fef1, 13044 },
+ { 0x00fef2, 13062 },
+ { 0x00fef3, 13080 },
+ { 0x00feee, 12986 },
+ { 0x00fefb, 13210 },
+ { 0x00fefc, 13230 },
+ { 0x00fee3, 12807 },
+ { 0x00fee6, 12851 },
+ { 0x00fee7, 12868 },
+ { 0x00fef5, 13116 },
+ { 0x00fef6, 13130 },
+ { 0x00fef7, 13144 },
+ { 0x00fef8, 13158 },
+ { 0x00fefd, 13250 },
+ { 0x00fef4, 13098 },
+ { 0x00fef9, 13172 },
+ { 0x00fee0, 12769 },
+ { 0x00fee1, 12782 },
+ { 0x00fee2, 12796 },
+ { 0x00fee4, 12820 },
+ { 0x00fee5, 12835 },
+ { 0x00fed1, 12692 },
+ { 0x00ff3e, 13685 },
+ { 0x00ff61, 13788 },
+ { 0x00ff55, 13750 },
+ { 0x000051, 239 },
+ { 0x000052, 241 },
+ { 0x0001c0, 1466 },
+ { 0x0001d8, 1558 },
+ { 0x0003a3, 1962 },
+ { 0x00ff66, 13814 },
+ { 0x00fe72, 12510 },
+ { 0x00ff0d, 13293 },
+ { 0x00ff53, 13731 },
+ { 0x00ff24, 13377 },
+ { 0x0020a8, 11110 },
+ { 0x000053, 243 },
+ { 0x0001a6, 1310 },
+ { 0x0001a9, 1317 },
+ { 0x0001aa, 1324 },
+ { 0x0002de, 1877 },
+ { 0x00ff14, 13306 },
+ { 0x00ff60, 13781 },
+ { 0x0006b1, 3786 },
+ { 0x0006bf, 4045 },
+ { 0x0006b8, 3923 },
+ { 0x0006b9, 3947 },
+ { 0x0006ba, 3972 },
+ { 0x0006bb, 3984 },
+ { 0x0006a1, 3504 },
+ { 0x0006af, 3763 },
+ { 0x0006a8, 3641 },
+ { 0x0006a9, 3665 },
+ { 0x0006aa, 3690 },
+ { 0x0006ab, 3702 },
+ { 0x00ffe1, 14385 },
+ { 0x00ffe6, 14431 },
+ { 0x00ffe2, 14393 },
+ { 0x00ff3c, 13651 },
+ { 0x00fe73, 12528 },
+ { 0x00fe75, 12562 },
+ { 0x00ffeb, 14468 },
+ { 0x00ffec, 14476 },
+ { 0x00ff15, 13318 },
+ { 0x000054, 245 },
+ { 0x0000de, 994 },
+ { 0x00ff09, 13274 },
+ { 0x0001ab, 1333 },
+ { 0x0001de, 1584 },
+ { 0x00fed5, 12752 },
+ { 0x000ddf, 9260 },
+ { 0x000dba, 8843 },
+ { 0x000da8, 8607 },
+ { 0x000daa, 8634 },
+ { 0x000da9, 8620 },
+ { 0x000dac, 8658 },
+ { 0x000dae, 8683 },
+ { 0x000db4, 8768 },
+ { 0x000dbd, 8882 },
+ { 0x000dbf, 8905 },
+ { 0x000dcb, 9039 },
+ { 0x000dce, 9073 },
+ { 0x000da2, 8525 },
+ { 0x000da5, 8566 },
+ { 0x000da3, 8538 },
+ { 0x000da4, 8552 },
+ { 0x000da6, 8579 },
+ { 0x000da1, 8514 },
+ { 0x000de5, 9343 },
+ { 0x000df7, 9556 },
+ { 0x000df5, 9533 },
+ { 0x000df6, 9544 },
+ { 0x000df9, 9582 },
+ { 0x000df1, 9484 },
+ { 0x000df8, 9569 },
+ { 0x000df3, 9510 },
+ { 0x000df4, 9522 },
+ { 0x000df2, 9497 },
+ { 0x000df0, 9472 },
+ { 0x000dcc, 9050 },
+ { 0x000dc5, 8972 },
+ { 0x000dc6, 8984 },
+ { 0x000deb, 9424 },
+ { 0x000de8, 9389 },
+ { 0x000dd1, 9113 },
+ { 0x000dde, 9237 },
+ { 0x000de7, 9374 },
+ { 0x000de9, 9400 },
+ { 0x000dea, 9412 },
+ { 0x000de6, 9360 },
+ { 0x000dc1, 8932 },
+ { 0x000da7, 8595 },
+ { 0x000ded, 9458 },
+ { 0x000db3, 8757 },
+ { 0x000db9, 8833 },
+ { 0x000dcd, 9063 },
+ { 0x000dcf, 9087 },
+ { 0x000dda, 9224 },
+ { 0x000dbe, 8892 },
+ { 0x000dbc, 8868 },
+ { 0x000dc0, 8916 },
+ { 0x000dbb, 8857 },
+ { 0x000dc3, 8953 },
+ { 0x000dc4, 8964 },
+ { 0x000dd0, 9102 },
+ { 0x000dd2, 9129 },
+ { 0x000de1, 9281 },
+ { 0x000de4, 9323 },
+ { 0x000de3, 9304 },
+ { 0x000dd3, 9141 },
+ { 0x000de0, 9270 },
+ { 0x000dd4, 9153 },
+ { 0x000dd5, 9164 },
+ { 0x000de2, 9293 },
+ { 0x000dd8, 9201 },
+ { 0x000dd6, 9176 },
+ { 0x000dd7, 9188 },
+ { 0x000dd9, 9212 },
+ { 0x000dc9, 9016 },
+ { 0x000dc8, 9004 },
+ { 0x000dab, 8648 },
+ { 0x000dca, 9028 },
+ { 0x000dec, 9441 },
+ { 0x000db1, 8722 },
+ { 0x000db2, 8741 },
+ { 0x000db7, 8804 },
+ { 0x000db0, 8709 },
+ { 0x000db8, 8819 },
+ { 0x000db6, 8790 },
+ { 0x000daf, 8696 },
+ { 0x000db5, 8779 },
+ { 0x000dc7, 8992 },
+ { 0x000dc2, 8942 },
+ { 0x000dad, 8671 },
+ { 0x0000de, 1000 },
+ { 0x00ff2b, 13452 },
+ { 0x0003ac, 2004 },
+ { 0x000055, 247 },
+ { 0x0000da, 957 },
+ { 0x0002dd, 1870 },
+ { 0x0000db, 964 },
+ { 0x0000dc, 976 },
+ { 0x0001db, 1571 },
+ { 0x0000d9, 950 },
+ { 0x0006b6, 3863 },
+ { 0x0006b4, 3824 },
+ { 0x0006b7, 3886 },
+ { 0x0006a6, 3581 },
+ { 0x0006a4, 3542 },
+ { 0x0006a7, 3604 },
+ { 0x0006b6, 3875 },
+ { 0x0006b4, 3837 },
+ { 0x0006b7, 3899 },
+ { 0x0006a6, 3593 },
+ { 0x0006a4, 3555 },
+ { 0x0006a7, 3617 },
+ { 0x0003de, 2143 },
+ { 0x00ff65, 13809 },
+ { 0x0003d9, 2128 },
+ { 0x00ff52, 13728 },
+ { 0x0001d9, 1565 },
+ { 0x0003dd, 2136 },
+ { 0x000056, 249 },
+ { 0xffffff, 14507 },
+ { 0x000057, 251 },
+ { 0x0020a9, 11120 },
+ { 0x000058, 253 },
+ { 0x000059, 255 },
+ { 0x0000dd, 987 },
+ { 0x0013be, 11018 },
+ { 0x00005a, 257 },
+ { 0x0001af, 1354 },
+ { 0x0001ac, 1340 },
+ { 0x0001ae, 1347 },
+ { 0x00ff28, 13420 },
+ { 0x00ff2a, 13436 },
+ { 0x000061, 333 },
+ { 0x0000e1, 1020 },
+ { 0x0001ff, 1720 },
+ { 0x0001e3, 1600 },
+ { 0x0000e2, 1027 },
+ { 0x0000b4, 612 },
+ { 0x0000e4, 1046 },
+ { 0x0000e6, 1063 },
+ { 0x0000e0, 1013 },
+ { 0x0003e0, 2151 },
+ { 0x000026, 48 },
+ { 0x0001b1, 1364 },
+ { 0x000027, 58 },
+ { 0x0008c8, 6376 },
+ { 0x0000e5, 1057 },
+ { 0x00005e, 294 },
+ { 0x00007e, 410 },
+ { 0x00002a, 101 },
+ { 0x000040, 204 },
+ { 0x0000e3, 1039 },
+ { 0x000062, 335 },
+ { 0x00005c, 271 },
+ { 0x000af4, 7692 },
+ { 0x00007c, 395 },
+ { 0x0009df, 6562 },
+ { 0x0008a5, 5952 },
+ { 0x0008ac, 6062 },
+ { 0x0008a8, 5995 },
+ { 0x0008b2, 6166 },
+ { 0x0008ae, 6091 },
+ { 0x0008aa, 6030 },
+ { 0x0008b6, 6253 },
+ { 0x0009f6, 6770 },
+ { 0x0008b4, 6209 },
+ { 0x00007b, 385 },
+ { 0x00007d, 399 },
+ { 0x00005b, 259 },
+ { 0x00005d, 281 },
+ { 0x0001a2, 1289 },
+ { 0x0000a6, 472 },
+ { 0x000063, 337 },
+ { 0x0002e5, 1889 },
+ { 0x0001e6, 1614 },
+ { 0x000ab8, 6996 },
+ { 0x000afc, 7801 },
+ { 0x0001b7, 1401 },
+ { 0x0001e8, 1621 },
+ { 0x0000e7, 1066 },
+ { 0x0002e6, 1899 },
+ { 0x0000b8, 646 },
+ { 0x0000a2, 445 },
+ { 0x0009e1, 6581 },
+ { 0x000af3, 7682 },
+ { 0x000bcf, 7950 },
+ { 0x000aec, 7630 },
+ { 0x00003a, 160 },
+ { 0x00002c, 115 },
+ { 0x0000a9, 500 },
+ { 0x0009e4, 6600 },
+ { 0x0009ee, 6668 },
+ { 0x0000a4, 459 },
+ { 0x000aff, 7845 },
+ { 0x000064, 339 },
+ { 0x000af1, 7662 },
+ { 0x0001ef, 1643 },
+ { 0x00fe56, 12290 },
+ { 0x00fe58, 12319 },
+ { 0x00fe51, 12229 },
+ { 0x00fe60, 12437 },
+ { 0x00fe55, 12279 },
+ { 0x00fe5a, 12351 },
+ { 0x00fe5b, 12362 },
+ { 0x00fe52, 12240 },
+ { 0x00fe57, 12304 },
+ { 0x00fe59, 12334 },
+ { 0x00fe50, 12218 },
+ { 0x00fe61, 12451 },
+ { 0x00fe62, 12461 },
+ { 0x00fe5d, 12387 },
+ { 0x00fe54, 12267 },
+ { 0x00fe5c, 12375 },
+ { 0x00fe5f, 12415 },
+ { 0x00fe53, 12256 },
+ { 0x00fe5e, 12397 },
+ { 0x000abd, 7028 },
+ { 0x0000b0, 569 },
+ { 0x0000a8, 490 },
+ { 0x000aed, 7635 },
+ { 0x000aa5, 6822 },
+ { 0x0000f7, 1204 },
+ { 0x000024, 33 },
+ { 0x000aaf, 6899 },
+ { 0x0001bd, 1437 },
+ { 0x000af2, 7669 },
+ { 0x000afe, 7826 },
+ { 0x0008fe, 6552 },
+ { 0x000ba8, 7873 },
+ { 0x000bd6, 7965 },
+ { 0x000bc4, 7915 },
+ { 0x000bc2, 7899 },
+ { 0x0001f0, 1650 },
+ { 0x000065, 341 },
+ { 0x0003ec, 2167 },
+ { 0x0000e9, 1082 },
+ { 0x0001ec, 1636 },
+ { 0x0000ea, 1089 },
+ { 0x0000eb, 1101 },
+ { 0x0000e8, 1075 },
+ { 0x000aae, 6890 },
+ { 0x000aa3, 6804 },
+ { 0x000aa4, 6813 },
+ { 0x0003ba, 2036 },
+ { 0x000aa9, 6864 },
+ { 0x000ade, 7409 },
+ { 0x000adf, 7424 },
+ { 0x000ace, 7191 },
+ { 0x000acf, 7204 },
+ { 0x000aa1, 6788 },
+ { 0x000aaa, 6871 },
+ { 0x000ae6, 7531 },
+ { 0x000ae7, 7550 },
+ { 0x0003bf, 2064 },
+ { 0x000ae0, 7437 },
+ { 0x000ae1, 7454 },
+ { 0x000aa2, 6796 },
+ { 0x0001ea, 1628 },
+ { 0x00003d, 181 },
+ { 0x0000f0, 1149 },
+ { 0x000021, 6 },
+ { 0x0000a1, 434 },
+ { 0x000066, 343 },
+ { 0x000af8, 7740 },
+ { 0x0009e3, 6597 },
+ { 0x000abb, 7003 },
+ { 0x000adc, 7368 },
+ { 0x000adb, 7351 },
+ { 0x000add, 7388 },
+ { 0x000ae9, 7585 },
+ { 0x000ae8, 7567 },
+ { 0x000ac5, 7089 },
+ { 0x000ab7, 6985 },
+ { 0x000ab5, 6965 },
+ { 0x0008f6, 6514 },
+ { 0x000067, 345 },
+ { 0x0002f5, 1911 },
+ { 0x0002bb, 1807 },
+ { 0x0003bb, 2044 },
+ { 0x0002f8, 1921 },
+ { 0x000060, 317 },
+ { 0x00003e, 187 },
+ { 0x0008be, 6315 },
+ { 0x0000ab, 522 },
+ { 0x0000bb, 676 },
+ { 0x000068, 347 },
+ { 0x000aa8, 6854 },
+ { 0x0002b6, 1786 },
+ { 0x000aee, 7643 },
+ { 0x000ce0, 8033 },
+ { 0x000cf2, 8350 },
+ { 0x000ce1, 8046 },
+ { 0x000ce1, 8057 },
+ { 0x000ce7, 8169 },
+ { 0x000ce3, 8096 },
+ { 0x000ce3, 8109 },
+ { 0x000cdf, 8012 },
+ { 0x000cea, 8226 },
+ { 0x000ced, 8268 },
+ { 0x000cef, 8295 },
+ { 0x000cf3, 8362 },
+ { 0x000cf5, 8387 },
+ { 0x000cf5, 8404 },
+ { 0x000ce2, 8069 },
+ { 0x000ce2, 8082 },
+ { 0x000ce4, 8123 },
+ { 0x000ce7, 8181 },
+ { 0x000ceb, 8243 },
+ { 0x000cf7, 8445 },
+ { 0x000cec, 8255 },
+ { 0x000cee, 8284 },
+ { 0x000cf0, 8311 },
+ { 0x000cf4, 8377 },
+ { 0x000cf7, 8456 },
+ { 0x000cf8, 8468 },
+ { 0x000cf1, 8322 },
+ { 0x000cf1, 8336 },
+ { 0x000cf9, 8480 },
+ { 0x000cfa, 8492 },
+ { 0x000cfa, 8503 },
+ { 0x000ce8, 8192 },
+ { 0x000ce8, 8203 },
+ { 0x000ce5, 8133 },
+ { 0x000ce9, 8215 },
+ { 0x000cf6, 8421 },
+ { 0x000cf6, 8433 },
+ { 0x000ce6, 8144 },
+ { 0x000ce6, 8156 },
+ { 0x000ada, 7342 },
+ { 0x0008a3, 5925 },
+ { 0x0009ef, 6682 },
+ { 0x0009f0, 6697 },
+ { 0x0009f1, 6712 },
+ { 0x0009f2, 6727 },
+ { 0x0009f3, 6742 },
+ { 0x0002b1, 1778 },
+ { 0x0009e2, 6594 },
+ { 0x0000ad, 544 },
+ { 0x000069, 349 },
+ { 0x0000ed, 1119 },
+ { 0x0000ee, 1126 },
+ { 0x0008cf, 6418 },
+ { 0x0000ef, 1138 },
+ { 0x0002b9, 1798 },
+ { 0x0008cd, 6401 },
+ { 0x0000ec, 1112 },
+ { 0x0003ef, 2177 },
+ { 0x0008ce, 6410 },
+ { 0x0008da, 6436 },
+ { 0x0008db, 6447 },
+ { 0x0008c2, 6361 },
+ { 0x0008bf, 6332 },
+ { 0x0008dc, 6456 },
+ { 0x0003e7, 2159 },
+ { 0x0003b5, 2020 },
+ { 0x00006a, 351 },
+ { 0x0002bc, 1814 },
+ { 0x000bca, 7934 },
+ { 0x00006b, 353 },
+ { 0x0004b1, 2439 },
+ { 0x0004c1, 2563 },
+ { 0x0004b4, 2460 },
+ { 0x0004cc, 2669 },
+ { 0x0004ca, 2653 },
+ { 0x0004cd, 2685 },
+ { 0x0004cb, 2661 },
+ { 0x0004ce, 2693 },
+ { 0x0004cc, 2677 },
+ { 0x0004b2, 2446 },
+ { 0x0004b6, 2474 },
+ { 0x0004b9, 2498 },
+ { 0x0004b7, 2482 },
+ { 0x0004ba, 2506 },
+ { 0x0004b8, 2490 },
+ { 0x0004cf, 2701 },
+ { 0x0004d2, 2725 },
+ { 0x0004d0, 2709 },
+ { 0x0004d3, 2733 },
+ { 0x0004d1, 2717 },
+ { 0x0004dd, 2813 },
+ { 0x0004c5, 2613 },
+ { 0x0004c8, 2637 },
+ { 0x0004c6, 2621 },
+ { 0x0004c9, 2645 },
+ { 0x0004c7, 2629 },
+ { 0x0004b5, 2467 },
+ { 0x0004d7, 2765 },
+ { 0x0004da, 2789 },
+ { 0x0004d8, 2773 },
+ { 0x0004db, 2797 },
+ { 0x0004d9, 2781 },
+ { 0x0004bb, 2514 },
+ { 0x0004be, 2539 },
+ { 0x0004bc, 2522 },
+ { 0x0004bf, 2547 },
+ { 0x0004bd, 2531 },
+ { 0x0004c0, 2555 },
+ { 0x0004c3, 2597 },
+ { 0x0004c1, 2572 },
+ { 0x0004c4, 2605 },
+ { 0x0004c2, 2580 },
+ { 0x0004c2, 2589 },
+ { 0x0004b3, 2453 },
+ { 0x0004dc, 2805 },
+ { 0x0004a6, 2340 },
+ { 0x0004d4, 2741 },
+ { 0x0004d6, 2757 },
+ { 0x0004d5, 2749 },
+ { 0x0004a7, 2348 },
+ { 0x0004a3, 2277 },
+ { 0x0004a4, 2297 },
+ { 0x0004a5, 2308 },
+ { 0x0004aa, 2369 },
+ { 0x0004a1, 2243 },
+ { 0x0004a8, 2355 },
+ { 0x0004a5, 2325 },
+ { 0x0004ab, 2376 },
+ { 0x0004a2, 2257 },
+ { 0x00ff7e, 13930 },
+ { 0x0004af, 2407 },
+ { 0x0004af, 2416 },
+ { 0x0004a9, 2362 },
+ { 0x0004ac, 2383 },
+ { 0x0004ae, 2399 },
+ { 0x0004ad, 2391 },
+ { 0x0003a2, 1952 },
+ { 0x0003f3, 2202 },
+ { 0x0003a2, 1958 },
+ { 0x00006c, 355 },
+ { 0x0001e5, 1607 },
+ { 0x000ad9, 7331 },
+ { 0x0001b5, 1387 },
+ { 0x0003b6, 2027 },
+ { 0x000abc, 7011 },
+ { 0x0008fb, 6523 },
+ { 0x000ba3, 7852 },
+ { 0x000ad2, 7261 },
+ { 0x0008af, 6106 },
+ { 0x000acc, 7156 },
+ { 0x000aea, 7605 },
+ { 0x0008a1, 5898 },
+ { 0x000bda, 7984 },
+ { 0x000ad0, 7220 },
+ { 0x0009f4, 6757 },
+ { 0x000bdc, 7993 },
+ { 0x00003c, 176 },
+ { 0x0008bc, 6292 },
+ { 0x0009e5, 6603 },
+ { 0x0008de, 6475 },
+ { 0x0008df, 6486 },
+ { 0x0009ed, 6654 },
+ { 0x0009ea, 6612 },
+ { 0x0001b3, 1379 },
+ { 0x00006d, 357 },
+ { 0x0000af, 562 },
+ { 0x000af7, 7729 },
+ { 0x000af0, 7649 },
+ { 0x000abf, 7059 },
+ { 0x0000ba, 666 },
+ { 0x00002d, 121 },
+ { 0x000ad6, 7315 },
+ { 0x0000b5, 618 },
+ { 0x0000d7, 932 },
+ { 0x000af6, 7717 },
+ { 0x000af5, 7704 },
+ { 0x00006e, 359 },
+ { 0x0008c5, 6370 },
+ { 0x0001f1, 1658 },
+ { 0x0001f2, 1665 },
+ { 0x0003f1, 2185 },
+ { 0x0009e8, 6606 },
+ { 0x0000a0, 421 },
+ { 0x0008bd, 6306 },
+ { 0x0000ac, 536 },
+ { 0x0000f1, 1153 },
+ { 0x000023, 22 },
+ { 0x0006b0, 3775 },
+ { 0x00006f, 361 },
+ { 0x0000f3, 1167 },
+ { 0x0000f4, 1174 },
+ { 0x0000f6, 1193 },
+ { 0x0001f5, 1672 },
+ { 0x0013bd, 11015 },
+ { 0x0001b2, 1372 },
+ { 0x0000f2, 1160 },
+ { 0x0003f2, 2194 },
+ { 0x000ac3, 7066 },
+ { 0x000ab2, 6934 },
+ { 0x0000bd, 702 },
+ { 0x0000bc, 691 },
+ { 0x000ab6, 6976 },
+ { 0x0000b9, 654 },
+ { 0x000ab0, 6915 },
+ { 0x000ae2, 7473 },
+ { 0x000ae5, 7522 },
+ { 0x000ae4, 7504 },
+ { 0x000ae3, 7488 },
+ { 0x0000aa, 510 },
+ { 0x0000f8, 1213 },
+ { 0x0000f5, 1186 },
+ { 0x000bc0, 7891 },
+ { 0x00047e, 2234 },
+ { 0x000070, 363 },
+ { 0x0000b6, 621 },
+ { 0x000028, 80 },
+ { 0x000029, 90 },
+ { 0x0008ef, 6496 },
+ { 0x000025, 40 },
+ { 0x00002e, 127 },
+ { 0x0000b7, 631 },
+ { 0x000afb, 7781 },
+ { 0x00002b, 110 },
+ { 0x0000b1, 576 },
+ { 0x000ad4, 7302 },
+ { 0x0004b0, 2424 },
+ { 0x000aa6, 6833 },
+ { 0x000071, 365 },
+ { 0x000bcc, 7938 },
+ { 0x00003f, 195 },
+ { 0x0000bf, 724 },
+ { 0x000022, 13 },
+ { 0x000060, 323 },
+ { 0x000027, 69 },
+ { 0x000072, 367 },
+ { 0x0001e0, 1593 },
+ { 0x0008d6, 6428 },
+ { 0x0001f8, 1685 },
+ { 0x0003b3, 2011 },
+ { 0x0000ae, 551 },
+ { 0x000abe, 7041 },
+ { 0x0008fd, 6541 },
+ { 0x000ba6, 7862 },
+ { 0x000ad3, 7281 },
+ { 0x0008b0, 6127 },
+ { 0x0008b7, 6271 },
+ { 0x000acd, 7173 },
+ { 0x000aeb, 7617 },
+ { 0x000bd8, 7974 },
+ { 0x000ad1, 7240 },
+ { 0x0009f5, 6763 },
+ { 0x000bfc, 8002 },
+ { 0x000073, 369 },
+ { 0x0001b6, 1394 },
+ { 0x0001b9, 1407 },
+ { 0x0001ba, 1414 },
+ { 0x0002fe, 1940 },
+ { 0x00ff7e, 13942 },
+ { 0x000ad7, 7323 },
+ { 0x0000a7, 482 },
+ { 0x00003b, 166 },
+ { 0x0004df, 2832 },
+ { 0x000ac6, 7101 },
+ { 0x000aca, 7124 },
+ { 0x000aac, 6878 },
+ { 0x0008c9, 6388 },
+ { 0x000afd, 7807 },
+ { 0x00002f, 134 },
+ { 0x0009e0, 6568 },
+ { 0x000020, 0 },
+ { 0x0000df, 1006 },
+ { 0x0000a3, 450 },
+ { 0x000074, 371 },
+ { 0x0001bb, 1423 },
+ { 0x0001fe, 1711 },
+ { 0x000af9, 7753 },
+ { 0x000afa, 7763 },
+ { 0x0008c0, 6341 },
+ { 0x000aa7, 6844 },
+ { 0x0000fe, 1264 },
+ { 0x000ac4, 7076 },
+ { 0x000ab4, 6953 },
+ { 0x0000be, 710 },
+ { 0x0000b3, 598 },
+ { 0x0008a4, 5940 },
+ { 0x0008ab, 6048 },
+ { 0x0008a2, 5910 },
+ { 0x0008a7, 5978 },
+ { 0x0008b1, 6149 },
+ { 0x0008ad, 6076 },
+ { 0x0008a9, 6012 },
+ { 0x0008b5, 6235 },
+ { 0x0009f7, 6775 },
+ { 0x0008b3, 6183 },
+ { 0x000ac9, 7114 },
+ { 0x000acb, 7138 },
+ { 0x0003bc, 2053 },
+ { 0x000ab3, 6943 },
+ { 0x0000b2, 586 },
+ { 0x000ab1, 6924 },
+ { 0x000075, 373 },
+ { 0x0000fa, 1227 },
+ { 0x0002fd, 1933 },
+ { 0x0000fb, 1234 },
+ { 0x0000fc, 1246 },
+ { 0x0001fb, 1698 },
+ { 0x0000f9, 1220 },
+ { 0x0003fe, 2226 },
+ { 0x000bc6, 7925 },
+ { 0x00005f, 306 },
+ { 0x0008dd, 6469 },
+ { 0x0003f9, 2211 },
+ { 0x0008fc, 6533 },
+ { 0x000ba9, 7883 },
+ { 0x0009ec, 6641 },
+ { 0x0009eb, 6627 },
+ { 0x000bc3, 7908 },
+ { 0x000bd3, 7957 },
+ { 0x000bce, 7943 },
+ { 0x0001f9, 1692 },
+ { 0x0003fd, 2219 },
+ { 0x000076, 375 },
+ { 0x0008c1, 6351 },
+ { 0x0009f8, 6780 },
+ { 0x0008a6, 5964 },
+ { 0x0004de, 2820 },
+ { 0x0009e9, 6609 },
+ { 0x000077, 377 },
+ { 0x000078, 379 },
+ { 0x000079, 381 },
+ { 0x0000fd, 1257 },
+ { 0x0000ff, 1270 },
+ { 0x0000a5, 468 },
+ { 0x00007a, 383 },
+ { 0x0001bf, 1456 },
+ { 0x0001bc, 1430 },
+ { 0x0001be, 1449 }};
+
+
+#if 0
+
+N_("keyboard label|BackSpace")
+N_("keyboard label|Tab")
+N_("keyboard label|Return")
+N_("keyboard label|Pause")
+N_("keyboard label|Scroll_Lock")
+N_("keyboard label|Sys_Req")
+N_("keyboard label|Escape")
+N_("keyboard label|Multi_key")
+N_("keyboard label|Home")
+N_("keyboard label|Left")
+N_("keyboard label|Up")
+N_("keyboard label|Right")
+N_("keyboard label|Down")
+N_("keyboard label|Page_Up")
+N_("keyboard label|Page_Down")
+N_("keyboard label|End")
+N_("keyboard label|Begin")
+N_("keyboard label|Print")
+N_("keyboard label|Insert")
+N_("keyboard label|Num_Lock")
+N_("keyboard label|KP_Space")
+N_("keyboard label|KP_Tab")
+N_("keyboard label|KP_Enter")
+N_("keyboard label|KP_Home")
+N_("keyboard label|KP_Left")
+N_("keyboard label|KP_Up")
+N_("keyboard label|KP_Right")
+N_("keyboard label|KP_Down")
+N_("keyboard label|KP_Page_Up")
+N_("keyboard label|KP_Prior")
+N_("keyboard label|KP_Page_Down")
+N_("keyboard label|KP_Next")
+N_("keyboard label|KP_End")
+N_("keyboard label|KP_Begin")
+N_("keyboard label|KP_Insert")
+N_("keyboard label|KP_Delete")
+N_("keyboard label|Delete")
+
+#endif
diff --git a/src/test-attribute.c b/src/test-attribute.c
new file mode 100644
index 0000000..b2ab4e5
--- /dev/null
+++ b/src/test-attribute.c
@@ -0,0 +1,44 @@
+#include "ibus.h"
+#include "stdio.h"
+
+int main()
+{
+ g_type_init ();
+ IBusAttrList *list;
+ IBusMessage *message;
+ gboolean retval;
+ IBusError *error;
+
+ list = ibus_attr_list_new ();
+ ibus_attr_list_append (list, ibus_attribute_new (1, 1, 1, 2));
+ ibus_attr_list_append (list, ibus_attribute_new (2, 1, 1, 2));
+ ibus_attr_list_append (list, ibus_attribute_new (3, 1, 1, 2));
+ ibus_attr_list_append (list, ibus_attribute_new (3, 1, 1, 2));
+
+ message = ibus_message_new_signal ("/org/freedesktop/IBus",
+ "org.freedesktop.IBus",
+ "Test");
+
+ IBusSerializable *p = ibus_serializable_new ();
+ retval = ibus_message_append_args (message,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ G_TYPE_INVALID);
+ g_assert (retval);
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ IBUS_TYPE_SERIALIZABLE, &p,
+ G_TYPE_INVALID);
+ g_assert (retval);
+
+ return 0;
+
+}
diff --git a/src/test-bus.c b/src/test-bus.c
new file mode 100644
index 0000000..a7756fa
--- /dev/null
+++ b/src/test-bus.c
@@ -0,0 +1,22 @@
+#include "ibus.h"
+
+int main()
+{
+ g_type_init ();
+
+ GMainLoop *mainloop;
+ IBusBus *bus;
+ IBusInputContext *context;
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+ bus = ibus_bus_new ();
+ context = ibus_bus_create_input_context (bus, "test");
+ ibus_input_context_set_capabilities (context, 0);
+ ibus_input_context_destroy (context);
+ g_object_unref (context);
+ g_object_unref (bus);
+
+ g_main_loop_run (mainloop);
+
+ return 0;
+}
diff --git a/src/test-engine.c b/src/test-engine.c
new file mode 100644
index 0000000..bea99cf
--- /dev/null
+++ b/src/test-engine.c
@@ -0,0 +1,16 @@
+#include "ibus.h"
+
+int main()
+{
+ g_type_init ();
+
+ GMainLoop *mainloop;
+ IBusConnection *connection;
+ IBusService *service;
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+ connection = ibus_connection_open ("unix:path=/tmp/ibus-phuang/ibus--0.0");
+ service = IBUS_SERVICE (ibus_engine_new ("/a/Engine", connection));
+ g_main_loop_run (mainloop);
+ return 0;
+}
diff --git a/src/test-keynames.c b/src/test-keynames.c
new file mode 100644
index 0000000..629f4d3
--- /dev/null
+++ b/src/test-keynames.c
@@ -0,0 +1,8 @@
+#include "ibus.h"
+
+int main()
+{
+ g_assert_cmpstr (ibus_keyval_name (IBUS_Home), ==, "Home");
+ g_assert (ibus_keyval_from_name ("Home") == IBUS_Home);
+ return 0;
+}
diff --git a/src/test-lookuptable.c b/src/test-lookuptable.c
new file mode 100644
index 0000000..ec56811
--- /dev/null
+++ b/src/test-lookuptable.c
@@ -0,0 +1,39 @@
+#include "ibus.h"
+
+int main()
+{
+ g_type_init ();
+ IBusLookupTable *table, *table1;
+ IBusMessage *message;
+ IBusError *error;
+ gboolean retval;
+
+ table = ibus_lookup_table_new (9, TRUE);
+ ibus_lookup_table_append_candidate (table, ibus_text_new_from_static_string ("Hello"));
+ ibus_lookup_table_append_candidate (table, ibus_text_new_from_static_string ("Cool"));
+
+ message = ibus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
+
+ retval = ibus_message_append_args (message,
+ IBUS_TYPE_LOOKUP_TABLE, &table,
+ IBUS_TYPE_LOOKUP_TABLE, &table,
+ G_TYPE_INVALID);
+ g_assert (retval);
+
+ g_object_unref (table);
+ table = table1 = NULL;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_LOOKUP_TABLE, &table,
+ IBUS_TYPE_LOOKUP_TABLE, &table1,
+ G_TYPE_INVALID);
+ g_assert (retval);
+ g_assert (table);
+ g_assert (table1);
+
+ g_object_unref (table);
+ g_object_unref (table1);
+
+ return 0;
+}
diff --git a/src/test-proxy.c b/src/test-proxy.c
new file mode 100644
index 0000000..31866f1
--- /dev/null
+++ b/src/test-proxy.c
@@ -0,0 +1,18 @@
+#include "ibus.h"
+
+int main()
+{
+ g_type_init ();
+
+ IBusConnection *connection;
+ IBusProxy *proxy;
+
+ connection = ibus_connection_new ();
+ proxy = ibus_proxy_new ("a", "/a", connection);
+ GValue value = {0};
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value, "aaa");
+ g_object_set_property (G_OBJECT (proxy), "name", &value);
+
+ return 0;
+}
diff --git a/src/test-server.c b/src/test-server.c
new file mode 100644
index 0000000..4e37085
--- /dev/null
+++ b/src/test-server.c
@@ -0,0 +1,30 @@
+#include "ibus.h"
+
+
+void connection_destroy_cb (IBusConnection *connection, gpointer user_data)
+{
+ g_debug ("connnection %p destroyed", connection );
+}
+
+void new_connection_cb (IBusServer *server, IBusConnection *connection, gpointer user_data)
+{
+ g_debug ("new-connection %p", connection);
+ g_signal_connect (connection, "destroy", (GCallback) connection_destroy_cb, 0);
+}
+
+int main()
+{
+ g_type_init ();
+
+ GMainLoop *mainloop;
+ IBusServer *server;
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+ server = ibus_server_new ();
+ ibus_server_listen (server, "unix:abstract=/tmp/1234567");
+ g_signal_connect (server, "new-connection", (GCallback) new_connection_cb, 0);
+
+ g_main_loop_run (mainloop);
+
+ return 0;
+}
diff --git a/src/test-text.c b/src/test-text.c
new file mode 100644
index 0000000..37bc3a6
--- /dev/null
+++ b/src/test-text.c
@@ -0,0 +1,42 @@
+#include "ibus.h"
+
+int main()
+{
+ g_type_init ();
+
+ IBusText *text1;
+ IBusText *text2;
+ IBusMessage *message;
+ IBusError *error;
+ gboolean retval;
+
+ text1 = ibus_text_new_from_string ("Hello");
+ text2 = ibus_text_new_from_static_string ("Hello");
+
+ message = ibus_message_new_signal ("/org/freedesktop/IBus",
+ "org.freedesktop.IBus",
+ "Test");
+
+ retval = ibus_message_append_args (message,
+ IBUS_TYPE_SERIALIZABLE, &text1,
+ IBUS_TYPE_SERIALIZABLE, &text2,
+ G_TYPE_INVALID);
+ g_assert (retval);
+ g_object_unref (text1);
+ g_object_unref (text2);
+
+ retval = ibus_message_get_args (message,
+ &error,
+ IBUS_TYPE_SERIALIZABLE, &text1,
+ IBUS_TYPE_SERIALIZABLE, &text2,
+ G_TYPE_INVALID);
+ g_assert (retval);
+ g_assert_cmpstr (text1->text, ==, "Hello");
+ g_assert_cmpstr (text2->text, ==, "Hello");
+
+ g_object_unref (text1);
+ g_object_unref (text2);
+
+ return 0;
+
+}
diff --git a/ui/gtk/.gitignore b/ui/gtk/.gitignore
index 17bbd09..abac3c8 100644
--- a/ui/gtk/.gitignore
+++ b/ui/gtk/.gitignore
@@ -1 +1,2 @@
ibus-ui-gtk
+gtkpanel.xml
diff --git a/ui/gtk/Makefile.am b/ui/gtk/Makefile.am
index 18f773e..e80cf96 100644
--- a/ui/gtk/Makefile.am
+++ b/ui/gtk/Makefile.am
@@ -31,10 +31,16 @@ ui_gtk_PYTHON = \
propitem.py \
toolitem.py \
$(NULL)
-
ui_gtkdir = $(pkgdatadir)/ui/gtk
-bin_SCRIPTS = ibus-ui-gtk
+libexec_SCRIPTS = \
+ ibus-ui-gtk \
+ $(NULL)
+
+component_DATA = \
+ gtkpanel.xml \
+ $(NULL)
+componentdir = $(pkgdatadir)/component
CLEANFILES = \
*.pyc \
@@ -42,9 +48,11 @@ CLEANFILES = \
EXTRA_DIST = \
ibus-ui-gtk.in \
+ gtkpanel.xml.in \
$(NULL)
test:
$(ENV) DBUS_DEBUG=true \
+ IBUS_PREFIX=@prefix@ \
PYTHONPATH=$(top_srcdir) \
$(PYTHON) $(srcdir)/main.py
diff --git a/ui/gtk/candidatepanel.py b/ui/gtk/candidatepanel.py
index 528c7e7..db02163 100644
--- a/ui/gtk/candidatepanel.py
+++ b/ui/gtk/candidatepanel.py
@@ -24,7 +24,7 @@ import gtk.gdk as gdk
import gobject
import pango
import ibus
-from ibus.gtk import PangoAttrList
+from ibus._gtk import PangoAttrList
class Label(gtk.Label): pass
gobject.type_register(Label, "IBusPanelLabel")
@@ -260,58 +260,53 @@ class CandidatePanel(gtk.VBox):
# self.hide_all()
# self.show_all()
- def show_preedit(self):
+ def show_preedit_text(self):
self.__preedit_visible = True
self.__preedit_label.show()
self.__check_show_states()
- def hide_preedit(self):
+ def hide_preedit_text(self):
self.__preedit_visible = False
self.__preedit_label.hide()
self.__check_show_states()
- def update_preedit(self, text, attrs, cursor_pos, visible):
- if attrs:
- attrs = PangoAttrList(attrs, text)
+ def update_preedit_text(self, text, cursor_pos, visible):
+ attrs = PangoAttrList(text.attributes, text.text)
if visible:
- self.show_preedit()
+ self.show_preedit_text()
else:
- self.hide_preedit()
- self.__preedit_string = text
- self.__preedit_label.set_text(text)
- if attrs == None:
- attrs = pango.AttrList()
+ self.hide_preedit_text()
+ self.__preedit_stribg = text.text
+ self.__preedit_label.set_text(text.text)
self.__preedit_attrs = attrs
self.__preedit_label.set_attributes(attrs)
- def show_aux_string(self):
+ def show_auxiliary_text(self):
self.__aux_string_visible = True
self.__aux_label.show()
self.__check_show_states()
- def hide_aux_string(self):
+ def hide_auxiliary_text(self):
self.__aux_string_visible = False
self.__aux_label.hide()
self.__check_show_states()
- def update_aux_string(self, text, attrs, show):
- attrs = PangoAttrList(attrs, text)
+ def update_auxiliary_text(self, text, show):
+ attrs = PangoAttrList(text.attributes, text.text)
if show:
- self.show_aux_string()
+ self.show_auxiliary_text()
else:
- self.hide_aux_string()
+ self.hide_auxiliary_text()
- self.__aux_string = text
- self.__aux_label.set_text(text)
- if attrs == None:
- attrs = pango.AttrList()
+ self.__aux_string = text.text
+ self.__aux_label.set_text(text.text)
self.__aux_attrs = attrs
self.__aux_label.set_attributes(attrs)
def __refresh_candidates(self):
- candidates = self.__lookup_table.get_canidates_in_current_page()
- candidates = map(lambda x: (x[0], PangoAttrList(x[1], x[0]) if x[1] else None), candidates)
+ candidates = self.__lookup_table.get_candidates_in_current_page()
+ candidates = map(lambda x: (x.text, PangoAttrList(x.attributes, x.text)), candidates)
self.__candidate_area.set_candidates(candidates,
self.__lookup_table.get_cursor_pos_in_current_page(),
self.__lookup_table.is_cursor_visible()
@@ -372,8 +367,8 @@ class CandidatePanel(gtk.VBox):
self.emit("hide")
def reset(self):
- self.update_preedit("", None, 0, False)
- self.update_aux_string("", None, False)
+ self.update_preedit_text(ibus.Text(""), 0, False)
+ self.update_auxiliary_text(ibus.Text(""), False)
self.update_lookup_table(None, False)
self.hide()
diff --git a/ui/gtk/gtkpanel.xml.in b/ui/gtk/gtkpanel.xml.in
new file mode 100644
index 0000000..961dc5a
--- /dev/null
+++ b/ui/gtk/gtkpanel.xml.in
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- filename: pinyin.xml -->
+<component>
+ <name>org.freedesktop.IBus.Panel</name>
+ <description>Gtk Panel Component</description>
+ <exec>@prefix@/libexec/ibus-ui-gtk</exec>
+ <version>@VERSION@</version>
+ <author>Peng Huang &lt;shawn.p.huang@gmail.com&gt;</author>
+ <license>GPL</license>
+ <homepage>http://code.google.com/p/ibus</homepage>
+ <textdomain>ibus</textdomain>
+</component>
diff --git a/ui/gtk/icon.py b/ui/gtk/icon.py
index 4a373a9..077848d 100644
--- a/ui/gtk/icon.py
+++ b/ui/gtk/icon.py
@@ -33,9 +33,6 @@ class IconWidget(gtk.Image):
theme = gtk.icon_theme_get_default()
pixbuf = theme.load_icon(icon, size, 0)
except:
- pass
-
- if pixbuf == None:
theme = gtk.icon_theme_get_default()
pixbuf = theme.load_icon(gtk.STOCK_MISSING_IMAGE, size, 0)
diff --git a/ui/gtk/languagebar.py b/ui/gtk/languagebar.py
index 65eb2e5..7a8a106 100644
--- a/ui/gtk/languagebar.py
+++ b/ui/gtk/languagebar.py
@@ -78,7 +78,7 @@ class LanguageBar(gtk.Toolbar):
self.insert(self.__handle, -1)
# create input methods menu
- prop = ibus.Property(name = "", type = ibus.PROP_TYPE_TOGGLE, icon = "ibus", tooltip = _("Switch engine"))
+ prop = ibus.Property(key = "", type = ibus.PROP_TYPE_TOGGLE, icon = "ibus", tooltip = _("Switch engine"))
self.__im_menu = ToggleToolButton(prop)
self.__im_menu.set_homogeneous(False)
self.__im_menu.connect("toggled", self.__im_menu_toggled_cb)
@@ -192,6 +192,8 @@ class LanguageBar(gtk.Toolbar):
self.__im_menu.set_sensitive(False)
if self.__auto_hide:
self.hide_all()
+ else:
+ self.show_all()
gobject.type_register(LanguageBar, "IBusLanguageBar")
diff --git a/ui/gtk/main.py b/ui/gtk/main.py
index 489f96a..f9f9ff6 100644
--- a/ui/gtk/main.py
+++ b/ui/gtk/main.py
@@ -31,19 +31,16 @@ import notifications
class UIApplication:
def __init__ (self):
self.__bus = ibus.Bus()
- self.__bus.connect("destroy", self.__bus_destroy_cb)
+ self.__bus.connect("disconnected", gtk.main_quit)
self.__panel = panel.Panel(self.__bus)
- self.__notify = notifications.Notifications(self.__bus)
- self.__notify.set_status_icon(self.__panel.get_status_icon())
+ self.__bus.request_name(ibus.IBUS_SERVICE_PANEL, 0)
+ # self.__notify = notifications.Notifications(self.__bus)
+ # self.__notify.set_status_icon(self.__panel.get_status_icon())
def run(self):
gtk.main()
- def __bus_destroy_cb(self, _ibus):
- gtk.main_quit()
-
-
def launch_panel():
# gtk.settings_get_default().props.gtk_theme_name = "/home/phuang/.themes/aud-Default/gtk-2.0/gtkrc"
# gtk.rc_parse("./themes/default/gtkrc")
diff --git a/ui/gtk/menu.py b/ui/gtk/menu.py
index 19911e8..9a3b30a 100644
--- a/ui/gtk/menu.py
+++ b/ui/gtk/menu.py
@@ -107,7 +107,7 @@ class ImageMenuItem (gtk.ImageMenuItem, PropItem):
self.hide_all ()
def do_activate (self):
- self.emit ("property-activate", self._prop.name, self._prop.state)
+ self.emit ("property-activate", self._prop.key, self._prop.state)
def property_changed (self):
self.set_sensitive (self._prop.sensitive)
@@ -145,7 +145,7 @@ class CheckMenuItem (gtk.CheckMenuItem, PropItem):
self._prop.state = ibus.PROP_STATE_CHECKED
else:
self._prop.state = ibus.PROP_STATE_UNCHECKED
- self.emit ("property-activate", self._prop.name, self._prop.state)
+ self.emit ("property-activate", self._prop.key, self._prop.state)
def property_changed (self):
self.set_active (self._prop.state == ibus.PROP_STATE_CHECKED)
@@ -167,7 +167,7 @@ class RadioMenuItem (gtk.RadioMenuItem, PropItem):
}
def __init__ (self, group, prop):
- gtk.RadioMenuItem.__init__ (self, group, label = prop.label)
+ gtk.RadioMenuItem.__init__ (self, group, label = prop.label.text)
PropItem.__init__ (self, prop)
self.set_active (self._prop.state == ibus.PROP_STATE_CHECKED)
@@ -194,7 +194,7 @@ class RadioMenuItem (gtk.RadioMenuItem, PropItem):
self._prop.state = ibus.PROP_STATE_CHECKED
else:
self._prop.state = ibus.PROP_STATE_UNCHECKED
- self.emit ("property-activate", self._prop.name, self._prop.state)
+ self.emit ("property-activate", self._prop.key, self._prop.state)
class SeparatorMenuItem (gtk.SeparatorMenuItem, PropItem):
__gsignals__ = {
diff --git a/ui/gtk/notifications.py b/ui/gtk/notifications.py
index cebedf5..1e990f3 100644
--- a/ui/gtk/notifications.py
+++ b/ui/gtk/notifications.py
@@ -34,17 +34,13 @@ from gettext import dgettext
_ = lambda a : dgettext("ibus", a)
N_ = lambda a : a
-BUS_NOTIFICATIONS_NAME = "org.freedesktop.Notifications"
-BUS_NOTIFICATIONS_PATH = "/org/freedesktop/Notifications"
-BUS_NOTIFICATIONS_IFACE = "org.freedesktop.Notifications"
-
class Notifications(ibus.NotificationsBase):
def __init__ (self, bus):
super(Notifications, self).__init__(bus)
self.__bus = bus
try:
self.__dbus = dbus.SessionBus()
- self.__dbus.watch_name_owner(BUS_NOTIFICATIONS_NAME,
+ self.__dbus.watch_name_owner(ibus.IBUS_SERVICE_NOTIFICATIONS,
self.__notifications_name_owner_changed_cb)
except:
self.__dbus = None
@@ -52,7 +48,7 @@ class Notifications(ibus.NotificationsBase):
self.__ids = set([])
self.__init_notifications()
self.__status_icons = None
- self.__bus.request_name(ibus.IBUS_NOTIFICATIONS_NAME, 0)
+ self.__bus.request_name(ibus.IBUS_SERVICE_NOTIFICATIONS, 0)
def __notifications_name_owner_changed_cb(self, unique_name):
if unique_name:
@@ -66,13 +62,13 @@ class Notifications(ibus.NotificationsBase):
try:
self.__notifications = self.__dbus.get_object(
- BUS_NOTIFICATIONS_NAME, BUS_NOTIFICATIONS_PATH)
+ ibus.IBUS_SERVICE_NOTIFICATIONS, ibus.IBUS_PATH_NOTIFICATIONS)
self.__notifications.connect_to_signal("NotificationClosed",
self.__notification_closed_cb,
- dbus_interface=BUS_NOTIFICATIONS_IFACE)
+ dbus_interface=ibus.IBUS_IFACE_NOTIFICATIONS)
self.__notifications.connect_to_signal("ActionInvoked",
self.__action_invoked_cb,
- dbus_interface=BUS_NOTIFICATIONS_IFACE)
+ dbus_interface=ibus.IBUS_IFACE_NOTIFICATIONS)
self.__ids = set([])
except:
self.__notifications = None
diff --git a/ui/gtk/panel.py b/ui/gtk/panel.py
index 1456cc4..284dbb6 100644
--- a/ui/gtk/panel.py
+++ b/ui/gtk/panel.py
@@ -55,6 +55,7 @@ class Panel(ibus.PanelBase):
def __init__ (self, bus):
super(Panel, self).__init__(bus)
self.__bus = bus
+ self.__config = self.__bus.get_config()
self.__focus_ic = None
self.__setup_pid = 0
self.__prefix = os.getenv("IBUS_PREFIX")
@@ -67,9 +68,9 @@ class Panel(ibus.PanelBase):
signal.signal(signal.SIGCHLD, self.__sigchld_cb)
# connect bus signal
- self.__bus.connect("config-value-changed", self.__config_value_changed_cb)
- self.__bus.connect("config-reloaded", self.__config_reloaded_cb)
- self.__bus.config_add_watch("panel")
+ self.__config.connect("value-changed", self.__config_value_changed_cb)
+ self.__config.connect("reloaded", self.__config_reloaded_cb)
+ # self.__bus.config_add_watch("panel")
# add icon search path
icon_theme = gtk.icon_theme_get_default()
@@ -101,28 +102,28 @@ class Panel(ibus.PanelBase):
self.__config_load_lookup_table_orientation()
self.__config_load_auto_hide()
self.__config_load_custom_font()
- self.__bus.request_name(ibus.panel.IBUS_PANEL_NAME, 0)
+ # self.__bus.request_name(ibus.panel.IBUS_SERVICE_PANEL, 0)
def set_cursor_location(self, x, y, w, h):
self.__candidate_panel.set_cursor_location(x + w, y + h)
- def update_preedit(self, text, attrs, cursor_pos, visible):
- self.__candidate_panel.update_preedit(text, attrs, cursor_pos, visible)
+ def update_preedit_text(self, text, cursor_pos, visible):
+ self.__candidate_panel.update_preedit_text(text, cursor_pos, visible)
- def show_preedit(self):
- self.__candidate_panel.show_preedit()
+ def show_preedit_text(self):
+ self.__candidate_panel.show_preedit_text()
- def hide_preedit(self):
- self.__candidate_panel.hide_preedit()
+ def hide_preedit_text(self):
+ self.__candidate_panel.hide_preedit_text()
- def update_aux_string(self, text, attrs, visible):
- self.__candidate_panel.update_aux_string(text, attrs, visible)
+ def update_auxiliary_text(self, text, visible):
+ self.__candidate_panel.update_auxiliary_text(text, visible)
- def show_aux_string(self):
- self.__candidate_panel.show_aux_string()
+ def show_auxiliary_text(self):
+ self.__candidate_panel.show_auxiliary_text()
- def hide_aux_string(self):
- self.__candidate_panel.hide_aux_string()
+ def hide_auxiliary_text(self):
+ self.__candidate_panel.hide_auxiliary_text()
def update_lookup_table(self, lookup_table, visible):
self.__candidate_panel.update_lookup_table(lookup_table, visible)
@@ -175,35 +176,43 @@ class Panel(ibus.PanelBase):
def focus_in(self, ic):
self.reset()
- self.__focus_ic = ic
-
- factory, enabled = self.__bus.get_input_context_states(ic)
+ self.__focus_ic = ibus.InputContext(self.__bus, ic)
+ enabled = self.__focus_ic.is_enabled()
self.__language_bar.set_enabled(enabled)
- if factory == "" or not enabled:
+ if not enabled:
self.__set_im_icon(self.__ibus_icon)
else:
- name, lang, icon, authors, credits = self.__bus.get_factory_info(factory)
- self.__set_im_icon(icon)
+ engine = self.__focus_ic.get_engine()
+ if engine:
+ self.__set_im_icon(engine.icon)
+ else:
+ self.__set_im_icon(self.__ibus_icon)
self.__language_bar.focus_in()
def focus_out(self, ic):
self.reset()
- if self.__focus_ic == ic:
- self.__focus_ic = None
- self.__language_bar.focus_out()
- self.__set_im_icon(self.__ibus_icon)
+ self.__focus_ic = None
+ self.__language_bar.focus_out()
+ self.__set_im_icon(self.__ibus_icon)
- def states_changed(self):
+ def state_changed(self):
if not self.__focus_ic:
return
- factory, enabled = self.__bus.get_input_context_states(self.__focus_ic)
+
+ enabled = self.__focus_ic.is_enabled()
self.__language_bar.set_enabled(enabled)
- if enabled == False or not factory:
+
+ if enabled == False:
+ self.reset()
self.__set_im_icon(self.__ibus_icon)
else:
- name, lang, icon, authors, credits = self.__bus.get_factory_info(factory)
- self.__set_im_icon(icon)
+ engine = self.__focus_ic.get_engine()
+ if engine:
+ self.__set_im_icon(engine.icon)
+ else:
+ self.__set_im_icon(self.__ibus_icon)
+
def reset(self):
self.__candidate_panel.reset()
@@ -216,7 +225,7 @@ class Panel(ibus.PanelBase):
gtk.main_quit()
def __config_load_lookup_table_orientation(self):
- value = self.__bus.config_get_value("panel", "lookup_table_orientation", 0)
+ value = self.__config.get_value("panel", "lookup_table_orientation", 0)
if value != 0 and value != 1:
value = 0
if value == 0:
@@ -225,14 +234,14 @@ class Panel(ibus.PanelBase):
self.__candidate_panel.set_orientation(gtk.ORIENTATION_VERTICAL)
def __config_load_auto_hide(self):
- auto_hide = self.__bus.config_get_value("panel", "auto_hide", False)
+ auto_hide = self.__config.get_value("panel", "auto_hide", False)
self.__language_bar.set_auto_hide(auto_hide)
def __config_load_custom_font(self):
- use_custom_font = self.__bus.config_get_value("panel", "use_custom_font", False)
+ use_custom_font = self.__config.get_value("panel", "use_custom_font", False)
font_name = gtk.settings_get_default().get_property("gtk-font-name")
font_name = unicode(font_name, "utf-8")
- custom_font = self.__bus.config_get_value("panel", "custom_font", font_name)
+ custom_font = self.__config.get_value("panel", "custom_font", font_name)
style_string = 'style "custom-font" { font_name="%s" }\n' \
'class "IBusPanelLabel" style "custom-font"\n'
if use_custom_font:
@@ -246,6 +255,8 @@ class Panel(ibus.PanelBase):
gtk.rc_reset_styles(settings)
def __config_value_changed_cb(self, bus, section, name, value):
+ if section != "panel":
+ return
if name == "lookup_table_orientation":
self.__config_load_lookup_table_orientation()
elif name == "auto_hide":
@@ -278,45 +289,44 @@ class Panel(ibus.PanelBase):
def __create_im_menu(self):
menu = gtk.Menu()
- factories = self.__bus.get_factories()
+ engines = self.__bus.list_active_engines()
- if not factories:
+ if not engines:
item = gtk.MenuItem(label = "no engine")
item.set_sensitive(False)
menu.add(item)
else:
tmp = {}
- for factory in factories:
- name, lang, icon, authors, credits = self.__bus.get_factory_info(factory)
- lang = ibus.get_language_name(lang)
- if not icon:
- icon = "engine-default"
+ for engine in engines:
+ lang = ibus.get_language_name(engine.language)
if lang not in tmp:
tmp[lang] = []
- tmp[lang].append((name, lang, icon, authors, credits, factory))
+ tmp[lang].append(engine)
+
langs = tmp.keys()
other = tmp.get(_("Other"), [])
if _("Other") in tmp:
langs.remove(_("Other"))
langs.append(_("Other"))
+
for lang in langs:
if len(tmp[lang]) == 1:
- name, lang, icon, authors, credits, factory = tmp[lang][0]
- item = gtk.ImageMenuItem("%s - %s" % (lang, name))
+ engine = tmp[lang][0]
+ item = gtk.ImageMenuItem("%s - %s" % (lang, engine.longname))
size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
- item.set_image (_icon.IconWidget(icon, size[0]))
- item.connect("activate", self.__im_menu_item_activate_cb, factory)
+ item.set_image (_icon.IconWidget(engine.icon, size[0]))
+ item.connect("activate", self.__im_menu_item_activate_cb, engine)
menu.add(item)
else:
item = gtk.MenuItem(lang)
menu.add(item)
submenu = gtk.Menu()
item.set_submenu(submenu)
- for name, __lang, icon, authors, credits, factory in tmp[lang]:
- item = gtk.ImageMenuItem(name)
+ for engine in tmp[lang]:
+ item = gtk.ImageMenuItem(engine.longname)
size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
- item.set_image (_icon.IconWidget(icon, size[0]))
- item.connect("activate", self.__im_menu_item_activate_cb, factory)
+ item.set_image (_icon.IconWidget(engine.icon, size[0]))
+ item.connect("activate", self.__im_menu_item_activate_cb, engine)
submenu.add(item)
menu.show_all()
@@ -345,8 +355,8 @@ class Panel(ibus.PanelBase):
gtk.get_current_event_time(),
self.__status_icon)
- def __im_menu_item_activate_cb(self, item, factory):
- self.__bus.set_factory(factory)
+ def __im_menu_item_activate_cb(self, item, engine):
+ self.__focus_ic.set_engine(engine)
def __sys_menu_item_activate_cb(self, item, command):
if command == gtk.STOCK_PREFERENCES:
diff --git a/ui/gtk/propitem.py b/ui/gtk/propitem.py
index 3d363ed..bb66174 100644
--- a/ui/gtk/propitem.py
+++ b/ui/gtk/propitem.py
@@ -30,7 +30,7 @@ class PropItem:
retval = False
- if self._prop.name == prop.name and self._prop.type == prop.type:
+ if self._prop.key == prop.key and self._prop.type == prop.type:
self._prop = prop
self.property_changed ()
retval = True
diff --git a/ui/gtk/toolitem.py b/ui/gtk/toolitem.py
index 48147a7..0e4e4ad 100644
--- a/ui/gtk/toolitem.py
+++ b/ui/gtk/toolitem.py
@@ -36,7 +36,7 @@ class ToolButton(gtk.ToolButton, PropItem):
}
def __init__(self, prop):
- gtk.ToolButton.__init__ (self, label = prop.label)
+ gtk.ToolButton.__init__ (self, label = prop.label.text)
self.set_homogeneous(False)
PropItem.__init__ (self, prop)
self.property_changed()
@@ -58,14 +58,14 @@ class ToolButton(gtk.ToolButton, PropItem):
def set_tooltip_text(self, text):
if text:
- gtk.ToolButton.set_tooltip_text(self, text)
+ gtk.ToolButton.set_tooltip_text(self, text.text)
else:
gtk.ToolButton.set_tooltip_text(self, None)
self._prop.tooltip = text
def property_changed(self):
- self.set_label(self._prop.label)
+ self.set_label(self._prop.label.text)
self.set_tooltip_text(self._prop.tooltip)
self.set_sensitive(self._prop.sensitive)
self.set_icon_name(self._prop.icon)
@@ -78,7 +78,7 @@ class ToolButton(gtk.ToolButton, PropItem):
self.hide_all()
def do_clicked(self):
- self.emit("property-activate", self._prop.name, self._prop.state)
+ self.emit("property-activate", self._prop.key, self._prop.state)
class ToggleToolButton(gtk.ToggleToolButton, PropItem):
@@ -112,7 +112,7 @@ class ToggleToolButton(gtk.ToggleToolButton, PropItem):
def set_tooltip_text(self, text):
if text:
- gtk.ToggleToolButton.set_tooltip_text(self, text)
+ gtk.ToggleToolButton.set_tooltip_text(self, text.text)
else:
gtk.ToggleToolButton.set_tooltip_text(self, None)
@@ -120,7 +120,7 @@ class ToggleToolButton(gtk.ToggleToolButton, PropItem):
def property_changed(self):
self.set_tooltip_text(self._prop.tooltip)
- self.set_label(self._prop.label)
+ self.set_label(self._prop.label.text)
self.set_icon_name(self._prop.icon)
self.set_active(self._prop.state == ibus.PROP_STATE_CHECKED)
self.set_sensitive(self._prop.sensitive)
@@ -136,7 +136,7 @@ class ToggleToolButton(gtk.ToggleToolButton, PropItem):
self._prop.state = ibus.PROP_STATE_CHECKED
else:
self._prop.state = ibus.PROP_STATE_UNCHECKED
- self.emit("property-activate", self._prop.name, self._prop.state)
+ self.emit("property-activate", self._prop.key, self._prop.state)
class SeparatorToolItem(gtk.SeparatorToolItem, PropItem):
def __init__ (self, prop):
diff --git a/util/Makefile.am b/util/Makefile.am
index 0fcbd4e..de4882b 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -21,5 +21,4 @@
SUBDIRS = \
IMdkit \
- gconf \
$(NULL)
diff --git a/util/gconf/Makefile.am b/util/gconf/Makefile.am
deleted file mode 100644
index 2317229..0000000
--- a/util/gconf/Makefile.am
+++ /dev/null
@@ -1,51 +0,0 @@
-INCLUDES = $(PYTHON_INCLUDES) $(PYGTK_CFLAGS)
-
-defsdir = $(datadir)/pygtk/2.0/defs
-
-if IBUS_BUILD_PYGCONF
-# defs_DATA = gconf.defs
-endif
-
-common_ldflags = -module -avoid-version $(PYTHON_LDFLAGS)
-
-# pkgpythondir = $(pyexecdir)/gtk-2.0
-# pkgpyexecdir = $(pyexecdir)/gtk-2.0
-
-# gconf binding
-
-if IBUS_BUILD_PYGCONF
-pkgpyexec_LTLIBRARIES = gconf.la
-endif
-gconf_la_CFLAGS = $(GCONF_CFLAGS)
-gconf_la_LDFLAGS = $(common_ldflags) -export-symbols-regex initgconf
-gconf_la_LIBADD = $(PYGTK_LIBS) $(GCONF_LIBS) $(PYTHON_LIBS)
-gconf_la_SOURCES = \
- gconfmodule.c \
- gconf-fixes.c \
- gconf-fixes.h \
- gconf-types.c \
- gconf-types.h
-nodist_gconf_la_SOURCES = gconf.c
-CLEANFILES = gconf.c
-EXTRA_DIST = gconf.defs gconf.override gconf-arg-types.py
-gconf.c: gconf.defs gconf.override gconf-arg-types.py
-
-argtypesdir = $(datadir)/pygtk/2.0/argtypes
-
-if IBUS_BUILD_PYGCONF
-# argtypes_PYTHON = gconf-arg-types.py
-endif
-
-.defs.c:
- (cd $(srcdir) \
- && $(PYGTK_CODEGEN) \
- --py_ssize_t-clean \
- --load-types gconf-arg-types.py \
- --override $*.override \
- --prefix py$* $*.defs) > gen-$*.c \
- && cp gen-$*.c $*.c \
- && rm -f gen-$*.c
-
-
-EXTRA_DIST += wscript
-
diff --git a/util/gconf/gconf-arg-types.py b/util/gconf/gconf-arg-types.py
deleted file mode 100644
index 1610495..0000000
--- a/util/gconf/gconf-arg-types.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import argtypes
-
-class GConfEngineArg (argtypes.ArgType):
- engine = (' %(name)s = pygconf_engine_from_pyobject (py_%(name)s);\n'
- ' if (PyErr_Occurred ())\n'
- ' return NULL;\n')
-
- def write_param(self, ptype, pname, pdflt, pnull, info):
- # pdflt and pnull not handled - we don't use "default" or "null-ok"
- info.varlist.add ('GConfEngine*', pname)
- info.varlist.add ('PyObject', '*py_' + pname + ' = NULL')
- info.codebefore.append (self.engine % { 'name' : pname })
- info.arglist.append (pname)
- info.add_parselist ('O', ['&py_' + pname], [pname])
-
- def write_return (self, ptype, ownsreturn, info):
- if ptype[-1] == '*':
- ptype = ptype[:-1]
- info.varlist.add (ptype, '*ret')
- if ownsreturn:
- info.varlist.add ('PyObject', '*py_ret')
- info.codeafter.append (' py_ret = pygconf_engine_new (ret);\n'
- ' if (ret != NULL)\n'
- ' gconf_engine_unref (ret);\n'
- ' return py_ret;')
- else:
- info.codeafter.append (' /* pygconf_engine_new() handles NULL checking */\n' +
- ' return pygconf_engine_new (ret);')
-
-argtypes.matcher.register ("GConfEngine*", GConfEngineArg ())
diff --git a/util/gconf/gconf-fixes.c b/util/gconf/gconf-fixes.c
deleted file mode 100644
index dbef754..0000000
--- a/util/gconf/gconf-fixes.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* GConf-python
- * Copyright (C) 2002 Johan Dahlin
- *
- * This library 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.
- *
- * Author: Johan Dahlin <jdahlin@telia.com>
- */
-
-#include <gconf/gconf-client.h>
-#include <gconf/gconf-value.h>
-
-#include "gconf-fixes.h"
-
-GConfMetaInfo*
-gconf_meta_info_copy (const GConfMetaInfo *src)
-{
- GConfMetaInfo *info;
-
- info = gconf_meta_info_new ();
-
- info->schema = g_strdup (src->schema);
- info->mod_user = g_strdup (src->mod_user);
- info->mod_time = src->mod_time;
-
- return info;
-}
-
-#define BOILERPLATE_TYPE_BOXED(func,name) \
-GType \
-py##func##_get_type (void) \
-{ \
- static GType type = 0; \
- if (type == 0) { \
- type = g_boxed_type_register_static(name, \
- (GBoxedCopyFunc)func##_copy, \
- (GBoxedFreeFunc)func##_free); \
- } \
- return type; \
-}
-
-BOILERPLATE_TYPE_BOXED(gconf_value, "GConfValue")
-BOILERPLATE_TYPE_BOXED(gconf_entry, "GConfEntry")
-BOILERPLATE_TYPE_BOXED(gconf_schema, "GConfSchema")
-BOILERPLATE_TYPE_BOXED(gconf_meta_info, "GConfMetaInfo")
diff --git a/util/gconf/gconf-fixes.h b/util/gconf/gconf-fixes.h
deleted file mode 100644
index 50eb7ec..0000000
--- a/util/gconf/gconf-fixes.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <glib-object.h>
-#include <gconf/gconf-value.h>
-
-extern GConfEntry* gconf_entry_copy (const GConfEntry *src);
-
-GType pygconf_value_get_type (void);
-GType pygconf_entry_get_type (void);
-GType pygconf_schema_get_type (void);
-GType pygconf_meta_info_get_type (void);
-
-#define GCONF_TYPE_VALUE (pygconf_value_get_type ())
-#define GCONF_TYPE_ENTRY (pygconf_entry_get_type ())
-#define GCONF_TYPE_SCHEMA (pygconf_schema_get_type ())
-#define GCONF_TYPE_METAINFO (pygconf_meta_info_get_type ())
diff --git a/util/gconf/gconf-types.c b/util/gconf/gconf-types.c
deleted file mode 100644
index 9e0b1a9..0000000
--- a/util/gconf/gconf-types.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2005 Red Hat, Inc.
- *
- * gconf-types.c: wrappers for some specialised GConf types.
- *
- * 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.1 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 "gconf-types.h"
-#define NO_IMPORT_PYGOBJECT
-#include <pygobject.h>
-
-typedef struct {
- PyObject_HEAD
- GConfEngine *engine;
-} PyGConfEngine;
-extern PyTypeObject PyGConfEngine_Type;
-
-static void
-pygconf_engine_dealloc (PyGConfEngine *self)
-{
- pyg_begin_allow_threads;
- gconf_engine_unref (self->engine);
- pyg_end_allow_threads;
- PyObject_DEL (self);
-}
-
-
-static PyObject *
-pygconf_engine_associate_schema(PyGConfEngine *self, PyObject *args, PyObject *kwargs)
-{
- gchar *key, *schema_key;
- gboolean result;
- GError *err = NULL;
- char *kwlist[] = {"key", "schema_key", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "ss:gconf.Engine.associate_schema",
- kwlist, &key, &schema_key))
- return NULL;
-
- result = gconf_engine_associate_schema(self->engine, key, schema_key, &err);
-
- if (pyg_error_check(&err))
- return NULL;
-
- if (result) {
- Py_INCREF(Py_True);
- return Py_True;
- } else {
- Py_INCREF(Py_False);
- return Py_False;
- }
-}
-
-static PyMethodDef pygconf_engine_methods[] = {
- {"associate_schema", (PyCFunction)pygconf_engine_associate_schema,
- METH_KEYWORDS, NULL},
-
- {NULL, NULL, 0, NULL}
-};
-
-
-PyTypeObject PyGConfEngine_Type = {
- PyObject_HEAD_INIT (NULL)
- 0,
- "gconf.GConfEngine",
- sizeof (PyGConfEngine),
- 0,
- (destructor) pygconf_engine_dealloc,
- (printfunc) 0,
- (getattrfunc) 0,
- (setattrfunc) 0,
- (cmpfunc) 0,
- (reprfunc) 0,
- 0,
- 0,
- 0,
- (hashfunc) 0,
- (ternaryfunc) 0,
- (reprfunc) 0,
- (getattrofunc) 0,
- (setattrofunc) 0,
- 0,
- Py_TPFLAGS_DEFAULT,
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- pygconf_engine_methods, /* tp_methods */
-};
-
-PyObject *
-pygconf_engine_new (GConfEngine *engine)
-{
- PyGConfEngine *self;
-
- if (engine == NULL)
- {
- Py_INCREF (Py_None);
- return Py_None;
- }
-
- self = (PyGConfEngine *) PyObject_NEW (PyGConfEngine, &PyGConfEngine_Type);
- if (self == NULL)
- return NULL;
-
- pyg_begin_allow_threads;
- self->engine = engine;
- gconf_engine_ref (engine);
- pyg_end_allow_threads;
-
- return (PyObject *) self;
-}
-
-GConfEngine *
-pygconf_engine_from_pyobject (PyObject *object)
-{
- PyGConfEngine *self;
-
- if (object == NULL)
- return NULL;
-
- if (!PyObject_TypeCheck (object, &PyGConfEngine_Type))
- {
- PyErr_SetString (PyExc_TypeError, "unable to convert argument to GConfEngine*");
- return NULL;
- }
-
- self = (PyGConfEngine *) object;
-
- return self->engine;
-}
-
-void
-pygconf_register_engine_type (PyObject *moddict)
-{
- PyGConfEngine_Type.ob_type = &PyType_Type;
-
- PyType_Ready(&PyGConfEngine_Type);
-}
diff --git a/util/gconf/gconf-types.h b/util/gconf/gconf-types.h
deleted file mode 100644
index 210a417..0000000
--- a/util/gconf/gconf-types.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2005 Red Hat, Inc.
- *
- * gconf-types.h: wrappers for some specialised GConf types.
- *
- * 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.1 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
- *
- * Author:
- * Mark McLoughlin <mark@skynet.ie>
- */
-
-#ifndef __GCONF_TYPES_H__
-#define __GCONF_TYPES_H__
-
-#include <Python.h>
-#include <gconf/gconf.h>
-
-void pygconf_register_engine_type (PyObject *moddict);
-PyObject *pygconf_engine_new (GConfEngine *engine);
-GConfEngine *pygconf_engine_from_pyobject (PyObject *object);
-
-#endif /* __GCONF_TYPES_H__ */
diff --git a/util/gconf/gconf.defs b/util/gconf/gconf.defs
deleted file mode 100644
index 7cc0229..0000000
--- a/util/gconf/gconf.defs
+++ /dev/null
@@ -1,1978 +0,0 @@
-;; -*- scheme -*-
-
-(define-object Client
- (in-module "GConf")
- (parent "GObject")
- (c-name "GConfClient")
- (gtype-id "GCONF_TYPE_CLIENT")
-)
-
-(define-boxed Value
- (in-module "GConf")
- (c-name "GConfValue")
- (gtype-id "GCONF_TYPE_VALUE")
- (copy-func "gconf_value_copy")
- (release-func "gconf_value_free")
- (fields
- '("GConfValueType" "type")
- )
-)
-
-(define-boxed Entry
- (in-module "GConf")
- (c-name "GConfEntry")
- (gtype-id "GCONF_TYPE_ENTRY")
- (copy-func "gconf_entry_copy")
- (release-func "gconf_entry_free")
- (fields
- '("gchar*" "key")
- '("GConfValue*" "value")
- )
-)
-
-(define-boxed Schema
- (in-module "GConf")
- (c-name "GConfSchema")
- (gtype-id "GCONF_TYPE_SCHEMA")
- (copy-func "gconf_schema_copy")
- (release-func "gconf_schema_free")
-)
-
-(define-boxed MetaInfo
- (in-module "GConf")
- (c-name "GConfMetaInfo")
- (gtype-id "GCONF_TYPE_METAINFO")
- (copy-func "gconf_metainfo_copy")
- (release-func "gconf_metainfo_free")
-)
-
-(define-boxed ChangeSet
- (in-module "GConf")
- (c-name "GConfChangeSet")
- (gtype-id "GCONF_TYPE_CHANGE_SET")
-)
-
-(define-enum ClientPreloadType
- (in-module "GConf")
- (c-name "GConfClientPreloadType")
- (gtype-id "GCONF_TYPE_CLIENT_PRELOAD_TYPE")
- (values
- '("none" "GCONF_CLIENT_PRELOAD_NONE")
- '("onelevel" "GCONF_CLIENT_PRELOAD_ONELEVEL")
- '("recursive" "GCONF_CLIENT_PRELOAD_RECURSIVE")
- )
-)
-
-(define-enum ClientErrorHandlingMode
- (in-module "GConf")
- (c-name "GConfClientErrorHandlingMode")
- (gtype-id "GCONF_TYPE_CLIENT_ERROR_HANDLING_MODE")
- (values
- '("none" "GCONF_CLIENT_HANDLE_NONE")
- '("unreturned" "GCONF_CLIENT_HANDLE_UNRETURNED")
- '("all" "GCONF_CLIENT_HANDLE_ALL")
- )
-)
-
-(define-enum Error
- (in-module "GConf")
- (c-name "GConfError")
- (gtype-id "GCONF_TYPE_ERROR")
- (values
- '("success" "GCONF_ERROR_SUCCESS")
- '("failed" "GCONF_ERROR_FAILED")
- '("no-server" "GCONF_ERROR_NO_SERVER")
- '("no-permission" "GCONF_ERROR_NO_PERMISSION")
- '("bad-address" "GCONF_ERROR_BAD_ADDRESS")
- '("bad-key" "GCONF_ERROR_BAD_KEY")
- '("parse-error" "GCONF_ERROR_PARSE_ERROR")
- '("corrupt" "GCONF_ERROR_CORRUPT")
- '("type-mismatch" "GCONF_ERROR_TYPE_MISMATCH")
- '("is-dir" "GCONF_ERROR_IS_DIR")
- '("is-key" "GCONF_ERROR_IS_KEY")
- '("overridden" "GCONF_ERROR_OVERRIDDEN")
- '("oaf-error" "GCONF_ERROR_OAF_ERROR")
- '("local-engine" "GCONF_ERROR_LOCAL_ENGINE")
- '("lock-failed" "GCONF_ERROR_LOCK_FAILED")
- '("no-writable-database" "GCONF_ERROR_NO_WRITABLE_DATABASE")
- '("in-shutdown" "GCONF_ERROR_IN_SHUTDOWN")
- )
-)
-
-(define-enum ValueType
- (in-module "GConf")
- (c-name "GConfValueType")
- (gtype-id "GCONF_TYPE_VALUE_TYPE")
- (values
- '("invalid" "GCONF_VALUE_INVALID")
- '("string" "GCONF_VALUE_STRING")
- '("int" "GCONF_VALUE_INT")
- '("float" "GCONF_VALUE_FLOAT")
- '("bool" "GCONF_VALUE_BOOL")
- '("schema" "GCONF_VALUE_SCHEMA")
- '("list" "GCONF_VALUE_LIST")
- '("pair" "GCONF_VALUE_PAIR")
- )
-)
-
-(define-flags UnsetFlags
- (in-module "GConf")
- (c-name "GConfUnsetFlags")
- (gtype-id "GCONF_TYPE_UNSET_FLAGS")
-)
-
-(define-method commit_change_set
- (of-object "GConfEngine")
- (c-name "gconf_engine_commit_change_set")
- (return-type "gboolean")
- (parameters
- '("GConfChangeSet*" "cs")
- '("gboolean" "remove_committed")
- '("GError**" "err")
- )
-)
-
-(define-method reverse_change_set
- (of-object "GConfEngine")
- (c-name "gconf_engine_reverse_change_set")
- (return-type "GConfChangeSet*")
- (parameters
- '("GConfChangeSet*" "cs")
- '("GError**" "err")
- )
-)
-
-(define-method change_set_from_currentv
- (of-object "GConfEngine")
- (c-name "gconf_engine_change_set_from_currentv")
- (return-type "GConfChangeSet*")
- (parameters
- '("const-gchar**" "keys")
- '("GError**" "err")
- )
-)
-
-(define-method change_set_from_current
- (of-object "GConfEngine")
- (c-name "gconf_engine_change_set_from_current")
- (return-type "GConfChangeSet*")
- (parameters
- '("GError**" "err")
- '("const-gchar*" "first_key")
- )
- (varargs #t)
-)
-
-(define-function change_set_get_type
- (c-name "gconf_change_set_get_type")
- (return-type "GType")
-)
-
-(define-function change_set_new
- (is-constructor-of "GConfChangeSet")
- (c-name "gconf_change_set_new")
- (caller-owns-return #t)
- (return-type "GConfChangeSet*")
-)
-
-(define-method ref
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_ref")
- (return-type "none")
-)
-
-(define-method unref
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_unref")
- (return-type "none")
-)
-
-(define-method clear
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_clear")
- (return-type "none")
-)
-
-(define-method size
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_size")
- (return-type "guint")
-)
-
-(define-method remove
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_remove")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- )
-)
-
-(define-method foreach
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_foreach")
- (return-type "none")
- (parameters
- '("GConfChangeSetForeachFunc" "func")
- '("gpointer" "user_data")
- )
-)
-
-(define-method check_value
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_check_value")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GConfValue**" "value_retloc")
- )
-)
-
-(define-method set
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("GConfValue*" "value")
- )
-)
-
-(define-method set_nocopy
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_nocopy")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("GConfValue*" "value")
- )
-)
-
-(define-method unset
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_unset")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- )
-)
-
-(define-method set_float
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_float")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("gdouble" "val")
- )
-)
-
-(define-method set_int
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_int")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("gint" "val")
- )
-)
-
-(define-method set_string
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_string")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("const-gchar*" "val")
- )
-)
-
-(define-method set_bool
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_bool")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("gboolean" "val")
- )
-)
-
-(define-method set_schema
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_schema")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("GConfSchema*" "val")
- )
-)
-
-(define-method set_list
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_list")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "list_type")
- '("GSList*" "list")
- )
-)
-
-(define-method set_pair
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_pair")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "car_type")
- '("GConfValueType" "cdr_type")
- '("gconstpointer" "address_of_car")
- '("gconstpointer" "address_of_cdr")
- )
-)
-
-(define-method set_user_data
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_set_user_data")
- (return-type "none")
- (parameters
- '("gpointer" "data")
- '("GDestroyNotify" "dnotify")
- )
-)
-
-(define-method get_user_data
- (of-object "GConfChangeSet")
- (c-name "gconf_change_set_get_user_data")
- (return-type "gpointer")
-)
-
-(define-function client_get_type
- (c-name "gconf_client_get_type")
- (return-type "GType")
-)
-
-(define-function client_get_default
- (c-name "gconf_client_get_default")
- (caller-owns-return #t)
- (return-type "GConfClient*")
-)
-
-(define-function client_get_for_engine
- (c-name "gconf_client_get_for_engine")
- (caller-owns-return #t)
- (return-type "GConfClient*")
- (parameters
- '("GConfEngine*" "engine")
- )
-)
-
-(define-method add_dir
- (of-object "GConfClient")
- (c-name "gconf_client_add_dir")
- (return-type "none")
- (parameters
- '("const-gchar*" "dir")
- '("GConfClientPreloadType" "preload")
- '("GError**" "err")
- )
-)
-
-(define-method remove_dir
- (of-object "GConfClient")
- (c-name "gconf_client_remove_dir")
- (return-type "none")
- (parameters
- '("const-gchar*" "dir")
- '("GError**" "err")
- )
-)
-
-(define-method notify_add
- (of-object "GConfClient")
- (c-name "gconf_client_notify_add")
- (return-type "guint")
- (parameters
- '("const-gchar*" "namespace_section")
- '("GConfClientNotifyFunc" "func")
- '("gpointer" "user_data")
- '("GFreeFunc" "destroy_notify")
- '("GError**" "err")
- )
-)
-
-(define-method notify_remove
- (of-object "GConfClient")
- (c-name "gconf_client_notify_remove")
- (return-type "none")
- (parameters
- '("guint" "cnxn")
- )
-)
-
-(define-method notify
- (of-object "GConfClient")
- (c-name "gconf_client_notify")
- (return-type "none")
- (parameters
- '("const-char*" "key")
- )
-)
-
-(define-method set_error_handling
- (of-object "GConfClient")
- (c-name "gconf_client_set_error_handling")
- (return-type "none")
- (parameters
- '("GConfClientErrorHandlingMode" "mode")
- )
-)
-
-(define-function client_set_global_default_error_handler
- (c-name "gconf_client_set_global_default_error_handler")
- (return-type "none")
- (parameters
- '("GConfClientErrorHandlerFunc" "func")
- )
-)
-
-(define-method clear_cache
- (of-object "GConfClient")
- (c-name "gconf_client_clear_cache")
- (return-type "none")
-)
-
-(define-method preload
- (of-object "GConfClient")
- (c-name "gconf_client_preload")
- (return-type "none")
- (parameters
- '("const-gchar*" "dirname")
- '("GConfClientPreloadType" "type")
- '("GError**" "err")
- )
-)
-
-(define-method set
- (of-object "GConfClient")
- (c-name "gconf_client_set")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("const-GConfValue*" "val")
- '("GError**" "err")
- )
-)
-
-(define-method get
- (of-object "GConfClient")
- (c-name "gconf_client_get")
- (caller-owns-return #t)
- (return-type "GConfValue*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_without_default
- (of-object "GConfClient")
- (c-name "gconf_client_get_without_default")
- (caller-owns-return #t)
- (return-type "GConfValue*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_entry
- (of-object "GConfClient")
- (c-name "gconf_client_get_entry")
- (caller-owns-return #t)
- (return-type "GConfEntry*")
- (parameters
- '("const-gchar*" "key")
- '("const-gchar*" "locale")
- '("gboolean" "use_schema_default")
- '("GError**" "err")
- )
-)
-
-(define-method get_default_from_schema
- (of-object "GConfClient")
- (c-name "gconf_client_get_default_from_schema")
- (caller-owns-return #t)
- (return-type "GConfValue*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method unset
- (of-object "GConfClient")
- (c-name "gconf_client_unset")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method recursive_unset
- (of-object "GConfClient")
- (c-name "gconf_client_recursive_unset")
- (return-type "gboolean")
- (parameters
- '("const-char*" "key")
- '("GConfUnsetFlags" "flags")
- '("GError**" "err")
- )
-)
-
-(define-method all_entries
- (of-object "GConfClient")
- (c-name "gconf_client_all_entries")
- (return-type "GSList*")
- (parameters
- '("const-gchar*" "dir")
- '("GError**" "err")
- )
-)
-
-(define-method all_dirs
- (of-object "GConfClient")
- (c-name "gconf_client_all_dirs")
- (return-type "GSList*")
- (parameters
- '("const-gchar*" "dir")
- '("GError**" "err")
- )
-)
-
-(define-method suggest_sync
- (of-object "GConfClient")
- (c-name "gconf_client_suggest_sync")
- (return-type "none")
- (parameters
- '("GError**" "err")
- )
-)
-
-(define-method dir_exists
- (of-object "GConfClient")
- (c-name "gconf_client_dir_exists")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "dir")
- '("GError**" "err")
- )
-)
-
-(define-method key_is_writable
- (of-object "GConfClient")
- (c-name "gconf_client_key_is_writable")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_float
- (of-object "GConfClient")
- (c-name "gconf_client_get_float")
- (return-type "gdouble")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_int
- (of-object "GConfClient")
- (c-name "gconf_client_get_int")
- (return-type "gint")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_string
- (of-object "GConfClient")
- (c-name "gconf_client_get_string")
- (caller-owns-return #t)
- (return-type "gchar*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_bool
- (of-object "GConfClient")
- (c-name "gconf_client_get_bool")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_schema
- (of-object "GConfClient")
- (c-name "gconf_client_get_schema")
- (caller-owns-return #t)
- (return-type "GConfSchema*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_list
- (of-object "GConfClient")
- (c-name "gconf_client_get_list")
- (caller-owns-return #t)
- (return-type "GSList*")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "list_type")
- '("GError**" "err")
- )
-)
-
-(define-method get_pair
- (of-object "GConfClient")
- (c-name "gconf_client_get_pair")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "car_type")
- '("GConfValueType" "cdr_type")
- '("gpointer" "car_retloc")
- '("gpointer" "cdr_retloc")
- '("GError**" "err")
- )
-)
-
-(define-method set_float
- (of-object "GConfClient")
- (c-name "gconf_client_set_float")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("gdouble" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_int
- (of-object "GConfClient")
- (c-name "gconf_client_set_int")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("gint" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_string
- (of-object "GConfClient")
- (c-name "gconf_client_set_string")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("const-gchar*" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_bool
- (of-object "GConfClient")
- (c-name "gconf_client_set_bool")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("gboolean" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_schema
- (of-object "GConfClient")
- (c-name "gconf_client_set_schema")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("const-GConfSchema*" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_list
- (of-object "GConfClient")
- (c-name "gconf_client_set_list")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "list_type")
- '("GSList*" "list")
- '("GError**" "err")
- )
-)
-
-(define-method set_pair
- (of-object "GConfClient")
- (c-name "gconf_client_set_pair")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "car_type")
- '("GConfValueType" "cdr_type")
- '("gconstpointer" "address_of_car")
- '("gconstpointer" "address_of_cdr")
- '("GError**" "err")
- )
-)
-
-(define-method error
- (of-object "GConfClient")
- (c-name "gconf_client_error")
- (return-type "none")
- (parameters
- '("GError*" "error")
- )
-)
-
-(define-method unreturned_error
- (of-object "GConfClient")
- (c-name "gconf_client_unreturned_error")
- (return-type "none")
- (parameters
- '("GError*" "error")
- )
-)
-
-(define-method value_changed
- (of-object "GConfClient")
- (c-name "gconf_client_value_changed")
- (return-type "none")
- (parameters
- '("const-gchar*" "key")
- '("GConfValue*" "value")
- )
-)
-
-(define-method commit_change_set
- (of-object "GConfClient")
- (c-name "gconf_client_commit_change_set")
- (return-type "gboolean")
- (parameters
- '("GConfChangeSet*" "cs")
- '("gboolean" "remove_committed")
- '("GError**" "err")
- )
-)
-
-(define-method reverse_change_set
- (of-object "GConfClient")
- (c-name "gconf_client_reverse_change_set")
- (return-type "GConfChangeSet*")
- (parameters
- '("GConfChangeSet*" "cs")
- '("GError**" "err")
- )
-)
-
-(define-method change_set_from_currentv
- (of-object "GConfClient")
- (c-name "gconf_client_change_set_from_currentv")
- (return-type "GConfChangeSet*")
- (parameters
- '("const-gchar**" "keys")
- '("GError**" "err")
- )
-)
-
-(define-method change_set_from_current
- (of-object "GConfClient")
- (c-name "gconf_client_change_set_from_current")
- (return-type "GConfChangeSet*")
- (parameters
- '("GError**" "err")
- '("const-gchar*" "first_key")
- )
- (varargs #t)
-)
-
-(define-function engine_get_default
- (c-name "gconf_engine_get_default")
- (return-type "GConfEngine*")
-)
-
-(define-function engine_get_for_address
- (c-name "gconf_engine_get_for_address")
- (caller-owns-return #t)
- (return-type "GConfEngine*")
- (parameters
- '("const-gchar*" "address")
- '("GError**" "err")
- )
-)
-
-(define-function engine_get_for_addresses
- (c-name "gconf_engine_get_for_addresses")
- (return-type "GConfEngine*")
- (parameters
- '("GSList*" "addresses")
- '("GError**" "err")
- )
-)
-
-(define-method unref
- (of-object "GConfEngine")
- (c-name "gconf_engine_unref")
- (return-type "none")
-)
-
-(define-method ref
- (of-object "GConfEngine")
- (c-name "gconf_engine_ref")
- (return-type "none")
-)
-
-(define-method set_user_data
- (of-object "GConfEngine")
- (c-name "gconf_engine_set_user_data")
- (return-type "none")
- (parameters
- '("gpointer" "data")
- '("GDestroyNotify" "dnotify")
- )
-)
-
-(define-method get_user_data
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_user_data")
- (return-type "gpointer")
-)
-
-(define-function value_type_get_type
- (c-name "gconf_value_type_get_type")
- (return-type "GType")
-)
-
-(define-function error_get_type
- (c-name "gconf_error_get_type")
- (return-type "GType")
-)
-
-(define-function client_preload_type_get_type
- (c-name "gconf_client_preload_type_get_type")
- (return-type "GType")
-)
-
-(define-function client_error_handling_mode_get_type
- (c-name "gconf_client_error_handling_mode_get_type")
- (return-type "GType")
-)
-
-(define-function error_quark
- (c-name "gconf_error_quark")
- (return-type "GQuark")
-)
-
-(define-function listeners_new
- (is-constructor-of "GConfListeners")
- (c-name "gconf_listeners_new")
- (caller-owns-return #t)
- (return-type "GConfListeners*")
-)
-
-(define-method free
- (of-object "GConfListeners")
- (c-name "gconf_listeners_free")
- (return-type "none")
-)
-
-(define-method add
- (of-object "GConfListeners")
- (c-name "gconf_listeners_add")
- (return-type "guint")
- (parameters
- '("const-gchar*" "listen_point")
- '("gpointer" "listener_data")
- '("GFreeFunc" "destroy_notify")
- )
-)
-
-(define-method remove
- (of-object "GConfListeners")
- (c-name "gconf_listeners_remove")
- (return-type "none")
- (parameters
- '("guint" "cnxn_id")
- )
-)
-
-(define-method notify
- (of-object "GConfListeners")
- (c-name "gconf_listeners_notify")
- (return-type "none")
- (parameters
- '("const-gchar*" "all_above")
- '("GConfListenersCallback" "callback")
- '("gpointer" "user_data")
- )
-)
-
-(define-method count
- (of-object "GConfListeners")
- (c-name "gconf_listeners_count")
- (return-type "guint")
-)
-
-(define-method foreach
- (of-object "GConfListeners")
- (c-name "gconf_listeners_foreach")
- (return-type "none")
- (parameters
- '("GConfListenersForeach" "callback")
- '("gpointer" "user_data")
- )
-)
-
-(define-method get_data
- (of-object "GConfListeners")
- (c-name "gconf_listeners_get_data")
- (return-type "gboolean")
- (parameters
- '("guint" "cnxn_id")
- '("gpointer*" "listener_data_p")
- '("const-gchar**" "location_p")
- )
-)
-
-(define-method remove_if
- (of-object "GConfListeners")
- (c-name "gconf_listeners_remove_if")
- (return-type "none")
- (parameters
- '("GConfListenersPredicate" "predicate")
- '("gpointer" "user_data")
- )
-)
-
-(define-function schema_new
- (is-constructor-of "GConfSchema")
- (c-name "gconf_schema_new")
- (caller-owns-return #t)
- (return-type "GConfSchema*")
-)
-
-(define-method free
- (of-object "GConfSchema")
- (c-name "gconf_schema_free")
- (return-type "none")
-)
-
-(define-method copy
- (of-object "GConfSchema")
- (c-name "gconf_schema_copy")
- (return-type "GConfSchema*")
-)
-
-(define-method set_type
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_type")
- (return-type "none")
- (parameters
- '("GConfValueType" "type")
- )
-)
-
-(define-method set_list_type
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_list_type")
- (return-type "none")
- (parameters
- '("GConfValueType" "type")
- )
-)
-
-(define-method set_car_type
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_car_type")
- (return-type "none")
- (parameters
- '("GConfValueType" "type")
- )
-)
-
-(define-method set_cdr_type
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_cdr_type")
- (return-type "none")
- (parameters
- '("GConfValueType" "type")
- )
-)
-
-(define-method set_locale
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_locale")
- (return-type "none")
- (parameters
- '("const-gchar*" "locale")
- )
-)
-
-(define-method set_short_desc
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_short_desc")
- (return-type "none")
- (parameters
- '("const-gchar*" "desc")
- )
-)
-
-(define-method set_long_desc
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_long_desc")
- (return-type "none")
- (parameters
- '("const-gchar*" "desc")
- )
-)
-
-(define-method set_owner
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_owner")
- (return-type "none")
- (parameters
- '("const-gchar*" "owner")
- )
-)
-
-(define-method set_default_value
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_default_value")
- (return-type "none")
- (parameters
- '("const-GConfValue*" "val")
- )
-)
-
-(define-method set_default_value_nocopy
- (of-object "GConfSchema")
- (c-name "gconf_schema_set_default_value_nocopy")
- (return-type "none")
- (parameters
- '("GConfValue*" "val")
- )
-)
-
-(define-method get_type
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_type")
- (return-type "GConfValueType")
-)
-
-(define-method get_list_type
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_list_type")
- (return-type "GConfValueType")
-)
-
-(define-method get_car_type
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_car_type")
- (return-type "GConfValueType")
-)
-
-(define-method get_cdr_type
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_cdr_type")
- (return-type "GConfValueType")
-)
-
-(define-method get_locale
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_locale")
- (return-type "const-char*")
-)
-
-(define-method get_short_desc
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_short_desc")
- (return-type "const-char*")
-)
-
-(define-method get_long_desc
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_long_desc")
- (return-type "const-char*")
-)
-
-(define-method get_owner
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_owner")
- (return-type "const-char*")
-)
-
-(define-method get_default_value
- (of-object "GConfSchema")
- (c-name "gconf_schema_get_default_value")
- (return-type "GConfValue*")
-)
-
-(define-method get_string
- (of-object "GConfValue")
- (c-name "gconf_value_get_string")
- (return-type "const-char*")
-)
-
-(define-method get_int
- (of-object "GConfValue")
- (c-name "gconf_value_get_int")
- (return-type "int")
-)
-
-(define-method get_float
- (of-object "GConfValue")
- (c-name "gconf_value_get_float")
- (return-type "double")
-)
-
-(define-method get_list_type
- (of-object "GConfValue")
- (c-name "gconf_value_get_list_type")
- (return-type "GConfValueType")
-)
-
-(define-method get_list
- (of-object "GConfValue")
- (c-name "gconf_value_get_list")
- (return-type "GSList*")
-)
-
-(define-method get_car
- (of-object "GConfValue")
- (c-name "gconf_value_get_car")
- (return-type "GConfValue*")
-)
-
-(define-method get_cdr
- (of-object "GConfValue")
- (c-name "gconf_value_get_cdr")
- (return-type "GConfValue*")
-)
-
-(define-method get_bool
- (of-object "GConfValue")
- (c-name "gconf_value_get_bool")
- (return-type "gboolean")
-)
-
-(define-method get_schema
- (of-object "GConfValue")
- (c-name "gconf_value_get_schema")
- (return-type "GConfSchema*")
-)
-
-(define-function value_new
- (is-constructor-of "GConfValue")
- (c-name "gconf_value_new")
- (caller-owns-return #t)
- (return-type "GConfValue*")
- (parameters
- '("GConfValueType" "type")
- )
-)
-
-(define-function value_new_from_string
- (c-name "gconf_value_new_from_string")
- (return-type "GConfValue*")
- (parameters
- '("GConfValueType" "type")
- '("const-gchar*" "str")
- '("GError**" "err")
- )
-)
-
-(define-method copy
- (of-object "GConfValue")
- (c-name "gconf_value_copy")
- (return-type "GConfValue*")
-)
-
-(define-method free
- (of-object "GConfValue")
- (c-name "gconf_value_free")
- (return-type "none")
-)
-
-(define-method set_int
- (of-object "GConfValue")
- (c-name "gconf_value_set_int")
- (return-type "none")
- (parameters
- '("gint" "the_int")
- )
-)
-
-(define-method set_string
- (of-object "GConfValue")
- (c-name "gconf_value_set_string")
- (return-type "none")
- (parameters
- '("const-gchar*" "the_str")
- )
-)
-
-(define-method set_float
- (of-object "GConfValue")
- (c-name "gconf_value_set_float")
- (return-type "none")
- (parameters
- '("gdouble" "the_float")
- )
-)
-
-(define-method set_bool
- (of-object "GConfValue")
- (c-name "gconf_value_set_bool")
- (return-type "none")
- (parameters
- '("gboolean" "the_bool")
- )
-)
-
-(define-method set_schema
- (of-object "GConfValue")
- (c-name "gconf_value_set_schema")
- (return-type "none")
- (parameters
- '("const-GConfSchema*" "sc")
- )
-)
-
-(define-method set_schema_nocopy
- (of-object "GConfValue")
- (c-name "gconf_value_set_schema_nocopy")
- (return-type "none")
- (parameters
- '("GConfSchema*" "sc")
- )
-)
-
-(define-method set_car
- (of-object "GConfValue")
- (c-name "gconf_value_set_car")
- (return-type "none")
- (parameters
- '("const-GConfValue*" "car")
- )
-)
-
-(define-method set_car_nocopy
- (of-object "GConfValue")
- (c-name "gconf_value_set_car_nocopy")
- (return-type "none")
- (parameters
- '("GConfValue*" "car")
- )
-)
-
-(define-method set_cdr
- (of-object "GConfValue")
- (c-name "gconf_value_set_cdr")
- (return-type "none")
- (parameters
- '("const-GConfValue*" "cdr")
- )
-)
-
-(define-method set_cdr_nocopy
- (of-object "GConfValue")
- (c-name "gconf_value_set_cdr_nocopy")
- (return-type "none")
- (parameters
- '("GConfValue*" "cdr")
- )
-)
-
-(define-method set_list_type
- (of-object "GConfValue")
- (c-name "gconf_value_set_list_type")
- (return-type "none")
- (parameters
- '("GConfValueType" "type")
- )
-)
-
-(define-method set_list_nocopy
- (of-object "GConfValue")
- (c-name "gconf_value_set_list_nocopy")
- (return-type "none")
- (parameters
- '("GSList*" "list")
- )
-)
-
-(define-method set_list
- (of-object "GConfValue")
- (c-name "gconf_value_set_list")
- (return-type "none")
- (parameters
- '("GSList*" "list")
- )
-)
-
-(define-method to_string
- (of-object "GConfValue")
- (c-name "gconf_value_to_string")
- (caller-owns-return #t)
- (return-type "gchar*")
-)
-
-(define-method get_schema
- (of-object "GConfMetaInfo")
- (c-name "gconf_meta_info_get_schema")
- (return-type "const-char*")
-)
-
-(define-method get_mod_user
- (of-object "GConfMetaInfo")
- (c-name "gconf_meta_info_get_mod_user")
- (return-type "const-char*")
-)
-
-(define-method mod_time
- (of-object "GConfMetaInfo")
- (c-name "gconf_meta_info_mod_time")
- (return-type "GTime")
-)
-
-(define-function meta_info_new
- (is-constructor-of "GConfMetaInfo")
- (c-name "gconf_meta_info_new")
- (caller-owns-return #t)
- (return-type "GConfMetaInfo*")
-)
-
-(define-method free
- (of-object "GConfMetaInfo")
- (c-name "gconf_meta_info_free")
- (return-type "none")
-)
-
-(define-method set_schema
- (of-object "GConfMetaInfo")
- (c-name "gconf_meta_info_set_schema")
- (return-type "none")
- (parameters
- '("const-gchar*" "schema_name")
- )
-)
-
-(define-method set_mod_user
- (of-object "GConfMetaInfo")
- (c-name "gconf_meta_info_set_mod_user")
- (return-type "none")
- (parameters
- '("const-gchar*" "mod_user")
- )
-)
-
-(define-method set_mod_time
- (of-object "GConfMetaInfo")
- (c-name "gconf_meta_info_set_mod_time")
- (return-type "none")
- (parameters
- '("GTime" "mod_time")
- )
-)
-
-(define-method get_key
- (of-object "GConfEntry")
- (c-name "gconf_entry_get_key")
- (return-type "const-char*")
-)
-
-(define-method get_value
- (of-object "GConfEntry")
- (c-name "gconf_entry_get_value")
- (return-type "GConfValue*")
-)
-
-(define-method get_schema_name
- (of-object "GConfEntry")
- (c-name "gconf_entry_get_schema_name")
- (return-type "const-char*")
-)
-
-(define-method get_is_default
- (of-object "GConfEntry")
- (c-name "gconf_entry_get_is_default")
- (return-type "gboolean")
-)
-
-(define-method get_is_writable
- (of-object "GConfEntry")
- (c-name "gconf_entry_get_is_writable")
- (return-type "gboolean")
-)
-
-(define-function entry_new
- (is-constructor-of "GConfEntry")
- (c-name "gconf_entry_new")
- (caller-owns-return #t)
- (return-type "GConfEntry*")
- (parameters
- '("const-gchar*" "key")
- '("const-GConfValue*" "val")
- )
-)
-
-(define-function entry_new_nocopy
- (c-name "gconf_entry_new_nocopy")
- (return-type "GConfEntry*")
- (parameters
- '("gchar*" "key")
- '("GConfValue*" "val")
- )
-)
-
-(define-method copy
- (of-object "GConfEntry")
- (c-name "gconf_entry_copy")
- (return-type "GConfEntry*")
-)
-
-(define-method free
- (of-object "GConfEntry")
- (c-name "gconf_entry_free")
- (return-type "none")
-)
-
-(define-method ref
- (of-object "GConfEntry")
- (c-name "gconf_entry_ref")
- (return-type "none")
-)
-
-(define-method unref
- (of-object "GConfEntry")
- (c-name "gconf_entry_unref")
- (return-type "none")
-)
-
-(define-method steal_value
- (of-object "GConfEntry")
- (c-name "gconf_entry_steal_value")
- (return-type "GConfValue*")
-)
-
-(define-method set_value
- (of-object "GConfEntry")
- (c-name "gconf_entry_set_value")
- (return-type "none")
- (parameters
- '("const-GConfValue*" "val")
- )
-)
-
-(define-method set_value_nocopy
- (of-object "GConfEntry")
- (c-name "gconf_entry_set_value_nocopy")
- (return-type "none")
- (parameters
- '("GConfValue*" "val")
- )
-)
-
-(define-method set_schema_name
- (of-object "GConfEntry")
- (c-name "gconf_entry_set_schema_name")
- (return-type "none")
- (parameters
- '("const-gchar*" "name")
- )
-)
-
-(define-method set_is_default
- (of-object "GConfEntry")
- (c-name "gconf_entry_set_is_default")
- (return-type "none")
- (parameters
- '("gboolean" "is_default")
- )
-)
-
-(define-method set_is_writable
- (of-object "GConfEntry")
- (c-name "gconf_entry_set_is_writable")
- (return-type "none")
- (parameters
- '("gboolean" "is_writable")
- )
-)
-
-(define-method notify_add
- (of-object "GConfEngine")
- (c-name "gconf_engine_notify_add")
- (return-type "guint")
- (parameters
- '("const-gchar*" "namespace_section")
- '("GConfNotifyFunc" "func")
- '("gpointer" "user_data")
- '("GError**" "err")
- )
-)
-
-(define-method notify_remove
- (of-object "GConfEngine")
- (c-name "gconf_engine_notify_remove")
- (return-type "none")
- (parameters
- '("guint" "cnxn")
- )
-)
-
-(define-method get
- (of-object "GConfEngine")
- (c-name "gconf_engine_get")
- (return-type "GConfValue*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_without_default
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_without_default")
- (caller-owns-return #t)
- (return-type "GConfValue*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_entry
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_entry")
- (caller-owns-return #t)
- (return-type "GConfEntry*")
- (parameters
- '("const-gchar*" "key")
- '("const-gchar*" "locale")
- '("gboolean" "use_schema_default")
- '("GError**" "err")
- )
-)
-
-(define-method get_with_locale
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_with_locale")
- (caller-owns-return #t)
- (return-type "GConfValue*")
- (parameters
- '("const-gchar*" "key")
- '("const-gchar*" "locale")
- '("GError**" "err")
- )
-)
-
-(define-method get_default_from_schema
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_default_from_schema")
- (caller-owns-return #t)
- (return-type "GConfValue*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method set
- (of-object "GConfEngine")
- (c-name "gconf_engine_set")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("const-GConfValue*" "value")
- '("GError**" "err")
- )
-)
-
-(define-method unset
- (of-object "GConfEngine")
- (c-name "gconf_engine_unset")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method associate_schema
- (of-object "GConfEngine")
- (c-name "gconf_engine_associate_schema")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("const-gchar*" "schema_key")
- '("GError**" "err")
- )
-)
-
-(define-method all_entries
- (of-object "GConfEngine")
- (c-name "gconf_engine_all_entries")
- (return-type "GSList*")
- (parameters
- '("const-gchar*" "dir")
- '("GError**" "err")
- )
-)
-
-(define-method all_dirs
- (of-object "GConfEngine")
- (c-name "gconf_engine_all_dirs")
- (return-type "GSList*")
- (parameters
- '("const-gchar*" "dir")
- '("GError**" "err")
- )
-)
-
-(define-method suggest_sync
- (of-object "GConfEngine")
- (c-name "gconf_engine_suggest_sync")
- (return-type "none")
- (parameters
- '("GError**" "err")
- )
-)
-
-(define-method dir_exists
- (of-object "GConfEngine")
- (c-name "gconf_engine_dir_exists")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "dir")
- '("GError**" "err")
- )
-)
-
-(define-method remove_dir
- (of-object "GConfEngine")
- (c-name "gconf_engine_remove_dir")
- (return-type "none")
- (parameters
- '("const-gchar*" "dir")
- '("GError**" "err")
- )
-)
-
-(define-method key_is_writable
- (of-object "GConfEngine")
- (c-name "gconf_engine_key_is_writable")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-function valid_key
- (c-name "gconf_valid_key")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("gchar**" "why_invalid")
- )
-)
-
-(define-function key_is_below
- (c-name "gconf_key_is_below")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "above")
- '("const-gchar*" "below")
- )
-)
-
-(define-function concat_dir_and_key
- (c-name "gconf_concat_dir_and_key")
- (caller-owns-return #t)
- (return-type "gchar*")
- (parameters
- '("const-gchar*" "dir")
- '("const-gchar*" "key")
- )
-)
-
-(define-function unique_key
- (c-name "gconf_unique_key")
- (caller-owns-return #t)
- (return-type "gchar*")
-)
-
-(define-function escape_key
- (c-name "gconf_escape_key")
- (caller-owns-return #t)
- (return-type "char*")
- (parameters
- '("const-char*" "arbitrary_text")
- '("int" "len")
- )
-)
-
-(define-function unescape_key
- (c-name "gconf_unescape_key")
- (caller-owns-return #t)
- (return-type "char*")
- (parameters
- '("const-char*" "escaped_key")
- '("int" "len")
- )
-)
-
-(define-method get_float
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_float")
- (return-type "gdouble")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_int
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_int")
- (return-type "gint")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_string
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_string")
- (caller-owns-return #t)
- (return-type "gchar*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_bool
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_bool")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_schema
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_schema")
- (caller-owns-return #t)
- (return-type "GConfSchema*")
- (parameters
- '("const-gchar*" "key")
- '("GError**" "err")
- )
-)
-
-(define-method get_list
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_list")
- (caller-owns-return #t)
- (return-type "GSList*")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "list_type")
- '("GError**" "err")
- )
-)
-
-(define-method get_pair
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_pair")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "car_type")
- '("GConfValueType" "cdr_type")
- '("gpointer" "car_retloc")
- '("gpointer" "cdr_retloc")
- '("GError**" "err")
- )
-)
-
-(define-method set_float
- (of-object "GConfEngine")
- (c-name "gconf_engine_set_float")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("gdouble" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_int
- (of-object "GConfEngine")
- (c-name "gconf_engine_set_int")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("gint" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_string
- (of-object "GConfEngine")
- (c-name "gconf_engine_set_string")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("const-gchar*" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_bool
- (of-object "GConfEngine")
- (c-name "gconf_engine_set_bool")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("gboolean" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_schema
- (of-object "GConfEngine")
- (c-name "gconf_engine_set_schema")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("const-GConfSchema*" "val")
- '("GError**" "err")
- )
-)
-
-(define-method set_list
- (of-object "GConfEngine")
- (c-name "gconf_engine_set_list")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "list_type")
- '("GSList*" "list")
- '("GError**" "err")
- )
-)
-
-(define-method set_pair
- (of-object "GConfEngine")
- (c-name "gconf_engine_set_pair")
- (return-type "gboolean")
- (parameters
- '("const-gchar*" "key")
- '("GConfValueType" "car_type")
- '("GConfValueType" "cdr_type")
- '("gconstpointer" "address_of_car")
- '("gconstpointer" "address_of_cdr")
- '("GError**" "err")
- )
-)
-
-(define-function string_to_enum
- (c-name "gconf_string_to_enum")
- (return-type "gboolean")
- (parameters
- '("GConfEnumStringPair[]" "lookup_table")
- '("const-gchar*" "str")
- '("gint*" "enum_value_retloc")
- )
-)
-
-(define-function enum_to_string
- (c-name "gconf_enum_to_string")
- (return-type "const-gchar*")
- (parameters
- '("GConfEnumStringPair[]" "lookup_table")
- '("gint" "enum_value")
- )
-)
-
-(define-function debug_shutdown
- (c-name "gconf_debug_shutdown")
- (return-type "int")
-)
-
-(define-function init
- (c-name "gconf_init")
- (return-type "gboolean")
- (parameters
- '("int" "argc")
- '("char**" "argv")
- '("GError**" "err")
- )
-)
-
-(define-function is_initialized
- (c-name "gconf_is_initialized")
- (return-type "gboolean")
-)
-
-(define-function preinit
- (c-name "gconf_preinit")
- (return-type "none")
- (parameters
- '("gpointer" "app")
- '("gpointer" "mod_info")
- )
-)
-
-(define-function postinit
- (c-name "gconf_postinit")
- (return-type "none")
- (parameters
- '("gpointer" "app")
- '("gpointer" "mod_info")
- )
-)
-
-(define-method get_full
- (of-object "GConfEngine")
- (c-name "gconf_engine_get_full")
- (return-type "GConfValue*")
- (parameters
- '("const-gchar*" "key")
- '("const-gchar*" "locale")
- '("gboolean" "use_schema_default")
- '("gboolean*" "is_default_p")
- '("gboolean*" "is_writable_p")
- '("GError**" "err")
- )
-)
-
diff --git a/util/gconf/gconf.override b/util/gconf/gconf.override
deleted file mode 100644
index 337653d..0000000
--- a/util/gconf/gconf.override
+++ /dev/null
@@ -1,920 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4 -*- */
-%%
-headers
-#include <Python.h>
-
-#include "gconf-fixes.h"
-#include "gconf-types.h"
-
-#define NO_IMPORT_PYGOBJECT
-#include "pygobject.h"
-#include <glib.h>
-#include <gconf/gconf-client.h>
-#include <gconf/gconf-enum-types.h>
-#include "config.h"
-
-static gpointer pygconf_parse_pygvalue(GConfValueType gvalue_type,
- PyObject *pyvalue);
-%%
-modulename gconf
-%%
-import gobject.GObject as PyGObject_Type
-%%
-ignore-glob
- _*
- gconf_*init
-%%
-ignore
- gconf_change_set_get_type
- gconf_client_get_type
- gconf_value_type_get_type
- gconf_error_get_type
- gconf_client_preload_type_get_type
- gconf_client_error_handling_mode_get_type
- gconf_value_set_car_nocopy
- gconf_value_set_cdr_nocopy
- gconf_client_change_set_from_currentv
- gconf_value_set_list_nocopy
-
-%%
-override-slot GConfClient.tp_init
-
-static int
-_wrap_gconf_client_tp_init(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, ":gconf.Client.__init__", kwlist)) {
- return -1;
- }
- self->obj = (GObject *) gconf_client_get_default();
- pygobject_register_wrapper((PyObject *)self);
- return 0;
-}
-
-%%
-override gconf_client_notify_add kwargs
-void
-pygconf_client_notify_add(GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- gpointer user_data)
-{
- PyObject *func;
- PyObject *userdata = NULL;
- PyObject *ret;
- PyObject *tuple = (PyObject*)user_data;
- PyGILState_STATE state;
-
- state = pyg_gil_state_ensure();
-
- g_assert(PyTuple_Check(tuple));
- func = PyTuple_GetItem(tuple, 0);
- userdata = PyTuple_GetItem(tuple, 1);
-
- if (!userdata) {
- ret = PyObject_CallFunction(func, "NNN",
- pygobject_new((GObject *)client),
- PyLong_FromUnsignedLong(cnxn_id),
- pyg_boxed_new(GCONF_TYPE_ENTRY,
- entry,
- TRUE, TRUE));
- } else {
- ret = PyObject_CallFunction(func, "NNNO",
- pygobject_new((GObject *)client),
- PyLong_FromUnsignedLong(cnxn_id),
- pyg_boxed_new(GCONF_TYPE_ENTRY,
- entry,
- TRUE, TRUE),
- userdata);
- }
-
- if (ret == NULL)
- PyErr_Print();
- else
- Py_DECREF(ret);
-
- pyg_gil_state_release(state);
-}
-
-static PyObject *
-_wrap_gconf_client_notify_add(PyGObject *self, PyObject *args,
- PyObject *kwargs)
-{
- static char *kwlist[] = { "namespace_section", "func",
- "user_data", NULL };
- gchar *namespace_section;
- PyObject *callback;
- PyObject *extra = NULL;
- PyObject *data;
- guint retval;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "sO|O:GConfClient.notify_ad",
- kwlist, &namespace_section,
- &callback, &extra)) {
- return NULL;
- }
-
- if (!PyCallable_Check(callback)) {
- PyErr_SetString(PyExc_TypeError, "second arg not callable");
- return NULL;
- }
-
- if (extra) {
- Py_INCREF(extra);
- } else {
- extra = PyTuple_New(0);
- }
-
- data = Py_BuildValue("(ON)", callback, extra);
-
- retval = gconf_client_notify_add(GCONF_CLIENT(self->obj),
- namespace_section,
- pygconf_client_notify_add,
- data,
- (GFreeFunc)pyg_destroy_notify,
- NULL);
-
- return PyLong_FromUnsignedLong((unsigned long) retval);
-}
-
-%%
-override gconf_client_all_entries args
-static PyObject *
-_wrap_gconf_client_all_entries(PyGObject *self, PyObject *args)
-{
- gchar *path;
- GError *err = NULL;
- GSList *values;
- GSList *list;
- PyObject *pylist;
- int i = 0;
-
- if (!PyArg_ParseTuple(args, "s:GConfClient.all_entries", &path)) {
- return NULL;
- }
-
- values = gconf_client_all_entries(GCONF_CLIENT(self->obj), path, &err);
- if (pyg_error_check(&err)) {
- return NULL;
- }
-
- pylist = PyTuple_New(g_slist_length(values));
- for (list = values; list; list = list->next) {
- GConfEntry *entry = list->data;
- PyObject *pyentry = pyg_boxed_new(GCONF_TYPE_ENTRY, entry,
- FALSE, TRUE);
- PyTuple_SetItem(pylist, i++, pyentry);
- }
-
- return pylist;
-}
-
-%%
-override gconf_client_all_dirs args
-static PyObject *
-_wrap_gconf_client_all_dirs(PyGObject *self, PyObject *args)
-{
- gchar *path;
- GError *err = NULL;
- GSList *values;
- GSList *list;
- PyObject *pylist;
- int i = 0;
-
- if (!PyArg_ParseTuple(args, "s:GConfClient.all_dirs", &path)) {
- return NULL;
- }
-
- values = gconf_client_all_dirs(GCONF_CLIENT(self->obj), path, &err);
- if (pyg_error_check(&err)) {
- return NULL;
- }
-
- pylist = PyTuple_New(g_slist_length(values));
- for (list = values; list; list = list->next) {
- PyObject *pystring = PyString_FromString(list->data);
-
- PyTuple_SetItem(pylist, i++, pystring);
- }
-
- return pylist;
-}
-
-%%
-override gconf_client_get_pair kwargs
-/* Return a proper PyObject for retloc based on its type. */
-static PyObject *
-pygconf_parse_gvalue(GConfValueType gvalue_type, gpointer retloc)
-{
- PyObject *retval;
- switch(gvalue_type) {
- case GCONF_VALUE_INT:
- case GCONF_VALUE_BOOL:
- retval = PyInt_FromLong(*(gint*)retloc);
- break;
- case GCONF_VALUE_FLOAT:
- retval = PyFloat_FromDouble(*(gdouble*)retloc);
- break;
- case GCONF_VALUE_STRING:
- {
- gchar **s = (gchar **) retloc;
- if (*s)
- retval = PyString_FromString(*s);
- else {
- Py_INCREF(Py_None);
- return Py_None;
- }
- break;
- }
- case GCONF_VALUE_SCHEMA:
- retval = pyg_boxed_new(GCONF_TYPE_SCHEMA, *(GConfSchema**)retloc,
- TRUE, TRUE);
- break;
- default:
- PyErr_SetString(PyExc_TypeError, "Unknown GConfValueType.");
- retval = NULL;
- break;
- }
- return retval;
-}
-
-/* Get the value of a PyObject from its type. */
-/* g_new0() on returned pointer, need to free it. */
-static gpointer
-pygconf_parse_pygvalue(GConfValueType gvalue_type, PyObject *pyvalue)
-{
- gpointer retval;
- retval = g_new0(gpointer, 1);
- switch(gvalue_type) {
- case GCONF_VALUE_INT:
- case GCONF_VALUE_BOOL:
- *(gint*)retval = (gint) PyInt_AsLong(pyvalue);
- break;
- case GCONF_VALUE_FLOAT:
- *(gdouble*)retval = PyFloat_AsDouble(pyvalue);
- break;
- case GCONF_VALUE_STRING:
- *(gchar**)retval = PyString_AsString(pyvalue);
- break;
- case GCONF_VALUE_SCHEMA:
- if (pyg_boxed_check(pyvalue, GCONF_TYPE_SCHEMA)) {
- *(GConfSchema**)retval = pyg_boxed_get(pyvalue, GConfSchema);
- } else {
- PyErr_SetString(PyExc_TypeError,
- "value should be a GConfSchema");
- free(retval);
- retval = NULL;
- }
- break;
- default:
- PyErr_SetString(PyExc_TypeError, "Unknown GConfValueType.");
- free(retval);
- retval = NULL;
- break;
- }
- return retval;
-}
-
-static gpointer
-pygconf_new_type(GConfValueType t)
-{
- gpointer retval;
- switch(t) {
- case GCONF_VALUE_INT:
- case GCONF_VALUE_BOOL:
- retval = g_new0(gint, 1);
- break;
- case GCONF_VALUE_FLOAT:
- retval = g_new0(gdouble, 1);
- break;
- case GCONF_VALUE_STRING:
- retval = g_new0(gchar, 1);
- break;
- case GCONF_VALUE_SCHEMA:
- retval = gconf_schema_new();
- break;
- default:
- PyErr_SetString(PyExc_TypeError, "Unknown GConfValueType.");
- retval = NULL;
- break;
- }
- return retval;
-}
-
-static PyObject *
-_wrap_gconf_client_get_pair(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "key", "car_type", "cdr_type", NULL };
- char *key;
- PyObject *pycar_type = NULL, *pycdr_type = NULL;
- PyObject *retcar = NULL, *retcdr = NULL;
- GConfValueType car_type, cdr_type;
- gpointer car_retloc = NULL;
- gpointer cdr_retloc = NULL;
- int ret;
-
- GError *err = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sOO:GConfClient.get_pair",
- kwlist, &key, &pycar_type, &pycdr_type))
- return NULL;
-
- if (pyg_enum_get_value(GCONF_TYPE_VALUE_TYPE,
- pycar_type, (gint *)&car_type))
- return NULL;
- if (pyg_enum_get_value(GCONF_TYPE_VALUE_TYPE,
- pycdr_type, (gint *)&cdr_type))
- return NULL;
-
- car_retloc = pygconf_new_type(car_type);
- if (!car_retloc)
- return NULL;
- cdr_retloc = pygconf_new_type(cdr_type);
- if (!cdr_retloc) {
- if(car_type == GCONF_VALUE_SCHEMA)
- gconf_schema_free(car_retloc);
- else
- g_free(car_retloc);
- return NULL;
- }
-
- ret = gconf_client_get_pair(GCONF_CLIENT(self->obj), key, car_type,
- cdr_type, car_retloc, cdr_retloc, &err);
- if (pyg_error_check(&err))
- return NULL;
- retcar = pygconf_parse_gvalue(car_type, car_retloc);
- retcdr = pygconf_parse_gvalue(cdr_type, cdr_retloc);
-
- if (car_type != GCONF_VALUE_SCHEMA)
- g_free(car_retloc);
- /* FIXME: gconf_schema_free(car_retloc)? */
- else
- gconf_schema_free(car_retloc);
-
- if (cdr_type != GCONF_VALUE_SCHEMA)
- g_free(cdr_retloc);
- else
- gconf_schema_free(cdr_retloc);
-
- if (!retcar || !retcdr)
- return NULL;
- return Py_BuildValue("(NN)", retcar, retcdr);
-}
-
-%%
-override gconf_client_set_pair kwargs
-static PyObject *
-_wrap_gconf_client_set_pair(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "key", "car_type", "cdr_type",
- "car", "cdr", NULL };
- char *key;
- PyObject *pycar_type = NULL, *pycdr_type = NULL;
- PyObject *pycar = NULL, *pycdr = NULL;
-
- GConfValueType car_type, cdr_type;
- gpointer car, cdr;
- int ret;
- GError *err = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "sOOOO:GConfClient.set_pair",
- kwlist, &key, &pycar_type, &pycdr_type,
- &pycar, &pycdr))
- return NULL;
-
- if (pyg_enum_get_value(GCONF_TYPE_VALUE_TYPE,
- pycar_type, (gint *)&car_type))
- return NULL;
- if (pyg_enum_get_value(GCONF_TYPE_VALUE_TYPE,
- pycdr_type, (gint *)&cdr_type))
- return NULL;
- car = pygconf_parse_pygvalue(car_type, pycar);
- if (!car)
- return NULL;
- cdr = pygconf_parse_pygvalue(cdr_type, pycdr);
- if (!cdr) {
- g_free(car);
- return NULL;
- }
-
-
- ret = gconf_client_set_pair(GCONF_CLIENT(self->obj),
- key, car_type, cdr_type,
- car, cdr, &err);
-
- g_free(car);
- g_free(cdr);
-
- if (pyg_error_check(&err))
- return NULL;
- return PyInt_FromLong(ret);
-}
-
-%%
-override gconf_client_get_list kwargs
- static PyObject *
-pygconf_parse_listvalue(GConfValueType gvalue_type, gpointer retloc)
-{
- PyObject *retval;
- switch(gvalue_type) {
- case GCONF_VALUE_INT:
- case GCONF_VALUE_BOOL:
- retval = PyInt_FromLong(GPOINTER_TO_INT(retloc));
- break;
- case GCONF_VALUE_FLOAT:
- retval = PyFloat_FromDouble(*(gdouble*)retloc);
- break;
- case GCONF_VALUE_STRING:
- retval = PyString_FromString((gchar*)retloc);
- break;
- case GCONF_VALUE_SCHEMA:
- retval = pyg_boxed_new(GCONF_TYPE_SCHEMA, (GConfSchema*)retloc,
- TRUE, TRUE);
- break;
- default:
- /* Should not reach here. get_list should always valid. */
- PyErr_SetString(PyExc_TypeError, "Unknown GConfValueType.");
- retval = NULL;
- break;
- }
- return retval;
-}
-
-static PyObject *
-_wrap_gconf_client_get_list(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "key", "list_type", NULL };
- char *key;
- PyObject *py_type = NULL;
- PyObject *py_list = NULL;
- GConfValueType lstype;
- GSList *retlist, *ilist;
- gpointer data;
- int lslen, i;
-
- GError *err = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO:GConfClient.get_list",
- kwlist, &key, &py_type))
- return NULL;
-
- if (pyg_enum_get_value(GCONF_TYPE_VALUE_TYPE, py_type, (gint *)&lstype))
- return NULL;
-
- retlist = gconf_client_get_list(GCONF_CLIENT(self->obj), key,
- lstype, &err);
- if (pyg_error_check(&err)) {
- return NULL;
- } else if (retlist == NULL) {
- return PyList_New(0);
- }
-
- lslen = g_slist_length(retlist);
- i = 0;
- py_list = PyList_New(lslen);
- for (ilist = retlist; ilist; ilist = ilist->next) {
- PyObject *py_data;
- data = ilist->data;
- py_data = pygconf_parse_listvalue(lstype, data);
- if (!py_data) {
- g_slist_free(retlist);
- return NULL;
- }
- PyList_SetItem(py_list, i, py_data);
- i++;
- if (lstype == GCONF_VALUE_SCHEMA)
- gconf_schema_free(data);
- else if(lstype == GCONF_VALUE_FLOAT || lstype == GCONF_VALUE_STRING)
- g_free(data);
- }
- g_slist_free(retlist);
- return py_list;
-}
-
-%%
-override gconf_client_set_list kwargs
-static PyObject *
-_wrap_gconf_client_set_list(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "key", "list_type", "list", NULL };
- char *key;
- PyObject *py_type = NULL;
- PyObject *py_list = NULL;
- GSList *clist = NULL;
- GSList *tmplist, *pointlist=NULL;
- GConfValueType list_type;
- int ret, i;
- int retdata; /* Error flag. */
- GError *err = NULL;
-
- ret = 1;
- retdata = 1;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sOO:GConfClient.set_list",
- kwlist, &key, &py_type, &py_list))
- return NULL;
- if (!PyTuple_Check(py_list) && !PyList_Check(py_list)) {
- PyErr_SetString(PyExc_TypeError,
- "3rd argument should be a sequence type.");
- return NULL;
- }
-
- if (pyg_enum_get_value(GCONF_TYPE_VALUE_TYPE, py_type, (gint *)&list_type))
- return NULL;
-
- for (i = 0; i < PySequence_Size(py_list) && retdata; i++) {
- gpointer data;
- data = pygconf_parse_pygvalue(list_type,
- PySequence_GetItem(py_list, i));
- if (data == NULL) {
- retdata = 0;
- break;
- }
- /* What to free the list later. */
- pointlist = g_slist_append(pointlist, data);
- switch(list_type){
- case GCONF_VALUE_INT:
- case GCONF_VALUE_BOOL:
- clist = g_slist_append(clist, GINT_TO_POINTER(*(gint*)data));
- break;
- case GCONF_VALUE_FLOAT:
- clist = g_slist_append(clist, (gdouble*)data);
- break;
- case GCONF_VALUE_STRING:
- clist = g_slist_append(clist, *(gchar**)data);
- break;
- case GCONF_VALUE_SCHEMA:
- clist = g_slist_append(clist, *(GConfSchema**)data);
- break;
- default:
- PyErr_SetString(PyExc_TypeError, "Unknown GConfValueType.");
- retdata = 0;
- break;
- }
- }
-
- if (retdata)
- ret = gconf_client_set_list(GCONF_CLIENT(self->obj), key, list_type,
- clist, &err);
-
- for (tmplist = pointlist; tmplist; tmplist = tmplist->next) {
- g_free(tmplist->data);
- }
- g_slist_free(pointlist);
- g_slist_free(clist);
-
- if (pyg_error_check(&err) || !retdata)
- return NULL;
- return PyInt_FromLong(ret);
-}
-
-%%
-override gconf_value_get_car args
-static PyObject *
-_wrap_gconf_value_get_car(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- GConfValue* vobj;
-
- vobj = gconf_value_get_car(pyg_boxed_get(self, GConfValue));
- return pyg_boxed_new(GCONF_TYPE_VALUE, vobj, TRUE, TRUE);
-}
-
-%%
-override gconf_value_get_cdr args
-static PyObject *
-_wrap_gconf_value_get_cdr(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- GConfValue* vobj;
-
- vobj = gconf_value_get_cdr(pyg_boxed_get(self, GConfValue));
- return pyg_boxed_new(GCONF_TYPE_VALUE, vobj, TRUE, TRUE);
-}
-%%
-override gconf_value_get_list args
-static PyObject *
-_wrap_gconf_value_get_list(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- GConfValue *value;
- PyObject *pylist;
- GSList *values = NULL, *list;
- int i = 0;
-
- value = pyg_boxed_get(self, GConfValue);
- if (value->type != GCONF_VALUE_LIST) {
- PyErr_SetString(PyExc_TypeError, "gconf value does not contain a list.");
- return NULL;
- }
- values = gconf_value_get_list(value);
-
- pylist = PyTuple_New(g_slist_length(values));
- for (list = values; list; list = list->next) {
- PyObject *pyvalue;
- value = list->data;
- pyvalue = pyg_boxed_new(GCONF_TYPE_VALUE, value, TRUE, TRUE);
-
- PyTuple_SetItem(pylist, i++, pyvalue);
- }
-
- return pylist;
-}
-%%
-override gconf_value_get_int noargs
-static PyObject *
-_wrap_gconf_value_get_int(PyObject *self)
-{
- int ret;
- GConfValue *value;
-
- value = pyg_boxed_get(self, GConfValue);
- if (value->type != GCONF_VALUE_INT) {
- PyErr_SetString(PyExc_TypeError, "gconf value does not contain an integer.");
- return NULL;
- }
- ret = gconf_value_get_int(value);
- return PyInt_FromLong(ret);
-}
-%%
-override gconf_value_get_string noargs
-static PyObject *
-_wrap_gconf_value_get_string(PyObject *self)
-{
- const gchar *ret;
- GConfValue *value;
-
- value = pyg_boxed_get(self, GConfValue);
- if (value->type != GCONF_VALUE_STRING) {
- PyErr_SetString(PyExc_TypeError, "gconf value does not contain a string.");
- return NULL;
- }
- ret = gconf_value_get_string(value);
- if (ret)
- return PyString_FromString(ret);
- Py_INCREF(Py_None);
- return Py_None;
-}
-%%
-override gconf_value_get_float noargs
-static PyObject *
-_wrap_gconf_value_get_float(PyObject *self)
-{
- double ret;
- GConfValue *value;
-
- value = pyg_boxed_get(self, GConfValue);
- if (value->type != GCONF_VALUE_FLOAT) {
- PyErr_SetString(PyExc_TypeError, "gconf value does not contain a float.");
- return NULL;
- }
- ret = gconf_value_get_float(value);
- return PyFloat_FromDouble(ret);
-}
-%%
-override gconf_value_get_bool noargs
-static PyObject *
-_wrap_gconf_value_get_bool(PyObject *self)
-{
- int ret;
- PyObject *py_ret;
- GConfValue *value;
-
- value = pyg_boxed_get(self, GConfValue);
- if (value->type != GCONF_VALUE_BOOL) {
- PyErr_SetString(PyExc_TypeError, "gconf value does not contain a boolean.");
- return NULL;
- }
- ret = gconf_value_get_bool(value);
- py_ret = ret ? Py_True : Py_False;
- Py_INCREF(py_ret);
- return py_ret;
-}
-%%
-override gconf_value_set_list kwargs
-static PyObject *
-_wrap_gconf_value_set_list(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "list", NULL };
- GSList *list;
- PyObject *py_list;
- int i, len;
- GConfValue *value = pyg_boxed_get(self, GConfValue);
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:GConfValue.set_list", kwlist,
- &PyList_Type, &py_list))
- return NULL;
- if (value->type != GCONF_VALUE_LIST) {
- PyErr_SetString(PyExc_TypeError, "gconf value type must be list.");
- return NULL;
- }
-
- len = PyList_Size(py_list);
- for (i = 0, list = NULL; i < len; i++) {
- PyObject *item = PyList_GET_ITEM(py_list, i);
- if (!pyg_boxed_check(item, GCONF_TYPE_VALUE)) {
- PyErr_SetString(PyExc_TypeError, "list elements must be of type gconf.Value");
- g_slist_free(list);
- return NULL;
- }
- list = g_slist_append(list, pyg_boxed_get(item, GConfValue));
- }
- gconf_value_set_list(value, list);
- g_slist_free(list);
- Py_INCREF(Py_None);
- return Py_None;
-}
-%%
-override gconf_client_change_set_from_current
-static PyObject *
-_wrap_gconf_client_change_set_from_current(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "keys", NULL };
- PyObject *py_list;
- const gchar **keys;
- GError *err = NULL;
- GConfChangeSet *ret;
- int len, i;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:GConfClient.change_set_from_current",
- kwlist, &PyList_Type, &py_list))
- return NULL;
- len = PyList_Size(py_list);
- keys = g_new(const gchar *, len + 1);
- for (i = 0; i < len; ++i) {
- PyObject *item = PyList_GET_ITEM(py_list, i);
- if (!PyString_Check(item)) {
- g_free(keys);
- PyErr_SetString(PyExc_TypeError, "list elements must be of type str");
- return NULL;
- }
- keys[i] = PyString_AsString(item);
- }
- keys[i] = NULL;
- ret = gconf_client_change_set_from_currentv(GCONF_CLIENT(self->obj), keys, &err);
- g_free(keys);
- if (pyg_error_check(&err))
- return NULL;
- /* pyg_boxed_new handles NULL checking */
- return pyg_boxed_new(GCONF_TYPE_CHANGE_SET, ret, TRUE, TRUE);
-}
-%%
-override gconf_change_set_set_list kwargs
-static PyObject *
-_wrap_gconf_change_set_set_list(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "key", "list_type", "list", NULL };
- char *key;
- PyObject *py_list_type = NULL, *py_list;
- GConfValueType list_type;
- int i, len;
- GSList *list;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sOO!:GConfChangeSet.set_list"
- , kwlist, &key, &py_list_type,
- &PyList_Type, &py_list))
- return NULL;
- if (pyg_enum_get_value(GCONF_TYPE_VALUE_TYPE, py_list_type, (gint *)&list_type))
- return NULL;
-
- len = PyList_Size(py_list);
- for (i = 0, list = NULL; i < len; i++) {
- PyObject *item = PyList_GET_ITEM(py_list, i);
- if (!pyg_boxed_check(item, GCONF_TYPE_VALUE)) {
- PyErr_SetString(PyExc_TypeError, "list elements must be of type gconf.Value");
- g_slist_free(list);
- return NULL;
- }
- list = g_slist_append(list, pyg_boxed_get(item, GConfValue));
- }
- gconf_change_set_set_list(pyg_boxed_get(self, GConfChangeSet), key, list_type, list);
- g_slist_free(list);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-%%
-define GConfClient.get_value kwargs
-
-static PyObject *
-_wrap_g_conf_client_get_value(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "key", NULL };
- char *key;
- GError *err = NULL;
- GConfValue *value;
- PyObject *py_ret;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,"s:GConfClient.get_value", kwlist, &key))
- return NULL;
-
- value = gconf_client_get(GCONF_CLIENT(self->obj), key, &err);
-
- if (pyg_error_check(&err))
- return NULL;
-
- if (value == NULL) {
- PyErr_Format(PyExc_ValueError, "gconf key %s has no value", key);
- return NULL;
- }
-
- switch (value->type)
- {
- case GCONF_VALUE_INVALID:
- PyErr_SetString(PyExc_TypeError, "invalid value");
- py_ret = NULL;
- break;
-
- case GCONF_VALUE_STRING:
- py_ret = PyString_FromString(gconf_value_get_string(value));
- break;
- case GCONF_VALUE_INT:
- py_ret = PyInt_FromLong(gconf_value_get_int(value));
- break;
- case GCONF_VALUE_FLOAT:
- py_ret = PyFloat_FromDouble(gconf_value_get_float(value));
- break;
- case GCONF_VALUE_BOOL:
- py_ret = PyBool_FromLong(gconf_value_get_bool(value));
- break;
-
- case GCONF_VALUE_SCHEMA:
- case GCONF_VALUE_LIST:
- case GCONF_VALUE_PAIR:
- PyErr_SetString(PyExc_TypeError, "value type not supported yet by this API");
- py_ret = NULL;
- break;
- default:
- py_ret = NULL;
- }
- gconf_value_free(value);
- return py_ret;
-}
-
-%%
-define GConfClient.set_value kwargs
-
-static PyObject *
-_wrap_g_conf_client_set_value(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "key", "val", NULL };
- char *key;
- PyObject *py_val;
- GError *err = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,"sO:GConfClient.set_value", kwlist, &key, &py_val))
- return NULL;
- if (pyg_boxed_check(py_val, GCONF_TYPE_VALUE)) {
- gconf_client_set(GCONF_CLIENT(self->obj), key, pyg_boxed_get(py_val, GConfValue), &err);
- if (pyg_error_check(&err))
- return NULL;
- } else {
- if (PyBool_Check(py_val)) {
- gconf_client_set_bool(GCONF_CLIENT(self->obj), key, PyInt_AsLong(py_val), &err);
- } else if (PyInt_Check(py_val)) {
- gconf_client_set_int(GCONF_CLIENT(self->obj), key, PyInt_AsLong(py_val), &err);
- } else if (PyFloat_Check(py_val)) {
- gconf_client_set_float(GCONF_CLIENT(self->obj), key, PyFloat_AsDouble(py_val), &err);
- } else if (PyString_Check(py_val)) {
- gconf_client_set_string(GCONF_CLIENT(self->obj), key, PyString_AsString(py_val), &err);
- } else {
- PyErr_SetString(PyExc_TypeError, "value type not supported yet by this API");
- return NULL;
- }
- if (pyg_error_check(&err))
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-%%
-override gconf_value_new_from_string kwargs
-static PyObject *
-_wrap_gconf_value_new_from_string(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "type", "str", NULL };
- PyObject *py_type = NULL;
- char *str;
- GConfValueType type;
- GError *err = NULL;
- GConfValue *ret;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os:value_new_from_string", kwlist, &py_type, &str))
- return NULL;
- if (pyg_enum_get_value(GCONF_TYPE_VALUE_TYPE, py_type, (gpointer)&type))
- return NULL;
-
- if (type == GCONF_VALUE_LIST || type == GCONF_VALUE_PAIR) {
- PyErr_SetString(PyExc_ValueError, "GConf value types LIST and PAIR are not valid for this function");
- return NULL;
- }
-
- ret = gconf_value_new_from_string(type, str, &err);
-
- if (pyg_error_check(&err))
- return NULL;
- /* pyg_boxed_new handles NULL checking */
- return pyg_boxed_new(GCONF_TYPE_VALUE, ret, TRUE, TRUE);
-}
diff --git a/util/gconf/gconfmodule.c b/util/gconf/gconfmodule.c
deleted file mode 100644
index 60273fb..0000000
--- a/util/gconf/gconfmodule.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4 -*- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* include this first, before NO_IMPORT_PYGOBJECT is defined */
-#include <pygobject.h>
-
-#include "gconf-types.h"
-
-void pygconf_register_classes (PyObject *d);
-void pygconf_add_constants(PyObject *module, const gchar *strip_prefix);
-
-extern PyMethodDef pygconf_functions[];
-extern PyTypeObject PyGConfEngine_Type;
-
-DL_EXPORT(void)
-initgconf (void)
-{
- PyObject *m, *d;
-
- init_pygobject ();
-
- m = Py_InitModule ("gconf", pygconf_functions);
- d = PyModule_GetDict (m);
-
- pygconf_register_classes (d);
- pygconf_add_constants (m, "GCONF_");
- pygconf_register_engine_type (m);
-
- PyModule_AddObject(m, "Engine", (PyObject *) &PyGConfEngine_Type);
-}
diff --git a/util/gconf/wscript b/util/gconf/wscript
deleted file mode 100644
index 442c629..0000000
--- a/util/gconf/wscript
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- python -*-
-# encoding: utf-8
-
-import os
-import Common
-
-def configure(conf):
- conf.env.append_value('MODULES_AVAILABLE', 'gconf')
- if 'gconf' in conf.env['ENABLE_MODULES'] or 'all' in conf.env['ENABLE_MODULES']:
- if conf.check_pkg('gconf-2.0 >= 2.12 pygobject-2.0',
- destvar='GCONF', mandatory=False):
- conf.env.append_value('MODULES_TO_BUILD', 'gconf')
-
-
-def codegen(bld, module):
- cmd = bld.create_obj('command-output')
- cmd.command = 'pygtk-codegen-2.0'
- cmd.command_is_external = True
- cmd.prio = 5
- cmd.argv = [
- '--py_ssize_t-clean',
- '--load-types', cmd.input_file('gconf-arg-types.py'),
- '--prefix', 'py'+module,
- '--override', cmd.input_file("%s.override" % module),
- cmd.input_file("%s.defs" % module),
- ]
- cmd.stdout = '%s.c' % module
- return cmd
-
-
-def build(bld):
-
- if 'gconf' in bld.env()['MODULES_TO_BUILD']:
- codegen(bld, 'gconf')
- pyext = bld.create_pyext()
- pyext.source = 'gconfmodule.c gconf.c gconf-fixes.c gconf-types.c'
- pyext.target = 'gconf'
- pyext.uselib = 'GCONF'
- pyext.includes = '.'
- pyext.inst_var = 'PYTHONDIR'
- pyext.inst_dir = 'gtk-2.0'
-
- Common.install_files('DATADIR', os.path.join('pygtk', '2.0', 'defs'),
- ['gconf.defs'])
-
- Common.install_files('DATADIR', os.path.join('pygtk', '2.0', 'argtypes'),
- 'gconf-arg-types.py')
diff --git a/xinput-ibus b/xinput-ibus
index 7f6737d..be3dc26 100644
--- a/xinput-ibus
+++ b/xinput-ibus
@@ -1,8 +1,8 @@
XIM=ibus
-XIM_PROGRAM="/usr/bin/ibus"
+XIM_PROGRAM="/usr/bin/ibus-daemon"
ICON="/usr/share/ibus/icons/ibus.svg"
# XIM_ARGS="0xffffffff"
PREFERENCE_PROGRAM=/usr/bin/ibus-setup
-SHORT_DESC="iBus"
+SHORT_DESC="IBus"
GTK_IM_MODULE=ibus
-QT_IM_MODULE=ibus
+# QT_IM_MODULE=ibus