From c241fb6e7d9035db1b89135ddb0f2dfd2eed95db Mon Sep 17 00:00:00 2001 From: Huang Peng Date: Mon, 15 Sep 2008 16:31:35 +0800 Subject: Hack japan [yen bar] key for qt immodule. --- client/qt4/Makefile.am | 10 ++--- client/qt4/ibus-client.cpp | 89 ++++++++++++++++++++++++++++++++++++++- client/qt4/ibus-client.h | 6 +++ client/qt4/ibus-input-context.cpp | 1 + client/qt4/ibus.pro | 2 +- 5 files changed, 101 insertions(+), 7 deletions(-) (limited to 'client') diff --git a/client/qt4/Makefile.am b/client/qt4/Makefile.am index 012a6b0..84eef3f 100644 --- a/client/qt4/Makefile.am +++ b/client/qt4/Makefile.am @@ -33,21 +33,21 @@ Makefile.qmake: ibus.pro $(QMAKE) -makefile -o Makefile.qmake $(srcdir)/ibus.pro all-local: Makefile.qmake - $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) all + $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) top_builddir=$(top_builddir) all check-local: Makefile.qmake clean-local: Makefile.qmake - $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) clean + $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) top_builddir=$(top_builddir) clean distclean-local: Makefile.qmake - $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) distclean + $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) top_builddir=$(top_builddir) distclean install-exec-local: Makefile.qmake - $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) INSTALL_ROOT=$(DESTDIR) install + $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) top_builddir=$(top_builddir) INSTALL_ROOT=$(DESTDIR) install uninstall-local: Makefile.qmake - $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) INSTALL_ROOT=$(DESTDIR) uninstall + $(MAKE) -f Makefile.qmake $(AM_MAKEFLAGS) top_builddir=$(top_builddir) INSTALL_ROOT=$(DESTDIR) uninstall test: all QT_IM_MODULE=ibus kwrite diff --git a/client/qt4/ibus-client.cpp b/client/qt4/ibus-client.cpp index 32b6d97..4b97739 100644 --- a/client/qt4/ibus-client.cpp +++ b/client/qt4/ibus-client.cpp @@ -19,6 +19,7 @@ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ +#include #include #include #include @@ -38,14 +39,21 @@ # include #endif +#ifdef HAVE_X11_XKBLIB_H +# define HAVE_XKB +# include +#endif + + #define IBUS_NAME "org.freedesktop.IBus" #define IBUS_PATH "/org/freedesktop/IBus" #define IBUS_INTERFACE "org.freedesktop.IBus" IBusClient::IBusClient () - : ibus (NULL) + : ibus (NULL), japan_groups (0) { + findYenBarKeys (); username = getlogin (); if (username.isEmpty ()) username = getenv ("SUDO_USER"); @@ -122,6 +130,76 @@ IBusClient::createInputContextRemote () return ic; } +void +IBusClient::findYenBarKeys () +{ +#ifdef HAVE_XKB + bool retval; + Status status; + XkbDescPtr desc; + + japan_groups = 0; + japan_yen_bar_keys.clear (); + + desc = XkbGetMap (QX11Info::display (), 0, XkbUseCoreKbd); + if (desc == NULL) { + qWarning ("Can not allocate XkbDescRec!"); + return; + } + + retval = + Success == (status = XkbGetControls (QX11Info::display (), + XkbSlowKeysMask, + desc)) && + Success == (status = XkbGetNames (QX11Info::display (), + XkbGroupNamesMask | XkbIndicatorNamesMask, + desc)) && + Success == (status = XkbGetIndicatorMap (QX11Info::display (), + XkbAllIndicatorsMask, + desc)); + if (retval) { + Atom *pa = desc->names->groups; + int i; + for (i = 0; i < desc->ctrls->num_groups; pa++, i++) { + QString group_name; + if (*pa == None) + continue; + group_name = XGetAtomName (QX11Info::display (), *pa); + if (group_name == "Japan") { + japan_groups |= (1 << i); + } + } + } + else { + qWarning ("Can not get groups' names from Xkb"); + } + + int min_keycode, max_keycode; + int keycode_count; + int keysyms_per_keycode; + int keycode; + KeySym *map, *syms; + + XDisplayKeycodes (QX11Info::display (), &min_keycode, &max_keycode); + keycode_count = max_keycode - min_keycode + 1; + map = XGetKeyboardMapping (QX11Info::display (), + min_keycode, keycode_count, &keysyms_per_keycode); + int group; + for (group = 0; group < desc->ctrls->num_groups; group ++) { + if (((group << 1) & japan_groups) == 0) + continue; + for (syms = map, keycode = min_keycode; keycode <= max_keycode; + keycode++, syms += keysyms_per_keycode) { + if (syms[group * 2] != XK_backslash || syms[group * 2 + 1] != XK_bar) + continue; + japan_yen_bar_keys.append (keycode); + } + } + + XkbFreeKeyboard(desc, XkbAllComponentsMask, True); +#endif +} + QInputContext * IBusClient::createInputContext () { @@ -246,6 +324,15 @@ IBusClient::x11FilterEvent (IBusInputContext *ctx, QWidget * /* keywidget */, XE if (!translate_x_key_event (xevent, &keyval, &is_press, &state)) return false; + +#ifdef HAVE_XKB + int group = XkbGroupForCoreState (state); + if (keyval == XK_backslash && japan_groups & (1 << group)) { + if (japan_yen_bar_keys.indexOf (xevent->xkey.keycode) != -1) + keyval = XK_yen; + } +#endif + QDBusMessage message = QDBusMessage::createMethodCall ( IBUS_NAME, IBUS_PATH, diff --git a/client/qt4/ibus-client.h b/client/qt4/ibus-client.h index 2095511..c2c79ab 100644 --- a/client/qt4/ibus-client.h +++ b/client/qt4/ibus-client.h @@ -74,6 +74,7 @@ private: bool connectToBus (); void disconnectFromBus (); QString createInputContextRemote (); + void findYenBarKeys (); QDBusConnection *ibus; QFileSystemWatcher watcher; @@ -83,6 +84,11 @@ private: QString session; QString ibus_path; QString ibus_addr; + + /* hack japan keyboard */ + unsigned int japan_groups; + QVector japan_yen_bar_keys; + }; #endif // __IBUS_CLIENT_H_ diff --git a/client/qt4/ibus-input-context.cpp b/client/qt4/ibus-input-context.cpp index 1afa426..12a6777 100644 --- a/client/qt4/ibus-input-context.cpp +++ b/client/qt4/ibus-input-context.cpp @@ -19,6 +19,7 @@ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ +#include #include "ibus-input-context.h" #include "ibus-client.h" #include diff --git a/client/qt4/ibus.pro b/client/qt4/ibus.pro index 7a4f267..086bbdc 100644 --- a/client/qt4/ibus.pro +++ b/client/qt4/ibus.pro @@ -22,7 +22,7 @@ TEMPLATE = lib TARGET = ibus DEPENDPATH += . -INCLUDEPATH += . +INCLUDEPATH += . $(top_builddir) CONFIG += qt qdbus plugin x11 -- cgit