diff options
author | Eitan Isaacson <eitan@monotonous.org> | 2011-05-02 10:23:17 -0700 |
---|---|---|
committer | Eitan Isaacson <eitan@monotonous.org> | 2011-05-02 10:23:26 -0700 |
commit | f5aed67a39df38f7becf4708a80f78797823c0d3 (patch) | |
tree | 1c0d2d7bc28f5e3c15f01bb98103da8e75490fbe | |
parent | 838a94e57bbbec96cdb476039934903fa40cf3b5 (diff) | |
parent | 18c12607e1412702053132862e08070b0278b0a6 (diff) | |
download | caribou-f5aed67a39df38f7becf4708a80f78797823c0d3.tar.gz |
Merge branch 'geometry'
Major Caribou changes:
* Couple keyboard layout with XKB state.
* Simplify layout format
* Create libcaribou, an introspectable C/GObject library for creating keyboard
UIs.
* DBusify UI, have main caribou app activate the keyboard via DBus.
67 files changed, 2463 insertions, 5011 deletions
@@ -9,10 +9,12 @@ aclocal.m4 autom4te.cache *.make bin/caribou +bin/caribou-preferences +bin/antler-keyboard install-sh missing py-compile -caribou/ui/i18n.py +caribou/i18n.py mkinstalldirs po/Makefile.in.in po/POTFILES @@ -33,8 +35,14 @@ libtool ltmain.sh m4 libcaribou/.libs/ -libcaribou/Caribou-1.0.gir -libcaribou/Caribou-1.0.typelib +libcaribou/*.gir +libcaribou/*.typelib *.lo +*.o libcaribou/libcaribou.la - +libcaribou/*.[ch] +caribou-1.0.vapi +caribou-internals-1.0.vapi +caribou-internals.h +*.stamp +data/org.gnome.Caribou.Antler.service diff --git a/bin/Makefile.am b/bin/Makefile.am index cae01c9..88f281d 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -1,4 +1,5 @@ -bin_SCRIPTS = caribou +bin_SCRIPTS = caribou caribou-preferences +libexec_SCRIPTS = antler-keyboard CLEANFILES = $(bin_SCRIPTS) diff --git a/bin/antler-keyboard.in b/bin/antler-keyboard.in new file mode 100644 index 0000000..b42734c --- /dev/null +++ b/bin/antler-keyboard.in @@ -0,0 +1,37 @@ +#!/bin/bash +# +# Antler - a Caribou keyboard implementation +# +# Copyright (C) 2011 Eitan Isaacson <eitan@monotonous.org> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 2.1 of the License, or (at your +# option) any later version. +# +# This 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +script_dir="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" + +if [ $script_dir == "@prefix@@libexecdir@" ] +then + export PYTHONPATH="@prefix@/lib/python@PYTHON_VERSION@/site-packages:${PYTHONPATH}" + export GI_TYPELIB_PATH="@prefix@@libdir@/girepository-1.0:${GI_TYPELIB_PATH}" + export LD_LIBRARY_PATH="@prefix@@libdir@:${LD_LIBRARY_PATH}" + export XDG_DATA_DIRS="@prefix@@datadir@:${XDG_DATA_DIRS}" +else + export PYTHONPATH="$(dirname $script_dir):${PYTHONPATH}" + export GI_TYPELIB_PATH="$(dirname $script_dir)/licaribou:${GI_TYPELIB_PATH}" + export LD_LIBRARY_PATH="$(dirname $script_dir)/licaribou/.lib:${LD_LIBRARY_PATH}" +fi + +@PYTHON@ -c " +from caribou.antler.main import AntlerKeyboardService +AntlerKeyboardService().run()" diff --git a/bin/caribou-preferences.in b/bin/caribou-preferences.in new file mode 100644 index 0000000..13948c8 --- /dev/null +++ b/bin/caribou-preferences.in @@ -0,0 +1,53 @@ +#!/bin/bash +# +# Antler - a Caribou keyboard implementation +# +# Copyright (C) 2011 Eitan Isaacson <eitan@monotonous.org> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 2.1 of the License, or (at your +# option) any later version. +# +# This 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +script_dir="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" + +if [ $script_dir == "@prefix@@libexecdir@" ] +then + export PYTHONPATH="@prefix@/lib/python@PYTHON_VERSION@/site-packages:${PYTHONPATH}" + export GI_TYPELIB_PATH="@libdir@/girepository-1.0:${GI_TYPELIB_PATH}" + export LD_LIBRARY_PATH="@libdir@:${LD_LIBRARY_PATH}" + export XDG_DATA_DIRS="@prefix@@datadir@:${XDG_DATA_DIRS}" +else + export PYTHONPATH="$(dirname $script_dir):${PYTHONPATH}" + export GI_TYPELIB_PATH="$(dirname $script_dir)/licaribou:${GI_TYPELIB_PATH}" + export LD_LIBRARY_PATH="$(dirname $script_dir)/licaribou/.lib:${LD_LIBRARY_PATH}" +fi + +@PYTHON@ -c " +import signal +signal.signal(signal.SIGINT, signal.SIG_DFL) + +from caribou.settings.preferences_window import PreferencesWindow +from caribou.settings import CaribouSettings +from gi.repository import Gtk + +w = PreferencesWindow(CaribouSettings()) + +w.connect('delete-event', lambda x, y: Gtk.main_quit()) + +w.show_all() + +try: + Gtk.main() +except KeyboardInterrupt: + Gtk.main_quit() +" diff --git a/bin/caribou.in b/bin/caribou.in index fb31d47..7bebd0d 100644 --- a/bin/caribou.in +++ b/bin/caribou.in @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/bin/bash # # Caribou - text entry and UI navigation application # @@ -24,61 +24,15 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -from optparse import OptionParser -import gettext -import sys -import pyatspi -import os +script_dir="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" -# We can't rely on prefix if we're installed by relocated RPM. Instead, we -# use __file__ and for now hope that lib is relative to bin. -_dirname = os.path.dirname(__file__) -sys.prefix = os.path.normpath(os.path.join(_dirname, '..')) -libs = os.path.join(sys.prefix, 'lib', - 'python@PYTHON_VERSION@', 'site-packages') -# point to the proper site-packages path -sys.path.insert(1, libs) - -# This might be run from the build dir. -if os.path.abspath(_dirname) != "@prefix@/bin": - srcdir = os.path.normpath(os.path.join(_dirname, '..')) - sys.path.insert(1, srcdir) - import caribou.common - import caribou.ui - caribou.data_path = os.path.abspath(os.path.join(_dirname, - "@top_srcdir@", - "data")) -else: - import caribou.common - import caribou.ui - caribou.data_path = os.path.join("@prefix@", "share", "caribou") - -import caribou.ui.window as window -import caribou.ui.keyboard as keyboard -import caribou.ui.main as main - -_ = gettext.gettext - -if __name__ == "__main__": - import signal - - signal.signal(signal.SIGINT, signal.SIG_DFL) - - parser = OptionParser(usage="usage: %prog [options]", - version="%prog @VERSION@") - parser.add_option("-d", "--debug", - action="store_true", dest="debug", default=False, - help="print debug messages on stdout") - (options, args) = parser.parse_args() - - main.debug = options.debug - - caribou = main.Caribou() - caribou.window.hide() - - try: - pyatspi.Registry.start() - except KeyboardInterrupt: - caribou.clean_exit() - pyatspi.Registry.stop() +if [ $script_dir == "@prefix@/bin" ] +then + export PYTHONPATH="@prefix@/lib/python@PYTHON_VERSION@/site-packages:${PYTHONPATH}" + export GI_TYPELIB_PATH="@libdir@/girepository-1.0":${GI_TYPELIB_PATH} +else + export PYTHONPATH="$(dirname $script_dir):${PYTHONPATH}" + export GI_TYPELIB_PATH="$(dirname $script_dir)/licaribou":${GI_TYPELIB_PATH} +fi +@PYTHON@ -c "from caribou.daemon.main import CaribouDaemon; CaribouDaemon().run()" diff --git a/caribou/Makefile.am b/caribou/Makefile.am index 962a2b4..713d8ad 100644 --- a/caribou/Makefile.am +++ b/caribou/Makefile.am @@ -1,11 +1,15 @@ cariboudir = $(pkgpythondir)/ caribou_PYTHON = \ - __init__.py + __init__.py \ + i18n.py SUBDIRS = \ - common/ \ - ui/ + antler/ \ + settings/ \ + daemon/ + +DISTCLEANFILES = i18n.py clean-local: rm -rf *.pyc *.pyo diff --git a/caribou/__init__.py b/caribou/__init__.py index 1aadcdc..cf8fdc7 100644 --- a/caribou/__init__.py +++ b/caribou/__init__.py @@ -1 +1,2 @@ -data_path = "data/" +from i18n import _ +APP_NAME=_("Caribou") diff --git a/caribou/antler/Makefile.am b/caribou/antler/Makefile.am new file mode 100644 index 0000000..51efe0f --- /dev/null +++ b/caribou/antler/Makefile.am @@ -0,0 +1,10 @@ +caribou_antlerdir = $(pkgpythondir)/antler/ + +caribou_antler_PYTHON = \ + __init__.py \ + keyboard_view.py \ + main.py \ + window.py + +clean-local: + rm -rf *.pyc *.pyo diff --git a/libcaribou/caribou-enum-types.c.tmpl b/caribou/antler/__init__.py index e69de29..e69de29 100644 --- a/libcaribou/caribou-enum-types.c.tmpl +++ b/caribou/antler/__init__.py diff --git a/caribou/antler/keyboard_view.py b/caribou/antler/keyboard_view.py new file mode 100644 index 0000000..6cea11b --- /dev/null +++ b/caribou/antler/keyboard_view.py @@ -0,0 +1,164 @@ +from caribou.settings.preferences_window import PreferencesDialog +from caribou.settings import CaribouSettings +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import Caribou +import gobject + +PRETTY_LABELS = { + "BackSpace" : u'\u232b', + "space" : u' ', + "Return" : u'\u23ce', + 'Caribou_Prefs' : u'\u2328', + 'Caribou_ShiftUp' : u'\u2b06', + 'Caribou_ShiftDown' : u'\u2b07', + 'Caribou_Emoticons' : u'\u263a', + 'Caribou_Symbols' : u'123', + 'Caribou_Symbols_More' : u'{#*', + 'Caribou_Alpha' : u'Abc' +} + +class AntlerKey(Gtk.Button): + def __init__(self, key): + gobject.GObject.__init__(self) + self.caribou_key = key + self.connect("pressed", self._on_pressed) + self.connect("released", self._on_released) + self.set_label(self._get_key_label()) + if key.props.name == "Caribou_Prefs": + key.connect("key-clicked", self._on_prefs_clicked) + if key.get_extended_keys (): + self._sublevel = AntlerSubLevel(self) + + def _on_prefs_clicked(self, key): + p = PreferencesDialog(CaribouSettings()) + p.show_all() + p.run() + p.destroy() + + def _get_key_label(self): + label = self.caribou_key.props.name + if PRETTY_LABELS.has_key(self.caribou_key.props.name): + label = PRETTY_LABELS[self.caribou_key.props.name] + elif self.caribou_key.props.name.startswith('Caribou_'): + label = self.caribou_key.name.replace('Caribou_', '') + else: + unichar = unichr(Gdk.keyval_to_unicode(self.caribou_key.props.keyval)) + if not unichar.isspace() and unichar != u'\x00': + label = unichar + + return label + + def _on_pressed(self, button): + self.caribou_key.press() + + def _on_released(self, button): + self.caribou_key.release() + + def do_get_preferred_width_for_height(self, w): + return (w, w) + + def do_get_request_mode(self): + return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH + +class AntlerSubLevel(Gtk.Window): + def __init__(self, key): + gobject.GObject.__init__(self, type=Gtk.WindowType.POPUP) + + self.set_decorated(False) + self.set_resizable(False) + self.set_accept_focus(False) + self.set_position(Gtk.WindowPosition.MOUSE) + self.set_type_hint(Gdk.WindowTypeHint.DIALOG) + + key.caribou_key.connect("notify::show-subkeys", self._on_show_subkeys) + self._key = key + + layout = AntlerLayout() + layout.add_row(key.caribou_key.get_extended_keys()) + self.add(layout) + + def _on_show_subkeys(self, key, prop): + parent = self._key.get_toplevel() + if key.props.show_subkeys: + self.set_transient_for(parent) + parent.set_sensitive(False) + self.show_all() + else: + parent.set_sensitive(True) + self.hide() + +class AntlerLayout(Gtk.Grid): + KEY_SPAN = 4 + + def __init__(self, level=None): + gobject.GObject.__init__(self) + self.set_column_homogeneous(True) + self.set_row_homogeneous(True) + self.set_row_spacing(4) + self.set_column_spacing(4) + if level: + self.load_rows(level.get_rows ()) + + def add_row(self, row, row_num=0): + col_num = 0 + for i, key in enumerate(row): + antler_key = AntlerKey(key) + self.attach(antler_key, + col_num + int(key.props.margin_left * self.KEY_SPAN), + row_num * self.KEY_SPAN, + int(self.KEY_SPAN * key.props.width), + self.KEY_SPAN) + col_num += int((key.props.width + key.props.margin_left ) * self.KEY_SPAN) + + + def load_rows(self, rows): + for row_num, row in enumerate(rows): + self.add_row(row.get_keys(), row_num) + +class AntlerKeyboardView(Gtk.Notebook): + def __init__(self): + gobject.GObject.__init__(self) + self.set_show_tabs(False) + self.keyboard_model = Caribou.KeyboardModel() + self.keyboard_model.connect("notify::active-group", self._on_group_changed) + self.layers = {} + for gname in self.keyboard_model.get_groups(): + group = self.keyboard_model.get_group(gname) + self.layers[gname] = {} + group.connect("notify::active-level", self._on_level_changed) + for lname in group.get_levels(): + level = group.get_level(lname) + layout = AntlerLayout(level) + layout.show() + self.layers[gname][lname] = self.append_page(layout, None) + + self._set_to_active_layer() + + def _on_level_changed(self, group, prop): + self._set_to_active_layer() + + def _on_group_changed(self, kb, prop): + self._set_to_active_layer() + + def _set_to_active_layer(self): + active_group_name = self.keyboard_model.props.active_group + active_group = self.keyboard_model.get_group(active_group_name) + active_level_name = active_group.props.active_level + + self.set_current_page(self.layers[active_group_name][active_level_name]) + + +if __name__ == "__main__": + import signal + signal.signal(signal.SIGINT, signal.SIG_DFL) + + w = Gtk.Window() + w.set_accept_focus(False) + + kb = AntlerKeyboardView() + w.add(kb) + + w.show_all() + + Gtk.main() diff --git a/caribou/antler/main.py b/caribou/antler/main.py new file mode 100644 index 0000000..ce0eca3 --- /dev/null +++ b/caribou/antler/main.py @@ -0,0 +1,30 @@ +from gi.repository import Caribou +from window import AntlerWindowEntry +from keyboard_view import AntlerKeyboardView +import gobject + +class AntlerKeyboardService(Caribou.KeyboardService): + def __init__(self): + gobject.GObject.__init__(self) + self.register_keyboard("Antler") + self.window = AntlerWindowEntry(AntlerKeyboardView()) + + def run(self): + loop = gobject.MainLoop() + loop.run() + + def do_show(self): + self.window.show_all() + + def do_hide(self): + self.window.hide() + + def do_set_cursor_location (self, x, y, w, h): + self.window.set_cursor_location(x, y, w, h) + + def do_set_entry_location (self, x, y, w, h): + self.window.set_entry_location(x, y, w, h) + +if __name__ == "__main__": + antler_keyboard_service = AntlerKeyboardService() + antler_keyboard_service.run() diff --git a/caribou/ui/window.py b/caribou/antler/window.py index 471ee1c..973824a 100644 --- a/caribou/ui/window.py +++ b/caribou/antler/window.py @@ -20,10 +20,6 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -from caribou import data_path -from opacity import ProximityWindowBase -from caribou.common.settings_manager import SettingsManager - from gi.repository import Gtk from gi.repository import Gdk from gi.repository import Clutter @@ -31,12 +27,71 @@ import os import sys import gobject -CARIBOU_LAYOUT_DIR = 'keyboards' +Clutter.init("antler") + +class ProximityWindowBase(object): + def __init__(self, min_alpha=1.0, max_alpha=1.0, max_distance=100): + if self.__class__ == ProximityWindowBase: + raise TypeError, \ + "ProximityWindowBase is an abstract class, " \ + "must be subclassed with a Gtk.Window" + self.connect('map-event', self.__onmapped) + self.max_distance = max_distance + if max_alpha < min_alpha: + raise ValueError, "min_alpha can't be larger than max_alpha" + self.min_alpha = min_alpha + self.max_alpha = max_alpha + + def __onmapped(self, obj, event): + if self.is_composited(): + self.set_opacity(self.max_alpha) + if self.max_alpha != self.min_alpha: + # Don't waste CPU if the max and min are equal. + glib.timeout_add(80, self._proximity_check) + + def _proximity_check(self): + px, py = self.get_pointer() + + ww = self.get_allocated_width() + wh = self.get_allocated_height() -Clutter.init("caribou") + distance = self._get_distance_to_bbox(px, py, ww, wh) -class CaribouWindow(Gtk.Window, Clutter.Animatable, ProximityWindowBase): - __gtype_name__ = "CaribouWindow" + opacity = (self.max_alpha - self.min_alpha) * \ + (1 - min(distance, self.max_distance)/self.max_distance) + opacity += self.min_alpha + + self.set_opacity(opacity) + return self.props.visible + + def _get_distance_to_bbox(self, px, py, bw, bh): + if px < 0: + x_distance = float(abs(px)) + elif px > bw: + x_distance = float(px - bw) + else: + x_distance = 0.0 + + if py < 0: + y_distance = float(abs(px)) + elif py > bh: + y_distance = float(py - bh) + else: + y_distance = 0.0 + + if y_distance == 0 and x_distance == 0: + return 0.0 + elif y_distance != 0 and x_distance == 0: + return y_distance + elif y_distance == 0 and x_distance != 0: + return x_distance + else: + x2 = 0 if x_distance > 0 else bw + y2 = 0 if y_distance > 0 else bh + return sqrt((px - x2)**2 + (py - y2)**2) + +class AntlerWindow(Gtk.Window, Clutter.Animatable, ProximityWindowBase): + __gtype_name__ = "AntlerWindow" __gproperties__ = { 'animated-window-position' : (gobject.TYPE_PYOBJECT, 'Window position', 'Window position in X, Y coordinates', @@ -52,7 +107,7 @@ class CaribouWindow(Gtk.Window, Clutter.Animatable, ProximityWindowBase): max_alpha=max_alpha, max_distance=max_distance) - self.set_name("CaribouWindow") + self.set_name("AntlerWindow") self._vbox = Gtk.VBox() self.add(self._vbox) @@ -64,11 +119,7 @@ class CaribouWindow(Gtk.Window, Clutter.Animatable, ProximityWindowBase): self._cursor_location = Rectangle() self._entry_location = Rectangle() self._default_placement = default_placement or \ - CaribouWindowPlacement() - - conf_file_path = self._get_keyboard_conf() - if conf_file_path: - text_entry_mech.load_kb(conf_file_path) + AntlerWindowPlacement() self.connect('show', self._on_window_show) @@ -118,13 +169,12 @@ class CaribouWindow(Gtk.Window, Clutter.Animatable, ProximityWindowBase): self.keyboard.destroy() super(Gtk.Window, self).destroy() - - def set_cursor_location(self, cursor_location): - self._cursor_location = cursor_location + def set_cursor_location(self, x, y, w, h): + self._cursor_location = Rectangle(x, y, w, h) self._update_position() - def set_entry_location(self, entry_location): - self._entry_location = entry_location + def set_entry_location(self, x, y, w, h): + self._entry_location = Rectangle(x, y, w, h) self._update_position() def set_default_placement(self, default_placement): @@ -182,49 +232,29 @@ class CaribouWindow(Gtk.Window, Clutter.Animatable, ProximityWindowBase): def _calculate_axis(self, axis_placement, root_bbox): bbox = root_bbox - if axis_placement.stickto == CaribouWindowPlacement.CURSOR: + if axis_placement.stickto == AntlerWindowPlacement.CURSOR: bbox = self._cursor_location - elif axis_placement.stickto == CaribouWindowPlacement.ENTRY: + elif axis_placement.stickto == AntlerWindowPlacement.ENTRY: bbox = self._entry_location offset = axis_placement.get_offset(bbox.x, bbox.y) - if axis_placement.align == CaribouWindowPlacement.END: + if axis_placement.align == AntlerWindowPlacement.END: offset += axis_placement.get_length(bbox.width, bbox.height) - if axis_placement.gravitate == CaribouWindowPlacement.INSIDE: + if axis_placement.gravitate == AntlerWindowPlacement.INSIDE: offset -= axis_placement.get_length( self.get_allocated_width(), self.get_allocated_height()) - elif axis_placement.align == CaribouWindowPlacement.START: - if axis_placement.gravitate == CaribouWindowPlacement.OUTSIDE: + elif axis_placement.align == AntlerWindowPlacement.START: + if axis_placement.gravitate == AntlerWindowPlacement.OUTSIDE: offset -= axis_placement.get_length( self.get_allocated_width(), self.get_allocated_height()) - elif axis_placement.align == CaribouWindowPlacement.CENTER: + elif axis_placement.align == AntlerWindowPlacement.CENTER: offset += axis_placement.get_length(bbox.width, bbox.height)/2 return offset - def _get_keyboard_conf(self): - layout = SettingsManager.layout.value - conf_file_path = os.path.join(data_path, CARIBOU_LAYOUT_DIR, layout) - - if os.path.exists(conf_file_path): - return conf_file_path - else: - json_path = '%s.json' % conf_file_path - - if os.path.exists(json_path): - return json_path - - xml_path = '%s.xml' % conf_file_path - - if os.path.exists(xml_path): - return xml_path - - raise Exception("Could not load keyboard %s" % conf_file_path) - - def show_all(self): Gtk.Window.show_all(self) self.keyboard.show_all() @@ -239,18 +269,18 @@ class CaribouWindow(Gtk.Window, Clutter.Animatable, ProximityWindowBase): req = child.size_request() self.resize(req.width + border, req.height + border) -class CaribouWindowDocked(CaribouWindow): - __gtype_name__ = "CaribouWindowDocked" +class AntlerWindowDocked(AntlerWindow): + __gtype_name__ = "AntlerWindowDocked" def __init__(self, text_entry_mech): - placement = CaribouWindowPlacement( - xalign=CaribouWindowPlacement.END, - yalign=CaribouWindowPlacement.START, - xstickto=CaribouWindowPlacement.SCREEN, - ystickto=CaribouWindowPlacement.SCREEN, - xgravitate=CaribouWindowPlacement.INSIDE) + placement = AntlerWindowPlacement( + xalign=AntlerWindowPlacement.END, + yalign=AntlerWindowPlacement.START, + xstickto=AntlerWindowPlacement.SCREEN, + ystickto=AntlerWindowPlacement.SCREEN, + xgravitate=AntlerWindowPlacement.INSIDE) - CaribouWindow.__init__(self, text_entry_mech, placement) + AntlerWindow.__init__(self, text_entry_mech, placement) self.connect('map-event', self.__onmapped) @@ -268,32 +298,32 @@ class CaribouWindowDocked(CaribouWindow): def hide(self): animation = self._roll_out() - animation.connect('completed', lambda x: CaribouWindow.hide(self)) + animation.connect('completed', lambda x: AntlerWindow.hide(self)) -class CaribouWindowEntry(CaribouWindow): - __gtype_name__ = "CaribouWindowEntry" +class AntlerWindowEntry(AntlerWindow): + __gtype_name__ = "AntlerWindowEntry" def __init__(self, text_entry_mech): - placement = CaribouWindowPlacement( - xalign=CaribouWindowPlacement.START, - xstickto=CaribouWindowPlacement.ENTRY, - ystickto=CaribouWindowPlacement.ENTRY, - xgravitate=CaribouWindowPlacement.INSIDE, - ygravitate=CaribouWindowPlacement.OUTSIDE) + placement = AntlerWindowPlacement( + xalign=AntlerWindowPlacement.START, + xstickto=AntlerWindowPlacement.ENTRY, + ystickto=AntlerWindowPlacement.ENTRY, + xgravitate=AntlerWindowPlacement.INSIDE, + ygravitate=AntlerWindowPlacement.OUTSIDE) - CaribouWindow.__init__(self, text_entry_mech, placement) + AntlerWindow.__init__(self, text_entry_mech, placement) def _calculate_axis(self, axis_placement, root_bbox): - offset = CaribouWindow._calculate_axis(self, axis_placement, root_bbox) + offset = AntlerWindow._calculate_axis(self, axis_placement, root_bbox) if axis_placement.axis == 'y': if offset + self.get_allocated_height() > root_bbox.height + root_bbox.y: - new_axis_placement = axis_placement.copy(align=CaribouWindowPlacement.START) - offset = CaribouWindow._calculate_axis(self, new_axis_placement, root_bbox) + new_axis_placement = axis_placement.copy(align=AntlerWindowPlacement.START) + offset = AntlerWindow._calculate_axis(self, new_axis_placement, root_bbox) return offset -class CaribouWindowPlacement(object): +class AntlerWindowPlacement(object): START = 'start' END = 'end' CENTER = 'center' @@ -354,7 +384,6 @@ class CaribouWindowPlacement(object): ystickto or self.CURSOR, ygravitate or self.OUTSIDE) - class Rectangle(object): def __init__(self, x=0, y=0, width=0, height=0): self.x = x @@ -363,11 +392,11 @@ class Rectangle(object): self.height = height if __name__ == "__main__": - import keyboard + import keyboard_view import signal signal.signal(signal.SIGINT, signal.SIG_DFL) - w = CaribouWindowDocked(keyboard.CaribouKeyboard()) + w = AntlerWindowDocked(keyboard_view.AntlerKeyboardView()) w.show_all() try: diff --git a/caribou/common/Makefile.am b/caribou/common/Makefile.am deleted file mode 100644 index 74805af..0000000 --- a/caribou/common/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -caribou_commondir = $(pkgpythondir)/common/ - -caribou_common_PYTHON = \ - __init__.py \ - const.py \ - settings_manager.py \ - settings.py \ - setting_types.py - -clean-local: - rm -rf *.pyc *.pyo diff --git a/caribou/common/__init__.py b/caribou/common/__init__.py deleted file mode 100644 index 8d1c8b6..0000000 --- a/caribou/common/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/caribou/common/const.py b/caribou/common/const.py deleted file mode 100644 index b3a13b7..0000000 --- a/caribou/common/const.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Caribou - text entry and UI navigation application -# -# Copyright (C) 2010 Warp Networks S.L. -# * Contributor: David Pellicer <dpellicer@warp.es> -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by the -# Free Software Foundation; either version 2.1 of the License, or (at your -# option) any later version. -# -# This 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -from os.path import join -from os.path import dirname - -from caribou import data_path - -# Application name -APP_NAME = 'Caribou' -APP_SLUG_NAME = 'caribou' - -# Paths -DATA_DIR = data_path -KEYBOARDS_DIR = join(DATA_DIR, 'keyboards') - -# Preferences -CARIBOU_GCONF = '/org/gnome/caribou/osk' - -# Key types -NORMAL_KEY_TYPE = 'normal' -LAYOUT_SWITCHER_KEY_TYPE = 'layout_switcher' -PREFERENCES_KEY_TYPE = 'preferences' -DUMMY_KEY_TYPE = 'dummy' -MASK_KEY_TYPE = 'mask' diff --git a/caribou/common/settings.py b/caribou/common/settings.py deleted file mode 100644 index a3d900d..0000000 --- a/caribou/common/settings.py +++ /dev/null @@ -1,179 +0,0 @@ -import os -from setting_types import * -from gettext import gettext as _ -import caribou.common.const as const -import caribou.ui.i18n -import xml.dom.minidom - -GSETTINGS_SCHEMA = "org.gnome.caribou" - -try: - import json -except ImportError: - HAS_JSON = False -else: - HAS_JSON = True - -def fetch_keyboards(): - try: - files = os.listdir(const.KEYBOARDS_DIR) - except: - files = [] - kbds = [] - for f in files: - if (HAS_JSON and f.endswith('.json')) or f.endswith('.xml'): - module = f.rsplit('.', 1)[0] - # TODO: verify keyboard before adding it to the list - kbds.append(module) - return kbds - -settings = SettingsGroup("_top", "", [ - SettingsGroup("keyboard", _("Keyboard"), [ - SettingsGroup("general", _("General"), [ - StringSetting( - "layout", _("Keyboard layout"), "qwerty", - _("The layout Caribou should use."), - _("The layout should be in the data directory of " - "Caribou (usually /usr/share/caribou/keyboards) " - "and should be a .xml or .json file."), - allowed=[(a,a) for a in fetch_keyboards()])]), - SettingsGroup("color", _("Color"), [ - BooleanSetting( - "default_colors", _("Use system theme"), True, - _("Use the default theme colors"), - insensitive_when_true=["normal_color", - "mouse_over_color"]), - ColorSetting( - "normal_color", _("Normal state"), "grey80", - _("Color of the keys when there is no " - "event on them")), - ColorSetting( - "mouse_over_color", _("Mouse over"), "yellow", - _("Color of the keys when the mouse goes " - "over the key"))]), - SettingsGroup("fontandsize", _("Font and size"), [ - BooleanSetting( - "default_font", _("Use system fonts"), True, - _("Use the default system font for keyboard"), - insensitive_when_true=["key_font"]), - FontSetting("key_font", _("Key font"), "Sans 12", - _("Custom font for keyboard")) - ]) - ]), - SettingsGroup("scanning", _("Scanning"), [ - BooleanSetting( - "scan_enabled", _("Enable scanning"), False, - _("Enable switch scanning"), - insensitive_when_false=["scanning_general", - "scanning_input", - "scanning_color"]), - SettingsGroup("scanning_general", _("General"), [ - StringSetting("scanning_type", _("Scanning mode"), - "block", - _("Scanning type, block or row"), - allowed=[("block", _("Block")), - ("row", _("Row"))]), - FloatSetting("step_time", _("Step time"), 1.0, - _("Time between key transitions"), - min=0.1, max=60.0), - BooleanSetting("reverse_scanning", - _("Reverse scanning"), False, - _("Scan in reverse order")) - ]), - SettingsGroup("scanning_input", _("Input"), [ - StringSetting("switch_type", _("Switch device"), - "keyboard", - _("Switch device, keyboard or mouse"), - entry_type=ENTRY_RADIO, - allowed=[("keyboard", _("Keyboard")), - ("mouse", _("Mouse"))], - children=[ - StringSetting("keyboard_key", _("Switch key"), - "Shift_R", - _( - "Key to use with scanning mode"), - allowed=[ - ("Shift_R", _("Right shift")), - ("Shift_L", _("Left shift")), - ("ISO_Level3_Shift", _("Alt Gr")), - ("Num_Lock", _("Num lock"))]), - StringSetting("mouse_button", _("Switch button"), - "2", - _( - "Mouse button to use in the scanning " - "mode"), - allowed=[("1", _("Button 1")), - ("2", _("Button 2")), - ("3", _("Button 3"))]) - ]), - ]), - SettingsGroup("scanning_color", _("Color"), [ - ColorSetting("block_scanning_color", _("Block color"), - "purple", _("Color of block scans")), - ColorSetting("row_scanning_color", _("Row color"), - "green", _("Color of row scans")), - ColorSetting("button_scanning_color", _("Key color"), - "cyan", _("Color of key scans")), - ColorSetting("cancel_scanning_color", - _("Cancel color"), - "red", _("Color of cancel scan")) - ]) - ]) - ]) - -if __name__ == "__main__": - from gi.repository import GLib - - class SchemasMaker: - def create_schemas(self): - doc = xml.dom.minidom.Document() - schemafile = doc.createElement('schemalist') - schema = doc.createElement('schema') - schema.setAttribute("id", GSETTINGS_SCHEMA) - schema.setAttribute("path", "/org/gnome/caribou/osk/") - schemafile.appendChild(schema) - self._create_schema(settings, doc, schema) - - self._pretty_xml(schemafile) - - def _attribs(self, e): - if not e.attributes.items(): - return "" - return ' ' + ' '.join(['%s="%s"' % (k,v) \ - for k,v in e.attributes.items()]) - - def _pretty_xml(self, e, indent=0): - if not e.childNodes or \ - (len(e.childNodes) == 1 and \ - e.firstChild.nodeType == e.TEXT_NODE): - print '%s%s' % (' '*indent*2, e.toxml().strip()) - else: - print '%s<%s%s>' % (' '*indent*2, e.tagName, self._attribs(e)) - for c in e.childNodes: - self._pretty_xml(c, indent + 1) - print '%s</%s>' % (' '*indent*2, e.tagName) - - def _append_children_element_value_pairs(self, doc, element, pairs): - for e, t in pairs: - el = doc.createElement(e) - te = doc.createTextNode(str(t)) - el.appendChild(te) - element.appendChild(el) - - def _create_schema(self, setting, doc, schemalist): - if hasattr(setting, 'gsettings_key'): - key = doc.createElement('key') - key.setAttribute('name', setting.gsettings_key) - key.setAttribute('type', setting.variant_type) - schemalist.appendChild(key) - self._append_children_element_value_pairs( - doc, key, [('default', - getattr(setting.gvariant, "print")(False)), - ('_summary', setting.short_desc), - ('_description', setting.long_desc)]) - - for s in setting: - self._create_schema(s, doc, schemalist) - - maker = SchemasMaker() - maker.create_schemas() diff --git a/caribou/daemon/Makefile.am b/caribou/daemon/Makefile.am new file mode 100644 index 0000000..859c29e --- /dev/null +++ b/caribou/daemon/Makefile.am @@ -0,0 +1,8 @@ +caribou_daemondir = $(pkgpythondir)/daemon/ + +caribou_daemon_PYTHON = \ + __init__.py \ + main.py + +clean-local: + rm -rf *.pyc *.pyo diff --git a/caribou/daemon/__init__.py b/caribou/daemon/__init__.py new file mode 100644 index 0000000..fd9812d --- /dev/null +++ b/caribou/daemon/__init__.py @@ -0,0 +1 @@ +from main import CaribouDaemon diff --git a/caribou/daemon/main.py b/caribou/daemon/main.py new file mode 100644 index 0000000..4f3def9 --- /dev/null +++ b/caribou/daemon/main.py @@ -0,0 +1,165 @@ +import pyatspi +import dbus +from gi.repository import Gio +from string import Template + +from caribou.i18n import _ +from caribou import APP_NAME + +debug = False + +class CaribouDaemon: + def __init__(self, keyboard_name="Antler"): + if not self._get_a11y_enabled(): + self._show_no_a11y_dialogs() + bus = dbus.SessionBus() + try: + dbus_obj = bus.get_object("org.gnome.Caribou.%s" % keyboard_name, + "/org/gnome/Caribou/%s" % keyboard_name) + except dbus.DBusException, e: + self._show_error_dialog(e.message) + self.keyboard_proxy = dbus.Interface(dbus_obj, "org.gnome.Caribou.Keyboard") + self._current_acc = None + self._register_event_listeners() + + def _show_error_dialog(self, message): + from gi.repository import Gtk + msgdialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.ERROR, + Gtk.ButtonsType.CLOSE, + _("Error starting %s") % APP_NAME) + msgdialog.format_secondary_text(message) + msgdialog.run() + quit() + + def _show_no_a11y_dialogs(self): + from gi.repository import Gtk + msgdialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.QUESTION, + Gtk.ButtonsType.YES_NO, + _("In order to use %s, accessibility needs " + "to be enabled. Do you want to enable " + "it now?") % APP_NAME) + resp = msgdialog.run() + if resp == Gtk.ResponseType.NO: + msgdialog.destroy() + quit() + if resp == Gtk.ResponseType.YES: + settings = Gio.Settings('org.gnome.desktop.interface') + atspi = settings.set_boolean("toolkit-accessibility", True) + msgdialog2 = Gtk.MessageDialog(msgdialog, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.INFO, + Gtk.ButtonsType.OK, + _("Accessibility has been enabled. " + "Log out and back in again to use " + "%s." % APP_NAME)) + msgdialog2.run() + msgdialog2.destroy() + msgdialog.destroy() + quit() + + + def _register_event_listeners(self): + pyatspi.Registry.registerEventListener( + self.on_focus, "object:state-changed:focused") + pyatspi.Registry.registerEventListener(self.on_focus, "focus") + pyatspi.Registry.registerEventListener( + self.on_text_caret_moved, "object:text-caret-moved") + + def _deregister_event_listeners(self): + pyatspi.Registry.deregisterEventListener( + self.on_focus, "object:state-changed:focused") + pyatspi.Registry.deregisterEventListener(self.on_focus, "focus") + pyatspi.Registry.deregisterEventListener( + self.on_text_caret_moved, "object:text-caret-moved") + + def _get_a11y_enabled(self): + try: + try: + settings = Gio.Settings('org.gnome.desktop.interface') + atspi = settings.get_boolean("toolkit-accessibility") + return atspi + except: + raise + from gi.repository import GConf + gconfc = GConf.Client.get_default() + atspi1 = gconfc.get_bool( + "/desktop/gnome/interface/accessibility") + atspi2 = gconfc.get_bool( + "/desktop/gnome/interface/accessibility2") + return atspi1 or atspi2 + except: + raise + return False + + def on_text_caret_moved(self, event): + if self._current_acc == event.source: + text = self._current_acc.queryText() + x, y, w, h = text.getCharacterExtents(text.caretOffset, + pyatspi.DESKTOP_COORDS) + if (x, y, w, h) == (0, 0, 0, 0): + component = self._current_acc.queryComponent() + bb = component.getExtents(pyatspi.DESKTOP_COORDS) + x, y, w, h = bb.x, bb.y, bb.width, bb.height + + self.keyboard_proxy.SetCursorLocation(x, y, w, h) + if debug == True: + print "object:text-caret-moved in", event.host_application.name, + print event.detail1, event.source.description + + def _set_entry_location(self, acc): + text = acc.queryText() + bx, by, bw, bh = text.getCharacterExtents(text.caretOffset, + pyatspi.DESKTOP_COORDS) + + component = acc.queryComponent() + entry_bb = component.getExtents(pyatspi.DESKTOP_COORDS) + + if (bx, by, bw, bh) == (0, 0, 0, 0): + bx, by, bw, bh = entry_bb.x, entry_bb.y, entry_bb.width, entry_bb.height + + self.keyboard_proxy.SetCursorLocation(bx, by, bw, bh) + + self.keyboard_proxy.SetEntryLocation(entry_bb.x, entry_bb.y, + entry_bb.width, entry_bb.height) + + self.keyboard_proxy.Show() + + def on_focus(self, event): + acc = event.source + source_role = acc.getRole() + if acc.getState().contains(pyatspi.STATE_EDITABLE) or \ + source_role == pyatspi.ROLE_TERMINAL: + if source_role in (pyatspi.ROLE_TEXT, + pyatspi.ROLE_PARAGRAPH, + pyatspi.ROLE_PASSWORD_TEXT, + pyatspi.ROLE_TERMINAL, + pyatspi.ROLE_ENTRY): + if event.type.startswith("focus") or event.detail1 == 1: + self._set_entry_location(acc) + self._current_acc = event.source + if debug == True: + print "enter text widget in", event.host_application.name + elif event.detail1 == 0 and acc == self._current_acc: + self.keyboard_proxy.Hide() + self._current_acc = None + if debug == True: + print "leave text widget in", event.host_application.name + else: + if debug == True: + print _("WARNING - Caribou: unhandled editable widget:"), \ + event.source + + def clean_exit(self): + self.keyboard_proxy.Hide() + self._deregister_event_listeners() + + def run(self): + try: + pyatspi.Registry.start() + except KeyboardInterrupt: + self.clean_exit() + pyatspi.Registry.stop() diff --git a/caribou/ui/i18n.py.in b/caribou/i18n.py.in index bf7ad0f..bf7ad0f 100644 --- a/caribou/ui/i18n.py.in +++ b/caribou/i18n.py.in diff --git a/caribou/settings/Makefile.am b/caribou/settings/Makefile.am new file mode 100644 index 0000000..468adab --- /dev/null +++ b/caribou/settings/Makefile.am @@ -0,0 +1,11 @@ +caribou_settingsdir = $(pkgpythondir)/settings/ + +caribou_settings_PYTHON = \ + __init__.py \ + preferences_window.py \ + settings_manager.py \ + caribou_settings.py \ + setting_types.py + +clean-local: + rm -rf *.pyc *.pyo diff --git a/caribou/settings/__init__.py b/caribou/settings/__init__.py new file mode 100644 index 0000000..0ec8b40 --- /dev/null +++ b/caribou/settings/__init__.py @@ -0,0 +1,5 @@ +GSETTINGS_SCHEMA = "org.gnome.caribou" + +from caribou_settings import CaribouSettings + +AllSettings = [CaribouSettings] diff --git a/caribou/settings/caribou_settings.py b/caribou/settings/caribou_settings.py new file mode 100644 index 0000000..638e1c4 --- /dev/null +++ b/caribou/settings/caribou_settings.py @@ -0,0 +1,64 @@ +from caribou.settings.setting_types import * +from caribou.i18n import _ + +CaribouSettings = SettingsTopGroup( + _("Caribou Preferences"), "/org/gnome/caribou/", "org.gnome.caribou", + [SettingsGroup("keyboard", _("Keyboard"), [ + SettingsGroup("general", _("General"), [ + StringSetting( + "keyboard_type", _("Keyboard Type"), "touch", + _("The keyboard geometery Caribou should use"), + _("The keyboard geometery determines the shape " + "and complexity of the keyboard, it could range from " + "a 'natural' look and feel good for composing simple " + "text, to a fullscale keyboard."), + allowed=[(('touch'), _('Touch'))])]), + ]), + SettingsGroup("scanning", _("Scanning"), [ + BooleanSetting( + "scan_enabled", _("Enable scanning"), False, + _("Enable switch scanning"), + insensitive_when_false=["scanning_general", + "scanning_input"]), + SettingsGroup("scanning_general", _("General"), [ + StringSetting("scanning_type", _("Scanning mode"), + "block", + _("Scanning type, block or row"), + allowed=[("block", _("Block")), + ("row", _("Row"))]), + FloatSetting("step_time", _("Step time"), 1.0, + _("Time between key transitions"), + min=0.1, max=60.0), + BooleanSetting("reverse_scanning", + _("Reverse scanning"), False, + _("Scan in reverse order")) + ]), + SettingsGroup("scanning_input", _("Input"), [ + StringSetting("switch_type", _("Switch device"), + "keyboard", + _("Switch device, keyboard or mouse"), + entry_type=ENTRY_RADIO, + allowed=[("keyboard", _("Keyboard")), + ("mouse", _("Mouse"))], + children=[ + StringSetting("keyboard_key", _("Switch key"), + "Shift_R", + _( + "Key to use with scanning mode"), + allowed=[ + ("Shift_R", _("Right shift")), + ("Shift_L", _("Left shift")), + ("ISO_Level3_Shift", _("Alt Gr")), + ("Num_Lock", _("Num lock"))]), + StringSetting("mouse_button", _("Switch button"), + "2", + _( + "Mouse button to use in the scanning " + "mode"), + allowed=[("1", _("Button 1")), + ("2", _("Button 2")), + ("3", _("Button 3"))]) + ]), + ]), + ]) + ]) diff --git a/caribou/ui/preferences_window.py b/caribou/settings/preferences_window.py index 0158ffb..58d1b4c 100644 --- a/caribou/ui/preferences_window.py +++ b/caribou/settings/preferences_window.py @@ -18,47 +18,24 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -import caribou.common.const as const -from caribou.common.setting_types import * -from caribou.common.settings_manager import SettingsManager +from caribou.settings.setting_types import * -from gi.repository import GConf import gobject from gi.repository import Gdk from gi.repository import Gtk -from gi.repository import Pango -import sys -import virtkey -import os -import traceback -from i18n import _ -try: - import json -except ImportError: - HAS_JSON = False -else: - HAS_JSON = True -import xml.etree.ElementTree as ET -from xml.dom import minidom -import gettext -import i18n - -class PreferencesWindow(Gtk.Dialog): - __gtype_name__ = "PreferencesWindow" - - def __init__(self): - gobject.GObject.__init__(self) - self.set_title(_("Caribou Preferences")) - self.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) - self.set_border_width(6) +class AbstractPreferencesUI: + def populate_settings(self, groups): notebook = Gtk.Notebook() - vbox = self.get_content_area() - vbox.add(notebook) - self._populate_settings(notebook, SettingsManager.groups) + self._populate_settings(notebook, groups) + if notebook.get_n_pages() == 1: + notebook.set_show_tabs(False) + + return notebook def _populate_settings(self, parent, setting, level=0): if level == 0: + self.set_title(setting.label) for s in setting: vbox = Gtk.VBox() parent.append_page(vbox, Gtk.Label(label=s.label)) @@ -248,11 +225,38 @@ class PreferencesWindow(Gtk.Dialog): self._update_setting(setting, combo.get_active_id(), handler_id) +class PreferencesDialog(Gtk.Dialog, AbstractPreferencesUI): + __gtype_name__ = "PreferencesDialog" + + def __init__(self, settings_manager): + gobject.GObject.__init__(self) + self.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) + self.set_border_width(6) + + notebook = self.populate_settings(settings_manager.groups) + vbox = self.get_content_area() + vbox.add(notebook) + +class PreferencesWindow(Gtk.Window, AbstractPreferencesUI): + __gtype_name__ = "PreferencesWindow" + + def __init__(self, settings_manager): + gobject.GObject.__init__(self) + self.set_border_width(6) + + notebook = self.populate_settings(settings_manager.groups) + self.add(notebook) + if __name__ == "__main__": + from caribou.settings.settings_manager import SettingsManager + from caribou.settings import CaribouSettings + import signal signal.signal(signal.SIGINT, signal.SIG_DFL) - w = PreferencesWindow() + + w = PreferencesDialog(CaribouSettings()) w.show_all() + try: w.run() except KeyboardInterrupt: diff --git a/caribou/common/setting_types.py b/caribou/settings/setting_types.py index 109bf1b..b0e374d 100644 --- a/caribou/common/setting_types.py +++ b/caribou/settings/setting_types.py @@ -53,6 +53,16 @@ class Setting(gobject.GObject): class SettingsGroup(Setting): pass +class SettingsTopGroup(SettingsGroup): + def __init__(self, label, path, schema_id, children=[]): + SettingsGroup.__init__(self, "_top", label, children) + self.path = path + self.schema_id = schema_id + + def __call__(self): + from caribou.settings.settings_manager import SettingsManager + return SettingsManager(self) + class ValueSetting(Setting): variant_type = '' entry_type=ENTRY_DEFAULT diff --git a/caribou/common/settings_manager.py b/caribou/settings/settings_manager.py index 66119f8..1368f3a 100644 --- a/caribou/common/settings_manager.py +++ b/caribou/settings/settings_manager.py @@ -1,10 +1,9 @@ import os from gi.repository import Gio -from setting_types import * -from settings import settings, GSETTINGS_SCHEMA -import const +from caribou.settings.setting_types import * +from caribou.settings import GSETTINGS_SCHEMA -class _SettingsManager(object): +class SettingsManager(object): def __init__(self, settings): self.groups = settings self._gsettings = Gio.Settings(GSETTINGS_SCHEMA) @@ -66,5 +65,3 @@ class _SettingsManager(object): def __call__(self): return self - -SettingsManager = _SettingsManager(settings) diff --git a/caribou/ui/Makefile.am b/caribou/ui/Makefile.am deleted file mode 100644 index fb24db4..0000000 --- a/caribou/ui/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -caribou_uidir = $(pkgpythondir)/ui/ - -caribou_ui_PYTHON = \ - __init__.py \ - i18n.py \ - keyboard.py \ - scan.py \ - main.py \ - opacity.py \ - preferences_window.py \ - window.py - -DISTCLEANFILES = i18n.py - -clean-local: - rm -rf *.pyc *.pyo diff --git a/caribou/ui/__init__.py b/caribou/ui/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/caribou/ui/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/caribou/ui/keyboard.py b/caribou/ui/keyboard.py deleted file mode 100644 index c390d49..0000000 --- a/caribou/ui/keyboard.py +++ /dev/null @@ -1,461 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Caribou - text entry and UI navigation application -# -# Copyright (C) 2009 Adaptive Technology Resource Centre -# * Contributor: Ben Konrath <ben@bagu.org> -# Copyright (C) 2009 Eitan Isaacson <eitan@monotonous.org> -# Copyright (C) 2010 Igalia S.L. -# * Contributor: Joaquim Rocha <jrocha@igalia.com> -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by the -# Free Software Foundation; either version 2.1 of the License, or (at your -# option) any later version. -# -# This 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -import caribou.common.const as const -from caribou.common.settings_manager import SettingsManager -from preferences_window import PreferencesWindow -from gi.repository import GConf -import gobject -from gi.repository import Gdk -from gi.repository import Gtk -from gi.repository import Pango -from gi.repository import Caribou -import sys -import os -import traceback -from caribou.ui.i18n import _ -from caribou.common.setting_types import * - -try: - import json -except ImportError: - HAS_JSON = False -else: - HAS_JSON = True -import xml.etree.ElementTree as ET -from xml.dom import minidom -import gettext -import i18n - -class BaseKey(object): - '''An abstract class the represents a key on the keyboard. - Inheriting classes also need to inherit from Gtk.Button or any - of it's subclasses.''' - - def __init__(self, label = '', value = '', key_type = 'normal', - width = 1, fill = False): - self.key_type = key_type - self.value = value - self.width = float(width) - self.fill = False - self.label = label or value - if self.key_type == const.DUMMY_KEY_TYPE: - self.set_relief(Gtk.ReliefStyle.NONE) - self.set_sensitive(False) - elif self.key_type == const.PREFERENCES_KEY_TYPE: - image = Gtk.Image() - image.set_from_stock(Gtk.STOCK_PREFERENCES, - Gtk.IconSize.BUTTON) - self.set_image(image) - else: - if label: - label_markup = Gtk.Label() - label_markup.set_markup(self.label) - self.add(label_markup) - else: - self.set_label(self.label) - - ctx = self.get_style_context() - ctx.add_class("caribou-keyboard-button") - - for name in ["default_font", "key_font"]: - getattr(SettingsManager, name).connect("value-changed", - self._key_font_changed) - - if not SettingsManager.default_font.value: - self._key_font_changed(None, None) - - def _key_font_changed(self, setting, value): - if SettingsManager.default_font.value: - self.reset_font() - else: - self.set_font(SettingsManager.key_font.value) - - def scan_highlight_key(self): - raise NotImplemented - - def scan_highlight_row(self): - raise NotImplemented - - def scan_highlight_block(self): - raise NotImplemented - - def scan_highlight_cancel(self): - raise NotImplemented - - def scan_highlight_clear(self): - raise NotImplemented - - def _on_image_key_mapped(self, key): - key_width = key.get_allocated_height() - icon_size = Gtk.IconSize.MENU - image = Gtk.Image() - for size in [Gtk.IconSize.MENU, - Gtk.IconSize.SMALL_TOOLBAR, - Gtk.IconSize.LARGE_TOOLBAR, - Gtk.IconSize.BUTTON, - Gtk.IconSize.DND, - Gtk.IconSize.DIALOG]: - pixbuf = image.render_icon_pixbuf(Gtk.STOCK_PREFERENCES, size) - pixel_size = pixbuf.get_width() - if pixel_size > key_width: - break - icon_size = size - image.set_from_stock(Gtk.STOCK_PREFERENCES, icon_size) - self.set_image(image) - - def set_font(self, font): - raise NotImplemented - - def reset_font(self): - raise NotImplemented - - def _get_value(self): - return self._value - - def _set_value(self, value): - if self.key_type in (const.NORMAL_KEY_TYPE, const.MASK_KEY_TYPE): - if type(value) == str: - value = value.decode('utf-8') - if type(value) == unicode: - if len(value) == 1: - self._value = Gdk.unicode_to_keyval(ord(value)) - else: - key_value = Gdk.keyval_from_name(value) - if key_value: - self._value = key_value - else: - self._value = value - - value = property(_get_value, _set_value) - -class Key(Gtk.Button, BaseKey): - def __init__(self, label = '', value = '', key_type = 'normal', - width = 1, fill = False): - gobject.GObject.__init__(self) - BaseKey.__init__(self, label, value, key_type, width, fill) - - def set_font(self, font): - child = self.get_child() - if isinstance(child, Gtk.Label): - child.modify_font(Pango.font_description_from_string(font)) - if child is not None: - child.queue_resize() - - def reset_font(self): - label = self.get_child() - if not isinstance(label, Gtk.Label): - return - label.modify_font(None) - - def _replace_scan_class_style(self, scan_class=None): - ctx = self.get_style_context() - for cls in ctx.list_classes(): - if cls.startswith('caribou-scan'): - ctx.remove_class(cls) - if scan_class: - ctx.add_class(scan_class) - self.queue_draw() - - def scan_highlight_key(self): - self._replace_scan_class_style("caribou-scan-key") - - def scan_highlight_row(self): - self._replace_scan_class_style("caribou-scan-row") - - def scan_highlight_block(self): - self._replace_scan_class_style("caribou-scan-block") - - def scan_highlight_cancel(self): - self._replace_scan_class_style("caribou-scan-cancel") - - def scan_highlight_clear(self): - self._replace_scan_class_style() - -class ModifierKey(Gtk.ToggleButton, Key): - pass - -class KeyboardLayout(Gtk.Table): - KEY_SPAN = 4 - def __init__(self, name): - gobject.GObject.__init__(self) - self.layout_name = name - self.rows = [] - self.set_homogeneous(True) - - def add_row(self, row): - row_num = len(self.rows) - self.rows.append(row) - last_col = 0 - for i, key in enumerate(row): - next_col = (last_col + (key.width * self.KEY_SPAN)) - self.attach(key, last_col, next_col, - row_num * self.KEY_SPAN, (row_num + 1) * self.KEY_SPAN, - Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, - Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, - 0, 0) - last_col = next_col - - def get_scan_rows(self): - return [filter(lambda x: x.is_sensitive(), row) for row in self.rows] - - def get_scan_blocks(self, optimal_block_size=8): - # TODO: smarter division using optimal block size. - scan_rows = self.get_scan_rows() - col_num = max([len(row) for row in scan_rows]) - blocks = [] - - for row_index in xrange(len(scan_rows)): - for col_index in xrange(max([len(row) for row in scan_rows])): - try: - key = scan_rows[row_index][col_index] - except IndexError: - continue - - try: - group = blocks[row_index/2] - except IndexError: - group = [] - blocks.append(group) - - try: - group[col_index/3].append(key) - except IndexError: - block = [] - block.append(key) - group.append(block) - - return reduce(lambda a, b: a + b, blocks) - - - -class KbLayoutDeserializer(object): - def __init__(self): - pass - - def deserialize(self, kb_layout_file): - kb_file = os.path.abspath(kb_layout_file) - if not os.path.isfile(kb_file): - return [] - kb_file_obj = open(kb_file) - contents = kb_file_obj.read() - kb_file_obj.close() - basename, ext = os.path.splitext(kb_file) - try: - kb_layouts = self._deserialize_from_format(ext, contents) - except Exception, e: - traceback.print_exc() - else: - return kb_layouts - return [] - - def _deserialize_from_format(self, format, contents): - if format == '.xml': - return self._deserialize_from_xml(contents) - if HAS_JSON and format == '.json': - return self._deserialize_from_json(contents) - return [] - - def _deserialize_from_json(self, contents): - contents_dict = json.loads(contents) - layouts = self._create_kb_layout_from_dict(contents_dict) - return layouts - - def _convert_xml_to_dict(self, element): - if element.text and element.text.strip(): - return element.text - attributes = element.attrib - for child in element.getchildren(): - if attributes.get(child.tag): - attributes[child.tag] += [self._convert_xml_to_dict(child)] - else: - attributes[child.tag] = [self._convert_xml_to_dict(child)] - for key, value in attributes.items(): - if isinstance(value, list) and len(value) == 1: - attributes[key] = value[0] - return attributes - - def _deserialize_from_xml(self, xml_string): - element = ET.fromstring(xml_string) - layout_dict = self._convert_xml_to_dict(element) - return self._create_kb_layout_from_dict(layout_dict) - - def _create_kb_layout_from_dict(self, dictionary): - if not isinstance(dictionary, dict): - return None - layouts = self._get_dict_value_as_list(dictionary, 'layout') - layouts_encoded = [] - for layout in layouts: - name = layout.get('name') - if not name: - continue - kb_layout = KeyboardLayout(name) - rows_list = self._get_dict_value_as_list(layout, 'rows') - for rows in rows_list: - for row_encoded in self._get_rows_from_dict(rows): - kb_layout.add_row(row_encoded) - layouts_encoded.append(kb_layout) - return layouts_encoded - - def _get_rows_from_dict(self, rows): - rows_encoded = [] - row_list = self._get_dict_value_as_list(rows, 'row') - for row in row_list: - keys = self._get_dict_value_as_list(row, 'key') - if keys: - rows_encoded.append(self._get_keys_from_list(keys)) - return rows_encoded - - def _get_keys_from_list(self, keys_list): - keys = [] - for key_vars in keys_list: - vars = {} - for key, value in key_vars.items(): - vars[str(key)] = value - if vars.get('key_type', '') == const.MASK_KEY_TYPE: - key = ModifierKey(**vars) - else: - key = Key(**vars) - keys.append(key) - return keys - - def _get_dict_value_as_list(self, dictionary, key): - if isinstance(dictionary, list): - return dictionary - value = dictionary.get(key) - if not value: - return None - if isinstance(value, list): - return value - return [value] - -class CaribouKeyboard(Gtk.Notebook): - __gtype_name__ = "CaribouKeyboard" - - def __init__(self): - gobject.GObject.__init__(self) - self.set_show_tabs(False) - self.vk = Caribou.VirtualKeyboard() - self.key_size = 30 - self.current_page = 0 - self.depressed_mods = [] - - self.row_height = -1 - - def load_kb(self, kb_location): - kb_deserializer = KbLayoutDeserializer() - layouts = kb_deserializer.deserialize(kb_location) - self._set_layouts(layouts) - - def _set_layouts(self, layout_list): - self._clear() - for layout in layout_list: - self.append_page(layout, None) - for row in layout.rows: - for key in row: - if key.key_type == const.LAYOUT_SWITCHER_KEY_TYPE: - key.connect('clicked', - self._pressed_layout_switcher_key) - elif key.key_type == const.MASK_KEY_TYPE: - key.connect('toggled', - self._toggled_mask_key) - elif key.key_type == const.PREFERENCES_KEY_TYPE: - key.connect('clicked', - self._pressed_preferences_key) - else: - key.connect('pressed', - self._pressed_normal_key) - key.connect('released', - self._released_normal_key) - - def _clear(self): - n_pages = self.get_n_pages() - for i in range(n_pages): - self.remove_page(i) - - def _pressed_normal_key(self, key): - self.vk.keyval_press(key.value) - - def _released_normal_key(self, key): - self.vk.keyval_release(key.value) - while True: - try: - mod = self.depressed_mods.pop() - except IndexError: - break - mod.set_active (False) - - def _pressed_layout_switcher_key(self, key): - self._switch_to_layout(key.value) - - def _toggled_mask_key(self, key): - if key.get_active(): - self.vk.keyval_press(key.value) - self.depressed_mods.append(key) - else: - self.vk.keyval_release(key.value) - try: - mod = self.depressed_mods.remove(key) - except ValueError: - pass - - def show_all_(self): - self.set_current_page(self.current_page) - Gtk.Notebook.show_all(self) - - def _pressed_preferences_key(self, key): - p = PreferencesWindow() - p.show_all() - p.run() - p.destroy() - - def _switch_to_layout(self, name): - n_pages = self.get_n_pages() - for i in range(n_pages): - if self.get_nth_page(i).layout_name == name: - self.set_current_page(i) - self.current_page = i - break - - def get_current_layout(self): - i = self.get_current_page() - return self.get_nth_page(i) - - def get_layouts(self): - return [self.get_nth_page(i) for i in xrange(self.get_n_pages())] - -if __name__ == "__main__": - import signal - signal.signal(signal.SIGINT, signal.SIG_DFL) - - w = Gtk.Window() - - kb = CaribouKeyboard() - kb.load_kb('data/keyboards/qwerty.xml') - - w.add(kb) - - w.show_all() - - Gtk.main() diff --git a/caribou/ui/main.py b/caribou/ui/main.py deleted file mode 100644 index 7e861b8..0000000 --- a/caribou/ui/main.py +++ /dev/null @@ -1,275 +0,0 @@ -import pyatspi -from gi.repository import Gtk -from gi.repository import Gdk -from gi.repository import Gio -from string import Template - -from window import CaribouWindowEntry, Rectangle -from keyboard import CaribouKeyboard -from caribou.common.settings_manager import SettingsManager -from caribou.ui.i18n import _ -import caribou.common.const as const -from scan import ScanMaster - -debug = False - -CSS_TEMPLATE = """ -.caribou-keyboard-button { -background-image: none; -background-color: $normal_bg; -} - -.caribou-keyboard-button:hover { -background-image: none; -background-color: $mouseover_bg; -} -""" - -SCAN_CSS_TEMPLATE = """ -.caribou-scan-key { -background-image: none; -background-color: $button_scan; -} - -.caribou-scan-row { -background-image: none; -background-color: $row_scan; -} - -.caribou-scan-block { -background-image: none; -background-color: $block_scan; -} - -.caribou-scan-cancel { -background-image: none; -background-color: $cancel_scan; -} -""" - -class Caribou: - def __init__(self, - kb_factory=CaribouKeyboard, - window_factory=CaribouWindowEntry): - if not self._get_a11y_enabled(): - msgdialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL, - Gtk.MessageType.QUESTION, - Gtk.ButtonsType.YES_NO, - _("In order to use %s, accessibility needs " - "to be enabled. Do you want to enable " - "it now?") % const.APP_NAME) - resp = msgdialog.run() - if resp == Gtk.ResponseType.NO: - msgdialog.destroy() - quit() - if resp == Gtk.ResponseType.YES: - settings = Gio.Settings('org.gnome.desktop.interface') - atspi = settings.set_boolean("toolkit-accessibility", True) - msgdialog2 = Gtk.MessageDialog(msgdialog, - Gtk.DialogFlags.MODAL, - Gtk.MessageType.INFO, - Gtk.ButtonsType.OK, - _("Accessibility has been enabled. " - "Log out and back in again to use " - "%s.") % const.APP_NAME) - msgdialog2.run() - msgdialog2.destroy() - msgdialog.destroy() - quit() - self.__current_acc = None - self.window_factory = window_factory - self.kb_factory = kb_factory - kb = kb_factory() - self.window = window_factory(kb) - self._register_event_listeners() - SettingsManager.layout.connect("value-changed", - self._on_layout_changed) - - # Scanning - self.scan_master = ScanMaster(self.window, kb) - SettingsManager.scan_enabled.connect("value-changed", - self._on_scan_toggled) - if SettingsManager.scan_enabled.value: - self.scan_master.start() - - self._custom_css_provider = Gtk.CssProvider() - - for name in ["normal_color", "mouse_over_color", "default_colors"]: - getattr(SettingsManager, name).connect("value-changed", - self._colors_changed) - self._colors_changed(None, None) - - self._scan_css_provider = Gtk.CssProvider() - Gtk.StyleContext.add_provider_for_screen( - Gdk.Screen.get_default(), - self._scan_css_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - - for name in ["button_scanning_color", - "row_scanning_color", - "block_scanning_color", - "cancel_scanning_color"]: - getattr(SettingsManager, name).connect("value-changed", - self._scan_colors_changed) - self._scan_colors_changed(None, None) - - def _colors_changed(self, setting, value): - if SettingsManager.default_colors.value: - Gtk.StyleContext.remove_provider_for_screen( - Gdk.Screen.get_default(), - self._custom_css_provider) - else: - Gtk.StyleContext.add_provider_for_screen( - Gdk.Screen.get_default(), - self._custom_css_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - self._custom_css_provider.load_from_data( - Template(CSS_TEMPLATE).substitute( - normal_bg=SettingsManager.normal_color.value, - mouseover_bg=SettingsManager.mouse_over_color.value), -1) - - def _scan_colors_changed(self, setting, value): - self._scan_css_provider.load_from_data(Template(SCAN_CSS_TEMPLATE).substitute( - button_scan=SettingsManager.button_scanning_color.value, - row_scan=SettingsManager.row_scanning_color.value, - block_scan=SettingsManager.block_scanning_color.value, - cancel_scan=SettingsManager.cancel_scanning_color.value), -1) - - - def _register_event_listeners(self): - pyatspi.Registry.registerEventListener( - self.on_focus, "object:state-changed:focused") - pyatspi.Registry.registerEventListener(self.on_focus, "focus") - pyatspi.Registry.registerEventListener( - self.on_text_caret_moved, "object:text-caret-moved") - - def _deregister_event_listeners(self): - pyatspi.Registry.deregisterEventListener( - self.on_focus, "object:state-changed:focused") - pyatspi.Registry.deregisterEventListener(self.on_focus, "focus") - pyatspi.Registry.deregisterEventListener( - self.on_text_caret_moved, "object:text-caret-moved") - - def _on_scan_toggled(self, setting, val): - if val: - self.scan_master.start() - else: - self.scan_master.stop() - - def _on_layout_changed(self, setting, val): - self._deregister_event_listeners() - self.window.destroy() - self._update_window() - self._register_event_listeners() - - def _update_window(self): - kb = self.kb_factory() - self.scan_master.set_keyboard(kb) - self.window = self.window_factory(kb) - - def _get_a11y_enabled(self): - try: - try: - settings = Gio.Settings('org.gnome.desktop.interface') - atspi = settings.get_boolean("toolkit-accessibility") - print "->", atspi - return atspi - except: - raise - from gi.repository import GConf - gconfc = GConf.Client.get_default() - atspi1 = gconfc.get_bool( - "/desktop/gnome/interface/accessibility") - atspi2 = gconfc.get_bool( - "/desktop/gnome/interface/accessibility2") - return atspi1 or atspi2 - except: - raise - return False - - def on_text_caret_moved(self, event): - if self.__current_acc == event.source: - self.__set_location(event.source) - if debug == True: - print "object:text-caret-moved in", event.host_application.name, - print event.detail1, event.source.description - - def __set_text_location(self, acc): - text = acc.queryText() - [x, y, width, height] = text.getCharacterExtents(text.caretOffset, pyatspi.DESKTOP_COORDS) - self.window.set_cursor_location(Rectangle(x, y, width, height)) - - component = acc.queryComponent() - entry_bb = component.getExtents(pyatspi.DESKTOP_COORDS) - self.window.set_entry_location(entry_bb) - self.window.show_all() - - def __set_entry_location(self, acc): - text = acc.queryText() - cursor_bb = Rectangle( - *text.getCharacterExtents(text.caretOffset, - pyatspi.DESKTOP_COORDS)) - - component = acc.queryComponent() - entry_bb = component.getExtents(pyatspi.DESKTOP_COORDS) - - if cursor_bb == Rectangle(0, 0, 0, 0): - cursor_bb = entry_bb - - self.window.set_cursor_location(cursor_bb) - self.window.set_entry_location(entry_bb) - - self.window.show_all() - - def on_focus(self, event): - acc = event.source - source_role = acc.getRole() - if acc.getState().contains(pyatspi.STATE_EDITABLE) or \ - source_role == pyatspi.ROLE_TERMINAL: - if source_role in (pyatspi.ROLE_TEXT, - pyatspi.ROLE_PARAGRAPH, - pyatspi.ROLE_PASSWORD_TEXT, - pyatspi.ROLE_TERMINAL): - if event.type.startswith("focus") or event.detail1 == 1: - self.__set_text_location(acc) - self.__current_acc = event.source - self.__set_location = self.__set_text_location - if debug == True: - print "enter text widget in", event.host_application.name - elif event.detail1 == 0 and acc == self.__current_acc: - self.window.hide() - self.__current_acc = None - self.__set_location = None - if debug == True: - print "leave text widget in", event.host_application.name - - elif source_role == pyatspi.ROLE_ENTRY: - if event.type.startswith("focus") or event.detail1 == 1: - self.__set_entry_location(acc) - self.__current_acc = event.source - self.__set_location = self.__set_entry_location - if debug == True: - print "enter entry widget in", event.host_application.name - elif event.detail1 == 0: - self.window.hide() - self.__current_acc = None - self.__set_location = None - if debug == True: - print "leave entry widget in", event.host_application.name - else: - if debug == True: - print _("WARNING - Caribou: unhandled editable widget:"), event.source - - # Firefox does not report leave entry widget events. - # This could be a way to get the entry widget leave events. - #else: - # if event.detail1 == 1: - # self.window.hide() - # print "--> LEAVE EDITABLE TEXT <--" - - def clean_exit(self): - self.scan_master.stop() - self._deregister_event_listeners() - - diff --git a/caribou/ui/opacity.py b/caribou/ui/opacity.py deleted file mode 100644 index be742d8..0000000 --- a/caribou/ui/opacity.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Caribou - text entry and UI navigation application -# -# Copyright (C) 2009 Eitan Isaacson <eitan@monotonous.org> -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by the -# Free Software Foundation; either version 2.1 of the License, or (at your -# option) any later version. -# -# This 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -import glib -from math import sqrt - -class ProximityWindowBase(object): - def __init__(self, min_alpha=1.0, max_alpha=1.0, max_distance=100): - if self.__class__ == ProximityWindowBase: - raise TypeError, \ - "ProximityWindowBase is an abstract class, " \ - "must be subclassed with a Gtk.Window" - self.connect('map-event', self.__onmapped) - self.max_distance = max_distance - if max_alpha < min_alpha: - raise ValueError, "min_alpha can't be larger than max_alpha" - self.min_alpha = min_alpha - self.max_alpha = max_alpha - - def __onmapped(self, obj, event): - if self.is_composited(): - self.set_opacity(self.max_alpha) - if self.max_alpha != self.min_alpha: - # Don't waste CPU if the max and min are equal. - glib.timeout_add(80, self._proximity_check) - - def _proximity_check(self): - px, py = self.get_pointer() - - ww = self.get_allocated_width() - wh = self.get_allocated_height() - - distance = self._get_distance_to_bbox(px, py, ww, wh) - - opacity = (self.max_alpha - self.min_alpha) * \ - (1 - min(distance, self.max_distance)/self.max_distance) - opacity += self.min_alpha - - self.set_opacity(opacity) - return self.props.visible - - def _get_distance_to_bbox(self, px, py, bw, bh): - if px < 0: - x_distance = float(abs(px)) - elif px > bw: - x_distance = float(px - bw) - else: - x_distance = 0.0 - - if py < 0: - y_distance = float(abs(px)) - elif py > bh: - y_distance = float(py - bh) - else: - y_distance = 0.0 - - if y_distance == 0 and x_distance == 0: - return 0.0 - elif y_distance != 0 and x_distance == 0: - return y_distance - elif y_distance == 0 and x_distance != 0: - return x_distance - else: - x2 = 0 if x_distance > 0 else bw - y2 = 0 if y_distance > 0 else bh - return sqrt((px - x2)**2 + (py - y2)**2) diff --git a/caribou/ui/scan.py b/caribou/ui/scan.py deleted file mode 100644 index 94aa8c2..0000000 --- a/caribou/ui/scan.py +++ /dev/null @@ -1,216 +0,0 @@ -import gobject -import pyatspi -from gi.repository import Gdk -from gi.repository import Gtk -import caribou.common.const as const -from caribou.common.settings_manager import SettingsManager - -# Scan constants -BUTTON = 'button' -ROW = 'row' -BLOCK = 'block' -CANCEL = 'cancel' -REVERSE = 'reverse' -MOUSE_SWITCH_TYPE = 'mouse' -KEYBOARD_SWITCH_TYPE = 'keyboard' -KEYBOARD_KEY_LIST = {"Shift R" : "Shift_R", - "Shift L" : "Shift_L", - "Alt Gr" : "ISO_Level3_Shift", - "Num Lock": "Num_Lock"} -DEFAULT_KEYBOARD_KEY = 'Shift R' -DEFAULT_MOUSE_BUTTON = '1' -MIN_STEP_TIME = 50 -MAX_STEP_TIME = 5000 -TIME_SINGLE_INCREMENT = 1 -TIME_MULTI_INCREMENT = 10 -DEFAULT_STEP_TIME = 1000 -DEFAULT_SCANNING_TYPE = ROW -DEFAULT_SWITCH_TYPE = KEYBOARD_SWITCH_TYPE - -class ScanMaster(): - def __init__(self, root_window, keyboard=None): - self.root_window = root_window - self._timer = 0 - self._scan_path = None - self.started = False - - SettingsManager.step_time.connect("value-changed", - self._on_step_time_changed) - SettingsManager.scanning_type.connect("value-changed", - self._on_scanning_type_changed) - if keyboard: - self.set_keyboard(keyboard) - - def start(self): - if self.started: return - - if self._timer == 0: - self._timer = gobject.timeout_add( - int(SettingsManager.step_time.value*1000), self._scan) - - self._grab_mouse_events() - - pyatspi.Registry.registerKeystrokeListener( - self._on_key_pressed, mask=0, kind=(pyatspi.KEY_PRESSED_EVENT,)) - - def stop(self): - if self.started: return - - self._ungrab_mouse_events() - - if self._last_block is not None: - self._multi_map(lambda x: x.scan_highlight_clear(), self._last_block) - - if self._timer != 0: - gobject.source_remove(self._timer) - self._timer = 0 - - pyatspi.Registry.deregisterKeystrokeListener( - self._on_key_pressed, mask=0, kind=pyatspi.KEY_PRESSED_EVENT) - - def _on_scanning_type_changed(self, setting, val): - layout = self.keyboard.get_current_layout() - if SettingsManager.scanning_type.value == ROW: - self._blocks = layout.get_scan_rows() - else: - self._blocks = layout.get_scan_blocks() - - def _on_step_time_changed(self, setting, val): - if self._timer != 0: - gobject.source_remove(self._timer) - self._timer = gobject.timeout_add(int(1000*val), self._scan) - - def _on_layout_activated(self, keyboard, layout, num): - if SettingsManager.scanning_type.value == ROW: - self._blocks = layout.get_scan_rows() - else: - self._blocks = layout.get_scan_blocks() - if SettingsManager.reverse_scanning.value: - self._scan_path = [0] - else: - self._scan_path = [-1] - - def set_keyboard(self, keyboard): - self._last_block = None - keyboard.connect("switch-page", self._on_layout_activated) - self.keyboard = keyboard - - def _multi_map(self, func, array): - if isinstance(array, list): - for item in array: - self._multi_map(func, item) - else: - func(array) - - def _get_element_at_path(self, array, path): - element = array - for index in path: - element = element[index] - return element - - def _get_next_reverse_block(self): - cancel = False - - if self._scan_path[-1] > 0: - self._scan_path = self._scan_path[:-1] + [0] - - self._scan_path += [self._scan_path.pop() - 1] - - try: - block = self._get_element_at_path(self._blocks, - self._scan_path) - except IndexError: - if len(self._scan_path) == 1: - block = self._blocks[-1] - self._scan_path = [-1] - else: - block = self._get_element_at_path( - self._blocks, self._scan_path[:-1]) - self._scan_path = self._scan_path[:-1] + [0] - cancel = True - - return cancel, block - - - def _get_next_block(self): - cancel = False - self._scan_path += [self._scan_path.pop() + 1] - try: - block = self._get_element_at_path(self._blocks, - self._scan_path) - except IndexError: - if len(self._scan_path) == 1: - block = self._blocks[0] - self._scan_path = [0] - else: - block = self._get_element_at_path( - self._blocks, self._scan_path[:-1]) - self._scan_path = self._scan_path[:-1] + [-1] - cancel = True - - return cancel, block - - def _scan(self): - if self._scan_path is None: return True - - if self._last_block is not None: - self._multi_map(lambda x: x.scan_highlight_clear(), self._last_block) - - if SettingsManager.reverse_scanning.value: - self._cancel, next_block = self._get_next_reverse_block() - else: - self._cancel, next_block = self._get_next_block() - - if self._cancel: - self._multi_map(lambda x: x.scan_highlight_cancel(), next_block) - elif isinstance(next_block, list): - if SettingsManager.scanning_type.value == ROW: - self._multi_map(lambda x: x.scan_highlight_row(), next_block) - else: - self._multi_map(lambda x: x.scan_highlight_block(), next_block) - else: - self._multi_map(lambda x: x.scan_highlight_key(), next_block) - - self._last_block = next_block - return True - - def _do_switch(self): - if self._cancel: - assert(len(self._scan_path) > 1) - self._scan_path.pop() - elif isinstance(self._last_block, list): - assert(len(self._last_block) > 0) - if SettingsManager.reverse_scanning.value: - self._scan_path.append(0) - else: - self._scan_path.append(-1) - else: - self._last_block.clicked() - - def _grab_mouse_events(self): - Gdk.event_handler_set(self._mouse_handler, None) - - def _ungrab_mouse_events(self): - Gdk.event_handler_set(Gtk.main_do_event, None) - - def _mouse_handler(self, event, user_data): - if SettingsManager.switch_type.value != MOUSE_SWITCH_TYPE or \ - event.type not in (Gdk.EventType.BUTTON_PRESS, - Gdk.EventType.ENTER_NOTIFY): - Gtk.main_do_event(event) - return - - if self.root_window.get_window().is_visible(): - if event.type == Gdk.EventType.BUTTON_PRESS and \ - str(event.button.button) == \ - SettingsManager.mouse_button.value: - self._do_switch() - elif event.type != Gdk.EventType.ENTER_NOTIFY: - Gtk.main_do_event(event) - else: - Gtk.main_do_event(event) - - def _on_key_pressed(self, event): - if SettingsManager.switch_type.value == KEYBOARD_SWITCH_TYPE and \ - SettingsManager.keyboard_key.value == event.event_string: - self._do_switch() diff --git a/configure.ac b/configure.ac index 366da21..f8f5783 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,6 @@ AM_MAINTAINER_MODE([enable]) # to configure or passing V=1 to make AM_SILENT_RULES([yes]) - AM_PATH_GLIB_2_0(2.27.5,,,gobject) if test "$GLIB_LIBS" = ""; then AC_MSG_ERROR(GLIB 2.27.5 or later is required to build libcaribou) @@ -37,10 +36,16 @@ PKG_CHECK_MODULES(CARIBOU, [ AC_SUBST(CARIBOU_CFLAGS) AC_SUBST(CARIBOU_LIBS) +AM_PROG_VALAC([0.9.3]) +AC_SUBST(VALAC) +AC_SUBST(VALAFLAGS) + PKG_CHECK_MODULES(LIBCARIBOU, [ gdk-3.0 >= $GDK_REQUIRED, xtst, - x11 + x11, + libxklavier, + json-glib-1.0 ]) AC_SUBST(LIBCARIBOU_CFLAGS) AC_SUBST(LIBCARIBOU_LIBS) @@ -67,12 +72,16 @@ AC_OUTPUT([ Makefile po/Makefile.in caribou/Makefile -caribou/common/Makefile -caribou/ui/i18n.py -caribou/ui/Makefile +caribou/i18n.py +caribou/antler/Makefile +caribou/settings/Makefile +caribou/daemon/Makefile bin/Makefile bin/caribou +bin/caribou-preferences +bin/antler-keyboard data/Makefile -data/keyboards/Makefile +data/layouts/Makefile +data/layouts/touch/Makefile libcaribou/Makefile ]) diff --git a/data/Makefile.am b/data/Makefile.am index 581ca65..11e2611 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = keyboards +SUBDIRS = layouts @GSETTINGS_RULES@ @INTLTOOL_XML_NOMERGE_RULE@ @@ -13,12 +13,19 @@ autostartdir = $(sysconfdir)/xdg/autostart autostart_in_files = caribou-autostart.desktop.in autostart_DATA = $(autostart_in_files:.desktop.in=.desktop) +servicefiledir = $(datadir)/dbus-1/services +servicefile_in_files = org.gnome.Caribou.Antler.service.in +servicefile_DATA = $(servicefile_in_files:.service.in=.service) + +org.gnome.Caribou.Antler.service: org.gnome.Caribou.Antler.service.in + $(AM_V_GEN)sed -e "s|[@]libexecdir[@]|$(libexecdir)|" $< > $@ + @INTLTOOL_DESKTOP_RULE@ EXTRA_DIST = $(desktop_in_files) $(autostart_in_files) -org.gnome.caribou.gschema.xml.in: $(top_srcdir)/caribou/common/settings.py - PYTHONPATH=${PYTHONPATH}:$(top_srcdir) $(PYTHON) $< > $@ +org.gnome.caribou.gschema.xml.in: $(top_srcdir)/tools/make_schema.py + $< org.gnome.caribou CLEANFILES = $(desktop_DATA) \ $(autostart_DATA) \ diff --git a/data/keyboards/Makefile.am b/data/keyboards/Makefile.am deleted file mode 100644 index 64d947e..0000000 --- a/data/keyboards/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -keyboardsdir = $(datadir)/caribou/keyboards/ -keyboards_DATA = \ - qwerty.xml \ - hebrew.xml \ - lexic_es.json \ - qwerty_en.json \ - qwerty_es.json - - -EXTRA_DIST = $(keyboards_DATA) diff --git a/data/keyboards/hebrew.xml b/data/keyboards/hebrew.xml deleted file mode 100644 index 251ec81..0000000 --- a/data/keyboards/hebrew.xml +++ /dev/null @@ -1,272 +0,0 @@ -<keyboard> - <layout> - <name>lowercase</name> - <rows> - <row> - <key key_type="preferences"/> - <key key_type="dummy" width="1.25"/> - <key value="ק"/> - <key value="ר"/> - <key value="א"/> - <key value="ט"/> - <key value="ו"/> - <key value="ן"/> - <key value="ם"/> - <key value="פ"/> - <key key_type="dummy" width="0.775"/> - <key> - <value>BackSpace</value> - <label><big>⌫</big></label> - <width>1.5</width> - </key> - </row> - <row> - <key> - <label><b><sup>←</sup><sub>→</sub></b>"</label> - <value>Tab</value> - </key> - <key value="ש"/> - <key value="ד"/> - <key value="ג"/> - <key value="כ"/> - <key value="ע"/> - <key value="י"/> - <key value="ח"/> - <key value="ל"/> - <key value="ך"/> - <key value="ף"/> - <key> - <value>Return</value> - <label><b>↲</b></label> - <width>1.5</width> - </key> - </row> - <row> - <key> - <label><b>↑</b></label> - <key_type>layout_switcher</key_type> - <value>uppercase</value> - <width>1.5</width> - </key> - <key value="ז"/> - <key value="ס"/> - <key value="ב"/> - <key value="ה"/> - <key value="נ"/> - <key value="מ"/> - <key value="צ"/> - <key value="ת"/> - <key value="ץ"/> - <key value=","/> - <key value="."/> - </row> - <row> - <key> - <label><small><i>1%+</i></small></label> - <key_type>layout_switcher</key_type> - <value>special</value> - <width>1.5</width> - </key> - <key> - <label><small><b>Ctrl</b></small></label> - <value>Control_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key> - <label><small><b>Alt</b></small></label> - <value>Alt_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key label="______" value=" " width="3"/> - <key key_type="dummy" width="0.5"/> - <key value="'"/> - <key value="""/> - <key value="!"/> - <key value="?"/> - </row> - </rows> - </layout> - - <layout> - <name>uppercase</name> - <rows> - <row> - <key key_type="preferences"/> - <key value="Q"/> - <key value="W"/> - <key value="E"/> - <key value="R"/> - <key value="T"/> - <key value="Y"/> - <key value="U"/> - <key value="I"/> - <key value="O"/> - <key value="P"/> - <key> - <value>BackSpace</value> - <label><big>⌫</big></label> - <width>1.5</width> - </key> - </row> - <row> - <key> - <label><b><sup>←</sup><sub>→</sub></b>"</label> - <value>Tab</value> - </key> - <key key_type="dummy" width="0.275"/> - <key value="A"/> - <key value="S"/> - <key value="D"/> - <key value="F"/> - <key value="G"/> - <key value="H"/> - <key value="J"/> - <key value="K"/> - <key value="L"/> - <key key_type="dummy" width="0.75"/> - <key> - <value>Return</value> - <label><b>↲</b></label> - <width>1.5</width> - </key> - </row> - <row> - <key> - <label><b>↓</b></label> - <key_type>layout_switcher</key_type> - <value>lowercase</value> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key value="Z"/> - <key value="X"/> - <key value="C"/> - <key value="V"/> - <key value="B"/> - <key value="N"/> - <key value="M"/> - <key key_type="dummy" width="0.5"/> - <key value=","/> - <key value="."/> - <key value=";"/> - </row> - <row> - <key> - <label><small><i>1%+</i></small></label> - <key_type>layout_switcher</key_type> - <value>special</value> - <width>1.5</width> - </key> - <key> - <label><small><b>Ctrl</b></small></label> - <value>Control_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key> - <label><small><b>Alt</b></small></label> - <value>Alt_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key label="______" value=" " width="3"/> - <key key_type="dummy" width="0.5"/> - <key value="'"/> - <key value="""/> - <key value="!"/> - <key value="?"/> - </row> - </rows> - </layout> - - <layout> - <name>special</name> - <rows> - <row> - <key key_type="preferences"/> - <key value="1"/> - <key value="2"/> - <key value="3"/> - <key value="4"/> - <key value="5"/> - <key value="6"/> - <key value="7"/> - <key value="8"/> - <key value="9"/> - <key value="0"/> - <key> - <value>BackSpace</value> - <label><big>⌫</big></label> - <width>1.5</width> - </key> - </row> - <row> - <key key_type="dummy" width="0.25"/> - <key key_type="dummy" width="0.25"/> - <key value="@"/> - <key value="#"/> - <key value="$"/> - <key value="%"/> - <key value="&"/> - <key value="*"/> - <key value="("/> - <key value=")"/> - <key value="-"/> - <key value="+"/> - <key key_type="dummy" width="0.25"/> - <key> - <value>Return</value> - <label><b>↲</b></label> - <width>2</width> - </key> - </row> - <row> - <key key_type="dummy" width="0.25"/> - <key value="<"/> - <key value=">"/> - <key value="€"/> - <key value="£"/> - <key value="{"/> - <key value="}"/> - <key value="["/> - <key value="]"/> - <key value="_" label="<small>_</small>"/> - <key value="="/> - <key key_type="dummy" width="0.25"/> - <key value="Up" label="<b>↑</b>"/> - <key value="\"/> - </row> - <row> - <key> - <label><small><i>abc</i></small></label> - <key_type>layout_switcher</key_type> - <value>lowercase</value> - <width>1.5</width> - </key> - <key> - <label><small><b>Ctrl</b></small></label> - <value>Control_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key> - <label><small><b>Alt</b></small></label> - <value>Alt_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key label="______" value=" " width="3"/> - <key key_type="dummy" width="0.5"/> - <key value="|"/> - <key value="Left" label="<b>←</b>"/> - <key value="Down" label="<b>↓</b>"/> - <key value="Right" label="<b>→</b>"/> - </row> - </rows> - </layout> -</keyboard> diff --git a/data/keyboards/lexic_es.json b/data/keyboards/lexic_es.json deleted file mode 100644 index 1d72adc..0000000 --- a/data/keyboards/lexic_es.json +++ /dev/null @@ -1,300 +0,0 @@ - -{"layout": [ - {"name": "lowercase", - "rows": {"row": [{"key": - [{"value" : "e", - "width": 2}, - {"value": "s", - "width": 2}, - {"value": "i", - "width": 2}, - {"value": "u", - "width": 2}, - {"value": "m", - "width": 2}, - {"value": "y", - "width": 2}, - {"value": "v", - "width": 2}, - {"value": "f", - "width": 2}, - {"value": "x", - "width": 2}, - {"key_type": "preferences", - "width": 2} - ] - }, - {"key":[{"value" : "a", - "width": 2}, - {"value": "n", - "width": 2}, - {"value": "l", - "width": 2}, - {"value": "t", - "width": 2}, - {"value": "p", - "width": 2}, - {"value": "b", - "width": 2}, - {"value": "g", - "width": 2}, - {"value": "z", - "width": 2}, - {"value": "w", - "width": 2}, - {"label": "<i>1%+</i>", - "key_type": "layout_switcher", - "value": "special", - "width": 2} - ] - }, - {"key":[{"value" : "o", - "width": 2}, - {"value": "r", - "width": 2}, - {"value": "d", - "width": 2}, - {"value": "c", - "width": 2}, - {"value": "q", - "width": 2}, - {"value": "h", - "width": 2}, - {"value": "j", - "width": 2}, - {"value": "ñ", - "width": 2}, - {"value": "k", - "width": 2}, - {"label": "<b>Ctrl D</b>", - "value": "Control_R", - "width": 2} - ] - }, - {"key": [{"value": "uppercase", - "label": "<b>⇧</b>", - "key_type": "layout_switcher", - "width": 3.33}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 3.33}, - {"label": "____", - "value": " ", - "width": 3.33}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 3.33}, - {"value": ",", - "width": 3.33}, - {"value": ".", - "width": 3.33} - ] - } - ] - } - }, - {"name": "special", - "rows": {"row": [{"key": - [{"value": "7", - "width": 2}, - {"value": "8", - "width": 2}, - {"value": "9", - "width": 2}, - {"value": ".", - "width": 2}, - {"value": "*", - "width": 2}, - {"value": "¿", - "width": 2}, - {"value": "\\", - "width": 2}, - {"value": ";", - "width": 2}, - {"value": "\"", - "width": 2}, - {"key_type": "preferences", - "width": 2} - ] - }, - {"key": [{"value": "4", - "width": 2}, - {"value": "5", - "width": 2}, - {"value": "6", - "width": 2}, - {"value": "+", - "width": 2}, - {"value": "/", - "width": 2}, - {"value": "?", - "width": 2}, - {"value": "(", - "width": 2}, - {"value": "€", - "width": 2}, - {"value": "@", - "width": 2}, - {"key_type": "layout_switcher", - "value": "lowercase", - "label": "abc", - "width": 2} - ] - }, - {"key": [{"value": "1", - "width": 2}, - {"value": "2", - "width": 2}, - {"value": "3", - "width": 2}, - {"value": "-", - "width": 2}, - {"value": "Up", - "label": "<b>↑</b>", - "width": 2}, - {"value": "%", - "width": 2}, - {"value": ")", - "width": 2}, - {"value": "_", - "width": 2}, - {"value": "#", - "width": 2}, - {"key_type": "mask", - "value": "Control_L", - "label": "<b>Ctrl I</b>", - "width": 2} - ] - }, - {"key": [{"value": "0", - "width": 3}, - {"label": "<big>⌫</big>", - "value": "BackSpace", - "width": 3}, - {"label": "<b>←</b>", - "width": 2, - "value": "Left"}, - {"label": "<b>↓</b>", - "width": 2, - "value": "Down"}, - {"label": "<b>→</b>", - "width": 2, - "value": "Right"}, - {"value": ":", - "width": 2}, - {"value": "'", - "width": 2}, - {"value": "$", - "width": 2}, - {"key_type": "mask", - "label": "<b>Alt I</b>", - "value": "Alt_L", - "width": 2} - ] - } - ] -} - }, - {"name": "uppercase", - "rows": {"row": [{"key":[ - {"value" : "E", - "width": 2}, - {"value": "S", - "width": 2}, - {"value": "I", - "width": 2}, - {"value": "U", - "width": 2}, - {"value": "M", - "width": 2}, - {"value": "Y", - "width": 2}, - {"value": "V", - "width": 2}, - {"value": "F", - "width": 2}, - {"value": "X", - "width": 2}, - {"key_type": "preferences", - "width": 2} - ] - }, - {"key":[{"value" : "A", - "width": 2}, - {"value": "N", - "width": 2}, - {"value": "L", - "width": 2}, - {"value": "T", - "width": 2}, - {"value": "P", - "width": 2}, - {"value": "B", - "width": 2}, - {"value": "G", - "width": 2}, - {"value": "Z", - "width": 2}, - {"value": "W", - "width": 2}, - {"label": "<i>1%+</i>", - "key_type": "layout_switcher", - "value": "special", - "width": 2} - ] - }, - {"key":[{"value" : "O", - "width": 2}, - {"value": "R", - "width": 2}, - {"value": "D", - "width": 2}, - {"value": "C", - "width": 2}, - {"value": "Q", - "width": 2}, - {"value": "H", - "width": 2}, - {"value": "J", - "width": 2}, - {"value": "Ñ", - "width": 2}, - {"value": "K", - "width": 2}, - {"label": "<b>Ctrl D</b>", - "value": "Control_R", - "width": 2} - ] - }, - {"key": [{"value": "lowercase", - "label": "<b>⇩</b>", - "key_type": "layout_switcher", - "width": 3.33}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 3.33}, - {"label": "____", - "value": " ", - "width": 3.33}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 3.33}, - {"value": ",", - "width": 3.33}, - {"value": ".", - "width": 3.33} - ] - } - ] - } - } - ] -} - - - - - - - - diff --git a/data/keyboards/qwerty.xml b/data/keyboards/qwerty.xml deleted file mode 100644 index af5bb6e..0000000 --- a/data/keyboards/qwerty.xml +++ /dev/null @@ -1,274 +0,0 @@ -<keyboard> - <layout> - <name>lowercase</name> - <rows> - <row> - <key key_type="preferences"/> - <key value="q"/> - <key value="w"/> - <key value="e"/> - <key value="r"/> - <key value="t"/> - <key value="y"/> - <key value="u"/> - <key value="i"/> - <key value="o"/> - <key value="p"/> - <key> - <value>BackSpace</value> - <label><big>⌫</big></label> - <width>1.5</width> - </key> - </row> - <row> - <key> - <label><b><sup>←</sup><sub>→</sub></b>"</label> - <value>Tab</value> - </key> - <key key_type="dummy" width="0.25"/> - <key value="a"/> - <key value="s"/> - <key value="d"/> - <key value="f"/> - <key value="g"/> - <key value="h"/> - <key value="j"/> - <key value="k"/> - <key value="l"/> - <key key_type="dummy" width="0.25"/> - <key> - <value>Return</value> - <label><b>↲</b></label> - <width>2</width> - </key> - </row> - <row> - <key> - <label><b>↑</b></label> - <key_type>layout_switcher</key_type> - <value>uppercase</value> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key value="z"/> - <key value="x"/> - <key value="c"/> - <key value="v"/> - <key value="b"/> - <key value="n"/> - <key value="m"/> - <key key_type="dummy" width="0.5"/> - <key value=","/> - <key value="."/> - <key value=";"/> - </row> - <row> - <key> - <label><small><i>1%+</i></small></label> - <key_type>layout_switcher</key_type> - <value>special</value> - <width>1.5</width> - </key> - <key> - <label><small><b>Ctrl</b></small></label> - <value>Control_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key> - <label><small><b>Alt</b></small></label> - <value>Alt_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key label="______" value=" " width="3"/> - <key key_type="dummy" width="0.5"/> - <key value="'"/> - <key value="""/> - <key value="!"/> - <key value="?"/> - </row> - </rows> - </layout> - - <layout> - <name>uppercase</name> - <rows> - <row> - <key key_type="preferences"/> - <key value="Q"/> - <key value="W"/> - <key value="E"/> - <key value="R"/> - <key value="T"/> - <key value="Y"/> - <key value="U"/> - <key value="I"/> - <key value="O"/> - <key value="P"/> - <key> - <value>BackSpace</value> - <label><big>⌫</big></label> - <width>1.5</width> - </key> - </row> - <row> - <key> - <label><b><sup>←</sup><sub>→</sub></b>"</label> - <value>Tab</value> - </key> - <key key_type="dummy" width="0.25"/> - <key value="A"/> - <key value="S"/> - <key value="D"/> - <key value="F"/> - <key value="G"/> - <key value="H"/> - <key value="J"/> - <key value="K"/> - <key value="L"/> - <key key_type="dummy" width="0.25"/> - <key> - <value>Return</value> - <label><b>↲</b></label> - <width>2</width> - </key> - </row> - <row> - <key> - <label><b>↓</b></label> - <key_type>layout_switcher</key_type> - <value>lowercase</value> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key value="Z"/> - <key value="X"/> - <key value="C"/> - <key value="V"/> - <key value="B"/> - <key value="N"/> - <key value="M"/> - <key key_type="dummy" width="0.5"/> - <key value=","/> - <key value="."/> - <key value=";"/> - </row> - <row> - <key> - <label><small><i>1%+</i></small></label> - <key_type>layout_switcher</key_type> - <value>special</value> - <width>1.5</width> - </key> - <key> - <label><small><b>Ctrl</b></small></label> - <value>Control_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key> - <label><small><b>Alt</b></small></label> - <value>Alt_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key label="______" value=" " width="3"/> - <key key_type="dummy" width="0.5"/> - <key value="'"/> - <key value="""/> - <key value="!"/> - <key value="?"/> - </row> - </rows> - </layout> - - <layout> - <name>special</name> - <rows> - <row> - <key key_type="preferences"/> - <key value="1"/> - <key value="2"/> - <key value="3"/> - <key value="4"/> - <key value="5"/> - <key value="6"/> - <key value="7"/> - <key value="8"/> - <key value="9"/> - <key value="0"/> - <key> - <value>BackSpace</value> - <label><big>⌫</big></label> - <width>1.5</width> - </key> - </row> - <row> - <key key_type="dummy" width="0.25"/> - <key key_type="dummy" width="0.25"/> - <key value="@"/> - <key value="#"/> - <key value="$"/> - <key value="%"/> - <key value="&"/> - <key value="*"/> - <key value="("/> - <key value=")"/> - <key value="-"/> - <key value="+"/> - <key key_type="dummy" width="0.25"/> - <key> - <value>Return</value> - <label><b>↲</b></label> - <width>2</width> - </key> - </row> - <row> - <key key_type="dummy" width="0.25"/> - <key value="<"/> - <key value=">"/> - <key value="€"/> - <key value="£"/> - <key value="{"/> - <key value="}"/> - <key value="["/> - <key value="]"/> - <key value="_" label="<small>_</small>"/> - <key value="="/> - <key key_type="dummy" width="0.25"/> - <key value="Up" label="<b>↑</b>"/> - <key value="\"/> - </row> - <row> - <key> - <label><small><i>abc</i></small></label> - <key_type>layout_switcher</key_type> - <value>lowercase</value> - <width>1.5</width> - </key> - <key> - <label><small><b>Ctrl</b></small></label> - <value>Control_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key> - <label><small><b>Alt</b></small></label> - <value>Alt_L</value> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.5"/> - <key label="______" value=" " width="3"/> - <key key_type="dummy" width="0.5"/> - <key value="|"/> - <key value="Left" label="<b>←</b>"/> - <key value="Down" label="<b>↓</b>"/> - <key value="Right" label="<b>→</b>"/> - </row> - </rows> - </layout> -</keyboard> diff --git a/data/keyboards/qwerty_en.json b/data/keyboards/qwerty_en.json deleted file mode 100644 index 8864085..0000000 --- a/data/keyboards/qwerty_en.json +++ /dev/null @@ -1,261 +0,0 @@ - -{"layout": [ - {"name": "lowercase", - "rows": {"row": [{"key": [{"key_type": "preferences"}, - {"value": "q"}, - {"value": "w"}, - {"value": "e"}, - {"value": "r"}, - {"value": "t"}, - {"value": "y"}, - {"value": "u"}, - {"value": "i"}, - {"value": "o"}, - {"value": "p"}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 1.5} - ] - }, - {"key": [{"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab"}, - {"key_type": "dummy", - "width": 0.25}, - {"value": "a"}, - {"value": "s"}, - {"value": "d"}, - {"value": "f"}, - {"value": "g"}, - {"value": "h"}, - {"value": "j"}, - {"value": "k"}, - {"value": "l"}, - {"key_type": "dummy", - "width": 0.25}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 2} - ] - }, - {"key": [{"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase", - "width": 1.5}, - {"key_type": "dummy", - "width": 0.5}, - {"value": "z"}, - {"value": "x"}, - {"value": "c"}, - {"value": "v"}, - {"value": "b"}, - {"value": "n"}, - {"value": "m"}, - {"key_type": "dummy", - "width": 0.5}, - {"value": ","}, - {"value": "."}, - {"value": ";"} - ] - }, - {"key": [{"label": "<small><i>1%+</i></small>", - "key_type": "layout_switcher", - "value": "special", - "width": 1.5}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.5}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.5}, - {"key_type": "dummy", - "width": 0.5}, - {"label": "______", - "value": " ", - "width": 3}, - {"key_type": "dummy", - "width": 0.5}, - {"value": "'"}, - {"value": "\""}, - {"value": "!"}, - {"value": "?"} - ] - } - ] - } - }, - {"name": "uppercase", - "rows": {"row": [{"key": [{"key_type": "preferences"}, - {"value": "Q"}, - {"value": "W"}, - {"value": "E"}, - {"value": "R"}, - {"value": "T"}, - {"value": "Y"}, - {"value": "U"}, - {"value": "I"}, - {"value": "O"}, - {"value": "P"}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 1.5} - ] - }, - {"key": [{"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab"}, - {"key_type": "dummy", - "width": 0.25}, - {"value": "A"}, - {"value": "S"}, - {"value": "D"}, - {"value": "F"}, - {"value": "G"}, - {"value": "G"}, - {"value": "H"}, - {"value": "J"}, - {"value": "K"}, - {"key_type": "dummy", - "width": 0.25}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 2} - ] - }, - {"key": [{"label": "<b>↓</b>", - "key_type": "layout_switcher", - "value": "lowercase", - "width": 1.5}, - {"key_type": "dummy", - "width": 0.5}, - {"value": "Z"}, - {"value": "X"}, - {"value": "C"}, - {"value": "V"}, - {"value": "B"}, - {"value": "N"}, - {"value": "M"}, - {"key_type": "dummy", - "width": 0.5}, - {"value": ","}, - {"value": "."}, - {"value": ";"} - ] - }, - {"key": [{"label": "<small><i>1%+</i></small>", - "key_type": "layout_switcher", - "value": "special", - "width": 1.5}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.5}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.5}, - {"key_type": "dummy", - "width": 0.5}, - {"label": "______", - "value": " ", - "width": 3}, - {"key_type": "dummy", - "width": 0.5}, - {"value": "'"}, - {"value": "\""}, - {"value": "!"}, - {"value": "?"} - ] - } - ] - } - }, - {"name": "special", - "rows": {"row": [{"key": [{"key_type": "preferences"}, - {"value": "1"}, - {"value": "2"}, - {"value": "3"}, - {"value": "4"}, - {"value": "5"}, - {"value": "6"}, - {"value": "7"}, - {"value": "8"}, - {"value": "9"}, - {"value": "0"}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 1.5} - ] - }, - {"key": [{"key_type": "dummy", - "width": 0.25}, - {"value": "@"}, - {"value": "#"}, - {"value": "$"}, - {"value": "%"}, - {"value": "&"}, - {"value": "*"}, - {"value": "("}, - {"value": ")"}, - {"value": "-"}, - {"value": "+"}, - {"key_type": "dummy", - "width": 0.25}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 2} - ] - }, - {"key": [{"key_type": "dummy", - "width": 0.25}, - {"value": "<"}, - {"value": ">"}, - {"value": "€"}, - {"value": "£"}, - {"value": "{"}, - {"value": "}"}, - {"value": "["}, - {"value": "]"}, - {"label": "<small>_</small>", - "value": "_"}, - {"value": "="}, - {"key_type": "dummy", - "width": 0.25}, - {"label": "<b>↑</b>", - "value": "Up"}, - {"value": "\\"} - ] - }, - {"key": [{"label": "<small><i>abc</i></small>", - "key_type": "layout_switcher", - "value": "lowercase", - "width": 1.5}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.5}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.5}, - {"key_type": "dummy", - "width": 0.5}, - {"label": "______", - "value": " ", - "width": 3}, - {"key_type": "dummy", - "width": 0.5}, - {"value": "|"}, - {"label": "<b>←</b>", - "value": "Left"}, - {"label": "<b>↓</b>", - "value": "Down"}, - {"label": "<b>→</b>", - "value": "Right"} - ] - } - ] - } - } - ] -} diff --git a/data/keyboards/qwerty_es.json b/data/keyboards/qwerty_es.json deleted file mode 100644 index 4136d08..0000000 --- a/data/keyboards/qwerty_es.json +++ /dev/null @@ -1,1318 +0,0 @@ -{"layout": -[ - {"name": "uppercase", - "rows": {"row": [{"key":[ - {"value": "Escape", "label": "<small>Esc</small>", "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"value": "F1", - "width": 1.2}, - {"value": "F2", - "width": 1.2}, - {"value": "F3", - "width": 1.2}, - {"value": "F4", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F5", - "width": 1.2}, - {"value": "F6", - "width": 1.2}, - {"value": "F7", - "width": 1.2}, - {"value": "F8", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F9", - "width": 1.2}, - {"value": "F10", - "width": 1.2}, - {"value": "F11", - "width": 1.2}, - {"value": "F12", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"key_type": "preferences", "width": 1.2} - ] - }, - {"key": [ - {"value": "º", "width": 1.2}, - {"value": "1", "width": 1.2}, - {"value": "2", "width": 1.2}, - {"value": "3", "width": 1.2}, - {"value": "4", "width": 1.2}, - {"value": "5", "width": 1.2}, - {"value": "6", "width": 1.2}, - {"value": "7", "width": 1.2}, - {"value": "8", "width": 1.2}, - {"value": "9", "width": 1.2}, - {"value": "0", "width": 1.2}, - {"value": "'", "width": 1.2}, - {"value": "¡", "width": 1.2}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 2.4} - ] - }, - {"key": [ - {"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab", - "width": 1.8}, - {"value": "Q", "width": 1.2}, - {"value": "W", "width": 1.2}, - {"value": "E", "width": 1.2}, - {"value": "R", "width": 1.2}, - {"value": "T", "width": 1.2}, - {"value": "Y", "width": 1.2}, - {"value": "U", "width": 1.2}, - {"value": "I", "width": 1.2}, - {"value": "O", "width": 1.2}, - {"value": "P", "width": 1.2}, - {"value": "`", "width": 1.2}, - {"value": "+", "width": 1.2}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 1.8} - ] - }, - {"key": [ - {"label": "<small>Bloq M</small>", - "value": "lowercase", - "key_type": "layout_switcher", - "width": 2.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "A", "width": 1.2}, - {"value": "S", "width": 1.2}, - {"value": "D", "width": 1.2}, - {"value": "F", "width": 1.2}, - {"value": "G", "width": 1.2}, - {"value": "H", "width": 1.2}, - {"value": "J", "width": 1.2}, - {"value": "K", "width": 1.2}, - {"value": "L", "width": 1.2}, - {"value": "Ñ", "width": 1.2}, - {"value": "´", "width": 1.2}, - {"value": "Ç", "width": 1.2}, - {"key_type": "dummy", - "width": 0.8} - ] - }, - {"key": [ - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase_shift", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "<", - "label": "<", "width": 1.2}, - {"value": "Z", "width": 1.2}, - {"value": "X", "width": 1.2}, - {"value": "C", "width": 1.2}, - {"value": "V", "width": 1.2}, - {"value": "B", "width": 1.2}, - {"value": "N", "width": 1.2}, - {"value": "M", "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": ",", "width": 1.2}, - {"value": ".", "width": 1.2}, - {"value": "-", "width": 1.2}, - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase_shift", - "width": 2.8} - ] - }, - {"key":[ - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.8}, - {"label": "<small><b>Win</b></small>", - "value": "Super_L", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "______", - "value": " ", - "width": 7.4}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "<small><b>Alt Gr</b></small>", - "value": "uppercase_alt", - "key_type": "layout_switcher", - "width": 1.6}, - {"label": "<small><b>Win</b></small>", - "value": "Super_R", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_R", - "width": 1.6} - ] - } - ] - } - }, - - - {"name": "lowercase_shift", - "rows": {"row": [{"key":[ - {"value": "Escape", "label": "<small>Esc</small>", "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"value": "F1", - "width": 1.2}, - {"value": "F2", - "width": 1.2}, - {"value": "F3", - "width": 1.2}, - {"value": "F4", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F5", - "width": 1.2}, - {"value": "F6", - "width": 1.2}, - {"value": "F7", - "width": 1.2}, - {"value": "F8", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F9", - "width": 1.2}, - {"value": "F10", - "width": 1.2}, - {"value": "F11", - "width": 1.2}, - {"value": "F12", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"key_type": "preferences", "width": 1.2} - ] - }, - {"key": [ - {"value": "º", "width": 1.2}, - {"value": "ª", "width": 1.2}, - {"value": "!", "width": 1.2}, - {"value": "\"", "width": 1.2}, - {"value": "·", "width": 1.2}, - {"value": "%", "width": 1.2}, - {"value": "&", "width": 1.2}, - {"value": "/", "width": 1.2}, - {"value": "(", "width": 1.2}, - {"value": ")", "width": 1.2}, - {"value": "=", "width": 1.2}, - {"value": "?", "width": 1.2}, - {"value": "¿", "width": 1.2}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 2.4} - ] - }, - {"key": [ - {"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab", - "width": 1.8}, - {"value": "Q", "width": 1.2}, - {"value": "W", "width": 1.2}, - {"value": "E", "width": 1.2}, - {"value": "R", "width": 1.2}, - {"value": "T", "width": 1.2}, - {"value": "Y", "width": 1.2}, - {"value": "U", "width": 1.2}, - {"value": "I", "width": 1.2}, - {"value": "O", "width": 1.2}, - {"value": "P", "width": 1.2}, - {"value": "^", "width": 1.2}, - {"value": "*", "width": 1.2}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 1.8} - ] - }, - {"key":[ - {"label": "<small>Bloq M</small>", - "value": "uppercase_shift", - "key_type": "layout_switcher", - "width": 2.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "A", "width": 1.2}, - {"value": "S", "width": 1.2}, - {"value": "D", "width": 1.2}, - {"value": "F", "width": 1.2}, - {"value": "G", "width": 1.2}, - {"value": "H", "width": 1.2}, - {"value": "J", "width": 1.2}, - {"value": "K", "width": 1.2}, - {"value": "L", "width": 1.2}, - {"value": "Ñ", "width": 1.2}, - {"value": "¨", "width": 1.2}, - {"value": "Ç", "width": 1.2}, - {"key_type": "dummy", - "width": 0.8} - ] - }, - {"key":[ - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "lowercase", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": ">", - "label": ">", "width": 1.2}, - {"value": "Z", "width": 1.2}, - {"value": "X", "width": 1.2}, - {"value": "C", "width": 1.2}, - {"value": "V", "width": 1.2}, - {"value": "B", "width": 1.2}, - {"value": "N", "width": 1.2}, - {"value": "M", "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": ";", "width": 1.2}, - {"value": ":", "width": 1.2}, - {"value": "_", "width": 1.2}, - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "lowercase", - "width": 2.8} - ] - }, - {"key":[ - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.8}, - {"label": "<small><b>Win</b></small>", - "value": "Super_L", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "______", - "value": " ", - "width": 7.4}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "<small><b>Alt Gr</b></small>", - "value": "lowercase_alt_shift", - "key_type": "layout_switcher", - "width": 1.6}, - {"label": "<small><b>Win</b></small>", - "value": "Super_R", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_R", - "width": 1.6} - ] - } - ] - } - }, - {"name": "uppercase_shift", - "rows": {"row": [{"key": [ - {"value": "Escape", "label": "<small>Esc</small>", "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"value": "F1", - "width": 1.2}, - {"value": "F2", - "width": 1.2}, - {"value": "F3", - "width": 1.2}, - {"value": "F4", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F5", - "width": 1.2}, - {"value": "F6", - "width": 1.2}, - {"value": "F7", - "width": 1.2}, - {"value": "F8", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F9", - "width": 1.2}, - {"value": "F10", - "width": 1.2}, - {"value": "F11", - "width": 1.2}, - {"value": "F12", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"key_type": "preferences", "width": 1.2} - ] - }, - {"key":[ - {"value": "º", "width": 1.2}, - {"value": "ª", "width": 1.2}, - {"value": "!", "width": 1.2}, - {"value": "\"", "width": 1.2}, - {"value": "·", "width": 1.2}, - {"value": "%", "width": 1.2}, - {"value": "&", "width": 1.2}, - {"value": "/", "width": 1.2}, - {"value": "(", "width": 1.2}, - {"value": ")", "width": 1.2}, - {"value": "=", "width": 1.2}, - {"value": "?", "width": 1.2}, - {"value": "¿", "width": 1.2}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 2.4} - ] - }, - {"key":[ - {"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab", - "width": 1.8}, - {"value": "q", "width": 1.2}, - {"value": "w", "width": 1.2}, - {"value": "e", "width": 1.2}, - {"value": "r", "width": 1.2}, - {"value": "t", "width": 1.2}, - {"value": "y", "width": 1.2}, - {"value": "u", "width": 1.2}, - {"value": "i", "width": 1.2}, - {"value": "o", "width": 1.2}, - {"value": "p", "width": 1.2}, - {"value": "^", "width": 1.2}, - {"value": "*", "width": 1.2}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 1.8} - ] - }, - {"key": [ - {"label": "<small>Bloq M</small>", - "value": "lowercase_shift", - "key_type": "layout_switcher", - "width": 2.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "a", "width": 1.2}, - {"value": "s", "width": 1.2}, - {"value": "d", "width": 1.2}, - {"value": "f", "width": 1.2}, - {"value": "g", "width": 1.2}, - {"value": "h", "width": 1.2}, - {"value": "j", "width": 1.2}, - {"value": "k", "width": 1.2}, - {"value": "l", "width": 1.2}, - {"value": "ñ", "width": 1.2}, - {"value": "¨", "width": 1.2}, - {"value": "Ç", "width": 1.2}, - {"key_type": "dummy", - "width": 0.8} - ] - }, - {"key":[ - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": ">", - "label": ">", "width": 1.2}, - {"value": "z", "width": 1.2}, - {"value": "x", "width": 1.2}, - {"value": "c", "width": 1.2}, - {"value": "v", "width": 1.2}, - {"value": "b", "width": 1.2}, - {"value": "n", "width": 1.2}, - {"value": "m", "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": ";", "width": 1.2}, - {"value": ":", "width": 1.2}, - {"value": "_", "width": 1.2}, - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase", - "width": 2.8} - ] - }, - {"key":[ - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.8}, - {"label": "<small><b>Win</b></small>", - "value": "Super_L", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "______", - "value": " ", - "width": 7.4}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "<small><b>Alt Gr</b></small>", - "value": "uppercase_alt_shift", - "key_type": "layout_switcher", - "width": 1.6}, - {"label": "<small><b>Win</b></small>", - "value": "Super_R", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_R", - "width": 1.6} - ] - } - ] - } - }, - {"name": "uppercase_alt", - "rows": {"row": [{"key":[ - {"value": "Escape", "label": "<small>Esc</small>", "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"value": "F1", - "width": 1.2}, - {"value": "F2", - "width": 1.2}, - {"value": "F3", - "width": 1.2}, - {"value": "F4", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F5", - "width": 1.2}, - {"value": "F6", - "width": 1.2}, - {"value": "F7", - "width": 1.2}, - {"value": "F8", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F9", - "width": 1.2}, - {"value": "F10", - "width": 1.2}, - {"value": "F11", - "width": 1.2}, - {"value": "F12", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"key_type": "preferences", "width": 1.2} - ] - }, - {"key": [ - {"value": "\\", "width": 1.2}, - {"value": "|", "width": 1.2}, - {"value": "@", "width": 1.2}, - {"value": "#", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "½", "width": 1.2}, - {"value": "¬", "width": 1.2}, - {"value": "{", "width": 1.2}, - {"value": "[", "width": 1.2}, - {"value": "]", "width": 1.2}, - {"value": "}", "width": 1.2}, - {"value": "\\", "width": 1.2}, - {"value": "¡", "width": 1.2}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 2.4} - ] - }, - {"key":[ - {"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab", - "width": 1.8}, - {"value": "@", "width": 1.2}, - {"value": "Ł", "width": 1.2}, - {"value": "€", "width": 1.2}, - {"value": "¶", "width": 1.2}, - {"value": "Ŧ", "width": 1.2}, - {"value": "←", "width": 1.2}, - {"value": "↓", "width": 1.2}, - {"value": "→", "width": 1.2}, - {"value": "Ø", "width": 1.2}, - {"value": "Þ", "width": 1.2}, - {"value": "[", "width": 1.2}, - {"value": "]", "width": 1.2}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 1.8} - ] - }, - {"key":[ - {"label": "<small>Bloq M</small>", - "value": "lowercase_alt", - "key_type": "layout_switcher", - "width": 2.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "Æ", "width": 1.2}, - {"value": "ß", "width": 1.2}, - {"value": "Ð", "width": 1.2}, - {"value": "Đ", "width": 1.2}, - {"value": "Ŋ", "width": 1.2}, - {"value": "Ħ", "width": 1.2}, - {"value": "J", "width": 1.2}, - {"value": "ĸ", "width": 1.2}, - {"value": "Ł", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "{", "width": 1.2}, - {"value": "}", "width": 1.2}, - {"key_type": "dummy", - "width": 0.8} - ] - }, - {"key":[ - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase_alt_shift", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "|", - "label": "|", "width": 1.2}, - {"value": "«", "width": 1.2}, - {"value": "»", "width": 1.2}, - {"value": "¢", "width": 1.2}, - {"value": "“", "width": 1.2}, - {"value": "”", "width": 1.2}, - {"value": "N", "width": 1.2}, - {"value": "M", "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": ",", "width": 1.2}, - {"value": ".", "width": 1.2}, - {"value": "-", "width": 1.2}, - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase_alt_shift", - "width": 2.8} - ] - }, - {"key":[ - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.8}, - {"label": "<small><b>Win</b></small>", - "value": "Super_L", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "______", - "value": " ", - "width": 7.4}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "<small><b>Alt Gr</b></small>", - "value": "uppercase", - "key_type": "layout_switcher", - "width": 1.6}, - {"label": "<small><b>Win</b></small>", - "value": "Super_R", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_R", - "width": 1.6} - ] - } - ] - } - }, -{"name": "lowercase_alt_shift", - "rows": {"row": [{"key": [ - {"value": "Escape", "label": "<small>Esc</small>", "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"value": "F1", - "width": 1.2}, - {"value": "F2", - "width": 1.2}, - {"value": "F3", - "width": 1.2}, - {"value": "F4", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F5", - "width": 1.2}, - {"value": "F6", - "width": 1.2}, - {"value": "F7", - "width": 1.2}, - {"value": "F8", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F9", - "width": 1.2}, - {"value": "F10", - "width": 1.2}, - {"value": "F11", - "width": 1.2}, - {"value": "F12", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"key_type": "preferences", "width": 1.2} - ] - }, - {"key":[ - {"value": "\\", "width": 1.2}, - {"value": "¡", "width": 1.2}, - {"value": "⅛", "width": 1.2}, - {"value": "£", "width": 1.2}, - {"value": "$", "width": 1.2}, - {"value": "⅜", "width": 1.2}, - {"value": "⅝", "width": 1.2}, - {"value": "⅞", "width": 1.2}, - {"value": "™", "width": 1.2}, - {"value": "±", "width": 1.2}, - {"value": "°", "width": 1.2}, - {"value": "¿", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 2.4} - ] - }, - {"key":[ - {"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab", - "width": 1.8}, - {"value": "@", "width": 1.2}, - {"value": "Ł", "width": 1.2}, - {"value": "€", "width": 1.2}, - {"value": "¶", "width": 1.2}, - {"value": "Ŧ", "width": 1.2}, - {"value": "←", "width": 1.2}, - {"value": "↓", "width": 1.2}, - {"value": "→", "width": 1.2}, - {"value": "Ø", "width": 1.2}, - {"value": "Þ", "width": 1.2}, - {"value": "[", "width": 1.2}, - {"value": "]", "width": 1.2}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 1.8} - ] - }, - {"key":[ - {"label": "<small>Bloq M</small>", - "value": "uppercase_alt_shift", - "key_type": "layout_switcher", - "width": 2.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "Æ", "width": 1.2}, - {"value": "ß", "width": 1.2}, - {"value": "Ð", "width": 1.2}, - {"value": "Đ", "width": 1.2}, - {"value": "Ŋ", "width": 1.2}, - {"value": "Ħ", "width": 1.2}, - {"value": "J", "width": 1.2}, - {"value": "ĸ", "width": 1.2}, - {"value": "Ł", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "{", "width": 1.2}, - {"value": "}", "width": 1.2}, - {"key_type": "dummy", - "width": 0.8} - ] - }, - {"key":[ - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "lowercase_alt", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "|", - "label": "|", "width": 1.2}, - {"value": "«", "width": 1.2}, - {"value": "»", "width": 1.2}, - {"value": "¢", "width": 1.2}, - {"value": "“", "width": 1.2}, - {"value": "”", "width": 1.2}, - {"value": "N", "width": 1.2}, - {"value": "M", "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": ",", "width": 1.2}, - {"value": ".", "width": 1.2}, - {"value": "-", "width": 1.2}, - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "lowercase_alt", - "width": 2.8} - ] - }, - {"key":[ - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.8}, - {"label": "<small><b>Win</b></small>", - "value": "Super_L", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "______", - "value": " ", - "width": 7.4}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "<small><b>Alt Gr</b></small>", - "value": "lowercase_shift", - "key_type": "layout_switcher", - "width": 1.6}, - {"label": "<small><b>Win</b></small>", - "value": "Super_R", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_R", - "width": 1.6} - ] - } - ] - } - }, - {"name": "lowercase_alt", - "rows": {"row": [{"key":[ - {"value": "Escape", "label": "<small>Esc</small>"}, - {"key_type": "dummy", - "width": 0.4}, - {"value": "F1", - "width": 1.2}, - {"value": "F2", - "width": 1.2}, - {"value": "F3", - "width": 1.2}, - {"value": "F4", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F5", - "width": 1.2}, - {"value": "F6", - "width": 1.2}, - {"value": "F7", - "width": 1.2}, - {"value": "F8", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F9", - "width": 1.2}, - {"value": "F10", - "width": 1.2}, - {"value": "F11", - "width": 1.2}, - {"value": "F12", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"key_type": "preferences"} - ] - }, - {"key":[ - {"value": "\\", "width": 1.2}, - {"value": "|", "width": 1.2}, - {"value": "@", "width": 1.2}, - {"value": "#", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "½", "width": 1.2}, - {"value": "¬", "width": 1.2}, - {"value": "{", "width": 1.2}, - {"value": "[", "width": 1.2}, - {"value": "[", "width": 1.2}, - {"value": "}", "width": 1.2}, - {"value": "\\", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 2.4} - ] - }, - {"key":[ - {"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab", - "width": 1.8}, - {"value": "@", "width": 1.2}, - {"value": "ł", "width": 1.2}, - {"value": "€", "width": 1.2}, - {"value": "¶", "width": 1.2}, - {"value": "ŧ", "width": 1.2}, - {"value": "←", "width": 1.2}, - {"value": "↓", "width": 1.2}, - {"value": "→", "width": 1.2}, - {"value": "ø", "width": 1.2}, - {"value": "þ", "width": 1.2}, - {"value": "[", "width": 1.2}, - {"value": "]", "width": 1.2}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 1.8} - ] - }, - {"key":[ - {"label": "<small>Bloq M</small>", - "value": "uppercase_alt", - "key_type": "layout_switcher", - "width": 2.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "æ", "width": 1.2}, - {"value": "ß", "width": 1.2}, - {"value": "ð", "width": 1.2}, - {"value": "đ", "width": 1.2}, - {"value": "ŋ", "width": 1.2}, - {"value": "ħ", "width": 1.2}, - {"value": "j", "width": 1.2}, - {"value": "ĸ", "width": 1.2}, - {"value": "ł", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "{", "width": 1.2}, - {"value": "}", "width": 1.2}, - {"key_type": "dummy", - "width": 0.8} - ] - }, - {"key":[ - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "lowercase_alt_shift", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "|", - "label": "<", "width": 1.2}, - {"value": "«", "width": 1.2}, - {"value": "»", "width": 1.2}, - {"value": "¢", "width": 1.2}, - {"value": "“", "width": 1.2}, - {"value": "”", "width": 1.2}, - {"value": "n", "width": 1.2}, - {"value": "µ", "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "─", "width": 1.2}, - {"value": "·", "width": 1.2}, - {"value": "-", "width": 1.2}, - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "lowercase_alt_shift", - "width": 2.8} - ] - }, - {"key":[ - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.8}, - {"label": "<small><b>Win</b></small>", - "value": "Super_L", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "______", - "value": " ", - "width": 7.4}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "<small><b>Alt Gr</b></small>", - "value": "lowercase", - "key_type": "layout_switcher", - "width": 1.6}, - {"label": "<small><b>Win</b></small>", - "value": "Super_R", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_R", - "width": 1.6} - ] - } - ] - } - }, -{"name": "uppercase_alt_shift", - "rows": {"row": [{"key":[ - {"value": "Escape", "label": "<small>Esc</small>", "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"value": "F1", - "width": 1.2}, - {"value": "F2", - "width": 1.2}, - {"value": "F3", - "width": 1.2}, - {"value": "F4", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F5", - "width": 1.2}, - {"value": "F6", - "width": 1.2}, - {"value": "F7", - "width": 1.2}, - {"value": "F8", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F9", - "width": 1.2}, - {"value": "F10", - "width": 1.2}, - {"value": "F11", - "width": 1.2}, - {"value": "F12", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"key_type": "preferences", "width": 1.2} - ] - }, - {"key":[ - {"value": "\\", "width": 1.2}, - {"value": "¡", "width": 1.2}, - {"value": "⅛", "width": 1.2}, - {"value": "£", "width": 1.2}, - {"value": "$", "width": 1.2}, - {"value": "⅜", "width": 1.2}, - {"value": "⅝", "width": 1.2}, - {"value": "⅞", "width": 1.2}, - {"value": "™", "width": 1.2}, - {"value": "±", "width": 1.2}, - {"value": "°", "width": 1.2}, - {"value": "¿", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 2.4} - ] - }, - {"key":[ - {"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab", - "width": 1.8}, - {"value": "@", "width": 1.2}, - {"value": "ł", "width": 1.2}, - {"value": "€", "width": 1.2}, - {"value": "¶", "width": 1.2}, - {"value": "ŧ", "width": 1.2}, - {"value": "←", "width": 1.2}, - {"value": "↓", "width": 1.2}, - {"value": "→", "width": 1.2}, - {"value": "ø", "width": 1.2}, - {"value": "þ", "width": 1.2}, - {"value": "[", "width": 1.2}, - {"value": "]", "width": 1.2}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 1.8} - ] - }, - {"key":[ - {"label": "<small>Bloq M</small>", - "value": "lowercase_alt_shift", - "key_type": "layout_switcher", - "width": 2.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "æ", "width": 1.2}, - {"value": "ß", "width": 1.2}, - {"value": "ð", "width": 1.2}, - {"value": "đ", "width": 1.2}, - {"value": "ŋ", "width": 1.2}, - {"value": "ħ", "width": 1.2}, - {"value": "j", "width": 1.2}, - {"value": "ĸ", "width": 1.2}, - {"value": "ł", "width": 1.2}, - {"value": "~", "width": 1.2}, - {"value": "{", "width": 1.2}, - {"value": "}", "width": 1.2}, - {"key_type": "dummy", - "width": 0.8} - ] - }, - {"key":[ - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase_alt", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "|", - "label": "<", "width": 1.2}, - {"value": "«", "width": 1.2}, - {"value": "»", "width": 1.2}, - {"value": "¢", "width": 1.2}, - {"value": "“", "width": 1.2}, - {"value": "”", "width": 1.2}, - {"value": "n", "width": 1.2}, - {"value": "µ", "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "─", "width": 1.2}, - {"value": "·", "width": 1.2}, - {"value": "-", "width": 1.2}, - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "uppercase_alt", - "width": 2.8} - ] - }, - {"key":[ - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.8}, - {"label": "<small><b>Win</b></small>", - "value": "Super_L", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "______", - "value": " ", - "width": 7.4}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "<small><b>Alt Gr</b></small>", - "value": "uppercase_shift", - "key_type": "layout_switcher", - "width": 1.6}, - {"label": "<small><b>Win</b></small>", - "value": "Super_R", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_R", - "width": 1.6} - ] - } - ] - } - }, - {"name": "lowercase", - "rows": {"row": [{"key":[ - {"value": "Escape", "label": "<small>Esc</small>", "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"value": "F1", - "width": 1.2}, - {"value": "F2", - "width": 1.2}, - {"value": "F3", - "width": 1.2}, - {"value": "F4", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F5", - "width": 1.2}, - {"value": "F6", - "width": 1.2}, - {"value": "F7", - "width": 1.2}, - {"value": "F8", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "F9", - "width": 1.2}, - {"value": "F10", - "width": 1.2}, - {"value": "F11", - "width": 1.2}, - {"value": "F12", - "width": 1.2}, - {"key_type": "dummy", - "width": 0.4}, - {"key_type": "preferences", "width": 1.2} - ] - }, - {"key":[ - {"value": "º", "width": 1.2}, - {"value": "1", "width": 1.2}, - {"value": "2", "width": 1.2}, - {"value": "3", "width": 1.2}, - {"value": "4", "width": 1.2}, - {"value": "5", "width": 1.2}, - {"value": "6", "width": 1.2}, - {"value": "7", "width": 1.2}, - {"value": "8", "width": 1.2}, - {"value": "9", "width": 1.2}, - {"value": "0", "width": 1.2}, - {"value": "'", "width": 1.2}, - {"value": "¡", "width": 1.2}, - {"value": "BackSpace", - "label": "<big>⌫</big>", - "width": 2.4} - ] - }, - {"key":[ - {"label": "<b><sup>←</sup><sub>→</sub></b>", - "value": "Tab", - "width": 1.8}, - {"value": "q", "width": 1.2}, - {"value": "w", "width": 1.2}, - {"value": "e", "width": 1.2}, - {"value": "r", "width": 1.2}, - {"value": "t", "width": 1.2}, - {"value": "y", "width": 1.2}, - {"value": "u", "width": 1.2}, - {"value": "i", "width": 1.2}, - {"value": "o", "width": 1.2}, - {"value": "p", "width": 1.2}, - {"value": "`", "width": 1.2}, - {"value": "+", "width": 1.2}, - {"value": "Return", - "label": "<b>↲</b>", - "width": 1.8} - ] - }, - {"key":[ - {"label": "<small>Bloq M</small>", - "value": "uppercase", - "key_type": "layout_switcher", - "width": 2.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "a", "width": 1.2}, - {"value": "s", "width": 1.2}, - {"value": "d", "width": 1.2}, - {"value": "f", "width": 1.2}, - {"value": "g", "width": 1.2}, - {"value": "h", "width": 1.2}, - {"value": "j", "width": 1.2}, - {"value": "k", "width": 1.2}, - {"value": "l", "width": 1.2}, - {"value": "ñ", "width": 1.2}, - {"value": "´", "width": 1.2}, - {"value": "ç", "width": 1.2}, - {"key_type": "dummy", - "width": 0.8} - ] - }, - {"key":[ - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "lowercase_shift", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.2}, - {"value": "<", - "label": "<", "width": 1.2}, - {"value": "z", "width": 1.2}, - {"value": "x", "width": 1.2}, - {"value": "c", "width": 1.2}, - {"value": "v", "width": 1.2}, - {"value": "b", "width": 1.2}, - {"value": "n", "width": 1.2}, - {"value": "m", "width": 1.2}, - {"key_type": "dummy", - "width": 0.2}, - {"value": ",", "width": 1.2}, - {"value": ".", "width": 1.2}, - {"value": "-", "width": 1.2}, - {"label": "<b>↑</b>", - "key_type": "layout_switcher", - "value": "lowercase_shift", - "width": 2.8} - ] - }, - {"key":[ - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_L", - "key_type": "mask", - "width": 1.8}, - {"label": "<small><b>Win</b></small>", - "value": "Super_L", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Alt</b></small>", - "value": "Alt_L", - "key_type": "mask", - "width": 1.6}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "______", - "value": " ", - "width": 7.4}, - {"key_type": "dummy", - "width": 0.4}, - {"label": "<small><b>Alt Gr</b></small>", - "value": "lowercase_alt", - "key_type": "layout_switcher", - "width": 1.6}, - {"label": "<small><b>Win</b></small>", - "value": "Super_R", - "key_type": "mask", - "width": 1.6}, - {"label": "<small><b>Ctrl</b></small>", - "value": "Control_R", - "width": 1.6} - ] - } - ] - } - } -] - } diff --git a/data/keyboards/qwerty_ja.xml b/data/keyboards/qwerty_ja.xml deleted file mode 100644 index 6515f15..0000000 --- a/data/keyboards/qwerty_ja.xml +++ /dev/null @@ -1,782 +0,0 @@ -<keyboard> - <layout> - <name>lowercase</name> - <rows> - <row> - <key> - <value>Escape</value> - <label><small>Esc</small></label> - <width>1.2</width> - </key> - <key key_type="dummy" width="0.4"/> - <key value="F1" width="1.2"/> - <key value="F2" width="1.2"/> - <key value="F3" width="1.2"/> - <key value="F4" width="1.2"/> - <key key_type="dummy" width="0.2"/> - <key value="F5" width="1.2"/> - <key value="F6" width="1.2"/> - <key value="F7" width="1.2"/> - <key value="F8" width="1.2"/> - <key key_type="dummy" width="0.2"/> - <key value="F9" width="1.2"/> - <key value="F10" width="1.2"/> - <key value="F11" width="1.2"/> - <key value="F12" width="1.2"/> - <key key_type="dummy" width="0.4"/> - <key key_type="preferences" width="1.2"/> - <key key_type="dummy" width="0.2" /> - <key value="Print" label="<small>PSc</small>" width="1.2" /> - <key value="Scroll_Lock" label="<small>SLk</small>" width="1.2" /> - <key value="Pause" label="<small>Pus</small>" width="1.2" /> - </row> - <row> - <key value="Zenkaku_Hankaku" label="<small>半/全</small>" width="1.2"/> - <key> - <value>1</value> - <label><sup>1</sup> <sub>ぬ</sub></label> - <width>1.2</width> - </key> - <key> - <value>2</value> - <label><sup>2</sup> <sub>ふ</sub></label> - <width>1.2</width> - </key> - <key> - <value>3</value> - <label><sup>3</sup> <sub>あ</sub></label> - <width>1.2</width> - </key> - <key> - <value>4</value> - <label><sup>4</sup> <sub>う</sub></label> - <width>1.2</width> - </key> - <key> - <value>5</value> - <label><sup>5</sup> <sub>え</sub></label> - <width>1.2</width> - </key> - <key> - <value>6</value> - <label><sup>6</sup> <sub>お</sub></label> - <width>1.2</width> - </key> - <key> - <value>7</value> - <label><sup>7</sup> <sub>や</sub></label> - <width>1.2</width> - </key> - <key> - <value>8</value> - <label><sup>8</sup> <sub>ゆ</sub></label> - <width>1.2</width> - </key> - <key> - <value>9</value> - <label><sup>9</sup> <sub>よ</sub></label> - <width>1.2</width> - </key> - <key> - <value>0</value> - <label><sup>0</sup> <sub>わ</sub></label> - <width>1.2</width> - </key> - <key> - <value>-</value> - <label><sup>-</sup> <sub>ほ</sub></label> - <width>1.2</width> - </key> - <key> - <value>^</value> - <label><sup>^</sup> <sub>へ</sub></label> - <width>1.2</width> - </key> - <key> - <value>\</value> - <label><sup>\</sup> <sub>ー</sub></label> - <width>1.2</width> - </key> - <key> - <value>BackSpace</value> - <label><big>⌫</big></label> - <width>1.2</width> - </key> - <key key_type="dummy" width="0.2" /> - <key value="Insert" label="<small>Ins</small>" width="1.2" /> - <key value="Home" label="<small>Hom</small>" width="1.2" /> - <key value="Prior" label="<small>PUp</small>" width="1.2" /> - </row> - <row> - <key> - <value>Tab</value> - <label><b><sup>←</sup><sub>→</sub></b></label> - <width>1.8</width> - </key> - <key> - <value>q</value> - <label><sup>q</sup> <sub>た</sub></label> - <width>1.2</width> - </key> - <key> - <value>w</value> - <label><sup>w</sup> <sub>て</sub></label> - <width>1.2</width> - </key> - <key> - <value>e</value> - <label><sup>e</sup> <sub>い</sub></label> - <width>1.2</width> - </key> - <key> - <value>r</value> - <label><sup>r</sup> <sub>す</sub></label> - <width>1.2</width> - </key> - <key> - <value>t</value> - <label><sup>t</sup> <sub>か</sub></label> - <width>1.2</width> - </key> - <key> - <value>y</value> - <label><sup>y</sup> <sub>ん</sub></label> - <width>1.2</width> - </key> - <key> - <value>u</value> - <label><sup>u</sup> <sub>な</sub></label> - <width>1.2</width> - </key> - <key> - <value>i</value> - <label><sup>i</sup> <sub>に</sub></label> - <width>1.2</width> - </key> - <key> - <value>o</value> - <label><sup>o</sup> <sub>ら</sub></label> - <width>1.2</width> - </key> - <key> - <value>p</value> - <label><sup>p</sup> <sub>せ</sub></label> - <width>1.2</width> - </key> - <key> - <value>@</value> - <label><sup>@</sup> <sub>゛</sub></label> - <width>1.2</width> - </key> - <key> - <value>[</value> - <label><sup>[</sup> <sub>゜</sub></label> - <width>1.2</width> - </key> - <key> - <value>Return</value> - <label><b>↲</b></label> - <width>1.8</width> - </key> - <key key_type="dummy" width="0.2" /> - <key value="Delete" label="<small>Del</small>" width="1.2" /> - <key value="End" label="<small>End</small>" width="1.2" /> - <key value="Next" label="<small>PDn</small>" width="1.2" /> - </row> - <row> - <key> - <value>lock</value> - <label><small><b>Caps</b></small></label> - <key_type>mask</key_type> - <width>2.1</width> - </key> - <key> - <value>a</value> - <label><sup>a</sup> <sub>ち</sub></label> - <width>1.2</width> - </key> - <key> - <value>s</value> - <label><sup>s</sup> <sub>と</sub></label> - <width>1.2</width> - </key> - <key> - <value>d</value> - <label><sup>d</sup> <sub>し</sub></label> - <width>1.2</width> - </key> - <key> - <value>f</value> - <label><sup>f</sup> <sub>は</sub></label> - <width>1.2</width> - </key> - <key> - <value>g</value> - <label><sup>g</sup> <sub>き</sub></label> - <width>1.2</width> - </key> - <key> - <value>h</value> - <label><sup>h</sup> <sub>く</sub></label> - <width>1.2</width> - </key> - <key> - <value>j</value> - <label><sup>j</sup> <sub>ま</sub></label> - <width>1.2</width> - </key> - <key> - <value>k</value> - <label><sup>k</sup> <sub>の</sub></label> - <width>1.2</width> - </key> - <key> - <value>l</value> - <label><sup>l</sup> <sub>り</sub></label> - <width>1.2</width> - </key> - <key> - <value>;</value> - <label><sup>;</sup> <sub>れ</sub></label> - <width>1.2</width> - </key> - <key> - <value>:</value> - <label><sup>:</sup> <sub>け</sub></label> - <width>1.2</width> - </key> - <key> - <value>]</value> - <label><sup>]</sup> <sub>む</sub></label> - <width>1.2</width> - </key> - <key key_type="dummy" width="1.5"/> - <key key_type="dummy" width="3.8" /> - </row> - <row> - <key> - <value>uppercase</value> - <key_type>layout_switcher</key_type> - <label><b>↑</b>Shift</label> - <width>2.7</width> - </key> - <key> - <value>z</value> - <label><sup>z</sup> <sub>つ</sub></label> - <width>1.2</width> - </key> - <key> - <value>x</value> - <label><sup>x</sup> <sub>さ</sub></label> - <width>1.2</width> - </key> - <key> - <value>c</value> - <label><sup>c</sup> <sub>そ</sub></label> - <width>1.2</width> - </key> - <key> - <value>v</value> - <label><sup>v</sup> <sub>ひ</sub></label> - <width>1.2</width> - </key> - <key> - <value>b</value> - <label><sup>b</sup> <sub>こ</sub></label> - <width>1.2</width> - </key> - <key> - <value>n</value> - <label><sup>n</sup> <sub>み</sub></label> - <width>1.2</width> - </key> - <key> - <value>m</value> - <label><sup>m</sup> <sub>も</sub></label> - <width>1.2</width> - </key> - <key> - <value>,</value> - <label><sup>,</sup> <sub>ね</sub></label> - <width>1.2</width> - </key> - <key> - <value>.</value> - <label><sup>.</sup> <sub>る</sub></label> - <width>1.2</width> - </key> - <key> - <value>/</value> - <label><sup>/</sup> <sub>め</sub></label> - <width>1.2</width> - </key> - <key> - <value>\</value> - <label><sup>\</sup> <sub>ろ</sub></label> - <width>1.2</width> - </key> - <key> - <value>uppercase</value> - <key_type>layout_switcher</key_type> - <label><b>↑</b>Shift</label> - <width>2.1</width> - </key> - <key key_type="dummy" width="0.2" /> - <key key_type="dummy" width="1.2"/> - <key value="Up" label="<b>↑</b>" width="1.2" /> - <key key_type="dummy" width="1.2"/> - </row> - <row> - <key> - <value>Control_L</value> - <label><small><b>Ctrl</b></small></label> - <key_type>mask</key_type> - <width>1.8</width> - </key> - <key> - <value>Super_L</value> - <label><small><b>Win</b></small></label> - <width>1.5</width> - </key> - <key> - <value>Alt_L</value> - <label><small><b>Alt</b></small></label> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key> - <value>Muhenkan</value> - <label><small>無変換</small></label> - <width>1.8</width> - </key> - <key value=" " label="______" width="3.0"/> - <key> - <value>Henkan_Mode</value> - <label><small>変換</small></label> - <width>1.8</width> - </key> - <key> - <value>Hiragana_Katakana</value> - <label><small>かな</small></label> - <width>1.5</width> - </key> - <key> - <value>Alt_L</value> - <label><small><b>Alt</b></small></label> - <key_type>mask</key_type> - <width>1.2</width> - </key> - <key> - <value>Super_R</value> - <label><small><b>Win</b></small></label> - <width>1.2</width> - </key> - <key> - <value>Menu</value> - <label><small>Menu</small></label> - <width>1.2</width> - </key> - <key> - <value>Control_L</value> - <label><small><b>Ctrl</b></small></label> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.2" /> - <key value="Left" label="<b>←</b>" width="1.2" /> - <key value="Down" label="<b>↓</b>" width="1.2" /> - <key value="Right" label="<b>→</b>" width="1.2" /> - </row> - </rows> - </layout> - <layout> - <name>uppercase</name> - <rows> - <row> - <key> - <value>Escape</value> - <label><small>Esc</small></label> - <width>1.2</width> - </key> - <key key_type="dummy" width="0.4"/> - <key value="F1" width="1.2"/> - <key value="F2" width="1.2"/> - <key value="F3" width="1.2"/> - <key value="F4" width="1.2"/> - <key key_type="dummy" width="0.2"/> - <key value="F5" width="1.2"/> - <key value="F6" width="1.2"/> - <key value="F7" width="1.2"/> - <key value="F8" width="1.2"/> - <key key_type="dummy" width="0.2"/> - <key value="F9" width="1.2"/> - <key value="F10" width="1.2"/> - <key value="F11" width="1.2"/> - <key value="F12" width="1.2"/> - <key key_type="dummy" width="0.4"/> - <key key_type="preferences" width="1.2"/> - <key key_type="dummy" width="0.2" /> - <key value="Print" label="<small>PSc</small>" width="1.2" /> - <key value="Scroll_Lock" label="<small>SLk</small>" width="1.2" /> - <key value="Pause" label="<small>Pus</small>" width="1.2" /> - </row> - <row> - <key value="Zenkaku_Hankaku" label="<small>半/全</small>" width="1.2"/> - <key> - <value>!</value> - <label><sup>!</sup> <sub>ぬ</sub></label> - <width>1.2</width> - </key> - <key> - <value>"</value> - <label><sup>"</sup> <sub>ふ</sub></label> - <width>1.2</width> - </key> - <key> - <value>#</value> - <label><sup>#</sup> <sub>ぁ</sub></label> - <width>1.2</width> - </key> - <key> - <value>$</value> - <label><sup>$</sup> <sub>ぅ</sub></label> - <width>1.2</width> - </key> - <key> - <value>%</value> - <label><sup>%</sup> <sub>ぇ</sub></label> - <width>1.2</width> - </key> - <key> - <value>&</value> - <label><sup>&amp;</sup> <sub>ぉ</sub></label> - <width>1.2</width> - </key> - <key> - <value>'</value> - <label><sup>'</sup> <sub>ゃ</sub></label> - <width>1.2</width> - </key> - <key> - <value>(</value> - <label><sup>(</sup> <sub>ゅ</sub></label> - <width>1.2</width> - </key> - <key> - <value>)</value> - <label><sup>)</sup> <sub>ょ</sub></label> - <width>1.2</width> - </key> - <key> - <value>~</value> - <label><sup> </sup> <sub>を</sub></label> - <width>1.2</width> - </key> - <key> - <value>=</value> - <label><sup>=</sup> <sub>ほ</sub></label> - <width>1.2</width> - </key> - <key> - <value>~</value> - <label><sup>~</sup> <sub> </sub></label> - <width>1.2</width> - </key> - <key> - <value>|</value> - <label><sup>|</sup> <sub> </sub></label> - <width>1.2</width> - </key> - <key> - <value>BackSpace</value> - <label><big>⌫</big></label> - <width>1.2</width> - </key> - <key key_type="dummy" width="0.2" /> - <key value="Insert" label="<small>Ins</small>" width="1.2" /> - <key value="Home" label="<small>Hom</small>" width="1.2" /> - <key value="Prior" label="<small>PUp</small>" width="1.2" /> - </row> - <row> - <key> - <value>Tab</value> - <label><b><sup>←</sup><sub>→</sub></b></label> - <width>1.8</width> - </key> - <key> - <value>Q</value> - <label><sup>Q</sup> <sub>た</sub></label> - <width>1.2</width> - </key> - <key> - <value>W</value> - <label><sup>W</sup> <sub>て</sub></label> - <width>1.2</width> - </key> - <key> - <value>E</value> - <label><sup>E</sup> <sub>ぃ</sub></label> - <width>1.2</width> - </key> - <key> - <value>R</value> - <label><sup>R</sup> <sub>す</sub></label> - <width>1.2</width> - </key> - <key> - <value>T</value> - <label><sup>T</sup> <sub>か</sub></label> - <width>1.2</width> - </key> - <key> - <value>Y</value> - <label><sup>Y</sup> <sub>ん</sub></label> - <width>1.2</width> - </key> - <key> - <value>U</value> - <label><sup>U</sup> <sub>な</sub></label> - <width>1.2</width> - </key> - <key> - <value>I</value> - <label><sup>I</sup> <sub>に</sub></label> - <width>1.2</width> - </key> - <key> - <value>O</value> - <label><sup>O</sup> <sub>ら</sub></label> - <width>1.2</width> - </key> - <key> - <value>P</value> - <label><sup>P</sup> <sub>せ</sub></label> - <width>1.2</width> - </key> - <key> - <value>`</value> - <label><sup>`</sup> <sub>゛</sub></label> - <width>1.2</width> - </key> - <key> - <value>{</value> - <label><sup>{</sup> <sub>「</sub></label> - <width>1.2</width> - </key> - <key> - <value>Return</value> - <label><b>↲</b></label> - <width>1.8</width> - </key> - <key key_type="dummy" width="0.2" /> - <key value="Delete" label="<small>Del</small>" width="1.2" /> - <key value="End" label="<small>End</small>" width="1.2" /> - <key value="Next" label="<small>PDn</small>" width="1.2" /> - </row> - <row> - <key> - <value>lock</value> - <label><small><b>Caps</b></small></label> - <key_type>mask</key_type> - <width>2.1</width> - </key> - <key> - <value>A</value> - <label><sup>A</sup> <sub>ち</sub></label> - <width>1.2</width> - </key> - <key> - <value>S</value> - <label><sup>S</sup> <sub>と</sub></label> - <width>1.2</width> - </key> - <key> - <value>D</value> - <label><sup>D</sup> <sub>し</sub></label> - <width>1.2</width> - </key> - <key> - <value>F</value> - <label><sup>F</sup> <sub>は</sub></label> - <width>1.2</width> - </key> - <key> - <value>G</value> - <label><sup>G</sup> <sub>き</sub></label> - <width>1.2</width> - </key> - <key> - <value>H</value> - <label><sup>H</sup> <sub>く</sub></label> - <width>1.2</width> - </key> - <key> - <value>J</value> - <label><sup>J</sup> <sub>ま</sub></label> - <width>1.2</width> - </key> - <key> - <value>K</value> - <label><sup>K</sup> <sub>の</sub></label> - <width>1.2</width> - </key> - <key> - <value>L</value> - <label><sup>L</sup> <sub>り</sub></label> - <width>1.2</width> - </key> - <key> - <value>+</value> - <label><sup>+</sup> <sub>れ</sub></label> - <width>1.2</width> - </key> - <key> - <value>*</value> - <label><sup>*</sup> <sub> </sub></label> - <width>1.2</width> - </key> - <key> - <value>}</value> - <label><sup>}</sup> <sub>」</sub></label> - <width>1.2</width> - </key> - <key key_type="dummy" width="1.5"/> - <key key_type="dummy" width="3.8" /> - </row> - <row> - <key> - <value>lowercase</value> - <label><b>↓</b>Shift</label> - <key_type>layout_switcher</key_type> - <width>2.7</width> - </key> - <key> - <value>Z</value> - <label><sup>Z</sup> <sub>っ</sub></label> - <width>1.2</width> - </key> - <key> - <value>X</value> - <label><sup>X</sup> <sub>さ</sub></label> - <width>1.2</width> - </key> - <key> - <value>C</value> - <label><sup>C</sup> <sub>そ</sub></label> - <width>1.2</width> - </key> - <key> - <value>V</value> - <label><sup>V</sup> <sub>ひ</sub></label> - <width>1.2</width> - </key> - <key> - <value>B</value> - <label><sup>B</sup> <sub>こ</sub></label> - <width>1.2</width> - </key> - <key> - <value>N</value> - <label><sup>N</sup> <sub>み</sub></label> - <width>1.2</width> - </key> - <key> - <value>M</value> - <label><sup>M</sup> <sub>も</sub></label> - <width>1.2</width> - </key> - <key> - <value><</value> - <label><sup>&lt;</sup> <sub>、</sub></label> - <width>1.2</width> - </key> - <key> - <value>></value> - <label><sup>&gt;</sup> <sub>。</sub></label> - <width>1.2</width> - </key> - <key> - <value>?</value> - <label><sup>?</sup> <sub>・</sub></label> - <width>1.2</width> - </key> - <key> - <value>_</value> - <label><sup>_</sup> <sub>ろ</sub></label> - <width>1.2</width> - </key> - <key> - <value>lowercase</value> - <label><b>↓</b>Shift</label> - <key_type>layout_switcher</key_type> - <width>2.1</width> - </key> - <key key_type="dummy" width="0.2" /> - <key key_type="dummy" width="1.2"/> - <key value="Up" label="<b>↑</b>" width="1.2" /> - <key key_type="dummy" width="1.2"/> - </row> - <row> - <key> - <value>Control_L</value> - <label><small><b>Ctrl</b></small></label> - <key_type>mask</key_type> - <width>1.8</width> - </key> - <key> - <value>Super_L</value> - <label><small><b>Win</b></small></label> - <width>1.5</width> - </key> - <key> - <value>Alt_L</value> - <label><small><b>Alt</b></small></label> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key> - <value>Muhenkan</value> - <label><small>無変換</small></label> - <width>1.8</width> - </key> - <key value=" " label="______" width="3"/> - <key> - <value>Henkan_Mode</value> - <label><small>変換</small></label> - <width>1.8</width> - </key> - <key> - <value>Hiragana_Katakana</value> - <label><small>かな</small></label> - <width>1.5</width> - </key> - <key> - <value>Alt_L</value> - <label><small><b>Alt</b></small></label> - <key_type>mask</key_type> - <width>1.2</width> - </key> - <key> - <value>Super_R</value> - <label><small><b>Win</b></small></label> - <width>1.2</width> - </key> - <key> - <value>Menu</value> - <label><small>Menu</small></label> - <width>1.2</width> - </key> - <key> - <value>Control_L</value> - <label><small><b>Ctrl</b></small></label> - <key_type>mask</key_type> - <width>1.5</width> - </key> - <key key_type="dummy" width="0.2" /> - <key value="Left" label="<b>←</b>" width="1.2" /> - <key value="Down" label="<b>↓</b>" width="1.2" /> - <key value="Right" label="<b>→</b>" width="1.2" /> - </row> - </rows> - </layout> -</keyboard> diff --git a/data/layouts/Makefile.am b/data/layouts/Makefile.am new file mode 100644 index 0000000..9d82efe --- /dev/null +++ b/data/layouts/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = touch diff --git a/data/layouts/touch/Makefile.am b/data/layouts/touch/Makefile.am new file mode 100644 index 0000000..f18d728 --- /dev/null +++ b/data/layouts/touch/Makefile.am @@ -0,0 +1,8 @@ +touchlayoutsdir = $(datadir)/caribou/layouts/touch + +touchlayouts_DATA = \ + ara.json \ + il.json \ + us.json + +EXTRA_DIST = $(touchlayouts_DATA) diff --git a/data/layouts/touch/ara.json b/data/layouts/touch/ara.json new file mode 100644 index 0000000..e757ee9 --- /dev/null +++ b/data/layouts/touch/ara.json @@ -0,0 +1,122 @@ +{ + "level1" : { + "mode" : "default", + "rows" : [ + [{"name" : "Arabic_dad"}, + {"name" : "Arabic_sad"}, + {"name" : "Arabic_qaf"}, + {"name" : "Arabic_feh"}, + {"name" : "Arabic_ghain"}, + {"name" : "Arabic_ain"}, + {"name" : "Arabic_ha"}, + {"name" : "Arabic_khah"}, + {"name" : "Arabic_hah"}, + {"name" : "Arabic_jeem"}, + {"name" : "BackSpace"}], + [{"name" : "Arabic_sheen", "margin_left" : 0.5}, + {"name" : "Arabic_seen"}, + {"name" : "Arabic_yeh"}, + {"name" : "Arabic_beh"}, + {"name" : "Arabic_lam"}, + {"name" : "Arabic_alef"}, + {"name" : "Arabic_teh"}, + {"name" : "Arabic_noon"}, + {"name" : "Arabic_meem"}, + {"name" : "Arabic_kaf"}], + [{"name" : "Arabic_zah"}, + {"name" : "Arabic_tah"}, + {"name" : "Arabic_thal"}, + {"name" : "Arabic_dal"}, + {"name" : "Arabic_zain"}, + {"name" : "Arabic_ra"}, + {"name" : "Arabic_waw"}, + {"name" : "Arabic_tehmarbuta"}, + {"name" : "Arabic_theh"}, + {"name" : "Return", "width" : 2.0}], + [{"name" : "Caribou_Symbols", "width" : 2.0, "toggle" : "symbols1"}, + {"name" : "Arabic_fathatan"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + }, + "symbols1" : { + "mode" : "locked", + "rows" : [ + [{"name" : "Arabic_1"}, + {"name" : "Arabic_2"}, + {"name" : "Arabic_3"}, + {"name" : "Arabic_4"}, + {"name" : "Arabic_5"}, + {"name" : "Arabic_6"}, + {"name" : "Arabic_7"}, + {"name" : "Arabic_8"}, + {"name" : "Arabic_9"}, + {"name" : "Arabic_0"}, + {"name" : "BackSpace"}], + [{"name" : "minus", "margin_left" : 0.5}, + {"name" : "slash"}, + {"name" : "colon"}, + {"name" : "Arabic_semicolon"}, + {"name" : "parenleft"}, + {"name" : "parenright"}, + {"name" : "dollar"}, + {"name" : "ampersand"}, + {"name" : "at"}, + {"name" : "Return", "width" : 1.5}], + [{"name" : "Caribou_Symbols_More", "width" : 2.0, "toggle" : "symbols2"}, + {"name" : "period"}, + {"name" : "Arabic_comma"}, + {"name" : "Arabic_question_mark"}, + {"name" : "slash"}, + {"name" : "exclam"}, + {"name" : "apostrophe"}, + {"name" : "quotedbl"}, + {"name" : "bar"}, + {"name" : "numbersign"}], + [{"name" : "Caribou_Alpha", "width" : 2.0, "toggle" : "default"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + }, + "symbols2" : { + "mode" : "locked", + "rows" : [ + [{"name" : "Arabic_percent"}, + {"name" : "bracketleft"}, + {"name" : "bracketright"}, + {"name" : "braceleft"}, + {"name" : "braceright"}, + {"name" : "backslash"}, + {"name" : "plus"}, + {"name" : "equal"}, + {"name" : "grave"}, + {"name" : "underscore"}, + {"name" : "BackSpace"}], + [{"name" : "less", "margin_left" : 0.5}, + {"name" : "greater"}, + {"name" : "asterisk"}, + {"name" : "semicolon"}, + {"name" : "parenleft"}, + {"name" : "parenright"}, + {"name" : "dollar"}, + {"name" : "ampersand"}, + {"name" : "at"}, + {"name" : "Return", "width" : 1.5}], + [{"name" : "Caribou_Symbols", "width" : 2.0, "toggle" : "symbols1"}, + {"name" : "period"}, + {"name" : "comma"}, + {"name" : "question"}, + {"name" : "slash"}, + {"name" : "exclam"}, + {"name" : "apostrophe"}, + {"name" : "quotedbl"}, + {"name" : "bar"}, + {"name" : "numbersign"}], + [{"name" : "Caribou_Alpha", "width" : 2.0, "toggle" : "default"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + } +} diff --git a/data/layouts/touch/il.json b/data/layouts/touch/il.json new file mode 100644 index 0000000..b0939ed --- /dev/null +++ b/data/layouts/touch/il.json @@ -0,0 +1,122 @@ +{ + "level1" : { + "mode" : "default", + "rows" : [ + [{"name" : "period"}, + {"name" : "comma"}, + {"name" : "hebrew_qoph"}, + {"name" : "hebrew_resh"}, + {"name" : "hebrew_aleph"}, + {"name" : "hebrew_tet"}, + {"name" : "hebrew_waw"}, + {"name" : "hebrew_finalnun"}, + {"name" : "hebrew_finalmem"}, + {"name" : "hebrew_pe"}, + {"name" : "BackSpace"}], + [{"name" : "hebrew_shin", "margin_left" : 0.5}, + {"name" : "hebrew_dalet"}, + {"name" : "hebrew_gimel"}, + {"name" : "hebrew_kaph"}, + {"name" : "hebrew_ayin"}, + {"name" : "hebrew_yod"}, + {"name" : "hebrew_chet"}, + {"name" : "hebrew_lamed"}, + {"name" : "hebrew_finalkaph"}, + {"name" : "hebrew_finalpe"}], + [{"name" : "hebrew_zain"}, + {"name" : "hebrew_samech"}, + {"name" : "hebrew_bet"}, + {"name" : "hebrew_he"}, + {"name" : "hebrew_nun"}, + {"name" : "hebrew_mem"}, + {"name" : "hebrew_zade"}, + {"name" : "hebrew_taw"}, + {"name" : "hebrew_finalzade"}, + {"name" : "Return", "width" : 2.0}], + [{"name" : "Caribou_Symbols", "width" : 2.0, "toggle" : "symbols1"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + }, + "symbols1" : { + "mode" : "locked", + "rows" : [ + [{"name" : "1"}, + {"name" : "2"}, + {"name" : "3"}, + {"name" : "4"}, + {"name" : "5"}, + {"name" : "6"}, + {"name" : "7"}, + {"name" : "8"}, + {"name" : "9"}, + {"name" : "0"}, + {"name" : "BackSpace"}], + [{"name" : "minus", "margin_left" : 0.5}, + {"name" : "slash"}, + {"name" : "colon"}, + {"name" : "semicolon"}, + {"name" : "parenleft"}, + {"name" : "parenright"}, + {"name" : "dollar"}, + {"name" : "ampersand"}, + {"name" : "at"}, + {"name" : "Return", "width" : 1.5}], + [{"name" : "Caribou_Symbols_More", "width" : 2.0, "toggle" : "symbols2"}, + {"name" : "period"}, + {"name" : "comma"}, + {"name" : "question"}, + {"name" : "slash"}, + {"name" : "exclam"}, + {"name" : "apostrophe"}, + {"name" : "quotedbl"}, + {"name" : "bar"}, + {"name" : "numbersign"}], + [{"name" : "Caribou_Alpha", "width" : 2.0, "toggle" : "default"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + }, + "symbols2" : { + "mode" : "locked", + "rows" : [ + [{"name" : "percent"}, + {"name" : "bracketleft"}, + {"name" : "bracketright"}, + {"name" : "braceleft"}, + {"name" : "braceright"}, + {"name" : "backslash"}, + {"name" : "plus"}, + {"name" : "equal"}, + {"name" : "grave"}, + {"name" : "underscore"}, + {"name" : "BackSpace"}], + [{"name" : "less", "margin_left" : 0.5}, + {"name" : "greater"}, + {"name" : "asterisk"}, + {"name" : "semicolon"}, + {"name" : "parenleft"}, + {"name" : "parenright"}, + {"name" : "dollar"}, + {"name" : "ampersand"}, + {"name" : "at"}, + {"name" : "Return", "width" : 1.5}], + [{"name" : "Caribou_Symbols", "width" : 2.0, "toggle" : "symbols1"}, + {"name" : "period"}, + {"name" : "comma"}, + {"name" : "question"}, + {"name" : "slash"}, + {"name" : "exclam"}, + {"name" : "apostrophe"}, + {"name" : "quotedbl"}, + {"name" : "bar"}, + {"name" : "numbersign"}], + [{"name" : "Caribou_Alpha", "width" : 2.0, "toggle" : "default"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + } +} diff --git a/data/layouts/touch/us.json b/data/layouts/touch/us.json new file mode 100644 index 0000000..20fcf04 --- /dev/null +++ b/data/layouts/touch/us.json @@ -0,0 +1,212 @@ +{ + "level1" : { + "mode" : "default", + "rows" : [ + [{"name" : "q"}, + {"name" : "w"}, + {"name" : "e", "extended_names" : ["egrave", + "eacute", + "ecircumflex", + "ediaeresis", + "emacron"]}, + {"name" : "r"}, + {"name" : "t"}, + {"name" : "y"}, + {"name" : "u", "extended_names" : ["ugrave", + "uacute", + "ucircumflex", + "udiaeresis", + "umacron"]}, + {"name" : "i", "extended_names" : ["igrave", + "iacute", + "icircumflex", + "idiaeresis", + "imacron"]}, + {"name" : "o", "extended_names" : ["ograve", + "oacute", + "ocircumflex", + "odiaeresis", + "omacron"]}, + {"name" : "p"}, + {"name" : "BackSpace"}], + [{"name" : "a", "extended_names" : ["agrave", + "aacute", + "acircumflex", + "adiaeresis", + "aring", + "atilde", + "ae", + "amacron"], + "margin_left" : 0.5}, + {"name" : "s"}, + {"name" : "d"}, + {"name" : "f"}, + {"name" : "g"}, + {"name" : "h"}, + {"name" : "j"}, + {"name" : "k"}, + {"name" : "l"}, + {"name" : "Return", "width" : 1.5}], + [{"name" : "Caribou_ShiftUp", "toggle" : "level2"}, + {"name" : "z"}, + {"name" : "x"}, + {"name" : "c", "extended_names" : ["ccedilla"]}, + {"name" : "v"}, + {"name" : "b"}, + {"name" : "n"}, + {"name" : "m"}, + {"name" : "comma"}, + {"name" : "period"}, + {"name" : "question"}], + [{"name" : "Caribou_Symbols", "width" : 2.0, "toggle" : "symbols1"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + }, + "level2" : { + "mode" : "latched", + "rows" : [ + [{"name" : "Q"}, + {"name" : "W"}, + {"name" : "E", "extended_names" : ["Egrave", + "Eacute", + "Ecircumflex", + "Ediaeresis", + "Emacron"]}, + {"name" : "R"}, + {"name" : "T"}, + {"name" : "Y"}, + {"name" : "U", "extended_names" : ["Ugrave", + "Uacute", + "Ucircumflex", + "Udiaeresis", + "Umacron"]}, + {"name" : "I", "extended_names" : ["Igrave", + "Iacute", + "Icircumflex", + "Idiaeresis", + "Imacron"]}, + {"name" : "O", "extended_names" : ["Ograve", + "Oacute", + "Ocircumflex", + "Odiaeresis", + "Omacron"]}, + {"name" : "P"}, + {"name" : "BackSpace"}], + [{"name" : "A", "extended_names" : ["Agrave", + "Aacute", + "Acircumflex", + "Adiaeresis", + "Aring", + "Atilde", + "Ae", + "Amacron"], + "margin_left" : 0.5}, + {"name" : "S"}, + {"name" : "D"}, + {"name" : "F"}, + {"name" : "G"}, + {"name" : "H"}, + {"name" : "J"}, + {"name" : "K"}, + {"name" : "L"}, + {"name" : "Return", "width" : 1.5}], + [{"name" : "Caribou_ShiftDown", "toggle" : "level1"}, + {"name" : "Z"}, + {"name" : "X"}, + {"name" : "C", "extended_names" : ["Ccedilla"]}, + {"name" : "V"}, + {"name" : "B"}, + {"name" : "N"}, + {"name" : "M"}, + {"name" : "comma"}, + {"name" : "period"}, + {"name" : "question"}], + [{"name" : "Caribou_Symbols", "width" : 2.0, "toggle" : "default"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + }, + "symbols1" : { + "mode" : "locked", + "rows" : [ + [{"name" : "1"}, + {"name" : "2"}, + {"name" : "3"}, + {"name" : "4"}, + {"name" : "5"}, + {"name" : "6"}, + {"name" : "7"}, + {"name" : "8"}, + {"name" : "9"}, + {"name" : "0"}, + {"name" : "BackSpace"}], + [{"name" : "minus", "margin_left" : 0.5}, + {"name" : "slash"}, + {"name" : "colon"}, + {"name" : "semicolon"}, + {"name" : "parenleft"}, + {"name" : "parenright"}, + {"name" : "dollar"}, + {"name" : "ampersand"}, + {"name" : "at"}, + {"name" : "Return", "width" : 1.5}], + [{"name" : "Caribou_Symbols_More", "width" : 2.0, "toggle" : "symbols2"}, + {"name" : "period"}, + {"name" : "comma"}, + {"name" : "question", "extended_names" : ["questiondown"]}, + {"name" : "slash"}, + {"name" : "exclam", "extended_names" : ["exclamdown"]}, + {"name" : "apostrophe"}, + {"name" : "quotedbl"}, + {"name" : "bar"}, + {"name" : "numbersign"}], + [{"name" : "Caribou_Alpha", "width" : 2.0, "toggle" : "default"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + }, + "symbols2" : { + "mode" : "locked", + "rows" : [ + [{"name" : "percent"}, + {"name" : "bracketleft"}, + {"name" : "bracketright"}, + {"name" : "braceleft"}, + {"name" : "braceright"}, + {"name" : "backslash"}, + {"name" : "plus"}, + {"name" : "equal"}, + {"name" : "grave"}, + {"name" : "underscore"}, + {"name" : "BackSpace"}], + [{"name" : "less", "margin_left" : 0.5}, + {"name" : "greater"}, + {"name" : "asterisk"}, + {"name" : "semicolon"}, + {"name" : "parenleft"}, + {"name" : "parenright"}, + {"name" : "dollar"}, + {"name" : "ampersand"}, + {"name" : "at"}, + {"name" : "Return", "width" : 1.5}], + [{"name" : "Caribou_Symbols", "width" : 2.0, "toggle" : "symbols1"}, + {"name" : "period"}, + {"name" : "comma"}, + {"name" : "question"}, + {"name" : "slash"}, + {"name" : "exclam"}, + {"name" : "apostrophe"}, + {"name" : "quotedbl"}, + {"name" : "bar"}, + {"name" : "numbersign"}], + [{"name" : "Caribou_Alpha", "width" : 2.0, "toggle" : "default"}, + {"name" : "Caribou_Emoticons"}, + {"name" : "space", "width" : 5.0}, + {"name" : "Caribou_Prefs", "margin_left" : 2.0}] + ] + } +} diff --git a/data/org.gnome.Caribou.Antler.service.in b/data/org.gnome.Caribou.Antler.service.in new file mode 100644 index 0000000..fd85a4e --- /dev/null +++ b/data/org.gnome.Caribou.Antler.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.gnome.Caribou.Antler +Exec=@libexecdir@/antler-keyboard diff --git a/libcaribou/Makefile.am b/libcaribou/Makefile.am index c7f7a0a..9e157e9 100644 --- a/libcaribou/Makefile.am +++ b/libcaribou/Makefile.am @@ -1,93 +1,73 @@ -INCLUDES = \ - -DG_LOG_DOMAIN=\"libcaribou\" \ - -I$(top_srcdir) \ - $(LIBCARIBOU_CFLAGS) - - -MARSHAL_GENERATED = caribou-marshal.c caribou-marshal.h -MKENUMS_GENERATED = caribou-enum-types.c caribou-enum-types.h - -caribou-marshal.h: caribou-marshal.list - $(AM_V_GEN) ( $(GLIB_GENMARSHAL) --prefix=caribou_marshal $(srcdir)/caribou-marshal.list --header > caribou-marshal.tmp \ - && mv caribou-marshal.tmp caribou-marshal.h ) \ - || ( rm -f caribou-marshal.tmp && exit 1 ) - -caribou-marshal.c: caribou-marshal.h - $(AM_V_GEN) ( (echo '#include "caribou-marshal.h"'; $(GLIB_GENMARSHAL) --prefix=caribou_marshal $(srcdir)/caribou-marshal.list --body) > caribou-marshal.tmp \ - && mv caribou-marshal.tmp caribou-marshal.c ) \ - || ( rm -f caribou-marshal.tmp && exit 1 ) - -caribou-enum-types.h: $(caribou_headers) - $(AM_V_GEN) ( cd $(srcdir) && $(GLIB_MKENUMS) --template caribou-enum-types.h.tmpl \ - $(caribou_headers) ) > caribou-enum-types.h.tmp \ - && mv caribou-enum-types.h.tmp caribou-enum-types.h \ - || rm -f caribou-enum-type.h.tmp +lib_LTLIBRARIES = libcaribou.la -caribou-enum-types.c: $(libcaribouinclude_HEADERS) - $(AM_V_GEN) ( cd $(srcdir) && $(GLIB_MKENUMS) --template caribou-enum-types.c.tmpl \ - $(caribou_headers) ) > caribou-enum-types.c.tmp \ - && mv caribou-enum-types.c.tmp caribou-enum-types.c \ - || rm -f caribou-enum-type.c.tmp +INCLUDES = \ + -DG_LOG_DOMAIN=\"caribou\" \ + -I$(top_srcdir) \ + $(LIBCARIBOU_CFLAGS) -BUILT_SOURCES = $(MARSHAL_GENERATED) $(MKENUMS_GENERATED) +libcaribou_la_VALAFLAGS = \ + -H caribou.h --vapi caribou-1.0.vapi \ + -h caribou-internals.h \ + --vapidir=. \ + --pkg x11 --pkg json-glib-1.0 --pkg gdk-3.0 --pkg gio-2.0 \ + --pkg libxklavier --pkg external-libs --pkg gdk-x11-3.0 \ + --internal-vapi caribou-internals-1.0.vapi \ + --library caribou-1.0 --gir _Caribou-1.0.gir \ + $(VALAFLAGS) -CLEANFILES = $(MARSHAL_GENERATED) $(MKENUMS_GENERATED) +libcaribou_la_CPPFLAGS = \ + $(INCLUDES) libcaribouincludedir = $(includedir)/libcaribou -caribou_headers = \ - caribou.h \ - caribou-virtual-keyboard.h - -libcaribouinclude_HEADERS = \ - $(caribou_headers) \ - caribou-enum-types.h +caribouinclude_headers = \ + caribou.h -lib_LTLIBRARIES = libcaribou.la +libcaribouinclude_HEADERS = \ + $(caribou_headers) libcaribou_la_LIBADD = \ $(LIBCARIBOU_LIBS) -libcaribou_la_SOURCES = \ - $(BUILT_SOURCES) \ - caribou-virtual-keyboard.c +libcaribou_la_SOURCES = \ + xadapter.vala \ + keyboard-model.vala \ + keyboard-service.vala \ + group-model.vala \ + level-model.vala \ + row-model.vala \ + key-model.vala \ + util.vala \ + json-deserializer.vala + +EXTRA_DIST = \ + external-libs.vapi \ + libxklavier.vapi # # Introspection support # -include $(INTROSPECTION_MAKEFILE) -INTROSPECTION_GIRS = -INTROSPECTION_SCANNER_ARGS = --add-include-path=. -INTROSPECTION_COMPILER_ARGS = --includedir=. if HAVE_INTROSPECTION +girdir = $(datadir)/gir-1.0 +gir_DATA = Caribou-1.0.gir -gi_caribou_files = \ - $(filter-out caribou.h caribou-enum-types.% caribou-marshal.h,\ - $(caribou_headers) $(filter-out %.h, $(libcaribou_la_SOURCES))) -# gi_built_caribou_files = caribou-enum-types.h - -Caribou-1.0.gir: libcaribou.la -Caribou_1_0_gir_INCLUDES = Gdk-3.0 -Caribou_1_0_gir_CFLAGS = $(INCLUDES) -Caribou_1_0_gir_LIBS = libcaribou.la -Caribou_1_0_gir_EXPORT_PACKAGES = libcaribou -Caribou_1_0_gir_SCANNERFLAGS = --c-include "libcaribou/caribou.h" -Caribou_1_0_gir_FILES = \ - $(addprefix $(srcdir)/, $(gi_caribou_files)) \ - $(foreach f,$(gi_built_caribou_files), \ - $(if $(shell test -f $(addprefix $(srcdir)/,$(f)) && echo yes), \ - $(addprefix $(srcdir)/,$(f)), \ - $(f))) - -INTROSPECTION_GIRS += Caribou-1.0.gir +typelibdir = $(libdir)/girepository-1.0 +typelib_DATA = Caribou-1.0.typelib -girdir = $(datadir)/gir-1.0 -gir_DATA = $(INTROSPECTION_GIRS) +Caribou-1.0.gir: _Caribou-1.0.gir + $(top_srcdir)/tools/fix_gir.py $< > $@ -typelibsdir = $(libdir)/girepository-1.0 -typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) +Caribou-1.0.typelib: Caribou-1.0.gir + @INTROSPECTION_COMPILER@ --shared-library=libcaribou -o $@ $^ +endif -CLEANFILES += $(gir_DATA) $(typelibs_DATA) +Caribou-1.0.gir caribou-internals-1.0.vapi caribou-1.0.vapi: libcaribou.la -endif
\ No newline at end of file +CLEANFILES = \ + caribou-1.0.vapi \ + caribou-internals-1.0.vapi \ + Caribou-1.0.typelib \ + Caribou-1.0.gir \ + _Caribou-1.0.gir \ + *.[ch]
\ No newline at end of file diff --git a/libcaribou/caribou-enum-types.h.tmpl b/libcaribou/caribou-enum-types.h.tmpl deleted file mode 100644 index e69de29..0000000 --- a/libcaribou/caribou-enum-types.h.tmpl +++ /dev/null diff --git a/libcaribou/caribou-marshal.list b/libcaribou/caribou-marshal.list deleted file mode 100644 index fa33740..0000000 --- a/libcaribou/caribou-marshal.list +++ /dev/null @@ -1 +0,0 @@ -NONE:NONE diff --git a/libcaribou/caribou-virtual-keyboard.c b/libcaribou/caribou-virtual-keyboard.c deleted file mode 100644 index 50846f8..0000000 --- a/libcaribou/caribou-virtual-keyboard.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2011, Eitan Isaacson <eitan@monotonous.org> - */ - -#include "caribou-virtual-keyboard.h" -#include "caribou-marshal.h" -#include <X11/Xlib.h> -#include <X11/extensions/XTest.h> -#include <gdk/gdk.h> -#include <gdk/gdkx.h> -#include <X11/XKBlib.h> - -struct _CaribouVirtualKeyboardPrivate { - GdkDisplay *display; -}; - -G_DEFINE_TYPE (CaribouVirtualKeyboard, caribou_virtual_keyboard, G_TYPE_OBJECT) - -enum { - PLACEHOLDER, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static void -dispose (GObject *object) -{ - CaribouVirtualKeyboard *self = CARIBOU_VIRTUAL_KEYBOARD (object); - - G_OBJECT_CLASS (caribou_virtual_keyboard_parent_class)->dispose (object); -} - -static void -caribou_virtual_keyboard_init (CaribouVirtualKeyboard *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), CARIBOU_TYPE_VIRTUAL_KEYBOARD, - CaribouVirtualKeyboardPrivate); - - self->priv->display = gdk_display_get_default (); -} - -static void -caribou_virtual_keyboard_class_init (CaribouVirtualKeyboardClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (CaribouVirtualKeyboardPrivate)); - - /* virtual method override */ - object_class->dispose = dispose; - - /* signals */ - signals[PLACEHOLDER] = - g_signal_new ("placeholder", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - caribou_marshal_NONE__NONE, - G_TYPE_NONE, 0); -} - -/** - * caribou_virtual_keyboard_new: - * - * Create a new #CaribouVirtualKeyboard. - * - * Returns: A new #CaribouVirtualKeyboard. - */ -CaribouVirtualKeyboard * -caribou_virtual_keyboard_new () -{ - return g_object_new (CARIBOU_TYPE_VIRTUAL_KEYBOARD, NULL); -} - -static Display * -_get_xdisplay (CaribouVirtualKeyboard *self) -{ - g_return_if_fail (self != NULL); - - return GDK_DISPLAY_XDISPLAY (self->priv->display); -} - -static KeyCode -keycode_for_keyval (guint keyval, - guint *modmask) -{ - GdkKeymap *km = gdk_keymap_get_default (); - GdkKeymapKey *kmk; - gint len; - KeyCode keycode; - - g_return_val_if_fail (modmask != NULL, 0); - - if (gdk_keymap_get_entries_for_keyval (km, keyval, &kmk, &len)) { - keycode = kmk[0].keycode; - *modmask = (kmk[0].level == 1) ? GDK_SHIFT_MASK : 0; - g_free (kmk); - } - - return keycode; -} - -/** - * caribou_virtual_keyboard_mod_latch: - * @mask: the modifier mask - * - * Simulate a keyboard modifier key press - */ -void -caribou_virtual_keyboard_mod_latch (CaribouVirtualKeyboard *self, - int mask) -{ - Bool b; - b = XkbLatchModifiers(_get_xdisplay (self), XkbUseCoreKbd, mask, mask); - g_print ("latching %d %d\n", mask, b); - gdk_display_sync (self->priv->display); -} - -/** - * caribou_virtual_keyboard_mod_unlatch: - * @mask: the modifier mask - * - * Simulate a keyboard modifier key release - */ -void -caribou_virtual_keyboard_mod_unlatch (CaribouVirtualKeyboard *self, - int mask) -{ - g_print ("unlatching %d\n", mask); - XkbLatchModifiers(_get_xdisplay (self), XkbUseCoreKbd, mask, 0); - gdk_display_sync (self->priv->display); -} - -/** - * caribou_virtual_keyboard_keyval_press: - * @keyval: the keyval to simulate - * - * Simulate a keyboard key press with a given keyval. - */ -void -caribou_virtual_keyboard_keyval_press (CaribouVirtualKeyboard *self, - guint keyval) -{ - guint mask; - KeyCode keycode = keycode_for_keyval (keyval, &mask); - - if (mask != 0) - caribou_virtual_keyboard_mod_latch (self, mask); - - XTestFakeKeyEvent(_get_xdisplay (self), keycode, TRUE, CurrentTime); - gdk_display_sync (self->priv->display); -} - -/** - * caribou_virtual_keyboard_keyval_release: - * @keyval: the keyval to simulate - * - * Simulate a keyboard key press with a given keyval. - */ -void -caribou_virtual_keyboard_keyval_release (CaribouVirtualKeyboard *self, - guint keyval) -{ - guint mask; - KeyCode keycode = keycode_for_keyval (keyval, &mask); - - XTestFakeKeyEvent(_get_xdisplay (self), keycode, FALSE, CurrentTime); - - if (mask != 0) - caribou_virtual_keyboard_mod_unlatch (self, mask); - - gdk_display_sync (self->priv->display); -} diff --git a/libcaribou/caribou-virtual-keyboard.h b/libcaribou/caribou-virtual-keyboard.h deleted file mode 100644 index 01e7499..0000000 --- a/libcaribou/caribou-virtual-keyboard.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2011, Eitan Isaacson <eitan@monotonous.org> - */ - -#ifndef CARIBOU_VIRTUAL_KEYBOARD_H -#define CARIBOU_VIRTUAL_KEYBOARD_H - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define CARIBOU_TYPE_VIRTUAL_KEYBOARD (caribou_virtual_keyboard_get_type ()) -#define CARIBOU_VIRTUAL_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CARIBOU_TYPE_VIRTUAL_KEYBOARD, CaribouVirtualKeyboard)) -#define CARIBOU_VIRTUAL_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CARIBOU_TYPE_VIRTUAL_KEYBOARD, CaribouVirtualKeyboardClass)) -#define CARIBOU_IS_VIRTUAL_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CARIBOU_TYPE_VIRTUAL_KEYBOARD)) -#define CARIBOU_IS_VIRTUAL_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CARIBOU_TYPE_VIRTUAL_KEYBOARD)) -#define CARIBOU_VIRTUAL_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CARIBOU_TYPE_VIRTUAL_KEYBOARD, CaribouVirtualKeyboardClass)) - -typedef struct _CaribouVirtualKeyboard CaribouVirtualKeyboard; -typedef struct _CaribouVirtualKeyboardClass CaribouVirtualKeyboardClass; -typedef struct _CaribouVirtualKeyboardPrivate CaribouVirtualKeyboardPrivate; - -struct _CaribouVirtualKeyboard { - GObject parent; - - CaribouVirtualKeyboardPrivate *priv; -}; - -struct _CaribouVirtualKeyboardClass { - GObjectClass parent_class; - -}; - -GType caribou_virtual_keyboard_get_type (void); - -CaribouVirtualKeyboard *caribou_virtual_keyboard_new (); - -void caribou_virtual_keyboard_keyval_press (CaribouVirtualKeyboard *self, - guint keyval); - -void caribou_virtual_keyboard_keyval_release (CaribouVirtualKeyboard *self, - guint keyval); - -void caribou_virtual_keyboard_mod_latch (CaribouVirtualKeyboard *self, - int mask); - -void caribou_virtual_keyboard_mod_unlatch (CaribouVirtualKeyboard *self, - int mask); - -G_END_DECLS - -#endif /* CARIBOU_VIRTUAL_KEYBOARD_H */ diff --git a/libcaribou/caribou.h b/libcaribou/caribou.h deleted file mode 100644 index 66b4c9f..0000000 --- a/libcaribou/caribou.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2011, Eitan Isaacson <eitan@monotonous.org> - */ - -#ifndef CARIBOU_H -#define CARIBOU_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#include <libcaribou/caribou-virtual-keyboard.h> - -#ifdef __cplusplus -} -#endif - -#endif /* CARIBOU_H */ diff --git a/libcaribou/external-libs.vapi b/libcaribou/external-libs.vapi new file mode 100644 index 0000000..6a87d33 --- /dev/null +++ b/libcaribou/external-libs.vapi @@ -0,0 +1,234 @@ +using X; + +[CCode (cprefix = "", lower_case_cprefix = "", + cheader_filename = "X11/extensions/XTest.h")] +namespace XTest { + [CCode (cname = "XTestFakeKeyEvent")] + public int fake_key_event (Display dpy, uchar keycode, bool key_press, + ulong delay); +} + +[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "X11/Xlib.h")] +namespace X { + [CCode (cname = "XKeycodeToKeysym")] + public int keycode_to_keysym (Display dpy, uchar keycode, int index); + +} + +[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "X11/XKBlib.h")] +namespace Xkb { + + [CCode (cname = "XkbGetKeyboard")] + public Desc get_keyboard (X.Display dpy, uint which, uint device_spec); + + [CCode (cname = "XkbSetMap")] + public void set_map (X.Display dpy, uint which, Desc xkb); + + [CCode (cname = "XkbFreeKeyboard")] + public void free_keyboard (Desc xkb, uint which, bool free_all); + + [CCode (cname = "XkbGetState")] + public void get_state (X.Display dpy, uint device_spec, out State state); + + [CCode (cname = "XkbSelectEvents")] + public void select_events (X.Display dpy, uint device_spec, ulong bits_to_change, + ulong values_for_bits); + + [CCode (cname = "XkbLatchModifiers")] + public void latch_modifiers (X.Display dpy, uint device_spec, uint affect, + uint values); + + [Compact] + [CCode (cname = "XkbAnyEvent", free_function = "")] + public struct AnyEvent { + int xkb_type; + } + + [Compact] + [CCode (cname = "XkbStateNotifyEvent", free_function = "")] + public struct StateNotifyEvent { + uint changed; + int group; + uint mods; + } + + [Compact] + [CCode (cname = "XkbEvent", free_function = "")] + public struct Event { + int type; + AnyEvent any; + StateNotifyEvent state; + } + + [Compact] + [CCode (cname = "XkbStateRec", free_function = "")] + public struct State { + uchar group; + uchar locked_group; + ushort base_group; + ushort latched_group; + uchar mods; + uchar base_mods; + uchar latched_mods; + uchar locked_mods; + uchar compat_state; + uchar grab_mods; + uchar compat_grab_mods; + uchar lookup_mods; + uchar compat_lookup_mods; + ushort ptr_buttons; + } + + [Compact] + [CCode (cname = "XkbDescRec", free_function = "")] + public class Desc { + public X.Display dpy; + public ushort flags; + public ushort device_spec; + public char min_key_code; + public char max_key_code; + public Controls ctrls; + public ServerMap server; + public ClientMap map; + public Indicator indicators; + public Names names; + public CompatMap compat; + public Geometry geom; + } + + [Compact] + [CCode (cname = "XkbControlsRec", free_function = "")] + public class Controls { + } + + [Compact] + [CCode (cname = "XkbServerMapRec", free_function = "")] + public class ServerMap { + } + + [Compact] + [CCode (cname = "XkbKeyTypeRec", free_function = "")] + public struct KeyType { + } + + [CCode (cname = "XkbSymMapRec", free_function = "")] + public struct SymMap { + uchar kt_index[4]; + uchar group_info; + uchar width; + ushort offset; + } + + [Compact] + [CCode (cname = "XkbClientMapRec", free_function = "")] + public class ClientMap { + public uchar size_types; + public uchar num_types; + public KeyType[] types; + + public ushort size_syms; + public ushort num_syms; + public uint[] syms; + public SymMap[] key_sym_map; + + public uchar[] modmap; + } + + [Compact] + [CCode (cname = "XkbIndicatorRec", free_function = "")] + public class Indicator { + } + + [Compact] + [CCode (cname = "XkbNamesRec", free_function = "")] + public class Names { + } + + [Compact] + [CCode (cname = "XkbCompatMapRec", free_function = "")] + public class CompatMap { + } + + [Compact] + [CCode (cname = "XkbGeometryRec", free_function = "")] + public class Geometry { + } + + [CCode (cname = "XkbUseCoreKbd")] + public int UseCoreKbd; + [CCode (cname = "XkbUseCorePtr")] + public int UseCorePtr; + [CCode (cname = "XkbDfltXIClass")] + public int DfltXIClass; + [CCode (cname = "XkbDfltXIId")] + public int DfltXIId; + [CCode (cname = "XkbAllXIClasses")] + public int AllXIClasses; + [CCode (cname = "XkbAllXIIds")] + public int AllXIIds; + [CCode (cname = "XkbXINone")] + public int XINone; + + [CCode (cname = "XkbGBN_TypesMask")] + public int GBN_TypesMask; + [CCode (cname = "XkbGBN_CompatMapMask")] + public int GBN_CompatMapMask; + [CCode (cname = "XkbGBN_ClientSymbolsMask")] + public int GBN_ClientSymbolsMask; + [CCode (cname = "XkbGBN_ServerSymbolsMask")] + public int GBN_ServerSymbolsMask; + [CCode (cname = "XkbGBN_SymbolsMask")] + public int GBN_SymbolsMask; + [CCode (cname = "XkbGBN_IndicatorMapMask")] + public int GBN_IndicatorMapMask; + [CCode (cname = "XkbGBN_KeyNamesMask")] + public int GBN_KeyNamesMask; + [CCode (cname = "XkbGBN_GeometryMask")] + public int GBN_GeometryMask; + [CCode (cname = "XkbGBN_OtherNamesMask")] + public int GBN_OtherNamesMask; + [CCode (cname = "XkbGBN_AllComponentsMask")] + public int GBN_AllComponentsMask; + + [CCode (cname = "XkbOneLevelIndex")] + public int OneLevelIndex; + + [CCode (cname = "XkbNewKeyboardNotifyMask")] + public int NewKeyboardNotifyMask; + [CCode (cname = "XkbMapNotifyMask")] + public int MapNotifyMask; + [CCode (cname = "XkbStateNotifyMask")] + public int StateNotifyMask; + [CCode (cname = "XkbControlsNotifyMask")] + public int ControlsNotifyMask; + [CCode (cname = "XkbIndicatorStateNotifyMask")] + public int IndicatorStateNotifyMask; + [CCode (cname = "XkbIndicatorMapNotifyMask")] + public int IndicatorMapNotifyMask; + [CCode (cname = "XkbNamesNotifyMask")] + public int NamesNotifyMask; + [CCode (cname = "XkbCompatMapNotifyMask")] + public int CompatMapNotifyMask; + [CCode (cname = "XkbBellNotifyMask")] + public int BellNotifyMask; + [CCode (cname = "XkbActionMessageMask")] + public int ActionMessageMask; + [CCode (cname = "XkbAccessXNotifyMask")] + public int AccessXNotifyMask; + [CCode (cname = "XkbExtensionDeviceNotifyMask")] + public int ExtensionDeviceNotifyMask; + [CCode (cname = "XkbAllEventsMask")] + public int AllEventsMask; + + [CCode (cname = "XkbStateNotify")] + public int StateNotify; + + [CCode (cname = "XkbGroupStateMask")] + public int GroupStateMask; + + [CCode (cname = "XkbModifierStateMask")] + public int ModifierStateMask; + + [CCode (cname = "XkbAllMapComponentsMask")] + public int AllMapComponentsMask; +}
\ No newline at end of file diff --git a/libcaribou/group-model.vala b/libcaribou/group-model.vala new file mode 100644 index 0000000..564dbd8 --- /dev/null +++ b/libcaribou/group-model.vala @@ -0,0 +1,50 @@ +using GLib; + +namespace Caribou { + public class GroupModel : GLib.Object { + public string active_level { get; private set; } + + public string group; + public string variant; + private string default_level; + private HashTable<string, LevelModel> levels; + + public GroupModel (string group, string variant) { + this.group = group; + this.variant = variant; + levels = new HashTable<string, LevelModel> (str_hash, str_equal); + active_level = default_level; + } + + public static string create_group_name (string group, string variant) { + if (variant != "") + return @"$(group)_$(variant)"; + else + return group; + } + + public void add_level (string lname, LevelModel level) { + levels.insert (lname, level); + level.level_toggled.connect(on_level_toggled); + if (level.mode == "default") { + default_level = lname; + active_level = lname; + } + } + + public string[] get_levels () { + return Util.list_to_array (levels.get_keys ()); + } + + public LevelModel get_level (string level_name) { + return levels.lookup(level_name); + } + + private void on_level_toggled (string new_level) { + if (new_level == "default") + active_level = default_level; + else + active_level = new_level; + } + } +}
\ No newline at end of file diff --git a/libcaribou/json-deserializer.vala b/libcaribou/json-deserializer.vala new file mode 100644 index 0000000..e136042 --- /dev/null +++ b/libcaribou/json-deserializer.vala @@ -0,0 +1,126 @@ +namespace Caribou { + + private class JsonDeserializer : Object { + + public static bool get_layout_file_inner (string data_dir, + string group, + string variant, + out File fp) { + string[] files = {@"$(group)_$(variant).json", @"$(group).json"}; + + foreach (string fn in files) { + string layout_fn = GLib.Path.build_filename (data_dir, fn); + fp = GLib.File.new_for_path (layout_fn); + if (fp.query_exists ()) + return true; + } + + return false; + } + + public static GLib.File get_layout_file (string group, + string variant) throws IOError { + Settings caribou_settings = new Settings ("org.gnome.caribou"); + string kb_type = caribou_settings.get_string("keyboard-type"); + + List<string> dirs = new List<string> (); + string custom_dir = Environment.get_variable("CARIBOU_LAYOUTS_DIR"); + + if (custom_dir != null) + dirs.append (Path.build_filename (custom_dir, "layouts", kb_type)); + + dirs.append (Path.build_filename (Environment.get_user_data_dir (), + "caribou", "layouts", kb_type)); + + foreach (string data_dir in Environment.get_system_data_dirs ()) { + dirs.append (Path.build_filename ( + data_dir, "caribou", "layouts", kb_type)); + } + + foreach (string data_dir in dirs) { + File fp; + if (get_layout_file_inner (data_dir, group, variant, out fp)) + return fp; + } + + throw new IOError.NOT_FOUND ( + "Could not find layout file for %s %s", group, variant); } + + public static void load_group (GroupModel group) { + Json.Parser parser = new Json.Parser (); + + try { + GLib.File f = get_layout_file (group.group, group.variant); + parser.load_from_stream (f.read (), (Cancellable) null); + create_levels_from_json (group, parser.get_root ()); + } catch (GLib.Error e) { + stdout.printf ("Failed to load JSON: %s\n", e.message); + return; + } + } + + public static void create_levels_from_json (GroupModel group, + Json.Node root) { + Json.Object obj = root.get_object (); + + if (root.get_node_type () != Json.NodeType.OBJECT) + return; + + foreach (string levelname in obj.get_members ()) { + unowned Json.Object json_level = obj.get_object_member (levelname); + string mode = ""; + + if (json_level.has_member ("mode")) + mode = json_level.get_string_member ("mode"); + + Json.Array json_rows = json_level.get_array_member ("rows"); + LevelModel level = new LevelModel(mode, json_rows.get_length ()); + + group.add_level(levelname, level); + + load_rows (level, json_rows); + } + } + + public static void load_rows (LevelModel level, Json.Array json_rows) { + uint i,j; + + for (i=0;i<level.n_rows;i++) { + Json.Array json_keys = json_rows.get_array_element (i); + uint nkeys = json_keys.get_length (); + for (j=0;j<nkeys;j++) { + Json.Object json_key = json_keys.get_object_element (j); + level.add_key (i, load_key (json_key)); + } + } + + } + + public static KeyModel load_key (Json.Object json_key) { + KeyModel key = new KeyModel (json_key.get_string_member ("name")); + + if (json_key.has_member ("toggle")) + key.toggle = json_key.get_string_member ("toggle"); + + if (json_key.has_member ("margin_left")) + key.margin_left = json_key.get_double_member ("margin_left"); + + if (json_key.has_member ("width")) + key.width = json_key.get_double_member ("width"); + + if (json_key.has_member ("extended_names")) { + Json.Array json_keys = json_key.get_array_member ("extended_names"); + uint nkeys = json_keys.get_length (); + uint i; + + key.add_subkey(key.name); + + for (i=0;i<nkeys;i++) + key.add_subkey(json_keys.get_string_element (i)); + } + + return key; + } + + } +}
\ No newline at end of file diff --git a/libcaribou/key-model.vala b/libcaribou/key-model.vala new file mode 100644 index 0000000..90f3625 --- /dev/null +++ b/libcaribou/key-model.vala @@ -0,0 +1,71 @@ +using GLib; + +namespace Caribou { + public class KeyModel : GLib.Object { + public double margin_left { get; set; default = 0.0; } + public double width { get; set; default = 1.0; } + public string toggle { get; set; default = ""; } + + public bool show_subkeys { get; private set; default = false; } + public string name { get; private set; } + public uint keyval { get; private set; } + + private uint hold_tid; + private XAdapter xadapter; + private List<KeyModel> _extended_keys; + + public signal void key_pressed (); + public signal void key_released (); + public signal void key_clicked (); + public signal void key_hold_end (); + public signal void key_hold (); + + public KeyModel (string name) { + this.name = name; + xadapter = XAdapter.get_default(); + keyval = Gdk.keyval_from_name (name); + } + + public void add_subkey (string name) { + KeyModel key = new KeyModel (name); + key.key_clicked.connect(on_subkey_clicked); + _extended_keys.append (key); + } + + private void on_subkey_clicked () { + show_subkeys = false; + } + + public void press () { + hold_tid = GLib.Timeout.add(1000, on_key_held); + key_pressed(); + } + + public void release () { + key_released(); + if (hold_tid != 0) { + GLib.Source.remove (hold_tid); + hold_tid = 0; + key_clicked(); + if (keyval != 0) { + xadapter.keyval_press(keyval); + xadapter.keyval_release(keyval); + } + } else { + key_hold_end (); + } + } + + private bool on_key_held () { + hold_tid = 0; + if (_extended_keys.length () != 0) + show_subkeys = true; + key_hold (); + return false; + } + + public unowned List<KeyModel> get_extended_keys () { + return _extended_keys; + } + } +}
\ No newline at end of file diff --git a/libcaribou/keyboard-model.vala b/libcaribou/keyboard-model.vala new file mode 100644 index 0000000..b9d96f4 --- /dev/null +++ b/libcaribou/keyboard-model.vala @@ -0,0 +1,49 @@ +using Bus; + +namespace Caribou { + public class KeyboardModel : Object { + public string active_group { get; private set; default = ""; } + + XAdapter xadapter; + HashTable<string, GroupModel> groups; + + construct { + uint grpid; + string group, variant; + string[] grps, variants; + int i; + + groups = new HashTable<string, GroupModel> (str_hash, str_equal); + + xadapter = XAdapter.get_default (); + xadapter.group_changed.connect (on_group_changed); + + grpid = xadapter.get_current_group (out group, out variant); + on_group_changed (grpid, group, variant); + + xadapter.get_groups (out grps, out variants); + + for (i=0;i<grps.length;i++) + populate_group (grps[i], variants[i]); + } + + private void populate_group (string group, string variant) { + GroupModel grp = new GroupModel (group, variant); + groups.insert (GroupModel.create_group_name (group, variant), grp); + JsonDeserializer.load_group (grp); + } + + public string[] get_groups () { + return Util.list_to_array (groups.get_keys ()); + } + + public GroupModel get_group (string group_name) { + return groups.lookup(group_name); + } + + private void on_group_changed (uint grpid, string group, string variant) { + active_group = group; + } + + } +}
\ No newline at end of file diff --git a/libcaribou/keyboard-service.vala b/libcaribou/keyboard-service.vala new file mode 100644 index 0000000..ee0035f --- /dev/null +++ b/libcaribou/keyboard-service.vala @@ -0,0 +1,35 @@ +namespace Caribou { + [DBus(name = "org.gnome.Caribou.Keyboard")] + public abstract class KeyboardService : Object { + public string name { get; private set; default = "CaribouKeyboard"; } + + public abstract void set_cursor_location(int x, int y, int w, int h); + public abstract void set_entry_location(int x, int y, int w, int h); + public abstract void show(); + public abstract void hide(); + + protected void register_keyboard (string name) { + this.name = name; + string dbus_name = @"org.gnome.Caribou.$name"; + Bus.own_name (BusType.SESSION, dbus_name, BusNameOwnerFlags.NONE, + on_bus_aquired, on_name_aquired, on_name_lost); + } + + private void on_name_aquired (DBusConnection conn, string name) { + } + + private void on_name_lost (DBusConnection conn, string name) { + stderr.printf ("Could not aquire %s\n", name); + } + + private void on_bus_aquired (DBusConnection conn) { + try { + string path = @"/org/gnome/Caribou/$name"; + conn.register_object (path, this); + } catch (IOError e) { + stderr.printf ("Could not register service: %s\n", e.message); + } + } + + } +}
\ No newline at end of file diff --git a/libcaribou/level-model.vala b/libcaribou/level-model.vala new file mode 100644 index 0000000..14e8ea8 --- /dev/null +++ b/libcaribou/level-model.vala @@ -0,0 +1,41 @@ +using GLib; + +namespace Caribou { + public class LevelModel : GLib.Object { + public signal void level_toggled (string new_level); + + public string mode { get; private set; default = ""; } + public int n_rows { + get { + return _rows.length; + } + } + + private RowModel[] _rows; + + public LevelModel (string mode, uint nrows) { + uint i; + this.mode = mode; + _rows = new RowModel[nrows]; + for (i=0;i<nrows;i++) + _rows[i] = new RowModel (); + } + + public void add_key (uint rownum, KeyModel key) { + key.key_clicked.connect (on_key_clicked); + _rows[rownum].add_key (key); + } + + public RowModel[] get_rows () { + return _rows; + } + + private void on_key_clicked (KeyModel key) { + if (key.toggle != "") + level_toggled (key.toggle); + else + level_toggled ("default"); + } + + } +}
\ No newline at end of file diff --git a/libcaribou/libxklavier.vapi b/libcaribou/libxklavier.vapi new file mode 100644 index 0000000..7d31572 --- /dev/null +++ b/libcaribou/libxklavier.vapi @@ -0,0 +1,182 @@ +/* libxklavier.vapi generated by vapigen, do not modify. */ + +[CCode (cprefix = "Xkl", lower_case_cprefix = "xkl_")] +namespace Xkl { + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public class ConfigItem : GLib.Object { + [CCode (array_length = false)] + public weak char[] description; + [CCode (array_length = false)] + public weak char[] name; + [CCode (array_length = false)] + public weak char[] short_description; + [CCode (has_construct_function = false)] + public ConfigItem (); + } + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public class ConfigRec : GLib.Object { + public string[] layouts; + public weak string model; + public string[] options; + public string[] variants; + [CCode (has_construct_function = false)] + public ConfigRec (); + public bool activate (Xkl.Engine engine); + public bool equals (Xkl.ConfigRec data2); + public bool get_from_backup (Xkl.Engine engine); + public bool get_from_root_window_property (X.Atom rules_atom_name, string rules_file_out, Xkl.Engine engine); + public bool get_from_server (Xkl.Engine engine); + public void reset (); + public bool set_to_root_window_property (X.Atom rules_atom_name, string rules_file, Xkl.Engine engine); + public static bool write_to_file (Xkl.Engine engine, string file_name, Xkl.ConfigRec data, bool binary); + } + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public class ConfigRegistry : GLib.Object { + [CCode (has_construct_function = false)] + protected ConfigRegistry (); + public bool find_layout (Xkl.ConfigItem item); + public bool find_model (Xkl.ConfigItem item); + public bool find_option (string option_group_name, Xkl.ConfigItem item); + public bool find_option_group (Xkl.ConfigItem item); + public bool find_variant (string layout_name, Xkl.ConfigItem item); + public void foreach_country (Xkl.ConfigItemProcessFunc func, void* data); + public void foreach_country_variant (string country_code, Xkl.TwoConfigItemsProcessFunc func, void* data); + public void foreach_language (Xkl.ConfigItemProcessFunc func, void* data); + public void foreach_language_variant (string language_code, Xkl.TwoConfigItemsProcessFunc func, void* data); + public void foreach_layout (Xkl.ConfigItemProcessFunc func, void* data); + public void foreach_layout_variant (string layout_name, Xkl.ConfigItemProcessFunc func, void* data); + public void foreach_model (Xkl.ConfigItemProcessFunc func, void* data); + public void foreach_option (string option_group_name, Xkl.ConfigItemProcessFunc func, void* data); + public void foreach_option_group (Xkl.ConfigItemProcessFunc func, void* data); + public static unowned Xkl.ConfigRegistry get_instance (Xkl.Engine engine); + public bool load (bool if_extras_needed); + public void search_by_pattern (string pattern, Xkl.TwoConfigItemsProcessFunc func, void* data); + [NoAccessorMethod] + public Xkl.Engine engine { owned get; construct; } + } + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public class Engine : GLib.Object { + [CCode (has_construct_function = false)] + protected Engine (); + public static void INT__LONG_LONG (GLib.Closure closure, GLib.Value return_value, uint n_param_values, GLib.Value param_values, void* invocation_hint, void* marshal_data); + public static void VOID__FLAGS_INT_BOOLEAN (GLib.Closure closure, GLib.Value return_value, uint n_param_values, GLib.Value param_values, void* invocation_hint, void* marshal_data); + public void allow_one_switch_to_secondary_group (); + public bool backup_names_prop (); + [NoWrapper] + public virtual void config_notify (); + public void delete_state (X.Window win); + public int filter_events (X.Event evt); + public unowned string get_backend_name (); + public unowned Xkl.State get_current_state (); + public X.Window get_current_window (); + public int get_current_window_group (); + public int get_default_group (); + public uint get_features (); + public unowned string get_groups_names (); + public bool get_indicators_handling (); + public unowned string get_indicators_names (); + public static unowned Xkl.Engine get_instance (X.Display display); + public uint get_max_num_groups (); + public int get_next_group (); + public uint get_num_groups (); + public int get_prev_group (); + public uint get_secondary_groups_mask (); + public bool get_state (X.Window win, Xkl.State state_out); + public unowned string get_window_title (X.Window win); + public bool grab_key (int keycode, uint modifiers); + public bool is_group_per_toplevel_window (); + public bool is_window_from_same_toplevel_window (X.Window win1, X.Window win2); + public bool is_window_transparent (X.Window win); + public void lock_group (int group); + public int pause_listen (); + public int resume_listen (); + public void save_state (X.Window win, Xkl.State state); + public void set_default_group (int group); + public void set_group_per_toplevel_window (bool is_global); + public void set_indicators_handling (bool whether_handle); + public void set_secondary_groups_mask (uint mask); + public void set_window_transparent (X.Window win, bool transparent); + public int start_listen (uint flags); + [NoWrapper] + public virtual void state_notify (Xkl.EngineStateChange change_type, int group, bool restore); + public int stop_listen (uint flags); + public bool ungrab_key (int keycode, uint modifiers); + [NoAccessorMethod] + public string backendName { owned get; } + public uint default_group { get; } + [NoAccessorMethod] + public void* display { get; construct; } + public Xkl.EngineFeatures features { get; } + public bool indicators_handling { get; } + public uint max_num_groups { get; } + public uint num_groups { get; } + public uint secondary_groups_mask { get; } + public virtual signal void X_config_changed (); + public virtual signal void X_new_device (); + public virtual signal void X_state_changed (int p0, int p1, bool p2); + public virtual signal int new_toplevel_window (long p0, long p1); + } + [Compact] + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public class State { + public int32 group; + public uint32 indicators; + } + [CCode (cprefix = "XKLF_", cheader_filename = "libxklavier/xklavier.h")] + [Flags] + public enum EngineFeatures { + CAN_TOGGLE_INDICATORS, + CAN_OUTPUT_CONFIG_AS_ASCII, + CAN_OUTPUT_CONFIG_AS_BINARY, + MULTIPLE_LAYOUTS_SUPPORTED, + REQUIRES_MANUAL_LAYOUT_MANAGEMENT, + DEVICE_DISCOVERY + } + [CCode (cprefix = "XKLL_", cheader_filename = "libxklavier/xklavier.h")] + public enum EngineListenModes { + MANAGE_WINDOW_STATES, + TRACK_KEYBOARD_STATE, + MANAGE_LAYOUTS + } + [CCode (cprefix = "", cheader_filename = "libxklavier/xklavier.h")] + public enum EngineStateChange { + GROUP_CHANGED, + INDICATORS_CHANGED + } + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public delegate void ConfigItemProcessFunc (Xkl.ConfigRegistry config, Xkl.ConfigItem item); + [CCode (cheader_filename = "libxklavier/xklavier.h", has_target = false)] + public delegate void LogAppender (char[] file, char[] function, int level, char[] format, void* args); + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public delegate void TwoConfigItemsProcessFunc (Xkl.ConfigRegistry config, Xkl.ConfigItem item, Xkl.ConfigItem subitem); + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public const int MAX_CI_DESC_LENGTH; + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public const int MAX_CI_NAME_LENGTH; + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public const int MAX_CI_SHORT_DESC_LENGTH; + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public const string XCI_PROP_ALLOW_MULTIPLE_SELECTION; + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public const string XCI_PROP_COUNTRY_LIST; + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public const string XCI_PROP_EXTRA_ITEM; + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public const string XCI_PROP_LANGUAGE_LIST; + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public const string XCI_PROP_VENDOR; + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public static void default_log_appender (char[] file, char[] function, int level, char[] format, void* args); + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public static unowned string get_country_name (string code); + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public static unowned string get_language_name (string code); + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public static unowned string get_last_error (); + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public static bool restore_names_prop (Xkl.Engine engine); + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public static void set_debug_level (int level); + [CCode (cheader_filename = "libxklavier/xklavier.h")] + public static void set_log_appender (Xkl.LogAppender fun); +} diff --git a/libcaribou/row-model.vala b/libcaribou/row-model.vala new file mode 100644 index 0000000..de4456c --- /dev/null +++ b/libcaribou/row-model.vala @@ -0,0 +1,22 @@ +namespace Caribou { + public class RowModel : GLib.Object { + + List<KeyModel> keys; + + public RowModel () { + keys = new List<KeyModel> (); + } + + public void add_key (KeyModel key) { + keys.append (key); + } + + public KeyModel get_key (uint index) { + return keys.nth (index).data; + } + + public unowned List<weak KeyModel> get_keys () { + return keys; + } + } +} diff --git a/libcaribou/util.vala b/libcaribou/util.vala new file mode 100644 index 0000000..c4625ae --- /dev/null +++ b/libcaribou/util.vala @@ -0,0 +1,13 @@ +namespace Caribou { + class Util { + public static string[] list_to_array (List<string> list) { + string[] rv = new string[list.length()]; + int i = 0; + foreach (string v in list) { + rv[i] = v; + i++; + } + return rv; + } + } +}
\ No newline at end of file diff --git a/libcaribou/xadapter.vala b/libcaribou/xadapter.vala new file mode 100644 index 0000000..d240f08 --- /dev/null +++ b/libcaribou/xadapter.vala @@ -0,0 +1,213 @@ +using Xkl; +using Gdk; +using Xkb; +using XTest; +using X; + +namespace Caribou { + public class XAdapter : Object { + + /* Signals */ + public signal void modifiers_changed (uint modifiers); + public signal void group_changed (uint gid, string group, string variant); + + /* Private properties */ + private static XAdapter instance; + X.Display xdisplay; + Xkb.Desc xkbdesc; + Xkl.Engine xkl_engine; + uint reserved_keysym; + uchar reserved_keycode; + uchar modifiers; + uchar group; + + construct { + Xkb.State state; + + this.xdisplay = new X.Display (); + this.xkbdesc = Xkb.get_keyboard (this.xdisplay, + Xkb.GBN_AllComponentsMask, + Xkb.UseCoreKbd); + this.xkl_engine = Xkl.Engine.get_instance (this.xdisplay); + + Xkb.get_state (this.xdisplay, Xkb.UseCoreKbd, out state); + + this.group = state.group; + this.modifiers = state.mods; + + this.reserved_keycode = 0; + + Xkb.select_events ( + this.xdisplay, Xkb.UseCoreKbd, + Xkb.StateNotifyMask | Xkb.AccessXNotifyMask, + Xkb.StateNotifyMask | Xkb.AccessXNotifyMask); + + ((Gdk.Window) null).add_filter (x_event_filter); // Did I blow your mind? + } + + ~XAdapter () { + Xkb.free_keyboard(this.xkbdesc, Xkb.GBN_AllComponentsMask, true); + } + + public static XAdapter get_default() { + if (instance == null) + instance = new XAdapter (); + return instance; + } + + private Gdk.FilterReturn x_event_filter (Gdk.XEvent xevent, Gdk.Event event) { + void* pointer = &xevent; + Xkb.Event *xev = (Xkb.Event *) pointer; + + if (xev.any.xkb_type == Xkb.StateNotify) { + Xkb.StateNotifyEvent *sevent = &xev.state; + if ((sevent.changed & Xkb.GroupStateMask) != 0) { + Xkl.ConfigRec config_rec = new Xkl.ConfigRec (); + config_rec.get_from_server (this.xkl_engine); + group_changed (sevent.group, config_rec.layouts[sevent.group], + config_rec.variants[sevent.group]); + this.group = (uchar) sevent.group; + } else if ((sevent.changed & Xkb.ModifierStateMask) != 0) { + this.modifiers = (uchar) sevent.mods; + } + } + + return Gdk.FilterReturn.CONTINUE; + } + + private uchar get_reserved_keycode () { + uchar i; + unowned Xkb.Desc xkbdesc = this.xkbdesc; + + for (i = xkbdesc.max_key_code; i >= xkbdesc.min_key_code; --i) { + if (xkbdesc.map.key_sym_map[i].kt_index[0] == Xkb.OneLevelIndex) { + if (X.keycode_to_keysym (this.xdisplay, i, 0) != 0) { + Gdk.error_trap_push (); + this.xdisplay.grab_key (i, 0, + Gdk.x11_get_default_root_xwindow (), true, + X.GrabMode.Sync, X.GrabMode.Sync); + this.xdisplay.flush (); + this.xdisplay.ungrab_key ( + i, 0, Gdk.x11_get_default_root_xwindow ()); + if (Gdk.error_trap_pop () == 0) + return i; + } + } + } + + return (uchar) this.xdisplay.keysym_to_keycode (0x0023); // XK_numbersign + } + + private void replace_keycode (uint keysym) { + if (this.reserved_keycode == 0) { + this.reserved_keycode = get_reserved_keycode (); + this.reserved_keysym = X.keycode_to_keysym (this.xdisplay, + this.reserved_keycode, 0); + } + + this.xdisplay.flush (); + uint offset = this.xkbdesc.map.key_sym_map[this.reserved_keycode].offset; + + this.xkbdesc.map.syms[offset] = keysym; + + Xkb.set_map (this.xdisplay, Xkb.AllMapComponentsMask, this.xkbdesc); + /** + * FIXME: the use of XkbChangeMap, and the reuse of the priv->xkb_desc + * structure, would be far preferable. HOWEVER it does not seem to work + * using XFree 4.3. + **/ + + this.xdisplay.flush (); + + if (keysym != this.reserved_keysym) + GLib.Timeout.add (500, reset_reserved); + } + + private bool reset_reserved () { + replace_keycode (this.reserved_keysym); + return false; + } + + private uchar keycode_for_keyval (uint keyval, out uint modmask) { + Gdk.Keymap kmap= Gdk.Keymap.get_default (); + Gdk.KeymapKey[] kmk; + uchar keycode = 0; + + if (kmap.get_entries_for_keyval (keyval, out kmk)) { + Gdk.KeymapKey best_match = kmk[0]; + foreach (KeymapKey km in kmk) + if (km.group == this.group) + best_match = km; + + keycode = (uchar) best_match.keycode; + modmask = (best_match.level == 1) ? Gdk.ModifierType.SHIFT_MASK : 0; + } else { + replace_keycode (keyval); + keycode = this.reserved_keycode; + } + + return keycode; + } + + public void keyval_press (uint keyval) { + uint mask; + uchar keycode = keycode_for_keyval (keyval, out mask); + + if (mask != 0) + mod_latch (mask); + + XTest.fake_key_event (this.xdisplay, keycode, true, X.CURRENT_TIME); + this.xdisplay.flush (); + } + + public void keyval_release (uint keyval) { + uchar keycode = keycode_for_keyval (keyval, null); + + XTest.fake_key_event (this.xdisplay, keycode, false, X.CURRENT_TIME); + this.xdisplay.flush (); + } + + public void mod_latch (uint mask) { + Xkb.latch_modifiers (this.xdisplay, Xkb.UseCoreKbd, mask, mask); + this.xdisplay.flush (); + } + + public void mod_unlatch (uint mask) { + Xkb.latch_modifiers (this.xdisplay, Xkb.UseCoreKbd, mask, 0); + this.xdisplay.flush (); + } + + public uint get_current_group (out string group_name, + out string variant_name) { + Xkl.ConfigRec config_rec = new Xkl.ConfigRec (); + config_rec.get_from_server (this.xkl_engine); + group_name = config_rec.layouts[this.group]; + variant_name = config_rec.variants[this.group]; + + return this.group; + } + + public void get_groups (out string[] group_names, + out string[] variant_names) { + int i; + Xkl.ConfigRec config_rec = new Xkl.ConfigRec (); + config_rec.get_from_server (this.xkl_engine); + + for (i=0; i<4; i++) + if (config_rec.layouts[i] == null) + break; + + group_names = new string[i]; + variant_names = new string[i]; + + for (; i>=0; i--) { + group_names[i] = config_rec.layouts[i]; + variant_names[i] = config_rec.variants[i]; + } + } + + public void me () { + stdout.printf("%p\n", this.xkl_engine); + } + } +} diff --git a/po/POTFILES.in b/po/POTFILES.in index 0a869dd..5f44bd0 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,5 +1,4 @@ [encoding: UTF-8] -caribou/ui/main.py -caribou/ui/keyboard.py -caribou/common/settings.py -caribou/ui/preferences_window.py +caribou/settings/caribou_settings.py +caribou/__init__.py +caribou/daemon/main.py diff --git a/tools/fix_gir.py b/tools/fix_gir.py new file mode 100755 index 0000000..31190e3 --- /dev/null +++ b/tools/fix_gir.py @@ -0,0 +1,63 @@ +#!/usr/bin/python + +from xml.dom import minidom + +def purge_white_space_and_fix_namespace(node, indent=0): + if getattr(node, "tagName", None) == "namespace": + name = node.getAttribute("name") + node.setAttribute("name", name.lstrip('_')) + for child in [c for c in node.childNodes]: + if child.nodeType == node.TEXT_NODE or \ + getattr(child, "tagName", None) == "annotation": + node.removeChild(child) + continue + purge_white_space_and_fix_namespace(child, indent+1) + +def find_ancestor(node, name): + if getattr(node, "tagName") == name: + return node + parent = getattr(node, "parentNode", None) + if not parent: + return None + return find_ancestor(parent, name) + +def fix_vfuncs(dom): + for f in dom.getElementsByTagName("callback"): + record = find_ancestor(f, "record") + if not record: + continue + + name = record.getAttribute("name") + cname = record.getAttribute("c:type") + + assert(name.endswith("Class")) + assert(cname.endswith("Class")) + + params = (f.getElementsByTagName("parameters") or [None])[0] + + if not params: + params = dom.createElement("parameters") + f.insertBefore(params, f.firstChild) + + param = dom.createElement("parameter") + param.setAttribute("name", "self") + param.setAttribute("transfer-ownership", "none") + ptype = dom.createElement("type") + ptype.setAttribute("name", name[:-5]) + ptype.setAttribute("c:type", cname[:-5]) + param.appendChild(ptype) + params.insertBefore(param, params.firstChild) + +if __name__ == "__main__": + import sys + + if len(sys.argv) != 2: + print "supply a gir file" + sys.exit(1) + + dom = minidom.parse(sys.argv[-1]) + + purge_white_space_and_fix_namespace(dom) + fix_vfuncs(dom) + + print dom.toprettyxml(indent=" ", newl="\n") diff --git a/tools/make_schema.py b/tools/make_schema.py new file mode 100755 index 0000000..c9ee361 --- /dev/null +++ b/tools/make_schema.py @@ -0,0 +1,84 @@ +#!/usr/bin/python + +from gi.repository import GLib +import xml.dom.minidom + +import os,sys +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from caribou.settings import caribou_settings + +class SchemasMaker: + def __init__(self, settings): + self.settings = settings + + def create_schemas(self): + doc = xml.dom.minidom.Document() + schemafile = doc.createElement('schemalist') + schema = doc.createElement('schema') + schema.setAttribute("id", self.settings.schema_id) + schemafile.appendChild(schema) + self._create_schema(self.settings, doc, schema) + + fp = open("%s.gschema.xml.in" % self.settings.schema_id, 'w') + self._pretty_xml(fp, schemafile) + fp.close() + + def _attribs(self, e): + if not e.attributes.items(): + return "" + return ' ' + ' '.join(['%s="%s"' % (k,v) \ + for k,v in e.attributes.items()]) + + def _pretty_xml(self, fp, e, indent=0): + if not e.childNodes or \ + (len(e.childNodes) == 1 and \ + e.firstChild.nodeType == e.TEXT_NODE): + fp.write('%s%s\n' % (' '*indent*2, e.toxml().strip())) + else: + fp.write('%s<%s%s>\n' % (' '*indent*2, e.tagName, self._attribs(e))) + for c in e.childNodes: + self._pretty_xml(fp, c, indent + 1) + fp.write('%s</%s>\n' % (' '*indent*2, e.tagName)) + + def _append_children_element_value_pairs(self, doc, element, pairs): + for e, t in pairs: + el = doc.createElement(e) + te = doc.createTextNode(str(t)) + el.appendChild(te) + element.appendChild(el) + + def _create_schema(self, setting, doc, schemalist): + if hasattr(setting, 'path'): + schemalist.setAttribute("path", setting.path) + if hasattr(setting, 'gsettings_key'): + key = doc.createElement('key') + key.setAttribute('name', setting.gsettings_key) + key.setAttribute('type', setting.variant_type) + schemalist.appendChild(key) + self._append_children_element_value_pairs( + doc, key, [('default', + getattr(setting.gvariant, "print")(False)), + ('_summary', setting.short_desc), + ('_description', setting.long_desc)]) + + for s in setting: + self._create_schema(s, doc, schemalist) + +if __name__ == "__main__": + from caribou.settings import AllSettings + + if (len(sys.argv) != 2): + print "usage: %s <schema id>" % sys.argv[0] + sys.exit(1) + + avail_settings = dict([(s.schema_id, s) for s in AllSettings]) + + try: + settings = avail_settings[sys.argv[-1]] + except KeyError: + print "Schema '%s' not available", sys.argv[-1] + sys.exit(1) + + maker = SchemasMaker(settings) + maker.create_schemas() |