diff --git a/bindings/python/eekboard/Makefile.am b/bindings/python/eekboard/Makefile.am index d3d1cb23..5209ea9f 100644 --- a/bindings/python/eekboard/Makefile.am +++ b/bindings/python/eekboard/Makefile.am @@ -15,7 +15,10 @@ # along with this program. If not, see # . -pkgpython_PYTHON = \ - __init__.py \ - eekboard.py \ +pkgpython_PYTHON = \ + __init__.py \ + serializable.py \ + symbol.py \ + keysym.py \ + client.py \ context.py diff --git a/bindings/python/eekboard/__init__.py b/bindings/python/eekboard/__init__.py index 3ca8dc17..d723f00e 100644 --- a/bindings/python/eekboard/__init__.py +++ b/bindings/python/eekboard/__init__.py @@ -15,53 +15,8 @@ # along with this program. If not, see # . -from gi.repository import Eek, EekXkl, Gio - -from eekboard import Eekboard -from context import Context - -Keyboard = Eek.Keyboard -Section = Eek.Section -Key = Eek.Key -Symbol = Eek.Symbol -Keysym = Eek.Keysym -SymbolMatrix = Eek.SymbolMatrix - -MODIFIER_BEHAVIOR_NONE, \ -MODIFIER_BEHAVIOR_LOCK, \ -MODIFIER_BEHAVIOR_LATCH = \ -(Eek.ModifierBehavior.NONE, - Eek.ModifierBehavior.LOCK, - Eek.ModifierBehavior.LATCH) - -SymbolCategory = Eek.SymbolCategory - -CSW = 640 -CSH = 480 - -def XmlKeyboard(path, modifier_behavior=MODIFIER_BEHAVIOR_NONE): - _file = Gio.file_new_for_path(path) - layout = Eek.XmlLayout.new(_file.read()) - keyboard = Eek.Keyboard.new(layout, CSW, CSH) - keyboard.set_modifier_behavior(modifier_behavior) - keyboard.set_alt_gr_mask(Eek.ModifierType.MOD5_MASK) - return keyboard - -def XklKeyboard(modifier_behavior=MODIFIER_BEHAVIOR_NONE): - layout = EekXkl.Layout.new() - keyboard = Eek.Keyboard.new(layout, CSW, CSH) - keyboard.set_modifier_behavior(modifier_behavior) - return keyboard - -__all__ = ['Eekboard', - 'Context', - 'Keyboard', - 'Section', - 'Key', - 'Symbol', - 'Keysym', - 'MODIFIER_BEHAVIOR_NONE', - 'MODIFIER_BEHAVIOR_LOCK', - 'MODIFIER_BEHAVIOR_LATCH', - 'XmlKeyboard', - 'XklKeyboard'] +from symbol import * +from keysym import * +from serializable import * +from client import * +from context import * diff --git a/bindings/python/eekboard/eekboard.py b/bindings/python/eekboard/client.py similarity index 57% rename from bindings/python/eekboard/eekboard.py rename to bindings/python/eekboard/client.py index 0af27c9d..3b21cb5e 100644 --- a/bindings/python/eekboard/eekboard.py +++ b/bindings/python/eekboard/client.py @@ -15,12 +15,14 @@ # along with this program. If not, see # . -from gi.repository import Gio -import gi.repository +import dbus +import dbus.mainloop.glib import gobject from context import Context -class Eekboard(gobject.GObject): +dbus.mainloop.glib.DBusGMainLoop(set_as_default = True) + +class Client(gobject.GObject): __gtype_name__ = "PYEekboardClient" __gsignals__ = { 'destroyed': ( @@ -30,20 +32,25 @@ class Eekboard(gobject.GObject): } def __init__(self): - super(Eekboard, self).__init__() - self.__connection = Gio.bus_get_sync(Gio.BusType.SESSION, None) - self.__client = gi.repository.Eekboard.Client.new(self.__connection, None); - self.__client.connect('destroyed', lambda *args: self.emit('destroyed')) + super(Client, self).__init__() + self.__bus = dbus.SessionBus() + _service = self.__bus.get_object("org.fedorahosted.Eekboard", + "/org/fedorahosted/Eekboard") + self.__service = dbus.Interface(_service, dbus_interface="org.fedorahosted.Eekboard") + self.__service.connect_to_signal("Destroyed", self.__destroyed_cb) + + def __destroyed_cb(self): + self.emit("destroyed") def create_context(self, client_name): - context = self.__client.create_context(client_name, None) - return Context(context) + object_path = self.__service.CreateContext(client_name) + return Context(self.__bus, object_path) def push_context(self, context): - self.__client.push_context(context.get_giobject(), None) + self.__service.PushContext(context.object_path) def pop_context(self): - self.__client.pop_context(None) + self.__service.PopContext() def destroy_context(self, context): - self.__client.destroy_context(context.get_giobject(), None) + self.__service.DestroyContext(context.object_path) diff --git a/bindings/python/eekboard/context.py b/bindings/python/eekboard/context.py index b4cb66f9..009e50c8 100644 --- a/bindings/python/eekboard/context.py +++ b/bindings/python/eekboard/context.py @@ -15,8 +15,9 @@ # along with this program. If not, see # . -from gi.repository import Eekboard +import dbus import gobject +import serializable class Context(gobject.GObject): __gtype_name__ = "PYEekboardContext" @@ -32,11 +33,7 @@ class Context(gobject.GObject): 'key-pressed': ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_UINT,)), - 'key-released': ( - gobject.SIGNAL_RUN_LAST, - gobject.TYPE_NONE, - (gobject.TYPE_UINT,)), + (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_UINT)), 'destroyed': ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, @@ -44,19 +41,59 @@ class Context(gobject.GObject): } __gproperties__ = { - 'keyboard-visible': (bool, None, None, False, gobject.PARAM_READWRITE), + 'visible': (gobject.TYPE_BOOLEAN, 'Visible', 'Visible', + False, gobject.PARAM_READWRITE), + 'keyboard': (gobject.TYPE_UINT, 'Keyboard', 'Keyboard', + 0, gobject.G_MAXUINT, 0, gobject.PARAM_READWRITE), + 'group': (gobject.TYPE_UINT, 'Group', 'Group', + 0, gobject.G_MAXUINT, 0, gobject.PARAM_READWRITE), } - def __init__(self, giobject): + def __init__(self, bus, object_path): super(Context, self).__init__() - self.__properties = dict() - self.__giobject = giobject - self.__giobject.connect('enabled', lambda *args: self.emit('enabled')) - self.__giobject.connect('disabled', lambda *args: self.emit('disabled')) - self.__giobject.connect('key-pressed', lambda *args: self.emit('key-pressed', args[1])) - self.__giobject.connect('key-released', lambda *args: self.emit('key-released', args[1])) - self.__giobject.connect('destroyed', lambda *args: self.emit('destroyed')) - self.__giobject.connect('notify::keyboard-visible', self.__notify_keyboard_visible_cb) + self.__bus = bus + self.__object_path = object_path + self.__properties = {} + _context = self.__bus.get_object("org.fedorahosted.Eekboard", + object_path) + self.__context = dbus.Interface(_context, dbus_interface="org.fedorahosted.Eekboard.Context") + + self.__context.connect_to_signal('Enabled', self.__enabled_cb) + self.__context.connect_to_signal('Disabled', self.__disabled_cb) + self.__context.connect_to_signal('KeyPressed', self.__key_pressed_cb) + self.__context.connect_to_signal('Destroyed', self.__destroyed_cb) + self.__context.connect_to_signal('VisibilityChanged', self.__visibility_changed_cb) + self.__context.connect_to_signal('KeyboardChanged', self.__keyboard_changed_cb) + self.__context.connect_to_signal('GroupChanged', self.__group_changed_cb) + + object_path = property(lambda self: self.__object_path) + + def __enabled_cb(self): + self.emit('enabled') + + def __disabled_cb(self): + self.emit('disabled') + + def __key_pressed_cb(self, *args): + keyname = args[0] + symbol = serializable.deserialize_object(args[1]) + modifiers = args[2] + self.emit('key-pressed', keyname, symbol, modifiers) + + def __visibility_changed_cb(self, *args): + self.set_property('visible', args[0]) + self.notify('visible') + + def __keyboard_changed_cb(self, *args): + self.set_property('keyboard', args[0]) + self.notify('keyboard') + + def __group_changed_cb(self, *args): + self.set_property('group', args[0]) + self.notify('group') + + def __destroyed_cb(self): + self.emit("destroyed") def do_set_property(self, pspec, value): self.__properties[pspec.name] = value @@ -64,37 +101,26 @@ class Context(gobject.GObject): def do_get_property(self, pspec): return self.__properties[pspec.name] - def __notify_keyboard_visible_cb(self, *args): - self.set_property('keyboard-visible', - self.__giobject.get_property(args[1].name)) - self.notify('keyboard-visible') - - def get_giobject(self): - return self.__giobject - - def add_keyboard(self, keyboard): - return self.__giobject.add_keyboard(keyboard, None) + def add_keyboard(self, keyboard_type): + return self.__context.AddKeyboard(keyboard_type) def remove_keyboard(self, keyboard_id): - return self.__giobject.remove_keyboard(keyboard_id, None) + return self.__context.RemoveKeyboard(keyboard_id) def set_keyboard(self, keyboard_id): - self.__giobject.set_keyboard(keyboard_id, None) + self.__context.SetKeyboard(keyboard_id) def show_keyboard(self): - self.__giobject.show_keyboard(None) + self.__context.ShowKeyboard() def hide_keyboard(self): - self.__giobject.hide_keyboard(None) + self.__context.HideKeyboard() def set_group(self, group): - self.__giobject.set_group(group, None) + self.__context.SetGroup(group) - def press_key(self, keycode): - self.__giobject.press_key(keycode, None) + def press_keycode(self, keycode): + self.__context.PressKeycode(keycode) - def release_key(self, keycode): - self.__giobject.release_key(keycode, None) - - def is_enabled(self): - return self.__giobject.is_enabled() + def release_keycode(self, keycode): + self.__context.ReleaseKeycode(keycode) diff --git a/bindings/python/eekboard/keysym.py b/bindings/python/eekboard/keysym.py new file mode 100644 index 00000000..b787e709 --- /dev/null +++ b/bindings/python/eekboard/keysym.py @@ -0,0 +1,35 @@ +# Copyright (C) 2011 Daiki Ueno +# Copyright (C) 2011 Red Hat, Inc. + +# 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 3 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, see +# . + +import symbol + +class Keysym(symbol.Symbol): + __gtype_name__ = "PYEekKeysym" + __NAME__ = "EekKeysym" + + def __init__(self): + super(Keysym, self).__init__() + + xkeysym = property(lambda self: self.xkeysym) + + def serialize(self, struct): + super(Keysym, self).serialize(struct) + struct.append(dbus.UInt32(self.__xkeysym)) + + def deserialize(self, struct): + super(Keysym, self).deserialize(struct) + self.__xkeysym = struct.pop(0) diff --git a/bindings/python/eekboard/serializable.py b/bindings/python/eekboard/serializable.py new file mode 100644 index 00000000..ad82a4a5 --- /dev/null +++ b/bindings/python/eekboard/serializable.py @@ -0,0 +1,76 @@ +# vim:set et sts=4 sw=4: +# +# ibus - The Input Bus +# +# Copyright (c) 2007-2010 Peng Huang +# Copyright (c) 2007-2010 Red Hat, Inc. +# +# 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", + "serialize_object", + "deserialize_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 SerializableMeta(gobject.GObjectMeta): + def __init__(cls, name, bases, dict_): + super(SerializableMeta, cls).__init__(name, bases, dict_) + if "__NAME__" in cls.__dict__: + serializable_register(cls) + +class Serializable(gobject.GObject): + __metaclass__ = SerializableMeta + __gtype_name__ = "PYEekSerializable" + __NAME__ = "EekSerializable" + def __init__(self): + super(Serializable, self).__init__() + + def serialize(self, struct): + pass + + def deserialize(self, struct): + pass + +__serializable_name_dict["EekSerializable"] = Serializable diff --git a/bindings/python/eekboard/symbol.py b/bindings/python/eekboard/symbol.py new file mode 100644 index 00000000..00d38562 --- /dev/null +++ b/bindings/python/eekboard/symbol.py @@ -0,0 +1,47 @@ +# Copyright (C) 2011 Daiki Ueno +# Copyright (C) 2011 Red Hat, Inc. + +# 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 3 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, see +# . + +import serializable + +class Symbol(serializable.Serializable): + __gtype_name__ = "PYEekSymbol" + __NAME__ = "EekSymbol" + + def __init__(self): + super(Symbol, self).__init__() + + name = property(lambda self: self.__name) + label = property(lambda self: self.__label) + category = property(lambda self: self.__category) + modifier_mask = property(lambda self: self.__modifier_mask) + icon_name = property(lambda self: self.__icon_name) + + def serialize(self, struct): + super(Symbol, self).serialize(struct) + struct.append(dbus.String(self.__name)) + struct.append(dbus.String(self.__label)) + struct.append(dbus.UInt32(self.__category)) + struct.append(dbus.UInt32(self.__modifier_mask)) + struct.append(dbus.String(self.__icon_name)) + + def deserialize(self, struct): + super(Symbol, self).deserialize(struct) + self.__name = struct.pop(0) + self.__label = struct.pop(0) + self.__category = struct.pop(0) + self.__modifier_mask = struct.pop(0) + self.__icon_name = struct.pop(0)