[caribou: 12/22] libcaribou: Ported XKB helper to Vala.
- From: Eitan Isaacson <eitani src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [caribou: 12/22] libcaribou: Ported XKB helper to Vala.
- Date: Mon, 2 May 2011 17:27:08 +0000 (UTC)
commit f72b4505ac6a46e03b106ea0b294e4fb2b67f535
Author: Eitan Isaacson <eitan monotonous org>
Date: Tue Apr 26 15:28:40 2011 -0700
libcaribou: Ported XKB helper to Vala.
.gitignore | 6 +
configure.ac | 5 +-
libcaribou/Makefile.am | 111 ++++------
libcaribou/caribou-marshal.list | 2 -
libcaribou/caribou-virtual-keyboard.c | 392 ---------------------------------
libcaribou/caribou-virtual-keyboard.h | 59 -----
libcaribou/caribou.h | 19 --
libcaribou/external-libs.vapi | 234 ++++++++++++++++++++
libcaribou/libxklavier.vapi | 182 +++++++++++++++
libcaribou/xadapter.vala | 213 ++++++++++++++++++
10 files changed, 678 insertions(+), 545 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index f770bfb..cb3be79 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,5 +36,11 @@ libcaribou/.libs/
libcaribou/Caribou-1.0.gir
libcaribou/Caribou-1.0.typelib
*.lo
+*.o
libcaribou/libcaribou.la
+libcaribou/*.[ch]
+caribou-1.0.vapi
+caribou-internals-1.0.vapi
+caribou-internals.h
+*.stamp
diff --git a/configure.ac b/configure.ac
index d41d3e3..7cdd299 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,6 +36,10 @@ 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,
diff --git a/libcaribou/Makefile.am b/libcaribou/Makefile.am
index c7f7a0a..ca2b6b7 100644
--- a/libcaribou/Makefile.am
+++ b/libcaribou/Makefile.am
@@ -1,93 +1,60 @@
-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 libxklavier --pkg external-libs --pkg gdk-3.0 --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
+
+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
-
-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
-
girdir = $(datadir)/gir-1.0
-gir_DATA = $(INTROSPECTION_GIRS)
+gir_DATA = Caribou-1.0.gir
+
+typelibdir = $(libdir)/girepository-1.0
+typelib_DATA = Caribou-1.0.typelib
-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 \
+ *.[ch]
\ No newline at end of file
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/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/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);
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]