2012-04-28 06:13:40 +00:00
|
|
|
From 5de26fdf6f300a4e532a39f8c3778e94ff629125 Mon Sep 17 00:00:00 2001
|
2010-08-23 02:55:19 +00:00
|
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
2012-04-28 06:13:40 +00:00
|
|
|
Date: Sat, 28 Apr 2012 13:07:30 +0900
|
2012-02-04 01:13:28 +00:00
|
|
|
Subject: [PATCH] Add ibus-xkb and libgnomekbd.
|
2010-08-23 02:55:19 +00:00
|
|
|
|
|
|
|
---
|
2012-04-28 06:13:40 +00:00
|
|
|
client/x11/gdk-private.c | 3 +-
|
2012-03-04 13:45:32 +00:00
|
|
|
configure.ac | 59 +++++
|
2012-04-28 06:13:40 +00:00
|
|
|
data/ibus.schemas.in | 102 ++++++++
|
|
|
|
engine/Makefile.am | 20 ++
|
2012-03-04 13:45:32 +00:00
|
|
|
engine/ibus-xkb-main.c | 111 +++++++++
|
|
|
|
engine/main.vala | 86 +++++++
|
|
|
|
engine/simple.xml.in.in | 531 +----------------------------------------
|
|
|
|
engine/xkblib.c | 327 +++++++++++++++++++++++++
|
|
|
|
engine/xkblib.h | 41 ++++
|
|
|
|
ibus-1.0.pc.in | 4 +
|
2012-04-28 06:13:40 +00:00
|
|
|
setup/main.py | 25 +-
|
2012-03-04 13:45:32 +00:00
|
|
|
src/Makefile.am | 5 +
|
|
|
|
src/ibus.h | 1 +
|
|
|
|
src/ibusxkbxml.c | 466 ++++++++++++++++++++++++++++++++++++
|
|
|
|
src/ibusxkbxml.h | 187 +++++++++++++++
|
|
|
|
ui/gtk3/Gkbd-3.0.metadata | 1 +
|
2012-03-18 09:41:41 +00:00
|
|
|
ui/gtk3/Makefile.am | 48 ++++
|
|
|
|
ui/gtk3/Xkl-1.0.metadata | 3 +
|
2012-03-04 13:45:32 +00:00
|
|
|
ui/gtk3/gkbdlayout.vala.false | 63 +++++
|
|
|
|
ui/gtk3/gkbdlayout.vala.true | 111 +++++++++
|
2012-04-28 06:13:40 +00:00
|
|
|
ui/gtk3/panel.vala | 275 +++++++++++++++++++--
|
2012-03-04 13:45:32 +00:00
|
|
|
ui/gtk3/xkblayout.vala | 466 ++++++++++++++++++++++++++++++++++++
|
2012-04-28 06:13:40 +00:00
|
|
|
22 files changed, 2380 insertions(+), 555 deletions(-)
|
2012-02-04 01:13:28 +00:00
|
|
|
create mode 100644 engine/ibus-xkb-main.c
|
|
|
|
create mode 100644 engine/xkblib.c
|
|
|
|
create mode 100644 engine/xkblib.h
|
2011-06-21 08:49:07 +00:00
|
|
|
create mode 100644 src/ibusxkbxml.c
|
|
|
|
create mode 100644 src/ibusxkbxml.h
|
2012-02-04 01:13:28 +00:00
|
|
|
create mode 100644 ui/gtk3/Gkbd-3.0.metadata
|
2012-03-18 09:41:41 +00:00
|
|
|
create mode 100644 ui/gtk3/Xkl-1.0.metadata
|
2012-02-04 01:13:28 +00:00
|
|
|
create mode 100644 ui/gtk3/gkbdlayout.vala.false
|
|
|
|
create mode 100644 ui/gtk3/gkbdlayout.vala.true
|
|
|
|
create mode 100644 ui/gtk3/xkblayout.vala
|
2010-08-23 02:55:19 +00:00
|
|
|
|
2012-04-28 06:13:40 +00:00
|
|
|
diff --git a/client/x11/gdk-private.c b/client/x11/gdk-private.c
|
|
|
|
index 009a5b0..20689c3 100644
|
|
|
|
--- a/client/x11/gdk-private.c
|
|
|
|
+++ b/client/x11/gdk-private.c
|
|
|
|
@@ -27,8 +27,7 @@
|
|
|
|
#include <gdk/gdkx.h>
|
|
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
|
|
|
|
-#ifdef HAVE_X11_XKBLIB_H
|
|
|
|
-# define HAVE_XKB
|
|
|
|
+#ifdef HAVE_XKB
|
|
|
|
# include <X11/XKBlib.h>
|
|
|
|
#endif
|
|
|
|
|
2010-08-23 02:55:19 +00:00
|
|
|
diff --git a/configure.ac b/configure.ac
|
2012-04-28 06:13:40 +00:00
|
|
|
index 8498efe..731cdf5 100644
|
2010-08-23 02:55:19 +00:00
|
|
|
--- a/configure.ac
|
|
|
|
+++ b/configure.ac
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -252,6 +252,63 @@ else
|
2010-08-23 02:55:19 +00:00
|
|
|
enable_xim="no (disabled, use --enable-xim to enable)"
|
|
|
|
fi
|
|
|
|
|
2012-02-04 01:13:28 +00:00
|
|
|
+# --enable-xkb option.
|
2010-08-23 02:55:19 +00:00
|
|
|
+AC_ARG_ENABLE(xkb,
|
2012-02-04 01:13:28 +00:00
|
|
|
+ AS_HELP_STRING([--enable-xkb],
|
|
|
|
+ [Build xkb]),
|
2010-08-23 02:55:19 +00:00
|
|
|
+ [enable_xkb=$enableval],
|
2012-02-04 01:13:28 +00:00
|
|
|
+ [enable_xkb=no]
|
2010-08-23 02:55:19 +00:00
|
|
|
+)
|
|
|
|
+AM_CONDITIONAL([ENABLE_XKB], [test x"$enable_xkb" = x"yes"])
|
|
|
|
+if test x"$enable_xkb" = x"yes"; then
|
|
|
|
+ PKG_CHECK_MODULES(X11, [
|
|
|
|
+ x11
|
|
|
|
+ ])
|
|
|
|
+ PKG_CHECK_MODULES(XKB,
|
|
|
|
+ [xkbfile],,
|
|
|
|
+ [XKB_LIBS="-lxkbfile"]
|
|
|
|
+ )
|
|
|
|
+ AC_DEFINE(HAVE_XKB, 1, [define to 1 if you have xkbfile])
|
2011-06-01 18:07:41 +00:00
|
|
|
+ HAVE_IBUS_XKB=true
|
2010-08-23 02:55:19 +00:00
|
|
|
+else
|
|
|
|
+ enable_xkb="no (disabled, use --enable-xkb to enable)"
|
2011-06-01 18:07:41 +00:00
|
|
|
+ HAVE_IBUS_XKB=false
|
2010-08-23 02:55:19 +00:00
|
|
|
+fi
|
2011-06-01 18:07:41 +00:00
|
|
|
+AC_SUBST(HAVE_IBUS_XKB)
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+# --enable-libgnomekbd option.
|
|
|
|
+AC_ARG_ENABLE(libgnomekbd,
|
|
|
|
+ AS_HELP_STRING([--enable-libgnomekbd],
|
|
|
|
+ [Use libgnomekbd to handle the keymaps]),
|
|
|
|
+ [enable_libgnomekbd=$enableval],
|
|
|
|
+ [enable_libgnomekbd=no]
|
|
|
|
+)
|
|
|
|
+AM_CONDITIONAL([ENABLE_LIBGNOMEKBD], [test x"$enable_libgnomekbd" = x"yes"])
|
|
|
|
+if test x"$enable_libgnomekbd" = x"yes"; then
|
|
|
|
+ # check for libgnomekbd
|
|
|
|
+ PKG_CHECK_MODULES(LIBGNOMEKBDUI, [
|
|
|
|
+ libgnomekbdui
|
|
|
|
+ ])
|
|
|
|
+ PKG_CHECK_MODULES(ATK, [
|
|
|
|
+ atk
|
|
|
|
+ ])
|
|
|
|
+ HAVE_IBUS_GKBD=true
|
|
|
|
+else
|
|
|
|
+ enable_libgnomekbd="no (disabled, use --enable-libgnomekbd to enable)"
|
|
|
|
+ HAVE_IBUS_GKBD=false
|
|
|
|
+fi
|
|
|
|
+AC_SUBST(HAVE_IBUS_GKBD)
|
|
|
|
+
|
|
|
|
+# Define XKB rules file
|
2010-08-23 02:55:19 +00:00
|
|
|
+AC_ARG_WITH(xkb-rules-xml,
|
|
|
|
+ AS_HELP_STRING([--with-xkb-rules-xml[=$DIR/evdev.xml]],
|
|
|
|
+ [Set evdev.xml file path (default: /usr/share/X11/xkb/rules/evdev.xml)]),
|
|
|
|
+ XKB_RULES_XML_FILE=$with_xkb_rules_xml,
|
|
|
|
+ XKB_RULES_XML_FILE="/usr/share/X11/xkb/rules/evdev.xml"
|
|
|
|
+)
|
|
|
|
+AC_DEFINE_UNQUOTED(XKB_RULES_XML_FILE, "$XKB_RULES_XML_FILE",
|
|
|
|
+ [Define file path of evdev.xml])
|
|
|
|
+
|
|
|
|
# GObject introspection
|
|
|
|
GOBJECT_INTROSPECTION_CHECK([0.6.8])
|
|
|
|
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -574,5 +631,7 @@ Build options:
|
2012-02-04 01:13:28 +00:00
|
|
|
Panel icon "$IBUS_ICON_KEYBOARD"
|
|
|
|
Enable surrounding-text $enable_surrounding_text
|
2012-03-04 13:45:32 +00:00
|
|
|
Run test cases $enable_tests
|
2012-02-04 01:13:28 +00:00
|
|
|
+ Build XKB $enable_xkb
|
|
|
|
+ Build libgnomebkd $enable_libgnomekbd
|
2010-08-23 02:55:19 +00:00
|
|
|
])
|
|
|
|
|
|
|
|
diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in
|
2012-04-28 06:13:40 +00:00
|
|
|
index 53ba05c..5e6c2d7 100644
|
2010-08-23 02:55:19 +00:00
|
|
|
--- a/data/ibus.schemas.in
|
|
|
|
+++ b/data/ibus.schemas.in
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -34,6 +34,62 @@
|
2012-03-18 09:41:41 +00:00
|
|
|
<default>[Control+space,Zenkaku_Hankaku,Alt+Kanji,Alt+grave,Hangul,Alt+Release+Alt_R]</default>
|
|
|
|
<locale name="C">
|
|
|
|
<short>Trigger shortcut keys</short>
|
|
|
|
+ <long>The shortcut keys for turning input method on or off</long>
|
|
|
|
+ </locale>
|
|
|
|
+ </schema>
|
|
|
|
+ <schema>
|
|
|
|
+ <key>/schemas/desktop/ibus/general/hotkey/trigger_accel</key>
|
|
|
|
+ <applyto>/desktop/ibus/general/hotkey/trigger_accel</applyto>
|
2010-09-14 11:20:08 +00:00
|
|
|
+ <owner>ibus</owner>
|
2012-02-04 01:13:28 +00:00
|
|
|
+ <type>list</type>
|
|
|
|
+ <list_type>string</list_type>
|
|
|
|
+ <default>[<Control>space]</default>
|
2010-09-14 11:20:08 +00:00
|
|
|
+ <locale name="C">
|
2012-02-04 01:13:28 +00:00
|
|
|
+ <short>Trigger shortcut keys for gtk_accelerator_parse</short>
|
2012-03-18 09:41:41 +00:00
|
|
|
+ <long>The shortcut keys for turning input method on or off</long>
|
2012-04-28 06:13:40 +00:00
|
|
|
+ </locale>
|
|
|
|
+ </schema>
|
|
|
|
+ <schema>
|
|
|
|
+ <key>/schemas/desktop/ibus/general/hotkey/trigger_shift</key>
|
|
|
|
+ <applyto>/desktop/ibus/general/hotkey/trigger_shift</applyto>
|
|
|
|
+ <owner>ibus</owner>
|
|
|
|
+ <type>list</type>
|
|
|
|
+ <list_type>string</list_type>
|
|
|
|
+ <default>[]</default>
|
|
|
|
+ <locale name="C">
|
|
|
|
+ <short>This is used for gnome-shell to work shift + modifiers</short>
|
|
|
|
+ <long>This is used for gnome-shell to work shift + modifiers
|
|
|
|
+ Currently gnome-shell assigns the shift reverse by
|
|
|
|
+ dconf key and the shift reverse works with modifiers.
|
|
|
|
+ But ibus supports multiple trigger keys;
|
|
|
|
+ <Control>space (with modifiers)
|
|
|
|
+ Zenkaku_hankaku (without modifiers)
|
|
|
|
+ I copy the modifier trigger keys here to set
|
|
|
|
+ the shift reverse at the moment.
|
|
|
|
+ </long>
|
|
|
|
+ </locale>
|
|
|
|
+ </schema>
|
|
|
|
+ <schema>
|
|
|
|
+ <key>/schemas/desktop/ibus/general/hotkey/trigger_ja</key>
|
|
|
|
+ <applyto>/desktop/ibus/general/hotkey/trigger_ja</applyto>
|
|
|
|
+ <owner>ibus</owner>
|
|
|
|
+ <type>list</type>
|
|
|
|
+ <list_type>string</list_type>
|
|
|
|
+ <default>[Zenkaku_Hankaku]</default>
|
|
|
|
+ <locale name="C">
|
|
|
|
+ <short>Trigger shortcut keys for ja gtk_accelerator_parse</short>
|
|
|
|
+ <long>The shortcut keys for turning input method on or off</long>
|
|
|
|
+ </locale>
|
|
|
|
+ </schema>
|
|
|
|
+ <schema>
|
|
|
|
+ <key>/schemas/desktop/ibus/general/hotkey/trigger_ko</key>
|
|
|
|
+ <applyto>/desktop/ibus/general/hotkey/trigger_ko</applyto>
|
|
|
|
+ <owner>ibus</owner>
|
|
|
|
+ <type>list</type>
|
|
|
|
+ <list_type>string</list_type>
|
|
|
|
+ <default>[Hangul, Alt_R]</default>
|
|
|
|
+ <locale name="C">
|
|
|
|
+ <short>Trigger shortcut keys for ko gtk_accelerator_parse</short>
|
|
|
|
<long>The shortcut keys for turning input method on or off</long>
|
2012-03-18 09:41:41 +00:00
|
|
|
</locale>
|
|
|
|
</schema>
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -203,6 +259,52 @@
|
2012-02-04 01:13:28 +00:00
|
|
|
</locale>
|
|
|
|
</schema>
|
|
|
|
<schema>
|
2011-11-18 10:55:48 +00:00
|
|
|
+ <key>/schemas/desktop/ibus/general/use_xmodmap</key>
|
|
|
|
+ <applyto>/desktop/ibus/general/use_xmodmap</applyto>
|
|
|
|
+ <owner>ibus</owner>
|
|
|
|
+ <type>bool</type>
|
|
|
|
+ <default>true</default>
|
|
|
|
+ <locale name="C">
|
|
|
|
+ <short>Use xmodmap</short>
|
|
|
|
+ <long>Run xmodmap if .xmodmap/.Xmodmap exists.</long>
|
|
|
|
+ </locale>
|
|
|
|
+ </schema>
|
|
|
|
+ <schema>
|
2010-08-23 02:55:19 +00:00
|
|
|
+ <key>/schemas/desktop/ibus/general/xkb_latin_layouts</key>
|
|
|
|
+ <applyto>/desktop/ibus/general/xkb_latin_layouts</applyto>
|
|
|
|
+ <owner>ibus</owner>
|
|
|
|
+ <type>list</type>
|
|
|
|
+ <list_type>string</list_type>
|
2010-10-06 02:10:04 +00:00
|
|
|
+ <default>[ara,bg,cz,dev,gr,gur,in,jp(kana),mal,mkd,ru,ua]</default>
|
2010-08-23 02:55:19 +00:00
|
|
|
+ <locale name="C">
|
|
|
|
+ <short>Latin layout which have no ASCII</short>
|
2012-02-04 01:13:28 +00:00
|
|
|
+ <long>us layout is appended to the latin layouts. variant is not needed.</long>
|
|
|
|
+ </locale>
|
|
|
|
+ </schema>
|
|
|
|
+ <schema>
|
|
|
|
+ <key>/schemas/desktop/ibus/general/load_xkb_layouts</key>
|
|
|
|
+ <applyto>/desktop/ibus/general/load_xkb_layouts</applyto>
|
|
|
|
+ <owner>ibus</owner>
|
|
|
|
+ <type>list</type>
|
|
|
|
+ <list_type>string</list_type>
|
|
|
|
+ <default>[us,us(chr),us(dvorak),ad,al,am,ara,az,ba,bd,be,bg,br,bt,by,
|
|
|
|
+de,dk,ca,ch,cn(tib),cz,ee,epo,es,et,fi,fo,fr,
|
|
|
|
+gb,ge,ge(dsb),ge(ru),ge(os),gh,gh(akan),gh(ewe),gh(fula),gh(ga),gh(hausa),
|
|
|
|
+gn,gr,hu,hr,ie,ie(CloGaelach),il,
|
|
|
|
+in,
|
|
|
|
+in(tel),in(bolnagri),iq,iq(ku),ir,ir(ku),is,it,jp,
|
|
|
|
+kg,kh,kz,la,latam,lk,lk(tam_unicode),lt,lv,ma,ma(tifinagh),mal,mao,
|
|
|
|
+me,mk,mm,mt,mv,ng,ng(hausa),ng,ng(igbo),ng(yoruba),nl,no,no(smi),np,
|
|
|
|
+pk,pl,pl(csb),pt,ro,rs,ru,ru(cv),ru(kom),ru(sah),ru(tt),ru(xal),
|
|
|
|
+se,si,sk,sy,sy(ku),th,tj,tr,ua,uz,vn
|
|
|
|
+]</default>
|
|
|
|
+ <locale name="C">
|
|
|
|
+ <short>XKB layout list which is shown on ibus-setup</short>
|
|
|
|
+ <long>XKB layout list which is shown on ibus-setup.
|
|
|
|
+ The format is "layout" or "layout(variant)".</long>
|
2010-08-23 02:55:19 +00:00
|
|
|
+ </locale>
|
|
|
|
+ </schema>
|
|
|
|
+ <schema>
|
|
|
|
<key>/schemas/desktop/ibus/panel/use_custom_font</key>
|
|
|
|
<applyto>/desktop/ibus/panel/use_custom_font</applyto>
|
|
|
|
<owner>ibus</owner>
|
2012-02-04 01:13:28 +00:00
|
|
|
diff --git a/engine/Makefile.am b/engine/Makefile.am
|
2012-04-28 06:13:40 +00:00
|
|
|
index b3b46be..a95736b 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
--- a/engine/Makefile.am
|
|
|
|
+++ b/engine/Makefile.am
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -78,6 +78,26 @@ component_DATA = \
|
2010-08-23 02:55:19 +00:00
|
|
|
|
2012-02-04 01:13:28 +00:00
|
|
|
componentdir = $(pkgdatadir)/component
|
2010-08-23 02:55:19 +00:00
|
|
|
|
|
|
|
+if ENABLE_XKB
|
2012-02-04 01:13:28 +00:00
|
|
|
+libexec_PROGRAMS += ibus-xkb
|
|
|
|
+ibus_xkb_SOURCES = \
|
|
|
|
+ ibus-xkb-main.c \
|
|
|
|
+ xkblib.h \
|
|
|
|
+ xkblib.c \
|
|
|
|
+ $(NULL)
|
|
|
|
+ibus_xkb_CFLAGS = \
|
|
|
|
+ @XKB_CFLAGS@ \
|
|
|
|
+ @X11_CFLAGS@ \
|
|
|
|
+ @GLIB2_CFLAGS@ \
|
|
|
|
+ $(NULL)
|
|
|
|
+ibus_xkb_LDADD = \
|
|
|
|
+ @XKB_LIBS@ \
|
|
|
|
+ @X11_LIBS@ \
|
|
|
|
+ @GLIB2_LIBS@ \
|
|
|
|
+ $(libibus) \
|
|
|
|
+ $(NULL)
|
2010-08-23 02:55:19 +00:00
|
|
|
+endif
|
|
|
|
+
|
|
|
|
CLEANFILES = \
|
2012-02-04 01:13:28 +00:00
|
|
|
simple.xml \
|
2010-09-14 11:20:08 +00:00
|
|
|
$(NULL)
|
2012-02-04 01:13:28 +00:00
|
|
|
diff --git a/engine/ibus-xkb-main.c b/engine/ibus-xkb-main.c
|
2010-08-23 02:55:19 +00:00
|
|
|
new file mode 100644
|
2012-04-28 06:13:40 +00:00
|
|
|
index 0000000..2529e4d
|
2010-08-23 02:55:19 +00:00
|
|
|
--- /dev/null
|
2012-02-04 01:13:28 +00:00
|
|
|
+++ b/engine/ibus-xkb-main.c
|
|
|
|
@@ -0,0 +1,111 @@
|
2010-10-06 02:10:04 +00:00
|
|
|
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
2010-08-23 02:55:19 +00:00
|
|
|
+/* vim:set et sts=4: */
|
|
|
|
+/* bus - The Input Bus
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * Copyright (C) 2012 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Red Hat, Inc.
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the
|
|
|
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
+ * Boston, MA 02111-1307, USA.
|
|
|
|
+ */
|
|
|
|
+#ifdef HAVE_CONFIG_H
|
|
|
|
+#include <config.h>
|
|
|
|
+#endif
|
|
|
|
+
|
2011-06-21 08:49:07 +00:00
|
|
|
+#include <glib.h>
|
2012-02-04 01:13:28 +00:00
|
|
|
+#include <glib/gprintf.h>
|
|
|
|
+#include <glib/gi18n.h>
|
|
|
|
+#include <X11/Xlib.h>
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#ifdef ENABLE_NLS
|
|
|
|
+#include <locale.h>
|
2011-06-21 08:49:07 +00:00
|
|
|
+#endif
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#include "xkblib.h"
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static gboolean get_layout = FALSE;
|
|
|
|
+static gboolean get_group = FALSE;
|
|
|
|
+static gchar *layout = NULL;
|
|
|
|
+static gchar *variant = NULL;
|
|
|
|
+static gchar *option = NULL;
|
|
|
|
+static int group = 0;
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static const GOptionEntry entries[] =
|
|
|
|
+{
|
|
|
|
+ { "get", 'g', 0, G_OPTION_ARG_NONE, &get_layout, N_("Get current xkb layout"), NULL },
|
|
|
|
+ { "layout", 'l', 0, G_OPTION_ARG_STRING, &layout, N_("Set xkb LAYOUT"), N_("LAYOUT") },
|
|
|
|
+ { "variant", 'v', 0, G_OPTION_ARG_STRING, &variant, N_("Set xkb VARIANT"), N_("VARIANT") },
|
|
|
|
+ { "option", 'o', 0, G_OPTION_ARG_STRING, &option, N_("Set xkb OPTION"), N_("OPTION") },
|
|
|
|
+ { "get-group", 'G', 0, G_OPTION_ARG_NONE, &get_group, N_("Get current xkb state"), NULL },
|
|
|
|
+ { NULL },
|
2011-06-21 08:49:07 +00:00
|
|
|
+};
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+int
|
|
|
|
+main (int argc, char *argv[])
|
|
|
|
+{
|
|
|
|
+ GOptionContext *context;
|
|
|
|
+ GError *error = NULL;
|
|
|
|
+ Display *xdisplay;
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#ifdef ENABLE_NLS
|
|
|
|
+ setlocale (LC_ALL, "");
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-04-28 06:13:40 +00:00
|
|
|
+ bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
|
2012-02-04 01:13:28 +00:00
|
|
|
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
|
|
|
+#endif
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ context = g_option_context_new ("- ibus daemon");
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
|
|
|
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
|
|
|
|
+
|
|
|
|
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
|
|
|
+ g_printerr ("Option parsing failed: %s\n", error->message);
|
|
|
|
+ return -1;
|
2011-06-21 08:49:07 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
+ xdisplay = XOpenDisplay (NULL);
|
|
|
|
+ if (xdisplay == NULL) {
|
|
|
|
+ g_warning ("Could not open display");
|
|
|
|
+ return -1;
|
2011-06-21 08:49:07 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ ibus_xkb_init (xdisplay);
|
|
|
|
+
|
|
|
|
+ if (layout) {
|
|
|
|
+ ibus_xkb_set_layout (layout, variant, option);
|
|
|
|
+ }
|
|
|
|
+ if (get_layout) {
|
|
|
|
+ layout = ibus_xkb_get_current_layout ();
|
|
|
|
+ variant = ibus_xkb_get_current_variant ();
|
|
|
|
+ option = ibus_xkb_get_current_option ();
|
|
|
|
+ g_printf ("layout: %s\n"
|
|
|
|
+ "variant: %s\n"
|
|
|
|
+ "option: %s\n",
|
|
|
|
+ layout ? layout : "",
|
|
|
|
+ variant ? variant : "",
|
|
|
|
+ option ? option : "");
|
|
|
|
+ g_free (layout);
|
|
|
|
+ g_free (variant);
|
|
|
|
+ g_free (option);
|
|
|
|
+ }
|
|
|
|
+ if (get_group) {
|
|
|
|
+ group = ibus_xkb_get_current_group ();
|
|
|
|
+ g_printf ("group: %d\n", group);
|
2011-06-21 08:49:07 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ ibus_xkb_finit ();
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
diff --git a/engine/main.vala b/engine/main.vala
|
2012-03-04 13:45:32 +00:00
|
|
|
index e1fd129..377fa2f 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
--- a/engine/main.vala
|
|
|
|
+++ b/engine/main.vala
|
2012-03-04 13:45:32 +00:00
|
|
|
@@ -21,6 +21,85 @@
|
2012-02-04 01:13:28 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
using IBus;
|
|
|
|
+using GLib;
|
|
|
|
+
|
|
|
|
+private void print_xml(string layout,
|
|
|
|
+ string layout_desc,
|
|
|
|
+ string? variant,
|
|
|
|
+ string? variant_desc,
|
|
|
|
+ string lang) {
|
|
|
|
+ string name = "xkb:%s:%s:%s".printf(layout, variant ?? "", lang);
|
|
|
|
+ string keymap = layout;
|
|
|
|
+ string desc = layout_desc;
|
|
|
|
+ string symbol = lang;
|
|
|
|
+
|
|
|
|
+ if (variant != null) {
|
|
|
|
+ keymap = "%s(%s)".printf(layout, variant);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (variant_desc != null) {
|
|
|
|
+ desc = variant_desc;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ desc = desc.replace("<", "<").replace(">", ">");
|
|
|
|
+
|
|
|
|
+ if (lang.length > 2) {
|
|
|
|
+ symbol = lang[0:2];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ string engine = "
|
|
|
|
+ <engine>
|
|
|
|
+ <name>%s</name>
|
|
|
|
+ <language>%s</language>
|
|
|
|
+ <license>GPL</license>
|
|
|
|
+ <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
+ <layout>%s</layout>
|
|
|
|
+ <longname>%s</longname>
|
|
|
|
+ <description>%s</description>
|
|
|
|
+ <icon>ibus-keyboard</icon>
|
|
|
|
+ <symbol>%s</symbol>
|
|
|
|
+ <rank>%d</rank>
|
|
|
|
+ </engine>".printf(name, lang, keymap, desc, desc, symbol, 99);
|
|
|
|
+ print (engine);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+private void print_component() {
|
|
|
|
+ IBus.XKBConfigRegistry registry = new IBus.XKBConfigRegistry();
|
2012-03-04 13:45:32 +00:00
|
|
|
+ GLib.List layouts = registry.layout_list_get_layouts();
|
|
|
|
+ GLib.List variants;
|
|
|
|
+ GLib.List langs;
|
2012-02-04 01:13:28 +00:00
|
|
|
+ string layout_desc;
|
|
|
|
+ const string header = "<engines>";
|
|
|
|
+ const string footer = "
|
|
|
|
+</engines>";
|
|
|
|
+
|
|
|
|
+ print (header);
|
|
|
|
+ for (unowned GLib.List<string> l = layouts; l != null; l = l.next) {
|
|
|
|
+ variants = registry.layout_list_get_variants(l.data);
|
|
|
|
+ langs = registry.layout_lang_get_langs(l.data);
|
|
|
|
+ layout_desc = registry.layout_desc_get_desc(l.data);
|
|
|
|
+ for (unowned GLib.List<string> lg = langs; lg != null; lg = lg.next) {
|
|
|
|
+ print_xml(l.data, layout_desc, null, null, lg.data);
|
2011-06-21 08:49:07 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ for (unowned GLib.List<string> v = variants; v != null; v = v.next) {
|
|
|
|
+ var l_v = "%s(%s)".printf(l.data, v.data);
|
2012-03-04 13:45:32 +00:00
|
|
|
+ unowned GLib.List<string> l_v_langs = null;
|
|
|
|
+ GLib.List<string> _l_v_langs = registry.layout_lang_get_langs(l_v);
|
|
|
|
+ l_v_langs = _l_v_langs;
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (l_v_langs == null) {
|
|
|
|
+ l_v_langs = langs;
|
|
|
|
+ }
|
|
|
|
+ for (unowned GLib.List<string> lg = l_v_langs; lg != null; lg = lg.next) {
|
|
|
|
+ print_xml(l.data,
|
|
|
|
+ layout_desc,
|
|
|
|
+ v.data,
|
|
|
|
+ registry.variant_desc_get_desc(l_v),
|
|
|
|
+ lg.data);
|
|
|
|
+ }
|
2011-06-21 08:49:07 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ }
|
|
|
|
+ print (footer);
|
|
|
|
+}
|
|
|
|
|
|
|
|
class DummyEngine : IBus.EngineSimple {
|
|
|
|
}
|
2012-03-04 13:45:32 +00:00
|
|
|
@@ -28,6 +107,13 @@ class DummyEngine : IBus.EngineSimple {
|
2012-02-04 01:13:28 +00:00
|
|
|
public int main(string[] args) {
|
|
|
|
IBus.init();
|
|
|
|
|
|
|
|
+ if (args.length >= 2) {
|
|
|
|
+ if (args[1] == "--xml" || args[1] == "-x") {
|
|
|
|
+ print_component();
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
IBus.Bus bus = new IBus.Bus();
|
|
|
|
if (!bus.is_connected()) {
|
|
|
|
warning("ibus-daemon does not exist.");
|
|
|
|
diff --git a/engine/simple.xml.in.in b/engine/simple.xml.in.in
|
|
|
|
index 25db578..7de949a 100644
|
|
|
|
--- a/engine/simple.xml.in.in
|
|
|
|
+++ b/engine/simple.xml.in.in
|
|
|
|
@@ -7,534 +7,5 @@
|
|
|
|
<license>GPL</license>
|
|
|
|
<homepage>http://code.google.com/p/ibus</homepage>
|
|
|
|
<textdomain>ibus</textdomain>
|
|
|
|
- <engines>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:us::eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>us</layout>
|
|
|
|
- <longname>English (US)</longname>
|
|
|
|
- <description>English (US)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:us:intl:eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>us(intl)</layout>
|
|
|
|
- <longname>English (US, international with dead keys)</longname>
|
|
|
|
- <description>English (US, international with dead keys)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:us:colemak:eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>us(colemak)</layout>
|
|
|
|
- <longname>English (Colemak)</longname>
|
|
|
|
- <description>English (Colemak)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:us:dvorak:eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>us(dvorak)</layout>
|
|
|
|
- <longname>English (Dvorak)</longname>
|
|
|
|
- <description>English (Dvorak)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:us:altgr-intl:eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>us(altgr-intl)</layout>
|
|
|
|
- <longname>English (international AltGr dead keys)</longname>
|
|
|
|
- <description>English (international AltGr dead keys)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:us:altgr-intl:eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>us(altgr-intl)</layout>
|
|
|
|
- <longname>English (international AltGr dead keys)</longname>
|
|
|
|
- <description>English (international AltGr dead keys)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:be::ger</name>
|
|
|
|
- <language>ger</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>be</layout>
|
|
|
|
- <longname>Belgian</longname>
|
|
|
|
- <description>Belgian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:be::nld</name>
|
|
|
|
- <language>nld</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>be</layout>
|
|
|
|
- <longname>Belgian</longname>
|
|
|
|
- <description>Belgian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:be::fra</name>
|
|
|
|
- <language>fra</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>be</layout>
|
|
|
|
- <longname>Belgian</longname>
|
|
|
|
- <description>Belgian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:br::por</name>
|
|
|
|
- <language>por</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>br</layout>
|
|
|
|
- <longname>Portuguese (Brazil)</longname>
|
|
|
|
- <description>Portuguese (Brazil)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:bg::bul</name>
|
|
|
|
- <language>bul</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>bg</layout>
|
|
|
|
- <longname>Bulgarian</longname>
|
|
|
|
- <description>Bulgarian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:bg:phonetic:bul</name>
|
|
|
|
- <language>bul</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>bg(phonetic)</layout>
|
|
|
|
- <longname>Bulgarian (traditional phonetic)</longname>
|
|
|
|
- <description>Bulgarian (traditional phonetic)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ca::fra</name>
|
|
|
|
- <language>fra</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ca</layout>
|
|
|
|
- <longname>French (Canada)</longname>
|
|
|
|
- <description>French (Canada)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ca:eng:eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ca(eng)</layout>
|
|
|
|
- <longname>English (Canada)</longname>
|
|
|
|
- <description>English (Canada)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:hr::scr</name>
|
|
|
|
- <language>scr</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>hr</layout>
|
|
|
|
- <longname>Croatian</longname>
|
|
|
|
- <description>Croatian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:cz::cze</name>
|
|
|
|
- <language>cze</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>cz</layout>
|
|
|
|
- <longname>Czech</longname>
|
|
|
|
- <description>Czech</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:dk::dan</name>
|
|
|
|
- <language>dan</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>dk</layout>
|
|
|
|
- <longname>Danish</longname>
|
|
|
|
- <description>Danish</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ee::est</name>
|
|
|
|
- <language>est</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ee</layout>
|
|
|
|
- <longname>Estonian</longname>
|
|
|
|
- <description>Estonian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:fi::fin</name>
|
|
|
|
- <language>fin</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>fi</layout>
|
|
|
|
- <longname>Finnish</longname>
|
|
|
|
- <description>Finnish</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:fr::fra</name>
|
|
|
|
- <language>fra</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>fr</layout>
|
|
|
|
- <longname>French</longname>
|
|
|
|
- <description>French</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:de::ger</name>
|
|
|
|
- <language>ger</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>de</layout>
|
|
|
|
- <longname>German</longname>
|
|
|
|
- <description>German</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:de:neo:ger</name>
|
|
|
|
- <language>ger</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>de(neo)</layout>
|
|
|
|
- <longname>German (Neo 2)</longname>
|
|
|
|
- <description>German (Neo 2)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:gr::gre</name>
|
|
|
|
- <language>gre</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>gr</layout>
|
|
|
|
- <longname>Greek</longname>
|
|
|
|
- <description>Greek</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:hu::hun</name>
|
|
|
|
- <language>hun</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>hu</layout>
|
|
|
|
- <longname>Hungarian</longname>
|
|
|
|
- <description>Hungarian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:il::heb</name>
|
|
|
|
- <language>heb</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>il</layout>
|
|
|
|
- <longname>Hebrew</longname>
|
|
|
|
- <description>Hebrew</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:it::ita</name>
|
|
|
|
- <language>ita</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>it</layout>
|
|
|
|
- <longname>Italian</longname>
|
|
|
|
- <description>Italian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:jp::jpn</name>
|
|
|
|
- <language>jpn</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>jp</layout>
|
|
|
|
- <longname>Japanese</longname>
|
|
|
|
- <description>Japanese</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:latam::spa</name>
|
|
|
|
- <language>spa</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>latam</layout>
|
|
|
|
- <longname>Spanish (Latin American)</longname>
|
|
|
|
- <description>Spanish (Latin American)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:lt::lit</name>
|
|
|
|
- <language>lit</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>lt</layout>
|
|
|
|
- <longname>Lithuanian</longname>
|
|
|
|
- <description>Lithuanian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:lv:apostrophe:lav</name>
|
|
|
|
- <language>lav</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>lv(apostrophe)</layout>
|
|
|
|
- <longname>Latvian (apostrophe variant)</longname>
|
|
|
|
- <description>Latvian (apostrophe variant)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:pl::pol</name>
|
|
|
|
- <language>pol</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>pl</layout>
|
|
|
|
- <longname>Polish</longname>
|
|
|
|
- <description>Polish</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:pt::por</name>
|
|
|
|
- <language>por</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>pt</layout>
|
|
|
|
- <longname>Portuguese</longname>
|
|
|
|
- <description>Portuguese</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ro::rum</name>
|
|
|
|
- <language>rum</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ro</layout>
|
|
|
|
- <longname>Romanian</longname>
|
|
|
|
- <description>Romanian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ru::rus</name>
|
|
|
|
- <language>rus</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ru</layout>
|
|
|
|
- <longname>Russian</longname>
|
|
|
|
- <description>Russian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ru:phonetic:rus</name>
|
|
|
|
- <language>rus</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ru(phonetic)</layout>
|
|
|
|
- <longname>Russian (phonetic)</longname>
|
|
|
|
- <description>Russian (phonetic)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:rs::srp</name>
|
|
|
|
- <language>srp</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>rs</layout>
|
|
|
|
- <longname>Serbian</longname>
|
|
|
|
- <description>Serbian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:si::slv</name>
|
|
|
|
- <language>slv</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>si</layout>
|
|
|
|
- <longname>Slovenian</longname>
|
|
|
|
- <description>Slovenian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:sk::slo</name>
|
|
|
|
- <language>slo</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>sk</layout>
|
|
|
|
- <longname>Slovak</longname>
|
|
|
|
- <description>Slovak</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:es::spa</name>
|
|
|
|
- <language>spa</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>es</layout>
|
|
|
|
- <longname>Spanish</longname>
|
|
|
|
- <description>Spanish</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:es:cat:cat</name>
|
|
|
|
- <language>cat</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>es(cat)</layout>
|
|
|
|
- <longname>Catalan (Spain, with middle-dot L)</longname>
|
|
|
|
- <description>Catalan (Spain, with middle-dot L)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:se::swe</name>
|
|
|
|
- <language>swe</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>se</layout>
|
|
|
|
- <longname>Swedish</longname>
|
|
|
|
- <description>Swedish</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ch::ger</name>
|
|
|
|
- <language>ger</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ch</layout>
|
|
|
|
- <longname>German (Switzerland)</longname>
|
|
|
|
- <description>German (Switzerland)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ch:fr:fra</name>
|
|
|
|
- <language>fra</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ch(fr)</layout>
|
|
|
|
- <longname>French (Switzerland)</longname>
|
|
|
|
- <description>French (Switzerland)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:tr::tur</name>
|
|
|
|
- <language>tur</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>tr</layout>
|
|
|
|
- <longname>Turkish</longname>
|
|
|
|
- <description>Turkish</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:ua::ukr</name>
|
|
|
|
- <language>ukr</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>ua</layout>
|
|
|
|
- <longname>Ukrainian</longname>
|
|
|
|
- <description>Ukrainian</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:gb:extd:eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>gb(extd)</layout>
|
|
|
|
- <longname>English (UK, extended WinKeys)</longname>
|
|
|
|
- <description>English (UK, extended WinKeys)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:gb:dvorak:eng</name>
|
|
|
|
- <language>eng</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>gb(dvorak)</layout>
|
|
|
|
- <longname>English (UK, Dvorak)</longname>
|
|
|
|
- <description>English (UK, Dvorak)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- <engine>
|
|
|
|
- <name>xkb:kr:kr104:kor</name>
|
|
|
|
- <language>kor</language>
|
|
|
|
- <license>GPL</license>
|
|
|
|
- <author>Peng Huang <shawn.p.huang@gmail.com></author>
|
|
|
|
- <layout>kr(kr104)</layout>
|
|
|
|
- <longname>Korean (101/104 key compatible)</longname>
|
|
|
|
- <description>Korean (101/104 key compatible)</description>
|
|
|
|
- <icon>ibus-keyboard</icon>
|
|
|
|
- <rank>99</rank>
|
|
|
|
- </engine>
|
|
|
|
- </engines>
|
|
|
|
+ <engines exec=\"${libexecdir}/ibus-engine-simple --xml\" />
|
|
|
|
</component>
|
|
|
|
diff --git a/engine/xkblib.c b/engine/xkblib.c
|
2011-06-21 08:49:07 +00:00
|
|
|
new file mode 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
index 0000000..bb25455
|
2011-06-21 08:49:07 +00:00
|
|
|
--- /dev/null
|
2012-02-04 01:13:28 +00:00
|
|
|
+++ b/engine/xkblib.c
|
|
|
|
@@ -0,0 +1,327 @@
|
2011-06-21 08:49:07 +00:00
|
|
|
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
|
|
+/* vim:set et sts=4: */
|
|
|
|
+/* bus - The Input Bus
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * Copyright (C) 2012 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Red Hat, Inc.
|
2011-06-21 08:49:07 +00:00
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the
|
|
|
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
+ * Boston, MA 02111-1307, USA.
|
|
|
|
+ */
|
|
|
|
+#ifdef HAVE_CONFIG_H
|
|
|
|
+#include <config.h>
|
|
|
|
+#endif
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#include <glib.h>
|
|
|
|
+#include <X11/Xlib.h>
|
|
|
|
+#include <X11/Xatom.h>
|
|
|
|
+#include <X11/XKBlib.h>
|
|
|
|
+#include <stdio.h> /* for XKBrules.h */
|
|
|
|
+#include <X11/extensions/XKBrules.h>
|
|
|
|
+#include <X11/extensions/XKBstr.h>
|
|
|
|
+#include <string.h>
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#include "xkblib.h"
|
|
|
|
+
|
|
|
|
+#ifndef XKB_RULES_XML_FILE
|
|
|
|
+#define XKB_RULES_XML_FILE "/usr/share/X11/xkb/rules/evdev.xml"
|
2011-06-21 08:49:07 +00:00
|
|
|
+#endif
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static gchar **default_layouts;
|
|
|
|
+static gchar **default_variants;
|
|
|
|
+static gchar **default_options;
|
|
|
|
+static int default_layout_group;
|
|
|
|
+
|
|
|
|
+static Display *
|
|
|
|
+get_xdisplay (Display *xdisplay)
|
|
|
|
+{
|
|
|
|
+ static Display *saved_xdisplay = NULL;
|
|
|
|
+ if (xdisplay != NULL) {
|
|
|
|
+ saved_xdisplay = xdisplay;
|
|
|
|
+ }
|
|
|
|
+ return saved_xdisplay;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+init_xkb_default_layouts (Display *xdisplay)
|
|
|
|
+{
|
|
|
|
+ XkbStateRec state;
|
|
|
|
+ Atom xkb_rules_name, type;
|
|
|
|
+ int format;
|
|
|
|
+ unsigned long l, nitems, bytes_after;
|
|
|
|
+ unsigned char *prop = NULL;
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ xkb_rules_name = XInternAtom (xdisplay, "_XKB_RULES_NAMES", TRUE);
|
|
|
|
+ if (xkb_rules_name == None) {
|
|
|
|
+ g_warning ("Could not get XKB rules atom");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (XGetWindowProperty (xdisplay,
|
|
|
|
+ XDefaultRootWindow (xdisplay),
|
|
|
|
+ xkb_rules_name,
|
|
|
|
+ 0, 1024, FALSE, XA_STRING,
|
|
|
|
+ &type, &format, &nitems, &bytes_after, &prop) != Success) {
|
|
|
|
+ g_warning ("Could not get X property");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (nitems < 3) {
|
|
|
|
+ g_warning ("Could not get group layout from X property");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (l = 0; l < 2; l++) {
|
|
|
|
+ prop += strlen ((const char *) prop) + 1;
|
|
|
|
+ }
|
|
|
|
+ if (prop == NULL || *prop == '\0') {
|
|
|
|
+ g_warning ("No layouts form X property");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ default_layouts = g_strsplit ((gchar *) prop, ",", -1);
|
|
|
|
+ prop += strlen ((const char *) prop) + 1;
|
|
|
|
+ default_variants = g_strsplit ((gchar *) prop, ",", -1);
|
|
|
|
+ prop += strlen ((const char *) prop) + 1;
|
|
|
|
+ default_options = g_strsplit ((gchar *) prop, ",", -1);
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (XkbGetState (xdisplay, XkbUseCoreKbd, &state) != Success) {
|
|
|
|
+ g_warning ("Could not get state");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ default_layout_group = state.group;
|
|
|
|
+}
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static Bool
|
|
|
|
+set_xkb_rules (Display *xdisplay,
|
|
|
|
+ const char *rules_file, const char *model,
|
|
|
|
+ const char *all_layouts, const char *all_variants,
|
|
|
|
+ const char *all_options)
|
2011-06-21 08:49:07 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ gchar *rules_path;
|
|
|
|
+ XkbRF_RulesPtr rules;
|
|
|
|
+ XkbRF_VarDefsRec rdefs;
|
|
|
|
+ XkbComponentNamesRec rnames;
|
|
|
|
+ XkbDescPtr xkb;
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ rules_path = g_strdup ("./rules/evdev");
|
|
|
|
+ rules = XkbRF_Load (rules_path, "C", TRUE, TRUE);
|
|
|
|
+ if (rules == NULL) {
|
|
|
|
+ g_return_val_if_fail (XKB_RULES_XML_FILE != NULL, FALSE);
|
|
|
|
+
|
|
|
|
+ g_free (rules_path);
|
|
|
|
+ if (g_str_has_suffix (XKB_RULES_XML_FILE, ".xml")) {
|
|
|
|
+ rules_path = g_strndup (XKB_RULES_XML_FILE,
|
|
|
|
+ strlen (XKB_RULES_XML_FILE) - 4);
|
|
|
|
+ } else {
|
|
|
|
+ rules_path = g_strdup (XKB_RULES_XML_FILE);
|
|
|
|
+ }
|
|
|
|
+ rules = XkbRF_Load (rules_path, "C", TRUE, TRUE);
|
|
|
|
+ }
|
|
|
|
+ g_return_val_if_fail (rules != NULL, FALSE);
|
|
|
|
+
|
|
|
|
+ memset (&rdefs, 0, sizeof (XkbRF_VarDefsRec));
|
|
|
|
+ memset (&rnames, 0, sizeof (XkbComponentNamesRec));
|
|
|
|
+ rdefs.model = model ? g_strdup (model) : NULL;
|
|
|
|
+ rdefs.layout = all_layouts ? g_strdup (all_layouts) : NULL;
|
|
|
|
+ rdefs.variant = all_variants ? g_strdup (all_variants) : NULL;
|
|
|
|
+ rdefs.options = all_options ? g_strdup (all_options) : NULL;
|
|
|
|
+ XkbRF_GetComponents (rules, &rdefs, &rnames);
|
|
|
|
+ xkb = XkbGetKeyboardByName (xdisplay, XkbUseCoreKbd, &rnames,
|
|
|
|
+ XkbGBN_AllComponentsMask,
|
|
|
|
+ XkbGBN_AllComponentsMask &
|
|
|
|
+ (~XkbGBN_GeometryMask), True);
|
|
|
|
+ if (!xkb) {
|
|
|
|
+ g_warning ("Cannot load new keyboard description.");
|
|
|
|
+ return FALSE;
|
|
|
|
+ }
|
|
|
|
+ XkbRF_SetNamesProp (xdisplay, rules_path, &rdefs);
|
|
|
|
+ g_free (rules_path);
|
|
|
|
+ g_free (rdefs.model);
|
|
|
|
+ g_free (rdefs.layout);
|
|
|
|
+ g_free (rdefs.variant);
|
|
|
|
+ g_free (rdefs.options);
|
|
|
|
+
|
|
|
|
+ return TRUE;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static Bool
|
|
|
|
+update_xkb_properties (Display *xdisplay,
|
|
|
|
+ const char *rules_file, const char *model,
|
|
|
|
+ const char *all_layouts, const char *all_variants,
|
|
|
|
+ const char *all_options)
|
2010-08-23 02:55:19 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ int len;
|
|
|
|
+ char *pval;
|
|
|
|
+ char *next;
|
|
|
|
+ Atom rules_atom;
|
|
|
|
+ Window root_window;
|
|
|
|
+
|
|
|
|
+ len = (rules_file ? strlen (rules_file) : 0);
|
|
|
|
+ len += (model ? strlen (model) : 0);
|
|
|
|
+ len += (all_layouts ? strlen (all_layouts) : 0);
|
|
|
|
+ len += (all_variants ? strlen (all_variants) : 0);
|
|
|
|
+ len += (all_options ? strlen (all_options) : 0);
|
|
|
|
+
|
|
|
|
+ if (len < 1) {
|
|
|
|
+ return TRUE;
|
|
|
|
+ }
|
|
|
|
+ len += 5; /* trailing NULs */
|
|
|
|
+
|
|
|
|
+ rules_atom = XInternAtom (xdisplay, _XKB_RF_NAMES_PROP_ATOM, False);
|
|
|
|
+ root_window = XDefaultRootWindow (xdisplay);
|
|
|
|
+ pval = next = g_new0 (char, len + 1);
|
|
|
|
+ if (!pval) {
|
|
|
|
+ return TRUE;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (rules_file) {
|
|
|
|
+ strcpy (next, rules_file);
|
|
|
|
+ next += strlen (rules_file);
|
|
|
|
+ }
|
|
|
|
+ *next++ = '\0';
|
|
|
|
+ if (model) {
|
|
|
|
+ strcpy (next, model);
|
|
|
|
+ next += strlen (model);
|
|
|
|
+ }
|
|
|
|
+ *next++ = '\0';
|
|
|
|
+ if (all_layouts) {
|
|
|
|
+ strcpy (next, all_layouts);
|
|
|
|
+ next += strlen (all_layouts);
|
|
|
|
+ }
|
|
|
|
+ *next++ = '\0';
|
|
|
|
+ if (all_variants) {
|
|
|
|
+ strcpy (next, all_variants);
|
|
|
|
+ next += strlen (all_variants);
|
|
|
|
+ }
|
|
|
|
+ *next++ = '\0';
|
|
|
|
+ if (all_options) {
|
|
|
|
+ strcpy (next, all_options);
|
|
|
|
+ next += strlen (all_options);
|
|
|
|
+ }
|
|
|
|
+ *next++ = '\0';
|
|
|
|
+ if ((next - pval) != len) {
|
|
|
|
+ g_free (pval);
|
|
|
|
+ return TRUE;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ XChangeProperty (xdisplay, root_window,
|
|
|
|
+ rules_atom, XA_STRING, 8, PropModeReplace,
|
|
|
|
+ (unsigned char *) pval, len);
|
|
|
|
+ XSync(xdisplay, False);
|
|
|
|
+
|
|
|
|
+ return TRUE;
|
2010-08-23 02:55:19 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+void
|
|
|
|
+ibus_xkb_init (Display *xdisplay)
|
2010-08-23 02:55:19 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ get_xdisplay (xdisplay);
|
|
|
|
+ init_xkb_default_layouts (xdisplay);
|
|
|
|
+}
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+void
|
|
|
|
+ibus_xkb_finit (void)
|
|
|
|
+{
|
|
|
|
+ g_strfreev (default_layouts);
|
|
|
|
+ default_layouts = NULL;
|
|
|
|
+ g_strfreev (default_variants);
|
|
|
|
+ default_variants = NULL;
|
|
|
|
+ g_strfreev (default_options);
|
|
|
|
+ default_options = NULL;
|
|
|
|
+}
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+gchar *
|
|
|
|
+ibus_xkb_get_current_layout (void)
|
|
|
|
+{
|
|
|
|
+ if (default_layouts == NULL) {
|
|
|
|
+ g_warning ("Your system seems not to support XKB.");
|
2011-08-06 15:54:54 +00:00
|
|
|
+ return NULL;
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2011-08-06 15:54:54 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return g_strjoinv (",", (gchar **) default_layouts);
|
2010-08-23 02:55:19 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+gchar *
|
|
|
|
+ibus_xkb_get_current_variant (void)
|
2010-08-23 02:55:19 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (default_variants == NULL) {
|
|
|
|
+ return NULL;
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
+ return g_strjoinv (",", (gchar **) default_variants);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+gchar *
|
|
|
|
+ibus_xkb_get_current_option (void)
|
|
|
|
+{
|
|
|
|
+ if (default_options == NULL) {
|
|
|
|
+ return NULL;
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return g_strjoinv (",", (gchar **) default_options);
|
2010-08-23 02:55:19 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+gboolean
|
|
|
|
+ibus_xkb_set_layout (const char *layouts,
|
|
|
|
+ const char *variants,
|
|
|
|
+ const char *options)
|
2010-08-23 02:55:19 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ Display *xdisplay;
|
|
|
|
+ gboolean retval;
|
|
|
|
+ gchar *layouts_line;
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (default_layouts == NULL) {
|
|
|
|
+ g_warning ("Your system seems not to support XKB.");
|
|
|
|
+ return FALSE;
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (layouts == NULL || g_strcmp0 (layouts, "default") == 0) {
|
|
|
|
+ layouts_line = g_strjoinv (",", (gchar **) default_layouts);
|
|
|
|
+ } else {
|
|
|
|
+ layouts_line = g_strdup (layouts);
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ xdisplay = get_xdisplay (NULL);
|
|
|
|
+ retval = set_xkb_rules (xdisplay,
|
|
|
|
+ "evdev", "evdev",
|
|
|
|
+ layouts_line, variants, options);
|
|
|
|
+ update_xkb_properties (xdisplay,
|
|
|
|
+ "evdev", "evdev",
|
|
|
|
+ layouts_line, variants, options);
|
|
|
|
+ g_free (layouts_line);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return retval;
|
2010-08-23 02:55:19 +00:00
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int
|
2012-02-04 01:13:28 +00:00
|
|
|
+ibus_xkb_get_current_group (void)
|
2010-08-23 02:55:19 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ Display *xdisplay = get_xdisplay (NULL);
|
|
|
|
+ XkbStateRec state;
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (default_layouts == NULL) {
|
|
|
|
+ g_warning ("Your system seems not to support XKB.");
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (xdisplay == NULL) {
|
|
|
|
+ g_warning ("ibus-xkb is not initialized.");
|
|
|
|
+ return 0;
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (XkbGetState (xdisplay, XkbUseCoreKbd, &state) != Success) {
|
|
|
|
+ g_warning ("Could not get state");
|
2010-08-23 02:55:19 +00:00
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return state.group;
|
2010-08-23 02:55:19 +00:00
|
|
|
+}
|
2012-02-04 01:13:28 +00:00
|
|
|
diff --git a/engine/xkblib.h b/engine/xkblib.h
|
2010-08-23 02:55:19 +00:00
|
|
|
new file mode 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
index 0000000..36597c3
|
2010-08-23 02:55:19 +00:00
|
|
|
--- /dev/null
|
2012-02-04 01:13:28 +00:00
|
|
|
+++ b/engine/xkblib.h
|
|
|
|
@@ -0,0 +1,41 @@
|
2010-10-06 02:10:04 +00:00
|
|
|
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
2010-08-23 02:55:19 +00:00
|
|
|
+/* vim:set et sts=4: */
|
|
|
|
+/* bus - The Input Bus
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * Copyright (C) 2012 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Red Hat, Inc.
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the
|
|
|
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
+ * Boston, MA 02111-1307, USA.
|
|
|
|
+ */
|
2012-02-04 01:13:28 +00:00
|
|
|
+#ifndef __XKBLIB_H_
|
|
|
|
+#define __XKBLIB_H_
|
|
|
|
+
|
|
|
|
+#include <X11/Xlib.h>
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2011-09-01 06:27:02 +00:00
|
|
|
+G_BEGIN_DECLS
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+void ibus_xkb_init (Display *xdisplay);
|
|
|
|
+void ibus_xkb_finit (void);
|
|
|
|
+gchar *ibus_xkb_get_current_layout (void);
|
|
|
|
+gchar *ibus_xkb_get_current_variant (void);
|
|
|
|
+gchar *ibus_xkb_get_current_option (void);
|
|
|
|
+gboolean ibus_xkb_set_layout (const char *layouts,
|
|
|
|
+ const char *variants,
|
|
|
|
+ const char *options);
|
|
|
|
+int ibus_xkb_get_current_group (void);
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
|
|
|
+G_END_DECLS
|
|
|
|
+#endif
|
2012-02-04 01:13:28 +00:00
|
|
|
diff --git a/ibus-1.0.pc.in b/ibus-1.0.pc.in
|
|
|
|
index 9f593ab..66b902a 100644
|
|
|
|
--- a/ibus-1.0.pc.in
|
|
|
|
+++ b/ibus-1.0.pc.in
|
|
|
|
@@ -1,9 +1,13 @@
|
|
|
|
prefix=@prefix@
|
|
|
|
exec_prefix=@exec_prefix@
|
|
|
|
libdir=@libdir@
|
|
|
|
+libexecdir=@libexecdir@
|
|
|
|
includedir=@includedir@
|
|
|
|
datadir=@datadir@
|
|
|
|
pkgdatadir=@datadir@/ibus
|
|
|
|
+have_ibus_xkb=@HAVE_IBUS_XKB@
|
|
|
|
+ibus_xkb=${libexecdir}/ibus-xkb
|
|
|
|
+have_ibus_gkbd=@HAVE_IBUS_GKBD@
|
|
|
|
|
|
|
|
Name: IBus
|
|
|
|
Description: IBus Library
|
|
|
|
diff --git a/setup/main.py b/setup/main.py
|
2012-04-28 06:13:40 +00:00
|
|
|
index fdfb33a..4f57106 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
--- a/setup/main.py
|
|
|
|
+++ b/setup/main.py
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -183,14 +183,22 @@ class Setup(object):
|
2012-02-04 01:13:28 +00:00
|
|
|
|
|
|
|
# init engine page
|
2012-03-18 09:41:41 +00:00
|
|
|
self.__engines = self.__bus.list_engines()
|
2012-02-04 01:13:28 +00:00
|
|
|
+ value = self.__config.get_value("general", "load_xkb_layouts")
|
|
|
|
+ load_layouts = []
|
|
|
|
+ if value != None:
|
2012-03-18 09:41:41 +00:00
|
|
|
+ load_layouts = value.dup_strv()[0]
|
2012-04-28 06:13:40 +00:00
|
|
|
+ engines = []
|
|
|
|
+ for engine in self.__engines:
|
|
|
|
+ if not engine.get_name().startswith('xkb:'):
|
|
|
|
+ engines.append(engine)
|
|
|
|
+ elif engine.get_layout() in load_layouts:
|
|
|
|
+ engines.append(engine)
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
self.__combobox = self.__builder.get_object("combobox_engines")
|
2012-03-18 09:41:41 +00:00
|
|
|
- self.__combobox.set_engines(self.__engines)
|
|
|
|
+ self.__combobox.set_engines(engines)
|
2012-02-04 01:13:28 +00:00
|
|
|
|
2012-03-18 09:41:41 +00:00
|
|
|
- tmp_dict = {}
|
2012-02-07 11:42:14 +00:00
|
|
|
- for e in self.__engines:
|
2012-03-18 09:41:41 +00:00
|
|
|
- tmp_dict[e.get_name()] = e
|
2012-02-07 11:42:14 +00:00
|
|
|
engine_names = values.get("preload_engines", [])
|
2012-03-18 09:41:41 +00:00
|
|
|
- engines = [tmp_dict[name] for name in engine_names if name in tmp_dict]
|
|
|
|
+ engines = self.__get_engine_descs_from_names(engine_names)
|
|
|
|
|
|
|
|
self.__treeview = self.__builder.get_object("treeview_engines")
|
|
|
|
self.__treeview.set_engines(engines)
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -263,6 +271,13 @@ class Setup(object):
|
2012-03-18 09:41:41 +00:00
|
|
|
args.append(path.basename(setup_path))
|
|
|
|
return args
|
|
|
|
|
|
|
|
+ def __get_engine_descs_from_names(self, engine_names):
|
|
|
|
+ tmp_dict = {}
|
|
|
|
+ for e in self.__engines:
|
|
|
|
+ tmp_dict[e.get_name()] = e
|
|
|
|
+ engines = [tmp_dict[name] for name in engine_names if name in tmp_dict]
|
|
|
|
+ return engines
|
|
|
|
+
|
|
|
|
def __treeview_notify_cb(self, treeview, prop):
|
|
|
|
if prop.name not in ("active-engine", "engines"):
|
|
|
|
return
|
2012-02-04 01:13:28 +00:00
|
|
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
2012-04-28 06:13:40 +00:00
|
|
|
index df4ada3..e249ada 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
--- a/src/Makefile.am
|
|
|
|
+++ b/src/Makefile.am
|
2012-03-18 09:41:41 +00:00
|
|
|
@@ -194,6 +194,11 @@ typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
|
2012-02-04 01:13:28 +00:00
|
|
|
CLEANFILES += $(dist_gir_DATA) $(typelibs_DATA)
|
|
|
|
endif
|
|
|
|
|
|
|
|
+if ENABLE_XKB
|
|
|
|
+ibus_sources += ibusxkbxml.c
|
|
|
|
+ibus_headers += ibusxkbxml.h
|
|
|
|
+endif
|
|
|
|
+
|
|
|
|
# gen enum types
|
|
|
|
ibusenumtypes.h: $(ibus_headers) ibusenumtypes.h.template
|
|
|
|
$(AM_V_GEN) ( top_builddir=`cd $(top_builddir) && pwd`; \
|
|
|
|
diff --git a/src/ibus.h b/src/ibus.h
|
|
|
|
index ef811a4..f82a162 100644
|
|
|
|
--- a/src/ibus.h
|
|
|
|
+++ b/src/ibus.h
|
|
|
|
@@ -47,6 +47,7 @@
|
|
|
|
#include <ibuskeys.h>
|
|
|
|
#include <ibusenumtypes.h>
|
|
|
|
#include <ibushotkey.h>
|
|
|
|
+#include <ibusxkbxml.h>
|
|
|
|
#include <ibusxml.h>
|
|
|
|
#include <ibusenginedesc.h>
|
|
|
|
#include <ibusobservedpath.h>
|
|
|
|
diff --git a/src/ibusxkbxml.c b/src/ibusxkbxml.c
|
2011-09-01 06:27:02 +00:00
|
|
|
new file mode 100644
|
2012-03-04 13:45:32 +00:00
|
|
|
index 0000000..4792664
|
2011-09-01 06:27:02 +00:00
|
|
|
--- /dev/null
|
2012-02-04 01:13:28 +00:00
|
|
|
+++ b/src/ibusxkbxml.c
|
2012-03-04 13:45:32 +00:00
|
|
|
@@ -0,0 +1,466 @@
|
2011-09-01 06:27:02 +00:00
|
|
|
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
|
|
+/* vim:set et sts=4: */
|
2012-02-04 01:13:28 +00:00
|
|
|
+/* bus - The Input Bus
|
|
|
|
+ * Copyright (C) 2012 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Red Hat, Inc.
|
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the
|
|
|
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
+ * Boston, MA 02111-1307, USA.
|
|
|
|
+ */
|
2010-08-23 02:55:19 +00:00
|
|
|
+#ifdef HAVE_CONFIG_H
|
2012-02-04 01:13:28 +00:00
|
|
|
+#include <config.h>
|
2011-09-01 06:27:02 +00:00
|
|
|
+#endif
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#include <glib.h>
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#include "ibus.h"
|
|
|
|
+#include "ibusxkbxml.h"
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#ifndef XKB_RULES_XML_FILE
|
|
|
|
+#define XKB_RULES_XML_FILE "/usr/share/X11/xkb/rules/evdev.xml"
|
|
|
|
+#endif
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#define IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE(o) \
|
|
|
|
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryPrivate))
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+typedef struct _IBusXKBConfigRegistryPrivate IBusXKBConfigRegistryPrivate;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+struct _IBusXKBConfigRegistryPrivate {
|
|
|
|
+ GHashTable *layout_list;
|
|
|
|
+ GHashTable *layout_lang;
|
|
|
|
+ GHashTable *layout_desc;
|
|
|
|
+ GHashTable *variant_desc;
|
2011-09-01 06:27:02 +00:00
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/* functions prototype */
|
2012-02-04 01:13:28 +00:00
|
|
|
+static void ibus_xkb_config_registry_destroy
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config);
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+G_DEFINE_TYPE (IBusXKBConfigRegistry, ibus_xkb_config_registry, IBUS_TYPE_OBJECT)
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
|
|
|
+static void
|
2012-02-04 01:13:28 +00:00
|
|
|
+parse_xkb_xml_languagelist_node (IBusXKBConfigRegistryPrivate *priv,
|
|
|
|
+ XMLNode *parent_node,
|
|
|
|
+ const gchar *layout_name)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ XMLNode *node = parent_node;
|
|
|
|
+ XMLNode *sub_node;
|
|
|
|
+ GList *p;
|
|
|
|
+ GList *lang_list = NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_assert (node != NULL);
|
|
|
|
+ g_assert (layout_name != NULL);
|
|
|
|
+ for (p = node->sub_nodes; p; p = p->next) {
|
|
|
|
+ sub_node = (XMLNode *) p->data;
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "iso639Id") == 0) {
|
|
|
|
+ lang_list = g_list_append (lang_list,
|
|
|
|
+ (gpointer) g_strdup (sub_node->text));
|
|
|
|
+ continue;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ }
|
|
|
|
+ if (lang_list == NULL) {
|
|
|
|
+ /* some nodes have no lang */
|
2011-09-01 06:27:02 +00:00
|
|
|
+ return;
|
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (g_hash_table_lookup (priv->layout_lang, layout_name) != NULL) {
|
|
|
|
+ g_warning ("duplicated name %s exists", layout_name);
|
|
|
|
+ return;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_hash_table_insert (priv->layout_lang,
|
|
|
|
+ (gpointer) g_strdup (layout_name),
|
|
|
|
+ (gpointer) lang_list);
|
2011-09-01 06:27:02 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static const gchar *
|
|
|
|
+parse_xkb_xml_configitem_node (IBusXKBConfigRegistryPrivate *priv,
|
|
|
|
+ XMLNode *parent_node)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ XMLNode *node = parent_node;
|
|
|
|
+ XMLNode *sub_node;
|
|
|
|
+ GList *p;
|
|
|
|
+ gchar *name = NULL;
|
|
|
|
+ gchar *description = NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_assert (node != NULL);
|
|
|
|
+ for (p = node->sub_nodes; p; p = p->next) {
|
|
|
|
+ sub_node = (XMLNode *) p->data;
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "name") == 0) {
|
|
|
|
+ name = sub_node->text;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "description") == 0) {
|
|
|
|
+ description = sub_node->text;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "languageList") == 0) {
|
|
|
|
+ if (name == NULL) {
|
|
|
|
+ g_warning ("layout name is NULL in node %s", node->name);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ parse_xkb_xml_languagelist_node (priv, sub_node, name);
|
|
|
|
+ continue;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (name == NULL) {
|
|
|
|
+ g_warning ("No name in layout node");
|
|
|
|
+ return NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (g_hash_table_lookup (priv->layout_desc, name) != NULL) {
|
|
|
|
+ g_warning ("duplicated name %s exists", name);
|
|
|
|
+ return name;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_hash_table_insert (priv->layout_desc,
|
|
|
|
+ (gpointer) g_strdup (name),
|
|
|
|
+ (gpointer) g_strdup (description));
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return name;
|
|
|
|
+}
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static const gchar *
|
|
|
|
+parse_xkb_xml_variant_configitem_node (IBusXKBConfigRegistryPrivate *priv,
|
|
|
|
+ XMLNode *parent_node,
|
|
|
|
+ const gchar *layout_name)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ XMLNode *node = parent_node;
|
|
|
|
+ XMLNode *sub_node;
|
|
|
|
+ GList *p;
|
|
|
|
+ gchar *name = NULL;
|
|
|
|
+ gchar *description = NULL;
|
|
|
|
+ gchar *variant_lang_name = NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_assert (node != NULL);
|
|
|
|
+ g_assert (layout_name != NULL);
|
|
|
|
+ for (p = node->sub_nodes; p; p = p->next) {
|
|
|
|
+ sub_node = (XMLNode *) p->data;
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "name") == 0) {
|
|
|
|
+ name = sub_node->text;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "description") == 0) {
|
|
|
|
+ description = sub_node->text;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "languageList") == 0) {
|
|
|
|
+ if (name == NULL) {
|
|
|
|
+ g_warning ("layout name is NULL in node %s", node->name);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ variant_lang_name = g_strdup_printf ("%s(%s)", layout_name, name);
|
|
|
|
+ parse_xkb_xml_languagelist_node (priv, sub_node, variant_lang_name);
|
|
|
|
+ g_free (variant_lang_name);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (name == NULL) {
|
|
|
|
+ g_warning ("No name in layout node");
|
|
|
|
+ return NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (g_hash_table_lookup (priv->variant_desc, name) != NULL) {
|
|
|
|
+ /* This is an expected case. */
|
|
|
|
+ return name;
|
|
|
|
+ }
|
|
|
|
+ variant_lang_name = g_strdup_printf ("%s(%s)", layout_name, name);
|
|
|
|
+ g_hash_table_insert (priv->variant_desc,
|
|
|
|
+ (gpointer) variant_lang_name,
|
|
|
|
+ (gpointer) g_strdup (description));
|
|
|
|
+ return name;
|
2011-09-01 06:27:02 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static const gchar *
|
|
|
|
+parse_xkb_xml_variant_node (IBusXKBConfigRegistryPrivate *priv,
|
|
|
|
+ XMLNode *parent_node,
|
|
|
|
+ const gchar *layout_name)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ XMLNode *node = parent_node;
|
|
|
|
+ XMLNode *sub_node;
|
|
|
|
+ GList *p;
|
|
|
|
+ const gchar *variant_name = NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_assert (node != NULL);
|
|
|
|
+ g_assert (layout_name != NULL);
|
|
|
|
+ for (p = node->sub_nodes; p; p = p->next) {
|
|
|
|
+ sub_node = (XMLNode *) p->data;
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "configItem") == 0) {
|
|
|
|
+ variant_name = parse_xkb_xml_variant_configitem_node (priv, sub_node, layout_name);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return variant_name;
|
2011-09-01 06:27:02 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static GList *
|
|
|
|
+parse_xkb_xml_variantlist_node (IBusXKBConfigRegistryPrivate *priv,
|
|
|
|
+ XMLNode *parent_node,
|
|
|
|
+ const gchar *layout_name,
|
|
|
|
+ GList *variant_list)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ XMLNode *node = parent_node;
|
|
|
|
+ XMLNode *sub_node;
|
|
|
|
+ GList *p;
|
|
|
|
+ const gchar *variant_name = NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_assert (node != NULL);
|
|
|
|
+ g_assert (layout_name != NULL);
|
|
|
|
+ for (p = node->sub_nodes; p; p = p->next) {
|
|
|
|
+ sub_node = (XMLNode *) p->data;
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "variant") == 0) {
|
|
|
|
+ variant_name = parse_xkb_xml_variant_node (priv, sub_node, layout_name);
|
|
|
|
+ if (variant_name != NULL) {
|
|
|
|
+ variant_list = g_list_append (variant_list,
|
|
|
|
+ (gpointer) g_strdup (variant_name));
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ continue;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return variant_list;
|
2011-09-01 06:27:02 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static void
|
|
|
|
+parse_xkb_xml_layout_node (IBusXKBConfigRegistryPrivate *priv,
|
|
|
|
+ XMLNode *parent_node)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ XMLNode *node = parent_node;
|
|
|
|
+ XMLNode *sub_node;
|
|
|
|
+ GList *p;
|
|
|
|
+ const gchar *name = NULL;
|
|
|
|
+ GList *variant_list = NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_assert (node != NULL);
|
|
|
|
+ for (p = node->sub_nodes; p; p = p->next) {
|
|
|
|
+ sub_node = (XMLNode *) p->data;
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "configItem") == 0) {
|
|
|
|
+ name = parse_xkb_xml_configitem_node (priv, sub_node);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "variantList") == 0) {
|
|
|
|
+ if (name == NULL) {
|
|
|
|
+ g_warning ("layout name is NULL in node %s", node->name);
|
|
|
|
+ continue;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ variant_list = parse_xkb_xml_variantlist_node (priv, sub_node,
|
|
|
|
+ name,
|
|
|
|
+ variant_list);
|
|
|
|
+ continue;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (g_hash_table_lookup (priv->layout_list, name) != NULL) {
|
|
|
|
+ g_warning ("duplicated name %s exists", name);
|
|
|
|
+ return;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_hash_table_insert (priv->layout_list,
|
|
|
|
+ (gpointer) g_strdup (name),
|
|
|
|
+ (gpointer) variant_list);
|
2011-09-01 06:27:02 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static void
|
|
|
|
+parse_xkb_xml_top_node (IBusXKBConfigRegistryPrivate *priv,
|
|
|
|
+ XMLNode *parent_node)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ XMLNode *node = parent_node;
|
|
|
|
+ XMLNode *sub_node;
|
|
|
|
+ GList *p;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_assert (priv != NULL);
|
|
|
|
+ g_assert (node != NULL);
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (g_strcmp0 (node->name, "xkbConfigRegistry") != 0) {
|
|
|
|
+ g_warning ("node has no xkbConfigRegistry name");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (p = node->sub_nodes; p; p = p->next) {
|
|
|
|
+ sub_node = (XMLNode *) p->data;
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "layoutList") == 0) {
|
|
|
|
+ break;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ }
|
|
|
|
+ if (p == NULL) {
|
|
|
|
+ g_warning ("xkbConfigRegistry node has no layoutList node");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ node = sub_node;
|
|
|
|
+ for (p = node->sub_nodes; p; p = p->next) {
|
|
|
|
+ sub_node = (XMLNode *) p->data;
|
|
|
|
+ if (g_strcmp0 (sub_node->name, "layout") == 0) {
|
|
|
|
+ parse_xkb_xml_layout_node (priv, sub_node);
|
|
|
|
+ continue;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static void
|
|
|
|
+free_lang_list (GList *list)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ GList *l = list;
|
|
|
|
+ while (l) {
|
|
|
|
+ g_free (l->data);
|
|
|
|
+ l->data = NULL;
|
|
|
|
+ l = l->next;
|
2011-09-01 06:27:02 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_list_free (list);
|
2011-09-01 06:27:02 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static void
|
|
|
|
+parse_xkb_config_registry_file (IBusXKBConfigRegistryPrivate *priv,
|
|
|
|
+ const gchar *file)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ XMLNode *node;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_assert (file != NULL);
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ priv->layout_list = g_hash_table_new_full (g_str_hash,
|
|
|
|
+ (GEqualFunc) g_str_equal,
|
|
|
|
+ (GDestroyNotify) g_free,
|
|
|
|
+ (GDestroyNotify) free_lang_list);
|
|
|
|
+ priv->layout_desc = g_hash_table_new_full (g_str_hash,
|
|
|
|
+ (GEqualFunc) g_str_equal,
|
|
|
|
+ (GDestroyNotify) g_free,
|
|
|
|
+ (GDestroyNotify) g_free);
|
|
|
|
+ priv->layout_lang = g_hash_table_new_full (g_str_hash,
|
|
|
|
+ (GEqualFunc) g_str_equal,
|
|
|
|
+ (GDestroyNotify) g_free,
|
|
|
|
+ (GDestroyNotify) free_lang_list);
|
|
|
|
+ priv->variant_desc = g_hash_table_new_full (g_str_hash,
|
|
|
|
+ (GEqualFunc) g_str_equal,
|
|
|
|
+ (GDestroyNotify) g_free,
|
|
|
|
+ (GDestroyNotify) g_free);
|
|
|
|
+ node = ibus_xml_parse_file (file);
|
|
|
|
+ parse_xkb_xml_top_node (priv, node);
|
|
|
|
+ ibus_xml_free (node);
|
2011-09-01 06:27:02 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static void
|
|
|
|
+ibus_xkb_config_registry_init (IBusXKBConfigRegistry *xkb_config)
|
2011-09-01 06:27:02 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ IBusXKBConfigRegistryPrivate *priv;
|
|
|
|
+ const gchar *file = XKB_RULES_XML_FILE;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config);
|
|
|
|
+ parse_xkb_config_registry_file (priv, file);
|
|
|
|
+}
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static void
|
|
|
|
+ibus_xkb_config_registry_destroy (IBusXKBConfigRegistry *xkb_config)
|
|
|
|
+{
|
|
|
|
+ IBusXKBConfigRegistryPrivate *priv;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_return_if_fail (xkb_config != NULL);
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config);
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_hash_table_destroy (priv->layout_list);
|
|
|
|
+ priv->layout_list = NULL;
|
|
|
|
+ g_hash_table_destroy (priv->layout_lang);
|
|
|
|
+ priv->layout_lang= NULL;
|
|
|
|
+ g_hash_table_destroy (priv->layout_desc);
|
|
|
|
+ priv->layout_desc= NULL;
|
|
|
|
+ g_hash_table_destroy (priv->variant_desc);
|
|
|
|
+ priv->variant_desc = NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ IBUS_OBJECT_CLASS(ibus_xkb_config_registry_parent_class)->destroy (IBUS_OBJECT (xkb_config));
|
|
|
|
+}
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+static void
|
|
|
|
+ibus_xkb_config_registry_class_init (IBusXKBConfigRegistryClass *klass)
|
|
|
|
+{
|
|
|
|
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ g_type_class_add_private (klass, sizeof (IBusXKBConfigRegistryPrivate));
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_xkb_config_registry_destroy;
|
|
|
|
+}
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+IBusXKBConfigRegistry *
|
|
|
|
+ibus_xkb_config_registry_new (void)
|
|
|
|
+{
|
|
|
|
+ IBusXKBConfigRegistry *xkb_config;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ xkb_config = IBUS_XKB_CONFIG_REGISTRY (g_object_new (IBUS_TYPE_XKB_CONFIG_REGISTRY, NULL));
|
|
|
|
+ return xkb_config;
|
|
|
|
+}
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#define TABLE_FUNC(field_name) const GHashTable * \
|
|
|
|
+ibus_xkb_config_registry_get_##field_name (IBusXKBConfigRegistry *xkb_config) \
|
|
|
|
+{ \
|
|
|
|
+ IBusXKBConfigRegistryPrivate *priv; \
|
|
|
|
+ \
|
|
|
|
+ g_return_val_if_fail (xkb_config != NULL, NULL); \
|
|
|
|
+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); \
|
|
|
|
+ return priv->field_name; \
|
|
|
|
+}
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+TABLE_FUNC (layout_list)
|
|
|
|
+TABLE_FUNC (layout_lang)
|
|
|
|
+TABLE_FUNC (layout_desc)
|
|
|
|
+TABLE_FUNC (variant_desc)
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#undef TABLE_FUNC
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+GList *
|
|
|
|
+ibus_xkb_config_registry_layout_list_get_layouts (IBusXKBConfigRegistry *xkb_config)
|
|
|
|
+{
|
|
|
|
+ GHashTable *table;
|
|
|
|
+ GList *list = NULL;
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ table = (GHashTable *)
|
|
|
|
+ ibus_xkb_config_registry_get_layout_list (xkb_config);
|
|
|
|
+ list = (GList *) g_hash_table_get_keys (table);
|
|
|
|
+ return list;
|
2011-09-01 06:27:02 +00:00
|
|
|
+}
|
|
|
|
+
|
2012-03-04 13:45:32 +00:00
|
|
|
+/* vala could use GLib.List<string> for the returned pointer and
|
|
|
|
+ * the declaration calls g_list_foreach (retval, g_free, NULL).
|
|
|
|
+ * When I think about GLib.List<string> v.s. GLib.List, probably
|
|
|
|
+ * I think GLib.List<string> is better for the function and set
|
|
|
|
+ * g_strdup() here. I do not know about GJS implementation.
|
|
|
|
+ */
|
2012-02-04 01:13:28 +00:00
|
|
|
+#define TABLE_LOOKUP_LIST_FUNC(field_name, value) GList * \
|
|
|
|
+ibus_xkb_config_registry_##field_name##_get_##value (IBusXKBConfigRegistry *xkb_config, const gchar *key) \
|
|
|
|
+{ \
|
|
|
|
+ GHashTable *table; \
|
|
|
|
+ GList *list = NULL; \
|
2012-03-04 13:45:32 +00:00
|
|
|
+ GList *retval= NULL; \
|
|
|
|
+ GList *p = NULL; \
|
2012-02-04 01:13:28 +00:00
|
|
|
+ \
|
|
|
|
+ table = (GHashTable *) \
|
|
|
|
+ ibus_xkb_config_registry_get_##field_name (xkb_config); \
|
|
|
|
+ list = (GList *) g_hash_table_lookup (table, key); \
|
2012-03-04 13:45:32 +00:00
|
|
|
+ retval = g_list_copy (list); \
|
|
|
|
+ for (p = retval; p; p = p->next) { \
|
|
|
|
+ p->data = g_strdup (p->data); \
|
|
|
|
+ } \
|
|
|
|
+ return retval; \
|
2012-02-04 01:13:28 +00:00
|
|
|
+}
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#define TABLE_LOOKUP_STRING_FUNC(field_name, value) gchar * \
|
|
|
|
+ibus_xkb_config_registry_##field_name##_get_##value (IBusXKBConfigRegistry *xkb_config, const gchar *key) \
|
|
|
|
+{ \
|
|
|
|
+ GHashTable *table; \
|
|
|
|
+ const gchar *desc = NULL; \
|
|
|
|
+ \
|
|
|
|
+ table = (GHashTable *) \
|
|
|
|
+ ibus_xkb_config_registry_get_##field_name (xkb_config); \
|
|
|
|
+ desc = (const gchar *) g_hash_table_lookup (table, key); \
|
|
|
|
+ return g_strdup (desc); \
|
|
|
|
+}
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+TABLE_LOOKUP_LIST_FUNC (layout_list, variants)
|
|
|
|
+TABLE_LOOKUP_LIST_FUNC (layout_lang, langs)
|
|
|
|
+TABLE_LOOKUP_STRING_FUNC (layout_desc, desc)
|
|
|
|
+TABLE_LOOKUP_STRING_FUNC (variant_desc, desc)
|
2011-09-01 06:27:02 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#undef TABLE_LOOKUP_LIST_FUNC
|
|
|
|
+#undef TABLE_LOOKUP_STRING_FUNC
|
|
|
|
diff --git a/src/ibusxkbxml.h b/src/ibusxkbxml.h
|
2010-08-23 02:55:19 +00:00
|
|
|
new file mode 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
index 0000000..6f5b7bd
|
2010-08-23 02:55:19 +00:00
|
|
|
--- /dev/null
|
2012-02-04 01:13:28 +00:00
|
|
|
+++ b/src/ibusxkbxml.h
|
|
|
|
@@ -0,0 +1,187 @@
|
2010-10-06 02:10:04 +00:00
|
|
|
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
2010-08-23 02:55:19 +00:00
|
|
|
+/* vim:set et sts=4: */
|
|
|
|
+/* bus - The Input Bus
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * Copyright (C) 2012 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
|
+ * Copyright (C) 2012 Red Hat, Inc.
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the
|
|
|
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
+ * Boston, MA 02111-1307, USA.
|
|
|
|
+ */
|
2012-02-04 01:13:28 +00:00
|
|
|
+#ifndef __IBUS_XKBXML_H_
|
|
|
|
+#define __IBUS_XKBXML_H_
|
|
|
|
+
|
|
|
|
+#if !defined (__IBUS_H_INSIDE__) && !defined (IBUS_COMPILATION)
|
|
|
|
+#error "Only <ibus.h> can be included directly"
|
2010-08-23 02:55:19 +00:00
|
|
|
+#endif
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+#include "ibus.h"
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Type macros.
|
|
|
|
+ */
|
|
|
|
+/* define IBusXKBConfigRegistry macros */
|
|
|
|
+#define IBUS_TYPE_XKB_CONFIG_REGISTRY \
|
|
|
|
+ (ibus_xkb_config_registry_get_type ())
|
|
|
|
+#define IBUS_XKB_CONFIG_REGISTRY(obj) \
|
|
|
|
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistry))
|
|
|
|
+#define IBUS_XKB_CONFIG_REGISTRY_CLASS(klass) \
|
|
|
|
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryClass))
|
|
|
|
+#define IBUS_IS_XKB_CONFIG_REGISTRY(obj) \
|
|
|
|
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY))
|
|
|
|
+#define IBUS_IS_XKB_CONFIG_REGISTRY_CLASS(klass) \
|
|
|
|
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_XKB_CONFIG_REGISTRY))
|
|
|
|
+#define IBUS_XKB_CONFIG_REGISTRY_GET_CLASS(obj) \
|
|
|
|
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryClass))
|
|
|
|
+
|
|
|
|
+G_BEGIN_DECLS
|
|
|
|
+
|
|
|
|
+typedef struct _IBusXKBConfigRegistry IBusXKBConfigRegistry;
|
|
|
|
+typedef struct _IBusXKBConfigRegistryClass IBusXKBConfigRegistryClass;
|
|
|
|
+
|
|
|
|
+struct _IBusXKBConfigRegistry {
|
|
|
|
+ IBusObject parent;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+struct _IBusXKBConfigRegistryClass {
|
|
|
|
+ IBusObjectClass parent;
|
|
|
|
+ /* signals */
|
|
|
|
+ /*< private >*/
|
|
|
|
+ /* padding */
|
|
|
|
+ gpointer pdummy[8];
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+GType ibus_xkb_config_registry_get_type
|
|
|
|
+ (void);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_new:
|
|
|
|
+ * @returns: A newly allocated IBusXKBConfigRegistry
|
|
|
|
+ *
|
|
|
|
+ * New an IBusXKBConfigRegistry.
|
|
|
|
+ */
|
|
|
|
+IBusXKBConfigRegistry *
|
|
|
|
+ ibus_xkb_config_registry_new
|
|
|
|
+ (void);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_get_layout_list: (skip)
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @returns: A const GHashTable
|
|
|
|
+ *
|
|
|
|
+ * a const GHashTable
|
|
|
|
+ */
|
|
|
|
+const GHashTable *
|
|
|
|
+ ibus_xkb_config_registry_get_layout_list
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_get_layout_lang: (skip)
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @returns: A const GHashTable
|
|
|
|
+ *
|
|
|
|
+ * a const GHashTable
|
|
|
|
+ */
|
|
|
|
+const GHashTable *
|
|
|
|
+ ibus_xkb_config_registry_get_layout_lang
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_get_layout_desc: (skip)
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @returns: A const GHashTable
|
|
|
|
+ *
|
|
|
|
+ * a const GHashTable
|
|
|
|
+ */
|
|
|
|
+const GHashTable *
|
|
|
|
+ ibus_xkb_config_registry_get_layout_desc
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_get_variant_desc: (skip)
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @returns: A const GHashTable
|
|
|
|
+ *
|
|
|
|
+ * a const GHashTable
|
|
|
|
+ */
|
|
|
|
+const GHashTable *
|
|
|
|
+ ibus_xkb_config_registry_get_variant_desc
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_layout_list_get_layouts:
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @returns: (transfer container) (element-type utf8): A GList of layouts
|
|
|
|
+ *
|
|
|
|
+ * a GList of layouts
|
|
|
|
+ */
|
|
|
|
+GList *
|
|
|
|
+ ibus_xkb_config_registry_layout_list_get_layouts
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_layout_list_get_variants:
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @layout: A layout.
|
|
|
|
+ * @returns: (transfer container) (element-type utf8): A GList
|
|
|
|
+ *
|
|
|
|
+ * a GList
|
|
|
|
+ */
|
|
|
|
+GList *
|
|
|
|
+ ibus_xkb_config_registry_layout_list_get_variants
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config,
|
|
|
|
+ const gchar *layout);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_layout_lang_get_langs:
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @layout: A layout.
|
|
|
|
+ * @returns: (transfer container) (element-type utf8): A GList
|
|
|
|
+ *
|
|
|
|
+ * a GList
|
|
|
|
+ */
|
|
|
|
+GList *
|
|
|
|
+ ibus_xkb_config_registry_layout_lang_get_langs
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config,
|
|
|
|
+ const gchar *layout);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_layout_desc_get_desc:
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @layout: A layout.
|
|
|
|
+ * @returns: A layout description
|
|
|
|
+ *
|
|
|
|
+ * a layout description
|
|
|
|
+ */
|
|
|
|
+gchar *
|
|
|
|
+ ibus_xkb_config_registry_layout_desc_get_desc
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config,
|
|
|
|
+ const gchar *layout);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+/**
|
|
|
|
+ * ibus_xkb_config_registry_variant_desc_get_desc:
|
|
|
|
+ * @xkb_config: An IBusXKBConfigRegistry.
|
|
|
|
+ * @variant: A variant.
|
|
|
|
+ * @returns: A variant description
|
|
|
|
+ *
|
|
|
|
+ * a variant description
|
|
|
|
+ */
|
|
|
|
+gchar *
|
|
|
|
+ ibus_xkb_config_registry_variant_desc_get_desc
|
|
|
|
+ (IBusXKBConfigRegistry *xkb_config,
|
|
|
|
+ const gchar *variant);
|
|
|
|
+G_END_DECLS
|
2010-08-23 02:55:19 +00:00
|
|
|
+#endif
|
2012-02-04 01:13:28 +00:00
|
|
|
diff --git a/ui/gtk3/Gkbd-3.0.metadata b/ui/gtk3/Gkbd-3.0.metadata
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..661e6fd
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/ui/gtk3/Gkbd-3.0.metadata
|
|
|
|
@@ -0,0 +1 @@
|
|
|
|
+Configuration cheader_filename="libgnomekbd/gkbd-configuration.h"
|
|
|
|
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
|
2012-04-28 06:13:40 +00:00
|
|
|
index 87a7373..6a426fa 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
--- a/ui/gtk3/Makefile.am
|
|
|
|
+++ b/ui/gtk3/Makefile.am
|
|
|
|
@@ -42,6 +42,9 @@ INCLUDES = \
|
|
|
|
-I$(top_builddir)/src \
|
|
|
|
$(NULL)
|
|
|
|
|
|
|
|
+HAVE_IBUS_XKB_C = $(strip $(subst false, FALSE, $(subst true, TRUE, $(HAVE_IBUS_XKB))))
|
|
|
|
+HAVE_IBUS_GKBD_C = $(strip $(subst false, FALSE, $(subst true, TRUE, $(HAVE_IBUS_GKBD))))
|
|
|
|
+
|
|
|
|
AM_CFLAGS = \
|
|
|
|
@GLIB2_CFLAGS@ \
|
|
|
|
@GIO2_CFLAGS@ \
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -57,6 +60,10 @@ AM_CFLAGS = \
|
2012-02-04 01:13:28 +00:00
|
|
|
-DBINDIR=\"@bindir@\" \
|
|
|
|
-DIBUS_DISABLE_DEPRECATED \
|
|
|
|
-DIBUS_VERSION=\"@IBUS_VERSION@\" \
|
|
|
|
+ -DHAVE_IBUS_XKB=$(HAVE_IBUS_XKB_C) \
|
|
|
|
+ -DHAVE_IBUS_GKBD=$(HAVE_IBUS_GKBD_C) \
|
|
|
|
+ -DIBUS_XKB_COMMAND=\"$(libexecdir)/ibus-xkb\" \
|
|
|
|
+ -DXKB_LAYOUTS_MAX_LENGTH=4 \
|
|
|
|
-Wno-unused-variable \
|
|
|
|
-Wno-unused-but-set-variable \
|
|
|
|
-Wno-unused-function \
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -87,6 +94,7 @@ ibus_ui_gtk3_SOURCES = \
|
2012-02-04 01:13:28 +00:00
|
|
|
application.vala \
|
|
|
|
candidatearea.vala \
|
|
|
|
candidatepanel.vala \
|
|
|
|
+ gkbdlayout.vala \
|
|
|
|
handle.vala \
|
|
|
|
iconwidget.vala \
|
|
|
|
keybindingmanager.vala \
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -95,6 +103,7 @@ ibus_ui_gtk3_SOURCES = \
|
2012-02-04 01:13:28 +00:00
|
|
|
property.vala \
|
|
|
|
separator.vala \
|
|
|
|
switcher.vala \
|
|
|
|
+ xkblayout.vala \
|
2012-03-18 09:41:41 +00:00
|
|
|
grabkeycode.c \
|
2012-02-04 01:13:28 +00:00
|
|
|
$(NULL)
|
|
|
|
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -102,12 +111,51 @@ ibus_ui_gtk3_LDADD = \
|
2012-02-04 01:13:28 +00:00
|
|
|
$(AM_LDADD) \
|
|
|
|
$(NULL)
|
|
|
|
|
|
|
|
+if ENABLE_LIBGNOMEKBD
|
|
|
|
+AM_CFLAGS += \
|
|
|
|
+ @LIBGNOMEKBDUI_CFLAGS@ \
|
|
|
|
+ @ATK_CFLAGS@ \
|
|
|
|
+ $(NULL)
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+AM_LDADD += \
|
|
|
|
+ @LIBGNOMEKBDUI_LIBS@ \
|
|
|
|
+ @ATK_LIBS@ \
|
|
|
|
+ $(NULL)
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+AM_VALAFLAGS += \
|
|
|
|
+ --vapidir=. \
|
2012-03-18 09:41:41 +00:00
|
|
|
+ --metadatadir=. \
|
2012-02-04 01:13:28 +00:00
|
|
|
+ --pkg=glib-2.0 \
|
|
|
|
+ --pkg=gmodule-2.0 \
|
|
|
|
+ --pkg=gkbd \
|
2012-03-18 09:41:41 +00:00
|
|
|
+ --pkg=Xkl-1.0 \
|
2012-02-04 01:13:28 +00:00
|
|
|
+ $(NULL)
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+$(srcdir)/gkbd.vapi:
|
|
|
|
+ $(VAPIGEN) --metadatadir . --library gkbd \
|
|
|
|
+ --pkg gtk+-3.0 --pkg glib-2.0 --pkg gmodule-2.0 \
|
|
|
|
+ /usr/share/gir-1.0/Gkbd-3.0.gir
|
|
|
|
+ $(NULL)
|
2010-09-14 11:20:08 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+$(srcdir)/gkbdlayout.vala: $(srcdir)/gkbd.vapi
|
|
|
|
+ @cp $(srcdir)/gkbdlayout.vala.true $(srcdir)/gkbdlayout.vala
|
|
|
|
+else
|
|
|
|
+$(srcdir)/gkbdlayout.vala:
|
|
|
|
+ @cp $(srcdir)/gkbdlayout.vala.false $(srcdir)/gkbdlayout.vala
|
|
|
|
+endif
|
2010-09-14 11:20:08 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
CLEANFILES = \
|
|
|
|
+ gkbd.vapi \
|
|
|
|
+ gkbdlayout.vala \
|
|
|
|
gtkpanel.xml \
|
|
|
|
$(NULL)
|
|
|
|
|
|
|
|
EXTRA_DIST = \
|
|
|
|
+ Gkbd-3.0.metadata \
|
|
|
|
+ gkbdlayout.vala.false \
|
|
|
|
+ gkbdlayout.vala.true \
|
|
|
|
gtkpanel.xml.in.in \
|
2012-03-18 09:41:41 +00:00
|
|
|
+ Xkl-1.0.metadata \
|
2012-02-04 01:13:28 +00:00
|
|
|
$(NULL)
|
|
|
|
|
2012-03-18 09:41:41 +00:00
|
|
|
|
|
|
|
diff --git a/ui/gtk3/Xkl-1.0.metadata b/ui/gtk3/Xkl-1.0.metadata
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..4961d0c
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/ui/gtk3/Xkl-1.0.metadata
|
|
|
|
@@ -0,0 +1,3 @@
|
|
|
|
+Xkl cheader_filename="libxklavier/xklavier.h"
|
|
|
|
+Engine
|
|
|
|
+ .filter_events.evt ref type="X.Event"
|
2012-02-04 01:13:28 +00:00
|
|
|
diff --git a/ui/gtk3/gkbdlayout.vala.false b/ui/gtk3/gkbdlayout.vala.false
|
2010-08-23 02:55:19 +00:00
|
|
|
new file mode 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
index 0000000..a387de9
|
2010-08-23 02:55:19 +00:00
|
|
|
--- /dev/null
|
2012-02-04 01:13:28 +00:00
|
|
|
+++ b/ui/gtk3/gkbdlayout.vala.false
|
|
|
|
@@ -0,0 +1,63 @@
|
|
|
|
+/* vim:set et sts=4 sw=4:
|
|
|
|
+ *
|
|
|
|
+ * ibus - The Input Bus
|
|
|
|
+ *
|
|
|
|
+ * Copyright 2012 Red Hat, Inc.
|
|
|
|
+ * Copyright(c) 2012 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
|
+ * Copyright(c) 2012 Takao Fujiwara <tfujiwar@redhat.com>
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * version 2 of the License, or(at your option) any later version.
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+ * GNU Lesser General Public License for more details.
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * License along with this program; if not, write to the
|
|
|
|
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
|
|
+ * Boston, MA 02111-1307 USA
|
2010-08-23 02:55:19 +00:00
|
|
|
+ */
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+public class GkbdLayout
|
2010-08-23 02:55:19 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public signal void changed();
|
|
|
|
+ public signal void group_changed (int object);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public GkbdLayout() {
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2011-03-10 09:07:52 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public string[] get_layouts() {
|
|
|
|
+ return new string[0];
|
2011-03-10 09:07:52 +00:00
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public string[] get_group_names() {
|
|
|
|
+ return new string[0];
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public void lock_group(int id) {
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public void start_listen() {
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public void stop_listen() {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ public static int main(string[] args) {
|
|
|
|
+ GkbdLayout ibus_layouts = new GkbdLayout();
|
|
|
|
+
|
|
|
|
+ string[] layouts = ibus_layouts.get_layouts();
|
|
|
|
+ string[] names = ibus_layouts.get_group_names();
|
|
|
|
+ for (int i = 0; layouts != null && i < layouts.length; i++) {
|
|
|
|
+ stdout.printf("%s %s\n", layouts[i], names[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ */
|
2010-08-23 02:55:19 +00:00
|
|
|
+}
|
2012-02-04 01:13:28 +00:00
|
|
|
diff --git a/ui/gtk3/gkbdlayout.vala.true b/ui/gtk3/gkbdlayout.vala.true
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..adacd81
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/ui/gtk3/gkbdlayout.vala.true
|
|
|
|
@@ -0,0 +1,111 @@
|
|
|
|
+/* vim:set et sts=4 sw=4:
|
|
|
|
+ *
|
|
|
|
+ * ibus - The Input Bus
|
|
|
|
+ *
|
|
|
|
+ * Copyright 2012 Red Hat, Inc.
|
|
|
|
+ * Copyright(c) 2012 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
|
+ * Copyright(c) 2012 Takao Fujiwara <tfujiwar@redhat.com>
|
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2 of the License, or(at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+ * GNU Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this program; if not, write to the
|
|
|
|
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
|
|
+ * Boston, MA 02111-1307 USA
|
|
|
|
+ */
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+using Gkbd;
|
|
|
|
+using Gtk;
|
|
|
|
+
|
|
|
|
+public class GkbdLayout
|
2010-08-23 02:55:19 +00:00
|
|
|
+{
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public signal void changed();
|
|
|
|
+ public signal void group_changed (int object);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private Gkbd.Configuration m_config = null;
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public GkbdLayout() {
|
|
|
|
+ m_config = Gkbd.Configuration.get();
|
|
|
|
+ if (m_config != null) {
|
|
|
|
+ m_config.changed.connect(config_changed_cb);
|
|
|
|
+ m_config.group_changed.connect(config_group_changed_cb);
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ ~GkbdLayout() {
|
|
|
|
+ if (m_config != null) {
|
|
|
|
+ m_config.changed.disconnect(config_changed_cb);
|
|
|
|
+ m_config.group_changed.disconnect(config_group_changed_cb);
|
|
|
|
+ /* gkbd_configuration_get reuses the object and do not
|
|
|
|
+ * destroy m_config here. */
|
|
|
|
+ m_config.ref();
|
|
|
|
+ m_config = null;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private void config_changed_cb() {
|
|
|
|
+ changed();
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
+ private void config_group_changed_cb(int object) {
|
|
|
|
+ group_changed(object);
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
+ public string[] get_layouts() {
|
|
|
|
+ if (m_config == null) {
|
|
|
|
+ return new string[0];
|
|
|
|
+ }
|
|
|
|
+ return m_config.get_short_group_names();
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
+ public string[] get_group_names() {
|
|
|
|
+ if (m_config == null) {
|
|
|
|
+ return new string[0];
|
|
|
|
+ }
|
|
|
|
+ return m_config.get_group_names();
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
+ public void lock_group(int id) {
|
|
|
|
+ if (m_config == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ m_config.lock_group(id);
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public void start_listen() {
|
|
|
|
+ if (m_config == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ m_config.start_listen();
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public void stop_listen() {
|
|
|
|
+ if (m_config == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ m_config.stop_listen();
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ /*
|
|
|
|
+ public static int main(string[] args) {
|
|
|
|
+ Gtk.init(ref args);
|
|
|
|
+ GkbdLayout ibus_layouts = new GkbdLayout();
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ string[] layouts = ibus_layouts.get_layouts();
|
|
|
|
+ string[] names = ibus_layouts.get_group_names();
|
|
|
|
+ for (int i = 0; layouts != null && i < layouts.length; i++) {
|
|
|
|
+ stdout.printf("%s %s\n", layouts[i], names[i]);
|
|
|
|
+ }
|
2010-09-14 11:20:08 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return 0;
|
2011-03-10 09:07:52 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ */
|
|
|
|
+}
|
|
|
|
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
|
2012-04-28 06:13:40 +00:00
|
|
|
index 251a65e..c08f188 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
--- a/ui/gtk3/panel.vala
|
|
|
|
+++ b/ui/gtk3/panel.vala
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -41,8 +41,16 @@ class Panel : IBus.PanelService {
|
2012-02-04 01:13:28 +00:00
|
|
|
private GLib.Pid m_setup_pid = 0;
|
|
|
|
private Gtk.AboutDialog m_about_dialog;
|
2012-04-28 06:13:40 +00:00
|
|
|
private Gtk.CssProvider m_css_provider;
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private GkbdLayout m_gkbdlayout = null;
|
|
|
|
+ private XKBLayout m_xkblayout = null;
|
|
|
|
+ private string[] m_layouts = {};
|
|
|
|
+ private string[] m_variants = {};
|
|
|
|
+ private int m_fallback_lock_id = -1;
|
|
|
|
+ private bool m_changed_xkb_option = false;
|
|
|
|
+ private GLib.Timer m_changed_layout_timer;
|
|
|
|
private const string ACCELERATOR_SWITCH_IME_FOREWARD = "<Control>space";
|
|
|
|
private const string ACCELERATOR_SWITCH_IME_BACKWARD = "<Control><Shift>space";
|
2012-02-07 11:42:14 +00:00
|
|
|
+ private string[] ACCELERATOR_IME_HOTKEYS = {};
|
|
|
|
|
|
|
|
public Panel(IBus.Bus bus) {
|
|
|
|
GLib.assert(bus.is_connected());
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -66,13 +74,6 @@ class Panel : IBus.PanelService {
|
2012-02-07 11:42:14 +00:00
|
|
|
|
|
|
|
m_switcher = new Switcher();
|
2012-02-04 01:13:28 +00:00
|
|
|
|
2012-02-07 11:42:14 +00:00
|
|
|
- var keybinding_manager = KeybindingManager.get_instance();
|
|
|
|
- keybinding_manager.bind(ACCELERATOR_SWITCH_IME_FOREWARD,
|
|
|
|
- (e) => handle_engine_switch(e, false));
|
|
|
|
-
|
|
|
|
- keybinding_manager.bind(ACCELERATOR_SWITCH_IME_BACKWARD,
|
|
|
|
- (e) => handle_engine_switch(e, true));
|
|
|
|
-
|
|
|
|
m_property_manager = new PropertyManager();
|
|
|
|
m_property_manager.property_activate.connect((k, s) => {
|
|
|
|
property_activate(k, s);
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -83,8 +84,66 @@ class Panel : IBus.PanelService {
|
2012-02-07 11:42:14 +00:00
|
|
|
|
|
|
|
~Panel() {
|
2012-02-04 01:13:28 +00:00
|
|
|
var keybinding_manager = KeybindingManager.get_instance();
|
2012-02-07 11:42:14 +00:00
|
|
|
- keybinding_manager.unbind(ACCELERATOR_SWITCH_IME_FOREWARD);
|
|
|
|
- keybinding_manager.unbind(ACCELERATOR_SWITCH_IME_BACKWARD);
|
|
|
|
+ foreach (string keybinding in ACCELERATOR_IME_HOTKEYS) {
|
|
|
|
+ keybinding_manager.unbind(keybinding);
|
|
|
|
+ if (keybinding == ACCELERATOR_SWITCH_IME_FOREWARD) {
|
|
|
|
+ keybinding_manager.unbind(ACCELERATOR_SWITCH_IME_BACKWARD);
|
|
|
|
+ }
|
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
+ if (HAVE_IBUS_GKBD && m_gkbdlayout != null) {
|
|
|
|
+ m_gkbdlayout.changed.disconnect(gkbdlayout_changed_cb);
|
|
|
|
+ m_gkbdlayout.stop_listen();
|
|
|
|
+ m_gkbdlayout = null;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ m_xkblayout = null;
|
2012-02-07 11:42:14 +00:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // ToDo: Customize the input method with ibus-setup
|
|
|
|
+ private void set_keybinding() {
|
|
|
|
+ string locale = GLib.Intl.setlocale(GLib.LocaleCategory.ALL,
|
|
|
|
+ null);
|
|
|
|
+ if (locale == null) {
|
|
|
|
+ locale = "C";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ACCELERATOR_IME_HOTKEYS += ACCELERATOR_SWITCH_IME_FOREWARD;
|
|
|
|
+
|
|
|
|
+ if (m_config != null) {
|
|
|
|
+ GLib.Variant variant = m_config.get_value("general/hotkey",
|
|
|
|
+ "trigger_accel");
|
|
|
|
+ if (variant != null) {
|
|
|
|
+ ACCELERATOR_IME_HOTKEYS = {};
|
|
|
|
+ for (int i = 0; i < variant.n_children(); i++) {
|
|
|
|
+ ACCELERATOR_IME_HOTKEYS += variant.get_child_value(i).dup_string();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ACCELERATOR_IME_HOTKEYS.length == 1 &&
|
|
|
|
+ ACCELERATOR_IME_HOTKEYS[0] == ACCELERATOR_SWITCH_IME_FOREWARD) {
|
|
|
|
+ // FIXME: When us keyboard is used, Zenkaku_Hankaku does not work.
|
|
|
|
+ /*
|
|
|
|
+ if (locale[0:2] == "ja") {
|
|
|
|
+ ACCELERATOR_IME_HOTKEYS += "Zenkaku_Hankaku";
|
|
|
|
+ }
|
|
|
|
+ */
|
|
|
|
+ if (locale[0:2] == "ko") {
|
|
|
|
+ ACCELERATOR_IME_HOTKEYS += "Hangul";
|
|
|
|
+ ACCELERATOR_IME_HOTKEYS += "Alt_R";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var keybinding_manager = KeybindingManager.get_instance();
|
|
|
|
+ foreach (string keybinding in ACCELERATOR_IME_HOTKEYS) {
|
|
|
|
+ keybinding_manager.bind(keybinding,
|
|
|
|
+ (e) => handle_engine_switch(e, false));
|
|
|
|
+ if (keybinding == ACCELERATOR_SWITCH_IME_FOREWARD) {
|
|
|
|
+ keybinding_manager.bind(ACCELERATOR_SWITCH_IME_BACKWARD,
|
|
|
|
+ (e) => handle_engine_switch(e, true));
|
|
|
|
+ }
|
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 09:41:41 +00:00
|
|
|
private void set_custom_font() {
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -152,12 +211,14 @@ class Panel : IBus.PanelService {
|
2012-02-07 11:42:14 +00:00
|
|
|
}
|
|
|
|
|
2012-02-04 01:13:28 +00:00
|
|
|
m_config = config;
|
2012-02-07 11:42:14 +00:00
|
|
|
+ set_keybinding();
|
2012-02-04 01:13:28 +00:00
|
|
|
if (m_config != null) {
|
|
|
|
m_config.value_changed.connect(config_value_changed_cb);
|
2012-03-18 09:41:41 +00:00
|
|
|
m_config.watch("general", "preload_engines");
|
|
|
|
m_config.watch("general", "engines_order");
|
|
|
|
m_config.watch("panel", "custom_font");
|
|
|
|
m_config.watch("panel", "use_custom_font");
|
2012-02-04 01:13:28 +00:00
|
|
|
+ init_engines_order();
|
|
|
|
update_engines(m_config.get_value("general", "preload_engines"),
|
|
|
|
m_config.get_value("general", "engines_order"));
|
|
|
|
} else {
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -167,6 +228,192 @@ class Panel : IBus.PanelService {
|
2012-03-18 09:41:41 +00:00
|
|
|
set_custom_font();
|
2012-02-04 01:13:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
+ private void gkbdlayout_changed_cb() {
|
|
|
|
+ /* The callback is called four times after set_layout is called
|
|
|
|
+ * so check the elapsed and take the first signal only. */
|
|
|
|
+ double elapsed = m_changed_layout_timer.elapsed();
|
|
|
|
+ if (elapsed < 1.0 && elapsed > 0.0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (m_fallback_lock_id != -1) {
|
|
|
|
+ /* Call lock_group only when set_layout is called. */
|
|
|
|
+ m_gkbdlayout.lock_group(m_fallback_lock_id);
|
|
|
|
+ m_fallback_lock_id = -1;
|
|
|
|
+ } else {
|
|
|
|
+ /* Reset default layout when gnome-control-center is called. */
|
|
|
|
+ m_xkblayout.reset_layout();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ update_xkb_engines();
|
|
|
|
+ m_changed_layout_timer.reset();
|
2010-09-14 11:20:08 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private void init_gkbd() {
|
|
|
|
+ m_gkbdlayout = new GkbdLayout();
|
|
|
|
+ m_gkbdlayout.changed.connect(gkbdlayout_changed_cb);
|
2010-09-14 11:20:08 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ /* Probably we cannot support both keyboard and ibus indicators
|
|
|
|
+ * How can I get the engine from keymap of group_id?
|
|
|
|
+ * e.g. 'en' could be owned by xkb:en and pinyin engines. */
|
|
|
|
+ //m_gkbdlayout.group_changed.connect((object) => {});
|
|
|
|
+
|
|
|
|
+ m_changed_layout_timer = new GLib.Timer();
|
|
|
|
+ m_changed_layout_timer.start();
|
|
|
|
+ m_gkbdlayout.start_listen();
|
2010-09-14 11:20:08 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private void init_engines_order() {
|
|
|
|
+ if (m_config == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
2010-09-14 11:20:08 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ m_xkblayout = new XKBLayout(m_config);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (HAVE_IBUS_GKBD) {
|
|
|
|
+ init_gkbd();
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ update_xkb_engines();
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private void update_xkb_engines() {
|
|
|
|
+ string var_layout = m_xkblayout.get_layout();
|
|
|
|
+ string var_variant = m_xkblayout.get_variant();
|
|
|
|
+ if (var_layout == "") {
|
|
|
|
+ return;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ m_layouts = var_layout.split(",");
|
|
|
|
+ m_variants = var_variant.split(",");
|
|
|
|
+
|
|
|
|
+ IBus.XKBConfigRegistry registry = new IBus.XKBConfigRegistry();
|
|
|
|
+ string[] var_xkb_engine_names = {};
|
|
|
|
+ for (int i = 0; i < m_layouts.length; i++) {
|
|
|
|
+ string name = m_layouts[i];
|
|
|
|
+ string lang = null;
|
|
|
|
+
|
|
|
|
+ if (i < m_variants.length && m_variants[i] != "") {
|
|
|
|
+ name = "%s:%s".printf(name, m_variants[i]);
|
|
|
|
+ string layout = "%s(%s)".printf(name, m_variants[i]);
|
2012-03-04 13:45:32 +00:00
|
|
|
+ GLib.List<string> langs =
|
|
|
|
+ registry.layout_lang_get_langs(layout);
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (langs.length() != 0) {
|
|
|
|
+ lang = langs.data;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ name = "%s:".printf(name);
|
|
|
|
+ }
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (lang == null) {
|
2012-03-04 13:45:32 +00:00
|
|
|
+ GLib.List<string> langs =
|
|
|
|
+ registry.layout_lang_get_langs(m_layouts[i]);
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (langs.length() != 0) {
|
|
|
|
+ lang = langs.data;
|
|
|
|
+ }
|
|
|
|
+ }
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ var_xkb_engine_names += "%s:%s:%s".printf("xkb", name, lang);
|
|
|
|
+ }
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ GLib.Variant var_engines =
|
|
|
|
+ m_config.get_value("general", "preload_engines");
|
|
|
|
+ string[] engine_names = {};
|
|
|
|
+ bool updated_engine_names = false;
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (var_engines != null) {
|
|
|
|
+ engine_names = var_engines.dup_strv();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ foreach (string name in var_xkb_engine_names) {
|
|
|
|
+ if (name in engine_names)
|
|
|
|
+ continue;
|
|
|
|
+ updated_engine_names = true;
|
|
|
|
+ engine_names += name;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (updated_engine_names) {
|
|
|
|
+ m_config.set_value("general",
|
|
|
|
+ "preload_engines",
|
|
|
|
+ new GLib.Variant.strv(engine_names));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ GLib.Variant var_order =
|
|
|
|
+ m_config.get_value("general", "engines_order");
|
|
|
|
+ string[] order_names = {};
|
|
|
|
+ bool updated_order_names = false;
|
|
|
|
+
|
|
|
|
+ if (var_order != null) {
|
|
|
|
+ order_names = var_order.dup_strv();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ foreach (var name in var_xkb_engine_names) {
|
|
|
|
+ if (name in order_names)
|
|
|
|
+ continue;
|
|
|
|
+ order_names += name;
|
|
|
|
+ updated_order_names = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (updated_order_names) {
|
|
|
|
+ m_config.set_value("general",
|
|
|
|
+ "engines_order",
|
|
|
|
+ new GLib.Variant.strv(order_names));
|
|
|
|
+ }
|
2011-06-21 08:49:07 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private void set_xkb_group_layout(string layout) {
|
|
|
|
+ int[] retval = m_xkblayout.set_layout(layout);
|
|
|
|
+ if (retval[0] >= 0) {
|
|
|
|
+ /* If an XKB keymap is added into the XKB group,
|
|
|
|
+ * this._gkbdlayout.lock_group will be called after
|
|
|
|
+ * 'group-changed' signal is received. */
|
|
|
|
+ m_fallback_lock_id = retval[0];
|
|
|
|
+ m_changed_xkb_option = (retval[1] != 0) ? true : false;
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private bool set_gkbd_layout(string layout) {
|
|
|
|
+ /* If a previous ibus engine changed XKB options, need to set the
|
|
|
|
+ * default XKB option. */
|
|
|
|
+ if (m_changed_xkb_option == true) {
|
|
|
|
+ m_changed_xkb_option = false;
|
|
|
|
+ return false;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ int gkbd_len = m_gkbdlayout.get_group_names().length;
|
|
|
|
+ for (int i = 0; i < m_layouts.length && i < gkbd_len; i++) {
|
|
|
|
+ string sys_layout = m_layouts[i];
|
|
|
|
+ if (i < m_variants.length && m_variants[i] != "") {
|
|
|
|
+ sys_layout = "%s(%s)".printf(sys_layout, m_variants[i]);
|
|
|
|
+ }
|
|
|
|
+ if (sys_layout == layout) {
|
|
|
|
+ m_gkbdlayout.lock_group(i);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private void set_layout(string layout) {
|
|
|
|
+ if (layout == "default" || layout == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (m_xkblayout == null) {
|
|
|
|
+ init_engines_order();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (HAVE_IBUS_GKBD) {
|
|
|
|
+ if (set_gkbd_layout(layout)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ set_xkb_group_layout(layout);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ m_xkblayout.set_layout(layout);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
private void switch_engine(int i, bool force = false) {
|
|
|
|
GLib.assert(i >= 0 && i < m_engines.length);
|
|
|
|
|
2012-04-28 06:13:40 +00:00
|
|
|
@@ -186,15 +433,7 @@ class Panel : IBus.PanelService {
|
2012-02-04 01:13:28 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// set xkb layout
|
|
|
|
- string cmdline = "setxkbmap %s".printf(engine.get_layout());
|
|
|
|
- try {
|
|
|
|
- if (!GLib.Process.spawn_command_line_sync(cmdline)) {
|
|
|
|
- warning("Switch xkb layout to %s failed.",
|
|
|
|
- engine.get_layout());
|
|
|
|
- }
|
|
|
|
- } catch (GLib.SpawnError e) {
|
|
|
|
- warning("execute setxkblayout failed");
|
|
|
|
- }
|
|
|
|
+ set_layout(engine.get_layout());
|
|
|
|
|
|
|
|
string[] names = {};
|
|
|
|
foreach(var desc in m_engines) {
|
|
|
|
diff --git a/ui/gtk3/xkblayout.vala b/ui/gtk3/xkblayout.vala
|
2010-08-23 02:55:19 +00:00
|
|
|
new file mode 100644
|
2012-02-04 01:13:28 +00:00
|
|
|
index 0000000..8b75387
|
2010-08-23 02:55:19 +00:00
|
|
|
--- /dev/null
|
2012-02-04 01:13:28 +00:00
|
|
|
+++ b/ui/gtk3/xkblayout.vala
|
|
|
|
@@ -0,0 +1,466 @@
|
|
|
|
+/* vim:set et sts=4 sw=4:
|
|
|
|
+ *
|
|
|
|
+ * ibus - The Input Bus
|
|
|
|
+ *
|
|
|
|
+ * Copyright 2012 Red Hat, Inc.
|
|
|
|
+ * Copyright(c) 2012 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
|
+ * Copyright(c) 2012 Takao Fujiwara <tfujiwar@redhat.com>
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * version 2 of the License, or(at your option) any later version.
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+ * GNU Lesser General Public License for more details.
|
2010-08-23 02:55:19 +00:00
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
2012-02-04 01:13:28 +00:00
|
|
|
+ * License along with this program; if not, write to the
|
|
|
|
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
|
|
+ * Boston, MA 02111-1307 USA
|
2010-08-23 02:55:19 +00:00
|
|
|
+ */
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+using IBus;
|
|
|
|
+
|
|
|
|
+public extern const bool HAVE_IBUS_GKBD;
|
|
|
|
+public extern const bool HAVE_IBUS_XKB;
|
|
|
|
+public extern const int XKB_LAYOUTS_MAX_LENGTH;
|
|
|
|
+public extern const string IBUS_XKB_COMMAND;
|
|
|
|
+
|
|
|
|
+class XKBLayout
|
|
|
|
+{
|
|
|
|
+ string m_xkb_command = IBUS_XKB_COMMAND;
|
|
|
|
+ IBus.Config m_config = null;
|
|
|
|
+ string[] m_xkb_latin_layouts = {};
|
|
|
|
+ GLib.Pid m_xkb_pid = -1;
|
|
|
|
+ GLib.Pid m_xmodmap_pid = -1;
|
|
|
|
+ string m_xmodmap_command = "xmodmap";
|
|
|
|
+ bool m_use_xmodmap = true;
|
|
|
|
+ string[] m_xmodmap_known_files = {".xmodmap", ".xmodmaprc",
|
|
|
|
+ ".Xmodmap", ".Xmodmaprc"};
|
|
|
|
+ string m_default_layout = "";
|
|
|
|
+ string m_default_variant = "";
|
|
|
|
+ string m_default_option = "";
|
|
|
|
+
|
|
|
|
+ public XKBLayout(IBus.Config? config) {
|
|
|
|
+ if (!HAVE_IBUS_XKB) {
|
|
|
|
+ m_xkb_command = "setxkbmap";
|
|
|
|
+ }
|
2011-06-21 08:49:07 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ m_config = config;
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (config != null) {
|
|
|
|
+ var value = config.get_value("general", "xkb_latin_layouts");
|
|
|
|
+ for (int i = 0; value != null && i < value.n_children(); i++) {
|
|
|
|
+ m_xkb_latin_layouts +=
|
|
|
|
+ value.get_child_value(i).dup_string();
|
|
|
|
+ }
|
|
|
|
+ if (m_use_xmodmap) {
|
|
|
|
+ m_use_xmodmap = config.get_value("general", "use_xmodmap").get_boolean();
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private string get_output_from_cmdline(string arg, string element) {
|
|
|
|
+ string[] exec_command = {};
|
|
|
|
+ exec_command += m_xkb_command;
|
|
|
|
+ exec_command += arg;
|
|
|
|
+ string standard_output = null;
|
|
|
|
+ string standard_error = null;
|
|
|
|
+ int exit_status = 0;
|
|
|
|
+ string retval = "";
|
|
|
|
+ try {
|
|
|
|
+ GLib.Process.spawn_sync(null,
|
|
|
|
+ exec_command,
|
|
|
|
+ null,
|
|
|
|
+ GLib.SpawnFlags.SEARCH_PATH,
|
|
|
|
+ null,
|
|
|
|
+ out standard_output,
|
|
|
|
+ out standard_error,
|
|
|
|
+ out exit_status);
|
|
|
|
+ } catch (GLib.SpawnError err) {
|
|
|
|
+ stderr.printf("IBUS_ERROR: %s\n", err.message);
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (exit_status != 0) {
|
|
|
|
+ stderr.printf("IBUS_ERROR: %s\n", standard_error ?? "");
|
|
|
|
+ }
|
|
|
|
+ if (standard_output == null) {
|
|
|
|
+ return "";
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+ foreach (string line in standard_output.split("\n")) {
|
|
|
|
+ if (element.length <= line.length &&
|
|
|
|
+ line[0:element.length] == element) {
|
|
|
|
+ retval = line[element.length:line.length];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return retval;
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private void set_layout_cb(GLib.Pid pid, int status) {
|
|
|
|
+ if (m_xkb_pid != pid) {
|
|
|
|
+ stderr.printf("IBUS_ERROR: set_layout_cb has another pid\n");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ GLib.Process.close_pid(m_xkb_pid);
|
|
|
|
+ m_xkb_pid = -1;
|
|
|
|
+ set_xmodmap();
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private void set_xmodmap_cb(GLib.Pid pid, int status) {
|
|
|
|
+ if (m_xmodmap_pid != pid) {
|
|
|
|
+ stderr.printf("IBUS_ERROR: set_xmodmap_cb has another pid\n");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ GLib.Process.close_pid(m_xmodmap_pid);
|
|
|
|
+ m_xmodmap_pid = -1;
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ private string get_fullpath(string command) {
|
|
|
|
+ string envpath = GLib.Environment.get_variable("PATH");
|
|
|
|
+ foreach (string dir in envpath.split(":")) {
|
|
|
|
+ string filepath = GLib.Path.build_filename(dir, command);
|
|
|
|
+ if (GLib.FileUtils.test(filepath, GLib.FileTest.EXISTS)) {
|
|
|
|
+ return filepath;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return "";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private string[] get_xkb_group_layout (string layout,
|
|
|
|
+ string variant,
|
|
|
|
+ int layouts_max_length) {
|
|
|
|
+ int group_id = 0;
|
|
|
|
+ int i = 0;
|
|
|
|
+ string[] layouts = m_default_layout.split(",");
|
|
|
|
+ string[] variants = m_default_variant.split(",");
|
|
|
|
+ string group_layouts = "";
|
|
|
|
+ string group_variants = "";
|
|
|
|
+ bool has_variant = false;
|
|
|
|
+ bool include_keymap = false;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < layouts.length; i++) {
|
|
|
|
+ if (i >= layouts_max_length - 1) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (i == 0) {
|
|
|
|
+ group_layouts = layouts[i];
|
|
|
|
+ } else {
|
|
|
|
+ group_layouts = "%s,%s".printf(group_layouts, layouts[i]);
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (i >= variants.length) {
|
|
|
|
+ if (i == 0) {
|
|
|
|
+ group_variants = "";
|
|
|
|
+ } else {
|
|
|
|
+ group_variants += ",";
|
|
|
|
+ }
|
|
|
|
+ if (layout == layouts[i] && variant == "") {
|
|
|
|
+ include_keymap = true;
|
|
|
|
+ group_id = i;
|
|
|
|
+ }
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (layout == layouts[i] && variant == variants[i]) {
|
|
|
|
+ include_keymap = true;
|
|
|
|
+ group_id = i;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (variants[i] != "") {
|
|
|
|
+ has_variant = true;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (i == 0) {
|
|
|
|
+ group_variants = variants[i];
|
|
|
|
+ } else {
|
|
|
|
+ group_variants = "%s,%s".printf(group_variants, variants[i]);
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (variant != "") {
|
|
|
|
+ has_variant = true;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (!include_keymap) {
|
|
|
|
+ group_layouts = "%s,%s".printf(group_layouts, layout);
|
|
|
|
+ group_variants = "%s,%s".printf(group_variants, variant);
|
|
|
|
+ group_id = i;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (!has_variant) {
|
|
|
|
+ group_variants = null;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return {group_layouts, group_variants, group_id.to_string()};
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public string[] get_variant_from_layout(string layout) {
|
|
|
|
+ int left_bracket = layout.index_of("(");
|
|
|
|
+ int right_bracket = layout.index_of(")");
|
|
|
|
+ if (left_bracket >= 0 && right_bracket > left_bracket) {
|
|
|
|
+ return {layout[0:left_bracket] +
|
|
|
|
+ layout[right_bracket + 1:layout.length],
|
|
|
|
+ layout[left_bracket + 1:right_bracket]};
|
|
|
|
+ }
|
|
|
|
+ return {layout, "default"};
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public string[] get_option_from_layout(string layout) {
|
|
|
|
+ int left_bracket = layout.index_of("[");
|
|
|
|
+ int right_bracket = layout.index_of("]");
|
|
|
|
+ if (left_bracket >= 0 && right_bracket > left_bracket) {
|
|
|
|
+ return {layout[0:left_bracket] +
|
|
|
|
+ layout[right_bracket + 1:layout.length],
|
|
|
|
+ layout[left_bracket + 1:right_bracket]};
|
|
|
|
+ }
|
|
|
|
+ return {layout, "default"};
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public string get_layout() {
|
|
|
|
+ if (HAVE_IBUS_XKB) {
|
|
|
|
+ return get_output_from_cmdline("--get", "layout: ");
|
|
|
|
+ } else {
|
|
|
|
+ return get_output_from_cmdline("-query", "layout: ");
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public string get_variant() {
|
|
|
|
+ if (HAVE_IBUS_XKB) {
|
|
|
|
+ return get_output_from_cmdline("--get", "variant: ");
|
|
|
|
+ } else {
|
|
|
|
+ return get_output_from_cmdline("-query", "variant: ");
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public string get_option() {
|
|
|
|
+ if (HAVE_IBUS_XKB) {
|
|
|
|
+ return get_output_from_cmdline("--get", "option: ");
|
|
|
|
+ } else {
|
|
|
|
+ return get_output_from_cmdline("-query", "options: ");
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+ }
|
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ /*
|
|
|
|
+ public string get_group() {
|
|
|
|
+ return get_output_from_cmdline("--get-group", "group: ");
|
|
|
|
+ }
|
|
|
|
+ */
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public int[] set_layout(string _layout="default",
|
|
|
|
+ string _variant="default",
|
|
|
|
+ string _option="default") {
|
|
|
|
+ assert (_layout != null);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ int xkb_group_id = 0;
|
|
|
|
+ int changed_option = 0;
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (m_xkb_pid != -1) {
|
|
|
|
+ return {-1, 0};
|
2011-08-14 00:10:20 +00:00
|
|
|
+ }
|
2012-02-04 01:13:28 +00:00
|
|
|
+
|
|
|
|
+ if (_layout == "default" && _variant == "default" &&
|
|
|
|
+ _option == "default") {
|
|
|
|
+ return {-1, 0};
|
|
|
|
+ }
|
|
|
|
+ // const gchar to gchar
|
|
|
|
+ string layout = _layout;
|
|
|
|
+ string variant = _variant;
|
|
|
|
+ string option = _option;
|
|
|
|
+
|
|
|
|
+ if (variant == "default") {
|
|
|
|
+ string[] array = get_variant_from_layout(layout);
|
|
|
|
+ layout = array[0];
|
|
|
|
+ variant = array[1];
|
2011-08-14 00:10:20 +00:00
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (option == "default") {
|
|
|
|
+ string[] array = get_option_from_layout(layout);
|
|
|
|
+ layout = array[0];
|
|
|
|
+ option = array[1];
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ bool need_us_layout = false;
|
|
|
|
+ foreach (string latin_layout in m_xkb_latin_layouts) {
|
|
|
|
+ if (layout == latin_layout && variant != "eng") {
|
|
|
|
+ need_us_layout = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (variant != null &&
|
|
|
|
+ "%s(%s)".printf(layout, variant) == latin_layout) {
|
|
|
|
+ need_us_layout = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ int layouts_max_length = XKB_LAYOUTS_MAX_LENGTH;
|
|
|
|
+ if (need_us_layout) {
|
|
|
|
+ layouts_max_length--;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (m_default_layout == "") {
|
|
|
|
+ m_default_layout = get_layout();
|
|
|
|
+ }
|
|
|
|
+ if (m_default_variant == "") {
|
|
|
|
+ m_default_variant = get_variant();
|
|
|
|
+ }
|
|
|
|
+ if (m_default_option == "") {
|
|
|
|
+ m_default_option = get_option();
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (layout == "default") {
|
|
|
|
+ layout = m_default_layout;
|
|
|
|
+ variant = m_default_variant;
|
|
|
|
+ } else {
|
|
|
|
+ if (HAVE_IBUS_GKBD) {
|
|
|
|
+ if (variant == "default") {
|
|
|
|
+ variant = "";
|
|
|
|
+ }
|
|
|
|
+ string[] retval = get_xkb_group_layout (layout, variant,
|
|
|
|
+ layouts_max_length);
|
|
|
|
+ layout = retval[0];
|
|
|
|
+ variant = retval[1];
|
|
|
|
+ xkb_group_id = int.parse(retval[2]);
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (layout == "") {
|
|
|
|
+ warning("Could not get the correct layout");
|
|
|
|
+ return {-1, 0};
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (variant == "default" || variant == "") {
|
|
|
|
+ variant = null;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (option == "default" || option == "") {
|
|
|
|
+ option = m_default_option;
|
|
|
|
+ } else {
|
|
|
|
+ if (!(option in m_default_option.split(","))) {
|
|
|
|
+ option = "%s,%s".printf(m_default_option, option);
|
|
|
|
+ changed_option = 1;
|
|
|
|
+ } else {
|
|
|
|
+ option = m_default_option;
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (option == "") {
|
|
|
|
+ option = null;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (need_us_layout) {
|
|
|
|
+ layout += ",us";
|
|
|
|
+ if (variant != null) {
|
|
|
|
+ variant += ",";
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ string[] args = {};
|
|
|
|
+ args += m_xkb_command;
|
|
|
|
+ if (HAVE_IBUS_XKB) {
|
|
|
|
+ args += "--layout";
|
|
|
|
+ args += layout;
|
|
|
|
+ if (variant != null) {
|
|
|
|
+ args += "--variant";
|
|
|
|
+ args += variant;
|
|
|
|
+ }
|
|
|
|
+ if (option != null) {
|
|
|
|
+ args += "--option";
|
|
|
|
+ args += option;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ args += layout;
|
|
|
|
+ if (variant != null) {
|
|
|
|
+ args += variant;
|
|
|
|
+ }
|
|
|
|
+ if (option != null) {
|
|
|
|
+ args += option;
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ GLib.Pid child_pid;
|
|
|
|
+ try {
|
|
|
|
+ GLib.Process.spawn_async(null,
|
|
|
|
+ args,
|
|
|
|
+ null,
|
|
|
|
+ GLib.SpawnFlags.DO_NOT_REAP_CHILD |
|
|
|
|
+ GLib.SpawnFlags.SEARCH_PATH,
|
|
|
|
+ null,
|
|
|
|
+ out child_pid);
|
|
|
|
+ } catch (GLib.SpawnError err) {
|
|
|
|
+ stderr.printf("IBUS_ERROR: %s\n", err.message);
|
|
|
|
+ return {-1, 0};
|
|
|
|
+ }
|
|
|
|
+ m_xkb_pid = child_pid;
|
|
|
|
+ GLib.ChildWatch.add(m_xkb_pid, set_layout_cb);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ return {xkb_group_id, changed_option};
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public void set_xmodmap() {
|
|
|
|
+ if (!m_use_xmodmap) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ if (m_xmodmap_pid != -1) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ string xmodmap_cmdpath = get_fullpath(m_xmodmap_command);
|
|
|
|
+ if (xmodmap_cmdpath == "") {
|
|
|
|
+ xmodmap_cmdpath = m_xmodmap_command;
|
|
|
|
+ }
|
|
|
|
+ string homedir = GLib.Environment.get_home_dir();
|
|
|
|
+ foreach (string xmodmap_file in m_xmodmap_known_files) {
|
|
|
|
+ string xmodmap_filepath = GLib.Path.build_filename(homedir, xmodmap_file);
|
|
|
|
+ if (!GLib.FileUtils.test(xmodmap_filepath, GLib.FileTest.EXISTS)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ string[] args = {xmodmap_cmdpath, xmodmap_filepath};
|
|
|
|
+
|
|
|
|
+ GLib.Pid child_pid;
|
|
|
|
+ try {
|
|
|
|
+ GLib.Process.spawn_async(null,
|
|
|
|
+ args,
|
|
|
|
+ null,
|
|
|
|
+ GLib.SpawnFlags.DO_NOT_REAP_CHILD |
|
|
|
|
+ GLib.SpawnFlags.SEARCH_PATH,
|
|
|
|
+ null,
|
|
|
|
+ out child_pid);
|
|
|
|
+ } catch (GLib.SpawnError err) {
|
|
|
|
+ stderr.printf("IBUS_ERROR: %s\n", err.message);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ m_xmodmap_pid = child_pid;
|
|
|
|
+ GLib.ChildWatch.add(m_xmodmap_pid, set_xmodmap_cb);
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
2010-08-23 02:55:19 +00:00
|
|
|
+
|
2012-02-04 01:13:28 +00:00
|
|
|
+ public void reset_layout() {
|
|
|
|
+ m_default_layout = get_layout();
|
|
|
|
+ m_default_variant = get_variant();
|
|
|
|
+ m_default_option = get_option();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ public static int main(string[] args) {
|
|
|
|
+ IBus.Bus bus = new IBus.Bus();
|
|
|
|
+ IBus.Config config = bus.get_config();
|
|
|
|
+ XKBLayout xkblayout = new XKBLayout(config);
|
|
|
|
+ stdout.printf ("layout: %s\n", xkblayout.get_layout());
|
|
|
|
+ stdout.printf ("variant: %s\n", xkblayout.get_variant());
|
|
|
|
+ stdout.printf ("option: %s\n", xkblayout.get_option());
|
|
|
|
+ xkblayout.set_layout("jp");
|
|
|
|
+ if (config != null) {
|
|
|
|
+ IBus.main();
|
|
|
|
+ } else {
|
|
|
|
+ Gtk.init (ref args);
|
|
|
|
+ Gtk.main();
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ */
|
|
|
|
+}
|
2010-08-23 02:55:19 +00:00
|
|
|
--
|
2012-04-28 06:13:40 +00:00
|
|
|
1.7.10
|
2010-08-23 02:55:19 +00:00
|
|
|
|