summaryrefslogtreecommitdiffstats
path: root/ibus
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 /ibus
parent41ad46305a88637dd99f00a2d2a3f455505d357b (diff)
downloadibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.tar.gz
ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.tar.xz
ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.zip
re-implement ibus in c language.
Diffstat (limited to 'ibus')
-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
30 files changed, 1509 insertions, 741 deletions
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()