Sophie

Sophie

distrib > Mageia > 9 > armv7hl > media > core-release-src > by-pkgid > 1c85592b61d40f1a362d33ca395a997b > files > 7

scim-1.4.18-7.mga9.src.rpm

From 7134200e0e73d813896a7c6be04df02c81e1d63a Mon Sep 17 00:00:00 2001
From: Derek Dai <daiderek@gmail.com>
Date: Sun, 1 Mar 2020 23:08:26 +0800
Subject: [PATCH 7/7] Add QT5 support

---
 .gitignore                                    |   3 -
 configure.ac                                  |  70 ++-
 extras/immodules/Makefile.am                  |   2 +-
 .../immodules/client-qt/im-scim-bridge-qt.cpp |  82 ++--
 .../immodules/client-qt/im-scim-bridge-qt.h   |  57 +++
 extras/immodules/client-qt/qt3/Makefile.am    |  72 +++
 extras/immodules/client-qt/qt4/Makefile.am    |  73 +++
 extras/immodules/client-qt/qt5/Makefile.am    |  72 +++
 .../client-qt/scim-bridge-client-common-qt.h  |   6 +
 .../scim-bridge-client-imcontext-qt.cpp       | 414 +++++++++++++++---
 .../scim-bridge-client-imcontext-qt.h         |  74 +++-
 ...cim-bridge-client-key-event-utility-qt.cpp | 128 +++++-
 .../scim-bridge-client-key-event-utility-qt.h |  28 ++
 .../client-qt/scim-bridge-client-qt.cpp       |   2 +
 .../client-qt/scim-bridge-client-qt.h         |   5 +
 extras/immodules/configure.ac                 |  31 +-
 utils/Makefile.am                             |   3 +-
 17 files changed, 986 insertions(+), 136 deletions(-)
 delete mode 100644 .gitignore
 create mode 100644 extras/immodules/client-qt/im-scim-bridge-qt.h
 create mode 100644 extras/immodules/client-qt/qt3/Makefile.am
 create mode 100644 extras/immodules/client-qt/qt4/Makefile.am
 create mode 100644 extras/immodules/client-qt/qt5/Makefile.am

diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index bb9bba5..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.c*
-.project
-.settings
diff --git a/configure.ac b/configure.ac
index 2841926..8c9eca6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -297,7 +297,7 @@ if test "$SCIM_HAS_QT3" = "yes"; then
   AC_SUBST(QT3_LIBDIR)
 fi
 
-PKG_CHECK_MODULES(QT4, [QtGui >= 4.0, QtCore >= 4.0],
+PKG_CHECK_MODULES(QT4, [x11, QtGui >= 4.0],
             [SCIM_HAS_QT4=yes],
             [SCIM_HAS_QT4=no])
 
@@ -306,7 +306,7 @@ if test "$SCIM_HAS_QT4" = "yes"; then
     QT4_PREFIX=`$PKG_CONFIG --variable=prefix QtCore`
     QT4_LIBDIR=`$PKG_CONFIG --variable=libdir QtCore`
   fi
-  QT4_MOC=$QT4_PREFIX/bin/moc
+  QT4_MOC=`$PKG_CONFIG --variable=moc_location QtCore`
   QT4_IM_MODULEDIR=$QT4_LIBDIR/qt4/plugins/inputmethods
   AC_SUBST(QT4_MOC)
   AC_SUBST(QT4_IM_MODULEDIR)
@@ -314,6 +314,35 @@ if test "$SCIM_HAS_QT4" = "yes"; then
   AC_SUBST(QT4_LIBDIR)
 fi
 
+PKG_CHECK_MODULES(QT5, [xproto, xcb-keysyms, Qt5X11Extras >= 5.0, Qt5Widgets >= 5.0],
+            [SCIM_HAS_QT5=yes],
+            [SCIM_HAS_QT5=no])
+
+if test "$SCIM_HAS_QT5" = "yes"; then
+  if test -z "$QT5_PREFIX"; then
+    QT5_PREFIX=`$PKG_CONFIG --variable=prefix Qt5Core`
+    QT5_LIBDIR=`$PKG_CONFIG --variable=libdir Qt5Core`
+  fi
+  QT5_INCDIR=`$PKG_CONFIG --variable=includedir Qt5Core`
+  QT5_VERSION=`$PKG_CONFIG --modversion Qt5Core`
+  QT5_CFLAGS="$QT5_CFLAGS -I$QT5_INCDIR/QtCore/$QT5_VERSION -I$QT5_INCDIR/QtCore/$QT5_VERSION/QtCore -I$QT5_INCDIR/QtGui/$QT5_VERSION"
+  QT5_MOC=`$PKG_CONFIG --variable=host_bins Qt5Core`/moc
+  QT5_IM_MODULEDIR=$QT5_LIBDIR/qt5/plugins/platforminputcontexts
+  AC_SUBST(QT5_MOC)
+  AC_SUBST(QT5_IM_MODULEDIR)
+  AC_SUBST(QT5_PREFIX)
+  AC_SUBST(QT5_LIBDIR)
+
+  tmp_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$QT5_CFLAGS -fPIC"
+  AC_LANG_PUSH([C++])
+  AC_CHECK_HEADERS([QtGui/qpa/qplatforminputcontext.h],
+                   [SCIM_HAS_QT5_PRIVATE=yes],
+                   [AC_MSG_ERROR([QT5 platform development headers are needed. In Debian based OS, install qtbase5-private-dev package])])
+  CPPFLAGS="$tmp_CPPFLAGS"
+  AC_LANG_POP
+fi
+
 # Check if we should build scim-bridge-clutter-immodule
 PKG_CHECK_MODULES(CLUTTER, clutter-1.0,
            [SCIM_HAS_CLUTTER=yes],
@@ -371,6 +400,11 @@ AC_ARG_WITH([qt4-moc],
 		[Select QT4 moc program (default to QT4_PREFIX/bin/moc)])],
 	[QT4_MOC=$with_qt4_moc])
 
+AC_ARG_WITH([qt5-moc],
+	[AS_HELP_STRING([--with-qt5-moc=file],
+		[Select QT5 moc program (default to QT5_PREFIX/bin/moc)])],
+	[QT5_MOC=$with_qt5_moc])
+
 AC_ARG_WITH([qt3-im-module-dir],
 	[AS_HELP_STRING([--with-qt3-im-module-dir=dir],
 		[Select QT3 immodule dir])],
@@ -381,6 +415,11 @@ AC_ARG_WITH([qt4-im-module-dir],
 		[Select QT4 immodule dir])],
 	[QT4_IM_MODULEDIR=$with_qt4_im_module_dir])
 
+AC_ARG_WITH([qt5-im-module-dir],
+	[AS_HELP_STRING([--with-qt5-im-module-dir=dir],
+		[Select QT5 immodule dir])],
+	[QT5_IM_MODULEDIR=$with_qt5_im_module_dir])
+
 AC_ARG_WITH([clutter-im-module-dir],
 	[AS_HELP_STRING([--with-clutter-im-module-dir=dir],
 		[Select clutter immodule dir])],
@@ -518,6 +557,12 @@ AC_ARG_ENABLE([qt4-immodule],
 	[],
 	[enable_qt4_immodule=yes])
 
+AC_ARG_ENABLE([qt5-immodule],
+	[AS_HELP_STRING([--disable-qt5-immodule],
+		[Do not build QT5 IMModule])],
+	[],
+	[enable_qt5_immodule=yes])
+
 AC_ARG_ENABLE([clutter-immodule],
 	[AS_HELP_STRING([--enable-clutter-immodule],
 		[Do not build CLUTTER IMModule])],
@@ -722,6 +767,17 @@ else
   enable_qt4_immodule=no
 fi
 
+if test "$enable_qt5_immodule" = "yes" -a "$SCIM_HAS_QT5" = "yes"; then
+  SCIM_BUILD_QT5_IMMODULE=1
+  SCIM_BUILD_IMMODULE=1
+  enable_immodule=yes
+  SCIM_BUILD_IM_AGENT=1
+  enable_im_agent=yes
+else
+  SCIM_BUILD_QT5_IMMODULE=0
+  enable_qt5_immodule=no
+fi
+
 if test "$enable_clutter_immodule" = "yes" -a \
 	"$SCIM_HAS_CLUTTER" = "yes" -a \
 	"$SCIM_HAS_CLUTTERIMCONTEXT" = "yes" ; then
@@ -888,6 +944,9 @@ AM_CONDITIONAL(SCIM_BUILD_QT3_IMMODULE,
 AM_CONDITIONAL(SCIM_BUILD_QT4_IMMODULE,
         [test "$enable_qt4_immodule" = "yes"])
 
+AM_CONDITIONAL(SCIM_BUILD_QT5_IMMODULE,
+        [test "$enable_qt5_immodule" = "yes"])
+
 AM_CONDITIONAL(SCIM_BUILD_CLUTTER_IMMODULE,
         [test "$enable_clutter_immodule" = "yes"])
 
@@ -935,6 +994,7 @@ AC_SUBST(SCIM_BUILD_GTK3_IMMODULE)
 AC_SUBST(SCIM_BUILD_GTK4_IMMODULE)
 AC_SUBST(SCIM_BUILD_QT3_IMMODULE)
 AC_SUBST(SCIM_BUILD_QT4_IMMODULE)
+AC_SUBST(SCIM_BUILD_QT5_IMMODULE)
 AC_SUBST(SCIM_BUILD_CLUTTER_IMMODULE)
 AC_SUBST(SCIM_BUILD_IMMODULE)
 
@@ -996,6 +1056,9 @@ AC_CONFIG_FILES([Makefile
 		 extras/immodules/client-gtk/gtk2/Makefile
 		 extras/immodules/client-gtk/gtk3/Makefile
 		 extras/immodules/client-gtk/gtk4/Makefile
+		 extras/immodules/client-qt/qt3/Makefile
+		 extras/immodules/client-qt/qt4/Makefile
+		 extras/immodules/client-qt/qt5/Makefile
 		 extras/immodules/client-clutter/Makefile
 		 extras/immodules/doc/Makefile
 		 tests/Makefile
@@ -1045,10 +1108,12 @@ Module options:
   GTK4 IMModule dir        $GTK4_IM_MODULEDIR
   QT3 IMModule dir         $QT3_IM_MODULEDIR
   QT4 IMModule dir         $QT4_IM_MODULEDIR
+  QT5 IMModule dir         $QT5_IM_MODULEDIR
   Clutter IMModule dir     $CLUTTER_IM_MODULEDIR
 
   QT3 moc program          $QT3_MOC
   QT4 moc program          $QT4_MOC
+  QT5 moc program          $QT5_MOC
 
   Original GTK2 IMModule   $enable_orig_gtk2_immodule
   Original GTK3 IMModule   $enable_orig_gtk3_immodule
@@ -1059,5 +1124,6 @@ Module options:
   GTK4 IMModule            $enable_gtk4_immodule
   QT3 IMModule             $enable_qt3_immodule
   QT4 IMModule             $enable_qt4_immodule
+  QT5 IMModule             $enable_qt5_immodule
   CLUTTER IMModule         $enable_clutter_immodule
 ])
diff --git a/extras/immodules/Makefile.am b/extras/immodules/Makefile.am
index 8fceaa8..607a926 100644
--- a/extras/immodules/Makefile.am
+++ b/extras/immodules/Makefile.am
@@ -37,4 +37,4 @@
 MAINTAINERCLEANFILES    = Makefile.in
 CLEANFILES      = *.bak
 
-SUBDIRS = common client-common client-gtk/gtk2 client-gtk/gtk3 client-gtk/gtk4 client-clutter agent doc
+SUBDIRS = common client-common client-gtk/gtk2 client-gtk/gtk3 client-gtk/gtk4 client-qt/qt3 client-qt/qt4 client-qt/qt5 client-clutter agent doc
diff --git a/extras/immodules/client-qt/im-scim-bridge-qt.cpp b/extras/immodules/client-qt/im-scim-bridge-qt.cpp
index ddf1df6..523e0cb 100644
--- a/extras/immodules/client-qt/im-scim-bridge-qt.cpp
+++ b/extras/immodules/client-qt/im-scim-bridge-qt.cpp
@@ -19,54 +19,18 @@
 
 #include <cassert>
 
-#include <Qt>
-#include <qpa/qplatforminputcontextplugin_p.h>
-
-using namespace Qt;
-
 #include "scim-bridge.h"
 #include "scim-bridge-client-common-qt.h"
-#include "scim-bridge-client-imcontext-qt.h"
 #include "scim-bridge-client-qt.h"
+#include "im-scim-bridge-qt.h"
+
+#if QT_VERSION >= 0x040000
+using namespace Qt;
+#endif
 
 /* Static Variables */
 static ScimBridgeClientQt *client = NULL;
 
-/* The class Definition */
-class ScimBridgeInputContextPlugin: public QPlatformInputContextPlugin
-{
-        Q_OBJECT
-        Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE "scim.json")
-
-    private:
-
-        /**
-         * The language list for SCIM.
-         */
-        static QStringList scim_languages;
-
-    public:
-
-        ScimBridgeInputContextPlugin ();
-
-        ~ScimBridgeInputContextPlugin ();
-
-        QStringList keys () const;
-
-        QStringList languages (const QString &key);
-
-        QString description (const QString &key);
-        
-        ScimBridgeClientIMContext *create (const QString &key, const QStringList &param) Q_DECL_OVERRIDE;
-
-        QString displayName (const QString &key);
-
-};
-
-
-/* Implementations */
-QStringList ScimBridgeInputContextPlugin::scim_languages;
-
 ScimBridgeInputContextPlugin::ScimBridgeInputContextPlugin ()
 {
 }
@@ -78,6 +42,12 @@ ScimBridgeInputContextPlugin::~ScimBridgeInputContextPlugin ()
     client = NULL;
 }
 
+#if QT_VERSION < 0x050000
+
+/* Implementations */
+QStringList ScimBridgeInputContextPlugin::scim_languages;
+
+
 QStringList ScimBridgeInputContextPlugin::keys () const {
     QStringList identifiers;
     identifiers.push_back (SCIM_BRIDGE_IDENTIFIER_NAME);
@@ -104,10 +74,24 @@ QString ScimBridgeInputContextPlugin::description (const QString &key)
 }
 
 
-ScimBridgeClientIMContext *ScimBridgeInputContextPlugin::create (const QString &key, const QStringList &param)
+QString ScimBridgeInputContextPlugin::displayName (const QString &key)
 {
-    Q_UNUSED(param);
+    return key;
+}
+
+#endif
+
+#if QT_VERSION >= 0x050000
+QInputContext *ScimBridgeInputContextPlugin::create (const QString &key, const QStringList &paramList)
+#else
+QInputContext *ScimBridgeInputContextPlugin::create (const QString &key)
+#endif
+{
+#if QT_VERSION >= 0x040000
     if (key.toLower () != SCIM_BRIDGE_IDENTIFIER_NAME) {
+#else
+    if (key.lower () != SCIM_BRIDGE_IDENTIFIER_NAME) {
+#endif
         return NULL;
     } else {
         if (client == NULL) client = new ScimBridgeClientQt ();
@@ -115,10 +99,8 @@ ScimBridgeClientIMContext *ScimBridgeInputContextPlugin::create (const QString &
     }
 }
 
-
-QString ScimBridgeInputContextPlugin::displayName (const QString &key)
-{
-    return key;
-}
-
-#include "im-scim-bridge-qt.moc"
+#if QT_VERSION < 0x040000
+Q_EXPORT_PLUGIN (ScimBridgeInputContextPlugin)
+#elif QT_VERSION < 0x050000
+Q_EXPORT_PLUGIN2 (ScimBridgeInputContextPlugin, ScimBridgeInputContextPlugin)
+#endif
diff --git a/extras/immodules/client-qt/im-scim-bridge-qt.h b/extras/immodules/client-qt/im-scim-bridge-qt.h
new file mode 100644
index 0000000..41fa1a7
--- /dev/null
+++ b/extras/immodules/client-qt/im-scim-bridge-qt.h
@@ -0,0 +1,57 @@
+#include <QtGlobal>
+#if QT_VERSION >= 0x050000
+#include <QObject>
+#include <QtCore/QStringList>
+#include <QtGui/qpa/qplatforminputcontextplugin_p.h>
+#include <QtGui/qpa/qplatforminputcontext.h>
+#elif QT_VERSION >= 0x040000
+#include <Qt>
+#include <QInputContextPlugin>
+#else
+#include <qinputcontextplugin.h>
+#endif
+
+#if QT_VERSION >= 0x050000
+typedef QPlatformInputContext QInputContext;
+typedef QPlatformInputContextPlugin QInputContextPlugin;
+#elif QT_VERSION >= 0x040000
+using namespace Qt;
+#endif
+
+/* The class Definition */
+class ScimBridgeInputContextPlugin: public QInputContextPlugin
+{
+#if QT_VERSION >= 0x050000
+    Q_OBJECT
+
+    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface.5.1" FILE "scim.json")
+#endif
+
+    public:
+
+        ScimBridgeInputContextPlugin ();
+
+        ~ScimBridgeInputContextPlugin ();
+
+#if QT_VERSION >= 0x050000
+        QInputContext *create(const QString &key, const QStringList &paramList);
+#else
+    private:
+
+        /**
+         * The language list for SCIM.
+         */
+        static QStringList scim_languages;
+
+    public:
+        QStringList keys () const;
+
+        QStringList languages (const QString &key);
+
+        QString description (const QString &key);
+
+        QString displayName (const QString &key);
+
+        QInputContext *create (const QString &key);
+#endif
+};
diff --git a/extras/immodules/client-qt/qt3/Makefile.am b/extras/immodules/client-qt/qt3/Makefile.am
new file mode 100644
index 0000000..e5ac16d
--- /dev/null
+++ b/extras/immodules/client-qt/qt3/Makefile.am
@@ -0,0 +1,72 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+##
+## Copyright (C) 2006 Ryo Dairiki
+##
+##
+## 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 and 
+## appearing in the file LICENSE.LGPL included in the package of this file.
+## You can also redistribute it and/or modify it under the terms of 
+## the GNU General Public License as published by the Free Software Foundation and 
+## appearing in the file LICENSE.GPL included in the package of this file.
+##
+## 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.
+
+if SCIM_BUILD_QT3_IMMODULE
+
+AM_CPPFLAGS	= -I$(top_builddir) \
+	    	  -I$(top_srcdir) \
+			  -I$(top_srcdir)/extras/immodules/common \
+			  -I$(top_srcdir)/extras/immodules/client-common
+
+noinst_HEADERS = ../scim-bridge-client-qt.h ../scim-bridge-client-imcontext-qt.h  ../scim-bridge-client-key-event-utility-qt.h ../scim-bridge-client-common-qt.h  ../im-scim-bridge-qt.h
+
+moduledir = @QT3_IM_MODULEDIR@
+module_LTLIBRARIES = im-scim.la
+
+im_scim_la_SOURCES = ../im-scim-bridge-qt.cpp \
+							../scim-bridge-client-qt.cpp \
+							../scim-bridge-client-imcontext-qt.cpp \
+							../scim-bridge-client-key-event-utility-qt.cpp \
+							moc_scim-bridge-client-qt.cpp
+
+im_scim_la_CXXFLAGS=@QT3_CFLAGS@ -DQT_IMMODULE -fPIC -Wl,-z,defs 
+im_scim_la_CFLAGS  =@QT3_CFLAGS@ -DQT_IMMODULE -fPIC -Wl,-z,defs 
+
+im_scim_la_LDFLAGS = -rpath $(moduledir) \
+							-avoid-version -no-undefined \
+							-module \
+							@QT3_LIBS@
+
+im_scim_la_LIBADD  = $(top_builddir)/extras/immodules/common/libscimbridgecommon.la \
+					$(top_builddir)/extras/immodules/client-common/libscimbridgeclientcommon.la
+
+MOC = @QT3_MOC@
+
+moc_scim-bridge-client-qt.cpp: ../scim-bridge-client-qt.h
+	$(MOC) $< -o $@
+
+moc_im-scim-bridge-qt.cpp: ../im-scim-bridge-qt.h
+	$(MOC) $< -o $@
+
+else
+
+moc_scim-bridge-client-qt.cpp:
+	touch $@
+
+moc_im-scim-bridge-qt.cpp:
+	touch $@
+
+endif
+
+dist-hook:
+	-rm -f $(distdir)/moc_scim-bridge-client-qt.cpp \
+                            $(distdir)/moc_im-scim-bridge-qt.cpp
+
+MAINTAINERCLEANFILES 	= Makefile.in
+CLEANFILES = moc_scim-bridge-client-qt.cpp \
+                            moc_im-scim-bridge-qt.cpp
+
diff --git a/extras/immodules/client-qt/qt4/Makefile.am b/extras/immodules/client-qt/qt4/Makefile.am
new file mode 100644
index 0000000..8bcaded
--- /dev/null
+++ b/extras/immodules/client-qt/qt4/Makefile.am
@@ -0,0 +1,73 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+##
+## Copyright (C) 2006 Ryo Dairiki
+##
+##
+## 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 and 
+## appearing in the file LICENSE.LGPL included in the package of this file.
+## You can also redistribute it and/or modify it under the terms of 
+## the GNU General Public License as published by the Free Software Foundation and 
+## appearing in the file LICENSE.GPL included in the package of this file.
+##
+## 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.
+
+if SCIM_BUILD_QT4_IMMODULE
+
+AM_CPPFLAGS	= -I$(top_builddir) \
+	    	  -I$(top_srcdir) \
+			  -I$(top_srcdir)/extras/immodules/common \
+			  -I$(top_srcdir)/extras/immodules/client-common
+
+noinst_HEADERS = ../scim-bridge-client-qt.h ../scim-bridge-client-imcontext-qt.h ../scim-bridge-client-key-event-utility-qt.h ../scim-bridge-client-common-qt.h ../im-scim-bridge-qt.h
+
+moduledir = @QT4_IM_MODULEDIR@
+module_LTLIBRARIES = im-scim.la
+
+im_scim_la_SOURCES = ../im-scim-bridge-qt.cpp \
+							../scim-bridge-client-qt.cpp \
+							../scim-bridge-client-imcontext-qt.cpp \
+							../scim-bridge-client-key-event-utility-qt.cpp \
+							moc_scim-bridge-client-qt.cpp \
+                            moc_im-scim-bridge-qt.cpp
+
+im_scim_la_CXXFLAGS=@QT4_CFLAGS@ -DQT_IMMODULE -DQT4 -fPIC -Wl,-z,defs 
+im_scim_la_CFLAGS  =@QT4_CFLAGS@ -DQT_IMMODULE -DQT4 -fPIC -Wl,-z,defs 
+
+im_scim_la_LDFLAGS = -rpath $(moduledir) \
+							-avoid-version -no-undefined \
+							-module \
+							@QT4_LIBS@
+
+im_scim_la_LIBADD  = $(top_builddir)/extras/immodules/common/libscimbridgecommon.la \
+					$(top_builddir)/extras/immodules/client-common/libscimbridgeclientcommon.la
+
+MOC = @QT4_MOC@
+
+moc_scim-bridge-client-qt.cpp: ../scim-bridge-client-qt.h
+	$(MOC) $< -o $@
+
+moc_im-scim-bridge-qt.cpp: ../im-scim-bridge-qt.h
+	$(MOC) $< -o $@
+
+else
+
+moc_scim-bridge-client-qt.cpp:
+	touch $@
+
+moc_im-scim-bridge-qt.cpp:
+	touch $@
+
+endif
+
+dist-hook:
+	-rm -f $(distdir)/moc_scim-bridge-client-qt.cpp \
+                            $(distdir)/moc_im-scim-bridge-qt.cpp
+
+MAINTAINERCLEANFILES 	= Makefile.in
+CLEANFILES = moc_scim-bridge-client-qt.cpp \
+                            moc_im-scim-bridge-qt.cpp
+
diff --git a/extras/immodules/client-qt/qt5/Makefile.am b/extras/immodules/client-qt/qt5/Makefile.am
new file mode 100644
index 0000000..48596de
--- /dev/null
+++ b/extras/immodules/client-qt/qt5/Makefile.am
@@ -0,0 +1,72 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+##
+## Copyright (C) 2006 Ryo Dairiki
+##
+##
+## 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 and 
+## appearing in the file LICENSE.LGPL included in the package of this file.
+## You can also redistribute it and/or modify it under the terms of 
+## the GNU General Public License as published by the Free Software Foundation and 
+## appearing in the file LICENSE.GPL included in the package of this file.
+##
+## 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.
+
+if SCIM_BUILD_QT5_IMMODULE
+
+AM_CPPFLAGS	= -I$(top_builddir) \
+	    	  -I$(top_srcdir) \
+			  -I$(top_srcdir)/extras/immodules/common \
+			  -I$(top_srcdir)/extras/immodules/client-common
+
+noinst_HEADERS = ../scim-bridge-client-qt.h ../scim-bridge-client-imcontext-qt.h ../scim-bridge-client-key-event-utility-qt.h ../scim-bridge-client-common-qt.h ../im-scim-bridge-qt.h
+
+moduledir = @QT5_IM_MODULEDIR@
+module_LTLIBRARIES = libscimplatforminputcontextplugin.la
+
+libscimplatforminputcontextplugin_la_SOURCES = ../im-scim-bridge-qt.cpp \
+							../scim-bridge-client-qt.cpp \
+							../scim-bridge-client-imcontext-qt.cpp \
+							../scim-bridge-client-key-event-utility-qt.cpp \
+							moc_scim-bridge-client-qt.cpp \
+							moc_im-scim-bridge-qt.cpp
+
+libscimplatforminputcontextplugin_la_CXXFLAGS=@QT5_CFLAGS@ -DQT_IMMODULE -DQT5 -fPIC
+libscimplatforminputcontextplugin_la_CFLAGS  =@QT5_CFLAGS@ -DQT_IMMODULE -DQT5 -fPIC
+libscimplatforminputcontextplugin_la_LDFLAGS = -rpath $(moduledir) \
+							-avoid-version -no-undefined \
+							-module \
+							@QT5_LIBS@
+
+libscimplatforminputcontextplugin_la_LIBADD  = $(top_builddir)/extras/immodules/common/libscimbridgecommon.la \
+					        $(top_builddir)/extras/immodules/client-common/libscimbridgeclientcommon.la
+
+MOC = @QT5_MOC@
+
+moc_scim-bridge-client-qt.cpp: ../scim-bridge-client-qt.h
+	$(MOC) $< -DQT_VERSION=0x050000 -o $@
+
+moc_im-scim-bridge-qt.cpp: ../im-scim-bridge-qt.h
+	$(MOC) $< -DQT_VERSION=0x050000 -o $@
+
+else
+
+moc_im-scim-bridge-qt.cpp:
+	touch $@
+
+moc_scim-bridge-client-qt.cpp:
+	touch $@
+
+endif
+
+dist-hook:
+	-rm -f $(distdir)/moc_scim-bridge-client-qt.cpp \
+                            $(distdir)/moc_im-scim-bridge-qt.cpp
+
+MAINTAINERCLEANFILES 	= Makefile.in
+CLEANFILES = moc_scim-bridge-client-qt.cpp \
+                            moc_im-scim-bridge-qt.cpp
+
diff --git a/extras/immodules/client-qt/scim-bridge-client-common-qt.h b/extras/immodules/client-qt/scim-bridge-client-common-qt.h
index 6fcac17..c19782d 100644
--- a/extras/immodules/client-qt/scim-bridge-client-common-qt.h
+++ b/extras/immodules/client-qt/scim-bridge-client-common-qt.h
@@ -27,8 +27,14 @@
 #ifndef SCIMBRIDGECOMMONQT_H_
 #define SCIMBRIDGECOMMONQT_H_
 
+#include <QtGlobal>
+#if QT_VERSION >= 0x040000
 #include <QString>
 #include <QStringList>
+#else
+#include <qstring.h>
+#include <qstringlist.h>
+#endif
 
 #include "scim-bridge.h"
 
diff --git a/extras/immodules/client-qt/scim-bridge-client-imcontext-qt.cpp b/extras/immodules/client-qt/scim-bridge-client-imcontext-qt.cpp
index 26c0027..865b8d4 100644
--- a/extras/immodules/client-qt/scim-bridge-client-imcontext-qt.cpp
+++ b/extras/immodules/client-qt/scim-bridge-client-imcontext-qt.cpp
@@ -20,12 +20,20 @@
 #include <cassert>
 #include <string>
 
+#include <QtGlobal>
+#if QT_VERSION >= 0x050000
+#include <QInputMethodEvent>
+#include <QTextCharFormat>
+#include <QAbstractNativeEventFilter>
+#elif QT_VERSION >= 0x040000
 #include <QColor>
 #include <QInputMethodEvent>
 #include <QPalette>
 #include <QTextCharFormat>
-
+#endif
+#if defined(Q_WS_X11) || (QT_VERSION >= 0x050000)
 #include <QX11Info>
+#endif
 
 #include "scim-bridge-output.h"
 #include "scim-bridge-string.h"
@@ -35,11 +43,20 @@
 #include "scim-bridge-client-imcontext-qt.h"
 #include "scim-bridge-client-key-event-utility-qt.h"
 
+#if QT_VERSION >= 0x040000
 using namespace std;
 
 using namespace Qt;
 
 typedef QInputMethodEvent::Attribute QAttribute;
+#endif
+
+#if QT_VERSION < 0x050000
+namespace Qt {
+    typedef QFlags<InputMethodQuery> InputMethodQueries;
+}
+class QAbstractNativeEventFilter {};
+#endif
 
 /* Static variables */
 class ScimBridgeClientIMContextImpl;
@@ -49,7 +66,7 @@ static ScimBridgeClientIMContextImpl *focused_imcontext = NULL;
 static bool key_event_forwarded = false;
 
 /* Class Definition */
-class ScimBridgeClientIMContextImpl: public _ScimBridgeClientIMContext
+class ScimBridgeClientIMContextImpl: public _ScimBridgeClientIMContext, private QAbstractNativeEventFilter
 {
 
     public:
@@ -57,19 +74,58 @@ class ScimBridgeClientIMContextImpl: public _ScimBridgeClientIMContext
         ScimBridgeClientIMContextImpl ();
         ~ScimBridgeClientIMContextImpl ();
 
+#ifdef Q_WS_X11
         bool x11FilterEvent (QWidget *widget, XEvent *event);
-        bool filterEvent (const QEvent *event);
+#endif
+
+#if QT_VERSION >= 0x050000
+        bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
+#endif
+
+#if QT_VERSION >= 0x050000
+        bool isValid() const;
+        //bool hasCapability(Capability capability) const;
+
+        //void invokeAction(QInputMethod::Action, int cursorPosition);
+        //QRectF keyboardRect() const;
+
+        void showInputPanel();
+        void hideInputPanel();
+        bool isInputPanelVisible() const;
+        //
+        //QLocale locale() const;
+        //Qt::LayoutDirection inputDirection() const;
+
+        void update(Qt::InputMethodQueries queries=Qt::ImMicroFocus);
+
+        void setFocusObject(QObject *object);
 
-        void update ();
+        // helper function to abstract behaviours between Qt4 and Qt5
+        void sendEvent(QInputMethodEvent &event);
+        QWidget *focusWidget() const;
+
+#elif QT_VERSION >= 0x040000
+        void update () { updateMicroFocus(); }
         QString identifierName ();
         QString language ();
 
-        bool isValid() const Q_DECL_OVERRIDE;
-        void setFocusObject (QObject *object) Q_DECL_OVERRIDE;
         void widgetDestroyed (QWidget *widget);
 
-        bool isComposing () const;
         void mouseHandler (int offset, QMouseEvent *event);
+#else
+        // since this function can't handling caps lock correctly (QEvent lack of information),
+        // I move it here to not be included in Qt >= 4.0
+        bool filterEvent (const QEvent *event);
+        void setFocus ();
+        void unsetFocus ();
+        void setMicroFocus (int x, int y, int w, int h, QFont *font = 0);
+        void mouseHandler (int offset, QEvent::Type type, ButtonState button, ButtonState state);
+#endif
+
+#if QT_VERSION >= 0x040000
+        bool isComposing () const { return preedit_string.size () > 0; }
+        void updateMicroFocus ();
+#endif
 
         void reset ();
 
@@ -91,9 +147,11 @@ class ScimBridgeClientIMContextImpl: public _ScimBridgeClientIMContext
         scim_bridge_imcontext_id_t get_id () const;
         void set_id (scim_bridge_imcontext_id_t new_id);
 
+#if QT_VERSION >= 0x040000
         bool get_surrounding_text (unsigned int before_max, unsigned int after_max, char **string, int *cursor_position);
         bool delete_surrounding_text (int offset, int length);
         bool replace_surrounding_text (const char *text, int cursor_position);
+#endif
 
     private:
 
@@ -103,7 +161,16 @@ class ScimBridgeClientIMContextImpl: public _ScimBridgeClientIMContext
 
         QString preedit_string;
 
+#if QT_VERSION >= 0x040000
         QList<QAttribute> preedit_attributes;
+#else
+        int preedit_selected_offset;
+        int preedit_selected_length;
+#endif
+
+#if QT_VERSION >= 0x050000
+        QObject *focused_object;
+#endif
 
         int preedit_cursor_position;
 
@@ -142,11 +209,19 @@ _ScimBridgeClientIMContext *_ScimBridgeClientIMContext::alloc ()
 }
 
 
-ScimBridgeClientIMContextImpl::ScimBridgeClientIMContextImpl (): id (-1), preedit_shown (false)
+ScimBridgeClientIMContextImpl::ScimBridgeClientIMContextImpl (): id (-1), preedit_shown (false), preedit_cursor_position(0)
 {
     scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::ScimBridgeClientIMContextImpl ()");
 
+#if QT_VERSION >= 0x040000
     preedit_attributes.push_back (QAttribute (QInputMethodEvent::Cursor, preedit_cursor_position, true, 0));
+#else
+    preedit_selected_offset = 0;
+    preedit_selected_length = 0;
+#endif
+#if QT_VERSION >= 0x050000
+    focused_object = NULL;
+#endif
 
     if (!scim_bridge_client_is_messenger_opened ()) {
         scim_bridge_perrorln ("The messenger is now down");
@@ -155,6 +230,10 @@ ScimBridgeClientIMContextImpl::ScimBridgeClientIMContextImpl (): id (-1), preedi
     } else {
         scim_bridge_pdebugln (1, "IMContext registered: id = %d", id);
     }
+
+#if QT_VERSION >= 0x050000
+    qApp->installNativeEventFilter(this);
+#endif
 }
 
 
@@ -162,6 +241,10 @@ ScimBridgeClientIMContextImpl::~ScimBridgeClientIMContextImpl ()
 {
     scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::~ScimBridgeClientIMContextImpl ()");
 
+#if QT_VERSION >= 0x050000
+    qApp->removeNativeEventFilter(this);
+#endif
+
     if (this == focused_imcontext) focus_out ();
 
     if (!scim_bridge_client_is_messenger_opened ()) {
@@ -173,6 +256,100 @@ ScimBridgeClientIMContextImpl::~ScimBridgeClientIMContextImpl ()
     }
 }
 
+
+#if QT_VERSION >= 0x050000
+
+void ScimBridgeClientIMContextImpl::update(Qt::InputMethodQueries queries)
+{
+    scim_bridge_pdebugln (4, "ScimBridgeClientIMContextImpl::update (0x%lx)", queries);
+
+    if(queries & Qt::ImMicroFocus) {
+        updateMicroFocus();
+    }
+}
+
+bool ScimBridgeClientIMContextImpl::isValid() const
+{
+    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::isValid ()");
+    return scim_bridge_client_is_initialized();
+}
+
+void ScimBridgeClientIMContextImpl::showInputPanel()
+{
+    if(scim_bridge_client_is_messenger_opened ()) return;
+
+    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::showInputPanel ()");
+
+    focus_in();
+}
+
+void ScimBridgeClientIMContextImpl::hideInputPanel()
+{
+    if(!scim_bridge_client_is_messenger_opened ()) return;
+
+    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::hideInputPanel ()");
+    
+    focus_out();
+}
+
+bool ScimBridgeClientIMContextImpl::isInputPanelVisible() const
+{
+    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::isInputPanelVisible ()");
+    return scim_bridge_client_is_messenger_opened ();
+}
+
+void ScimBridgeClientIMContextImpl::setFocusObject(QObject *object)
+{
+    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::setFocusObject");
+
+    focused_object = object;
+}
+
+void ScimBridgeClientIMContextImpl::sendEvent(QInputMethodEvent &event)
+{
+    if(focused_object) {
+        qApp->sendEvent(focused_object, &event);
+    }
+}
+
+QWidget *ScimBridgeClientIMContextImpl::focusWidget() const
+{
+    return qobject_cast<QWidget *>(focused_object);
+}
+
+bool ScimBridgeClientIMContextImpl::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
+{
+    bool isXcb = eventType.startsWith("xcb");
+    if (!isXcb && !focused_object) return false;
+
+    xcb_generic_event_t *event = static_cast<xcb_generic_event_t*>(message);
+    uint8_t event_type = event->response_type & ~0x80;
+    if (key_event_forwarded || (event_type != XCB_KEY_PRESS && event_type != XCB_KEY_RELEASE)) return false;
+    
+    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::nativeEventFilter");
+
+    if (focused_imcontext != this) focus_in ();
+
+    if (scim_bridge_client_is_messenger_opened ()) {
+        ScimBridgeKeyEvent *bridge_key_event = scim_bridge_key_event_xcb_to_bridge (event, QX11Info::connection());
+
+        boolean consumed = FALSE;
+        const retval_t retval_error = scim_bridge_client_handle_key_event (this, bridge_key_event, &consumed);
+
+        scim_bridge_free_key_event (bridge_key_event);
+
+        if (retval_error) {
+            scim_bridge_perrorln ("An IOException at x11FilterEvent ()");
+        } else {
+            return consumed;
+        }
+    }
+
+    return false;
+}
+
+#elif QT_VERSION >= 0x040000
+
 QString ScimBridgeClientIMContextImpl::identifierName ()
 {
     return SCIM_BRIDGE_IDENTIFIER_NAME;
@@ -190,28 +367,79 @@ void ScimBridgeClientIMContextImpl::widgetDestroyed (QWidget *widget)
     update ();
 }
 
-bool ScimBridgeClientIMContextImpl::isValid() const
+void ScimBridgeClientIMContextImpl::mouseHandler (int offset, QMouseEvent *mevent)
 {
-    return true;
 }
 
-void ScimBridgeClientIMContextImpl::setFocusObject (QObject *object)
+#else
+
+void ScimBridgeClientIMContextImpl::setFocus ()
 {
-    scim_bridge_pdebugln (4, "ScimBridgeClientIMContextImpl::setFocusObject ()");
-    QPlatformInputContext::setFocusObject (object);
-    if (object == NULL) {
-        focus_out ();
-    } else {
-        focus_in ();
-    }
-    update ();
+    scim_bridge_pdebugln (4, "ScimBridgeClientIMContextImpl::setFocus ()");
+    
+    focus_in ();
 }
 
-void ScimBridgeClientIMContextImpl::update ()
+
+void ScimBridgeClientIMContextImpl::unsetFocus ()
 {
-    scim_bridge_pdebugln (4, "ScimBridgeClientIMContextImpl::update ()");
+    scim_bridge_pdebugln (4, "ScimBridgeClientIMContextImpl::unsetFocus ()");
+    
+    focus_out ();
+}
 
-    QWidget *focused_widget = qApp->focusWidget ();
+
+void ScimBridgeClientIMContextImpl::setMicroFocus (int x, int y, int w, int h, QFont *qfont)
+{
+    scim_bridge_pdebugln (4, "ScimBridgeClientIMContextImpl::setMicroFocus ()");
+
+    QPoint new_cursor_location (x, y + h);
+    set_cursor_location (new_cursor_location);
+}
+
+void ScimBridgeClientIMContextImpl::mouseHandler (int offset, QEvent::Type type, ButtonState button, ButtonState state)
+{
+}
+
+bool ScimBridgeClientIMContextImpl::filterEvent (const QEvent *qevent)
+{
+    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::filterEvent ()");
+
+#ifndef Q_WS_X11
+    if (key_event_forwarded || (qevent->type () != QEvent::KeyPress && qevent->type () != QEvent::KeyRelease)) return false;
+    
+    if (focused_imcontext != this) focus_in ();
+
+    if (scim_bridge_client_is_messenger_opened ()) {
+        const QKeyEvent *key_event = static_cast<const QKeyEvent*> (qevent);
+        ScimBridgeKeyEvent *bridge_key_event = scim_bridge_key_event_qt_to_bridge (key_event);
+        
+        if (scim_bridge_key_event_get_code (bridge_key_event) == SCIM_BRIDGE_KEY_CODE_NullKey)
+            return false;
+        
+        boolean consumed = FALSE;
+        const retval_t retval_error = scim_bridge_client_handle_key_event (this, bridge_key_event, &consumed);
+
+        scim_bridge_free_key_event (bridge_key_event);
+
+        if (retval_error) {
+            scim_bridge_perrorln ("An IOException at filterEvent ()");
+        } else {
+            return consumed;
+        }
+    }
+#endif
+
+    return false;
+}
+
+#endif
+
+#if QT_VERSION >= 0x040000
+
+void ScimBridgeClientIMContextImpl::updateMicroFocus ()
+{
+    QWidget *focused_widget = focusWidget ();
     if (focused_widget != NULL) {
         if (focused_imcontext == NULL)
             focus_in ();
@@ -223,16 +451,6 @@ void ScimBridgeClientIMContextImpl::update ()
     }
 }
 
-bool ScimBridgeClientIMContextImpl::isComposing () const
-{
-    scim_bridge_pdebugln (4, "ScimBridgeClientIMContextImpl::isComposing ()");
-    return preedit_string.size () > 0;
-}
-
-void ScimBridgeClientIMContextImpl::mouseHandler (int offset, QMouseEvent *mevent)
-{
-}
-
 bool ScimBridgeClientIMContextImpl::get_surrounding_text (unsigned int before_max, unsigned int after_max, char **text, int *cursor_position)
 {
     scim_bridge_pdebugln (6, "ScimBridgeClientIMContextImpl::get_surrounding_text ()");
@@ -254,6 +472,10 @@ bool ScimBridgeClientIMContextImpl::replace_surrounding_text (const char *text,
     return false;
 }
 
+#endif
+
+#ifdef Q_WS_X11
+
 bool ScimBridgeClientIMContextImpl::x11FilterEvent (QWidget *widget, XEvent *xevent)
 {
     scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::x11FilterEvent ()");
@@ -280,44 +502,20 @@ bool ScimBridgeClientIMContextImpl::x11FilterEvent (QWidget *widget, XEvent *xev
     return false;
 }
 
-bool ScimBridgeClientIMContextImpl::filterEvent (const QEvent *qevent)
-{
-    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::filterEvent ()");
-
-    if (key_event_forwarded || (qevent->type () != QEvent::KeyPress && qevent->type () != QEvent::KeyRelease)) return false;
-    
-    if (focused_imcontext != this) focus_in ();
-
-    if (scim_bridge_client_is_messenger_opened ()) {
-        const QKeyEvent *key_event = static_cast<const QKeyEvent*> (qevent);
-        ScimBridgeKeyEvent *bridge_key_event = scim_bridge_key_event_qt_to_bridge (key_event);
-        
-        if (scim_bridge_key_event_get_code (bridge_key_event) == SCIM_BRIDGE_KEY_CODE_NullKey)
-            return false;
-        
-        boolean consumed = FALSE;
-        const retval_t retval_error = scim_bridge_client_handle_key_event (this, bridge_key_event, &consumed);
-
-        scim_bridge_free_key_event (bridge_key_event);
-
-        if (retval_error) {
-            scim_bridge_perrorln ("An IOException at filterEvent ()");
-        } else {
-            return consumed;
-        }
-    }
-
-    return false;
-}
-
+#endif
 
 void ScimBridgeClientIMContextImpl::reset ()
 {
     scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::reset ()");
 
     preedit_cursor_position = 0;
+#if QT_VERSION >= 0x040000
     preedit_attributes.clear ();
     preedit_attributes.push_back (QAttribute (QInputMethodEvent::Cursor, preedit_cursor_position, true, 0));
+#else
+    preedit_selected_offset = 0;
+    preedit_selected_length = 0;
+#endif
     preedit_string = "";
 
     if (scim_bridge_client_is_messenger_opened ()) {
@@ -325,6 +523,10 @@ void ScimBridgeClientIMContextImpl::reset ()
             scim_bridge_perrorln ("An IOException at filterEvent ()");
         }
     }
+
+#if QT_VERSION < 0x040000
+    QInputContext::reset ();
+#endif
 }
 
 
@@ -398,19 +600,26 @@ void ScimBridgeClientIMContextImpl::set_commit_string (const char *new_string)
 
 void ScimBridgeClientIMContextImpl::commit ()
 {
-    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::commit ()");
-    
     if (commit_string.length () <= 0) return;
-    scim_bridge_pdebugln (9, "commit string: %s", commit_string.toUtf8 ().data ());
 
-    QObject *input = qApp->focusObject();
-    if (!input) return;
+    scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::commit (): '%s', %d", commit_string.toUtf8().constData(), commit_string.length());
+    
+#if QT_VERSION >= 0x040000
+    scim_bridge_pdebugln (9, "commit string: %s", commit_string.toUtf8 ().constData ());
+#endif
 
     const bool is_composing = isComposing ();
 
+#if QT_VERSION >= 0x040000
     QInputMethodEvent commit_event;
     commit_event.setCommitString (commit_string);
-    QCoreApplication::sendEvent (input, &commit_event);
+    sendEvent (commit_event);
+#else
+    if (!is_composing) sendIMEvent (QEvent::IMStart);
+    sendIMEvent (QEvent::IMEnd, commit_string);
+#endif
+
+    commit_string.resize(0);
 
     if (is_composing) update_preedit ();
 }
@@ -423,9 +632,21 @@ void ScimBridgeClientIMContextImpl::forward_key_event (const ScimBridgeKeyEvent
     QWidget *focused_widget = qApp->focusWidget ();
     if (focused_widget != NULL) {
         key_event_forwarded = true;
+#ifdef Q_WS_X11
+        const WId window_id = focused_widget->winId ();
+#if QT_VERSION >= 0x040000
+        Display *x11_display = QX11Info::display();
+#else
+        Display *x11_display = qt_xdisplay ();
+#endif
+        XEvent *x_event = scim_bridge_key_event_bridge_to_x11 (key_event, x11_display, window_id);
+        qApp->x11ProcessEvent (x_event);
+        free (x_event);
+#else
         QKeyEvent *forwarded_key_event = scim_bridge_key_event_bridge_to_qt (key_event);
         QApplication::sendEvent (focused_widget, forwarded_key_event);
         delete forwarded_key_event;
+#endif
         key_event_forwarded = false;
     } else {
         scim_bridge_pdebugln (4, "No widget is focused");
@@ -441,8 +662,13 @@ void ScimBridgeClientIMContextImpl::set_preedit_shown (bool shown)
     if (!preedit_shown) {
         preedit_string = "";
         preedit_cursor_position = 0;
+#if QT_VERSION >= 0x040000
         preedit_attributes.clear ();
         preedit_attributes.push_back (QAttribute (QInputMethodEvent::Cursor, preedit_cursor_position, true, 0));
+#else
+        preedit_selected_offset = 0;
+        preedit_selected_length = 0;
+#endif
     }
 }
 
@@ -465,8 +691,13 @@ void ScimBridgeClientIMContextImpl::set_preedit_attributes (ScimBridgeAttribute*
 {
     scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::set_preedit_attribute ()");
     
+#if QT_VERSION >= 0x040000
     preedit_attributes.clear ();
     preedit_attributes.push_back (QAttribute (QInputMethodEvent::Cursor, preedit_cursor_position, true, 0));
+#else
+    preedit_selected_offset = 0;
+    preedit_selected_length = 0;
+#endif
 
     for (int i = 0; i < attribute_count; ++i) {
         const ScimBridgeAttribute *attribute = attributes[i];
@@ -476,9 +707,13 @@ void ScimBridgeClientIMContextImpl::set_preedit_attributes (ScimBridgeAttribute*
         const scim_bridge_attribute_type_t attribute_type = scim_bridge_attribute_get_type (attribute);
         const scim_bridge_attribute_value_t attribute_value = scim_bridge_attribute_get_value (attribute);
 
+#if QT_VERSION >= 0x040000
         const size_t attribute_length = attribute_end - attribute_begin;
 
         const QWidget *focused_widget = qApp->focusWidget ();
+        if(!focused_widget) {
+            break;
+        }
         const QPalette &palette = focused_widget->palette ();
 
         const QBrush &reversed_foreground = palette.base ();
@@ -542,6 +777,13 @@ void ScimBridgeClientIMContextImpl::set_preedit_attributes (ScimBridgeAttribute*
         default:
             break;
         }
+#else
+        if (attribute_type == ATTRIBUTE_DECORATE && (attribute_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_HIGHLIGHT || attribute_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_REVERSE)) {
+            preedit_selected_offset = attribute_begin;
+            preedit_selected_length = attribute_end - attribute_begin;
+            break;
+        }
+#endif
     }
 }
 
@@ -550,13 +792,26 @@ void ScimBridgeClientIMContextImpl::update_preedit ()
 {
     scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::update_preedit ()");
 
-    QObject *input = qApp->focusObject();
-    if (!input) return;
-
+#if QT_VERSION >= 0x040000
     preedit_attributes[0] = QAttribute (QInputMethodEvent::Cursor, preedit_cursor_position, true, 0);
     QInputMethodEvent im_event (preedit_string, preedit_attributes);
-    QCoreApplication::sendEvent(input, &im_event);
+    sendEvent (im_event);
     update ();
+#else
+    if (preedit_shown) {
+        if (!isComposing ()) sendIMEvent (QEvent::IMStart);
+        const size_t preedit_length = preedit_string.length ();
+
+        size_t cursor_position = preedit_cursor_position;
+        if (cursor_position > preedit_length) cursor_position = preedit_length;
+
+        size_t selected_length = preedit_selected_length;
+        if (cursor_position + selected_length > preedit_length) selected_length = preedit_length - cursor_position;
+        sendIMEvent (QEvent::IMCompose, preedit_string, cursor_position, selected_length);
+    } else {
+        if (isComposing ()) sendIMEvent (QEvent::IMEnd);
+    }
+#endif
 }
 
 
@@ -665,22 +920,37 @@ void scim_bridge_client_imcontext_update_preedit (ScimBridgeClientIMContext *imc
 
 boolean scim_bridge_client_imcontext_get_surrounding_text (ScimBridgeClientIMContext *imcontext, int before_max, int after_max, char **string, int *cursor_position)
 {
+#if QT_VERSION >= 0x040000
     ScimBridgeClientIMContextImpl *imcontext_impl = static_cast<ScimBridgeClientIMContextImpl*> (imcontext);
     return imcontext_impl->get_surrounding_text (before_max, after_max, string, cursor_position);
+#else
+    scim_bridge_perrorln ("FIXME: scim_bridge_client_imcontext_get_surrounding_text () is not yet implemented.");
+    return FALSE;
+#endif
 }
 
 
 boolean scim_bridge_client_imcontext_delete_surrounding_text (ScimBridgeClientIMContext *imcontext, int offset, int length)
 {
+#if QT_VERSION >= 0x040000
     ScimBridgeClientIMContextImpl *imcontext_impl = static_cast<ScimBridgeClientIMContextImpl*> (imcontext);
     return imcontext_impl->delete_surrounding_text (offset, length);
+#else
+    scim_bridge_perrorln ("FIXME: scim_bridge_client_imcontext_delete_surrounding_text () is not yet implemented.");
+    return FALSE;
+#endif
 }
 
 
 boolean scim_bridge_client_imcontext_replace_surrounding_text (ScimBridgeClientIMContext *imcontext, int cursor_position, const char *string)
 {
+#if QT_VERSION >= 0x040000
     ScimBridgeClientIMContextImpl *imcontext_impl = static_cast<ScimBridgeClientIMContextImpl*> (imcontext);
     return imcontext_impl->replace_surrounding_text (string, cursor_position);
+#else
+    scim_bridge_perrorln ("FIXME: scim_bridge_client_imcontext_replace_surrounding_text () is not yet implemented.");
+    return FALSE;
+#endif
 }
 
 
diff --git a/extras/immodules/client-qt/scim-bridge-client-imcontext-qt.h b/extras/immodules/client-qt/scim-bridge-client-imcontext-qt.h
index 4bec2f7..7530acd 100644
--- a/extras/immodules/client-qt/scim-bridge-client-imcontext-qt.h
+++ b/extras/immodules/client-qt/scim-bridge-client-imcontext-qt.h
@@ -26,14 +26,30 @@
 #ifndef SCIMBRIDGECLIENTIMCONTEXTQT_H_
 #define SCIMBRIDGECLIENTIMCONTEXTQT_H_
 
+#include <QtGlobal>
+#if QT_VERSION >= 0x040000
 #include <QApplication>
 #include <QEvent>
 #include <QFont>
-#include <qpa/qplatforminputcontext.h>
-#include <QInputMethodEvent>
 #include <QObject>
 #include <QPoint>
 #include <QWidget>
+#else
+#include <qapplication.h>
+#include <qevent.h>
+#include <qfont.h>
+#include <qinputcontext.h>
+#include <qobject.h>
+#include <qptrlist.h>
+#include <qpoint.h>
+#include <qwidget.h>
+#endif
+#if QT_VERSION >= 0x050000
+#include <QtGui/qpa/qplatforminputcontext.h>
+#elif QT_VERSION >= 0x040000
+#include <QInputContext>
+#include <QInputMethodEvent>
+#endif
 
 #include "scim-bridge.h"
 #include "scim-bridge-attribute.h"
@@ -42,10 +58,14 @@
 
 #include "scim-bridge-client-common-qt.h"
 
+#if QT_VERSION >= 0x050000
+typedef QPlatformInputContext QInputContext;
+#endif
+
 /**
  * IMContext class for qt client.
  */
-struct _ScimBridgeClientIMContext: public QPlatformInputContext
+struct _ScimBridgeClientIMContext: public QInputContext
 {
 
     public:
@@ -82,6 +102,50 @@ struct _ScimBridgeClientIMContext: public QPlatformInputContext
          */
         virtual ~_ScimBridgeClientIMContext () {}
 
+#ifdef Q_WS_X11
+        /**
+         * Filter a event from X11.
+         *
+         * @param widget The widget.
+         * @param A event from X11.
+         * @return If this event is consumed or not.
+         */
+        virtual bool x11FilterEvent (QWidget *widget, XEvent *event) = 0;
+#endif
+
+#if QT_VERSION < 0x040000
+
+        /**
+         * Focus an IMContext.
+         */
+        virtual void setFocus () = 0;
+
+        /**
+         * Unfocus an IMContext.
+         */
+        virtual void unsetFocus () = 0;
+        
+        /**
+         * Set the focused area in the display.
+         *
+         * @param x The X loation of the focused area.
+         * @param y The Y loation of the focused area.
+         * @param w The width of the focused area.
+         * @param h The height of the focused area.
+         * @param font The font.
+         */
+        virtual void setMicroFocus (int x, int y, int w, int h, QFont *font = 0) = 0;
+
+        /**
+         * Filter a mouse event.
+         *
+         * @param offset The cursor offset in the preedit string.
+         * @param type The type of the event.
+         * @param button The button of this event.
+         * @param state The state of the button.
+         */
+        virtual void mouseHandler (int offset, QEvent::Type type, ButtonState button, ButtonState state) = 0;
+
         /**
          * Filter a key event.
          *
@@ -90,6 +154,8 @@ struct _ScimBridgeClientIMContext: public QPlatformInputContext
          */
         virtual bool filterEvent (const QEvent *event) = 0;
 
+#elif QT_VERSION < 0x050000
+
         /**
          * The focus has been changed.
          */
@@ -124,6 +190,8 @@ struct _ScimBridgeClientIMContext: public QPlatformInputContext
          */
         virtual void widgetDestroyed (QWidget *widget) = 0;
 
+#endif
+
         /**
          * Reset the current IME.
          */
diff --git a/extras/immodules/client-qt/scim-bridge-client-key-event-utility-qt.cpp b/extras/immodules/client-qt/scim-bridge-client-key-event-utility-qt.cpp
index 5d52ea3..f83d550 100644
--- a/extras/immodules/client-qt/scim-bridge-client-key-event-utility-qt.cpp
+++ b/extras/immodules/client-qt/scim-bridge-client-key-event-utility-qt.cpp
@@ -22,10 +22,16 @@
 #include <cstdlib>
 #include <map>
 
+#include <QtGlobal>
+#if QT_VERSION >= 0x040000
 #include <QApplication>
 #include <QChar>
 #include <QEvent>
 #include <QKeyEvent>
+#else
+#include <qapplication.h>
+#include <qkeycode.h>
+#endif
 
 #include "scim-bridge-output.h"
 #include "scim-bridge-client-key-event-utility-qt.h"
@@ -43,7 +49,7 @@ static map<scim_bridge_key_code_t, int> bridge_to_qt_key_map;
 static void register_key (int qt_key_code, scim_bridge_key_code_t bridge_key_code)
 {
     qt_to_bridge_key_map[qt_key_code] = bridge_key_code;
-    qt_to_bridge_key_map[bridge_key_code] = qt_key_code;
+    bridge_to_qt_key_map[bridge_key_code] = qt_key_code;
 }
 
 
@@ -77,8 +83,13 @@ static void static_initialize ()
     register_key (Qt::Key_Up, SCIM_BRIDGE_KEY_CODE_Up);
     register_key (Qt::Key_Right, SCIM_BRIDGE_KEY_CODE_Right);
     register_key (Qt::Key_Down, SCIM_BRIDGE_KEY_CODE_Down);
+#if QT_VERSION >= 0x040000
     register_key (Qt::Key_PageUp, SCIM_BRIDGE_KEY_CODE_Prior);
-    register_key (Qt::Key_PageDown, SCIM_BRIDGE_KEY_CODE_Next);
+    register_key (Qt::Key_PageUp, SCIM_BRIDGE_KEY_CODE_Next);
+#else
+    register_key (Qt::Key_Prior, SCIM_BRIDGE_KEY_CODE_Prior);
+    register_key (Qt::Key_Next, SCIM_BRIDGE_KEY_CODE_Next);
+#endif
     register_key (Qt::Key_CapsLock, SCIM_BRIDGE_KEY_CODE_Caps_Lock);
     register_key (Qt::Key_NumLock, SCIM_BRIDGE_KEY_CODE_Num_Lock);
     register_key (Qt::Key_ScrollLock, SCIM_BRIDGE_KEY_CODE_Scroll_Lock);
@@ -174,17 +185,36 @@ QKeyEvent *scim_bridge_key_event_bridge_to_qt (const ScimBridgeKeyEvent *bridge_
     if (bridge_key_code < 0x1000) {
         if (bridge_key_code >= SCIM_BRIDGE_KEY_CODE_a && bridge_key_code <= SCIM_BRIDGE_KEY_CODE_z) {
             ascii_code = bridge_key_code;
+#if QT_VERSION >= 0x050000
             qt_key_code = QChar (ascii_code).toUpper ().toLatin1 ();
+#elif QT_VERSION >= 0x040000
+            qt_key_code = QChar (ascii_code).toUpper ().toAscii ();
+#else
+            qt_key_code = QChar (ascii_code).upper ();
+#endif
         } else {
             ascii_code = bridge_key_code;
             qt_key_code = bridge_key_code;
         }
     } else if (bridge_key_code < 0x3000) {
+#ifdef Q_WS_WIN
         qt_key_code = bridge_key_code;
     } else {
-        qt_key_code = Qt::Key_unknown;
+        qt_key_code = Key_unknown;
+    }
+#else
+        qt_key_code = bridge_key_code | Qt::UNICODE_ACCEL;
+    } else {
+        map<scim_bridge_key_code_t, int>::iterator iter = bridge_to_qt_key_map.find (bridge_key_code);
+        if (iter != bridge_to_qt_key_map.end ()) {
+            qt_key_code = iter->second;
+        } else {
+            qt_key_code = Qt::Key_unknown;
+        }
     }
+#endif
 
+#if QT_VERSION >= 0x040000
     Qt::KeyboardModifiers modifiers = Qt::NoModifier;
 
     if (scim_bridge_key_event_is_alt_down (bridge_key_event)) modifiers |= Qt::AltModifier;
@@ -193,6 +223,16 @@ QKeyEvent *scim_bridge_key_event_bridge_to_qt (const ScimBridgeKeyEvent *bridge_
     if (scim_bridge_key_event_is_meta_down (bridge_key_event)) modifiers |= Qt::MetaModifier;
 
     return new QKeyEvent (type, qt_key_code, modifiers);
+#else
+    unsigned int modifiers = 0;
+
+    if (scim_bridge_key_event_is_alt_down (bridge_key_event)) modifiers |= Qt::AltButton;
+    if (scim_bridge_key_event_is_shift_down (bridge_key_event)) modifiers |= Qt::ShiftButton;
+    if (scim_bridge_key_event_is_control_down (bridge_key_event)) modifiers |= Qt::ControlButton;
+    if (scim_bridge_key_event_is_meta_down (bridge_key_event)) modifiers |= Qt::MetaButton;
+
+    return new QKeyEvent (type, qt_key_code, ascii_code, modifiers);
+#endif
 }
 
 
@@ -202,6 +242,7 @@ ScimBridgeKeyEvent *scim_bridge_key_event_qt_to_bridge (const QKeyEvent *key_eve
     
     ScimBridgeKeyEvent *bridge_key_event = scim_bridge_alloc_key_event ();
 
+#if QT_VERSION >= 0x040000
     const Qt::KeyboardModifiers modifiers = key_event->modifiers ();
 
     if (modifiers & Qt::ShiftModifier) {
@@ -216,6 +257,22 @@ ScimBridgeKeyEvent *scim_bridge_key_event_qt_to_bridge (const QKeyEvent *key_eve
     if (modifiers & Qt::MetaModifier) {
         scim_bridge_key_event_set_meta_down (bridge_key_event, TRUE);
     }
+#else
+    const int modifiers = key_event->state ();
+
+    if (modifiers & Qt::ShiftButton) {
+        scim_bridge_key_event_set_shift_down (bridge_key_event, TRUE);
+    }
+    if (modifiers & Qt::ControlButton) {
+        scim_bridge_key_event_set_control_down (bridge_key_event, TRUE);
+    }
+    if (modifiers & Qt::AltButton) {
+        scim_bridge_key_event_set_alt_down (bridge_key_event, TRUE);
+    }
+    if (modifiers & Qt::MetaButton) {
+        scim_bridge_key_event_set_meta_down (bridge_key_event, TRUE);
+    }
+#endif
 
     const int qt_key_code = key_event->key ();
     int bridge_key_code;
@@ -240,9 +297,17 @@ ScimBridgeKeyEvent *scim_bridge_key_event_qt_to_bridge (const QKeyEvent *key_eve
         }
         
         if (!scim_bridge_key_event_is_caps_lock_down (bridge_key_event) ^ scim_bridge_key_event_is_shift_down (bridge_key_event)) {
+#if QT_VERSION >= 0x040000
 	        bridge_key_code = QChar (qt_key_code).toLower ().unicode ();
+#else
+	        bridge_key_code = QChar (qt_key_code).lower ().unicode ();
+#endif
 	    } else {
+#if QT_VERSION >= 0x040000
 	        bridge_key_code = QChar (qt_key_code).toUpper ().unicode ();
+#else
+	        bridge_key_code = QChar (qt_key_code).upper ().unicode ();
+#endif
 	    }
     } else {
         map<int, scim_bridge_key_code_t>::iterator iter = qt_to_bridge_key_map.find (qt_key_code);
@@ -262,6 +327,7 @@ ScimBridgeKeyEvent *scim_bridge_key_event_qt_to_bridge (const QKeyEvent *key_eve
 }
 
 
+#ifdef Q_WS_X11
 XEvent *scim_bridge_key_event_bridge_to_x11 (const ScimBridgeKeyEvent *bridge_key_event, Display *display, WId window_id)
 {
     XEvent *x_event = static_cast<XEvent*> (malloc (sizeof (XEvent)));
@@ -349,3 +415,59 @@ ScimBridgeKeyEvent* scim_bridge_key_event_x11_to_bridge (const XEvent *x_event)
     
     return bridge_key_event;
 }
+
+#endif
+
+#if QT_VERSION >= 0x050000
+ScimBridgeKeyEvent* scim_bridge_key_event_xcb_to_bridge (xcb_generic_event_t *xcb_event, xcb_connection_t *xcb_connection)
+{
+    xcb_key_press_event_t *key_event = (xcb_key_press_event_t *) xcb_event;
+    
+    ScimBridgeKeyEvent *bridge_key_event = scim_bridge_alloc_key_event ();
+
+    uint8_t event_type = key_event->response_type & ~0x80;
+    scim_bridge_key_event_set_pressed (bridge_key_event, event_type == XCB_KEY_PRESS);
+
+    xcb_key_symbols_t *key_symbols = xcb_key_symbols_alloc(xcb_connection);
+    if(key_symbols == NULL) {
+        return bridge_key_event;
+    }
+    
+    xcb_keysym_t keysym = (event_type == XCB_KEY_PRESS)
+        ? xcb_key_press_lookup_keysym(key_symbols, key_event, 0)
+        : xcb_key_release_lookup_keysym(key_symbols, key_event, 0);
+    scim_bridge_key_event_set_code (bridge_key_event, keysym);
+    xcb_key_symbols_free(key_symbols);
+
+    if (key_event->state & XCB_MOD_MASK_SHIFT || (event_type == XCB_KEY_PRESS && (keysym == XK_Shift_L || keysym == XK_Shift_R))) {
+        scim_bridge_key_event_set_shift_down (bridge_key_event, TRUE);
+    }
+    if (key_event->state & XCB_MOD_MASK_CONTROL || (event_type == XCB_KEY_PRESS && (keysym == XK_Control_L || keysym == XK_Control_R))) {
+        scim_bridge_key_event_set_control_down (bridge_key_event, TRUE);
+    }
+    if (key_event->state & XCB_MOD_MASK_LOCK || (event_type == XCB_KEY_PRESS && (keysym == XK_Caps_Lock))) {
+        scim_bridge_key_event_set_caps_lock_down (bridge_key_event, TRUE);
+    }
+    if (key_event->state & XCB_MOD_MASK_1 || (event_type == XCB_KEY_PRESS && (keysym == XK_Alt_L || keysym == XK_Alt_R))) {
+        scim_bridge_key_event_set_alt_down (bridge_key_event, TRUE);
+    }
+    // super or window key
+    if (key_event->state & XCB_MOD_MASK_4 || (event_type == XCB_KEY_PRESS && (keysym == XK_Meta_L || keysym == XK_Meta_R))) {
+        scim_bridge_key_event_set_meta_down (bridge_key_event, TRUE);
+    }
+
+    if (scim_bridge_key_event_get_code (bridge_key_event) == SCIM_BRIDGE_KEY_CODE_backslash) {
+        boolean kana_ro = FALSE;
+        int keysym_size = 0;
+        xcb_key_symbols_t *key_symbols = xcb_key_symbols_alloc(xcb_connection);
+        if(key_symbols != NULL) {
+            kana_ro = (xcb_key_symbols_get_keysym(key_symbols, key_event->detail, 0) == XK_backslash
+                    && xcb_key_symbols_get_keysym(key_symbols, key_event->detail, 1) == XK_underscore);
+            xcb_key_symbols_free(key_symbols);
+        }
+        scim_bridge_key_event_set_quirk_enabled (bridge_key_event, SCIM_BRIDGE_KEY_QUIRK_KANA_RO, kana_ro);
+    }
+    
+    return bridge_key_event;
+}
+#endif
diff --git a/extras/immodules/client-qt/scim-bridge-client-key-event-utility-qt.h b/extras/immodules/client-qt/scim-bridge-client-key-event-utility-qt.h
index 09f2f5d..dcefd96 100644
--- a/extras/immodules/client-qt/scim-bridge-client-key-event-utility-qt.h
+++ b/extras/immodules/client-qt/scim-bridge-client-key-event-utility-qt.h
@@ -32,13 +32,22 @@
 
 #include "scim-bridge-client-common-qt.h"
 
+#ifdef Q_WS_X11
 #include <X11/Xlib.h>
 #include <X11/keysym.h>
 #include <X11/Xutil.h>
+#elif QT_VERSION >= 0x050000
+#include <xcb/xcb.h>
+#include <xcb/xcb_keysyms.h>
+#include <X11/keysym.h>
+#endif
+
+#ifdef Q_WS_X11
 static const int XKeyPress = KeyPress;
 static const int XKeyRelease = KeyRelease;
 #undef KeyPress
 #undef KeyRelease
+#endif
 
 class QKeyEvent;
 
@@ -58,6 +67,7 @@ QKeyEvent *scim_bridge_key_event_bridge_to_qt (const ScimBridgeKeyEvent *bridge_
  */
 ScimBridgeKeyEvent *scim_bridge_key_event_qt_to_bridge (const QKeyEvent *qt_key_event);
 
+#ifdef Q_WS_X11
 /**
  * Translate a key event from scim-bridge into X11.
  *
@@ -76,5 +86,23 @@ XEvent *scim_bridge_key_event_bridge_to_x11 (const ScimBridgeKeyEvent *bridge_ke
  * @return The key event from scim-bridge.
  */
 ScimBridgeKeyEvent* scim_bridge_key_event_x11_to_bridge (const XEvent *x11_event);
+#endif
 
+#if QT_VERSION >= 0x050000
+/**
+ * Translate a key event from scim-bridge into xcb.
+ *
+ * @param bridge_key_event The key event from scim-bridge.
+ * @return The key event for xcb.
+ */
+xcb_generic_event_t *scim_bridge_key_event_bridge_to_xcb (const ScimBridgeKeyEvent *bridge_key_event);
+
+/**
+ * Translate a key event from xcb into scim-bridge.
+ *
+ * @param xcb_event The event from xcb.
+ * @return The key event from scim-bridge.
+ */
+ScimBridgeKeyEvent* scim_bridge_key_event_xcb_to_bridge (xcb_generic_event_t *xcb_event, xcb_connection_t *xcb_connection);
+#endif
 #endif                                            /*SCIMBRIDGECLIENTKEYEVENTUTILITYQT_H_*/
diff --git a/extras/immodules/client-qt/scim-bridge-client-qt.cpp b/extras/immodules/client-qt/scim-bridge-client-qt.cpp
index 7495ca6..8926d1b 100644
--- a/extras/immodules/client-qt/scim-bridge-client-qt.cpp
+++ b/extras/immodules/client-qt/scim-bridge-client-qt.cpp
@@ -23,7 +23,9 @@
 
 #include "scim-bridge-client-qt.h"
 
+#if QT_VERSION >= 0x040000
 using namespace Qt;
+#endif
 
 /* Static variables */
 static ScimBridgeClientQt *client = NULL;
diff --git a/extras/immodules/client-qt/scim-bridge-client-qt.h b/extras/immodules/client-qt/scim-bridge-client-qt.h
index 65ad450..408d2e4 100644
--- a/extras/immodules/client-qt/scim-bridge-client-qt.h
+++ b/extras/immodules/client-qt/scim-bridge-client-qt.h
@@ -26,8 +26,13 @@
 #ifndef SCIMBRIDGECLIENTQT_H_
 #define SCIMBRIDGECLIENTQT_H_
 
+#if QT_VERSION >= 0x040000
 #include <QObject>
 #include <QSocketNotifier>
+#else
+#include <qobject.h>
+#include <qsocketnotifier.h>
+#endif
 
 #include "scim-bridge.h"
 #include "scim-bridge-client-imcontext-qt.h"
diff --git a/extras/immodules/configure.ac b/extras/immodules/configure.ac
index 4959dac..790c1f4 100644
--- a/extras/immodules/configure.ac
+++ b/extras/immodules/configure.ac
@@ -136,6 +136,17 @@ if test "$SCIM_BRIDGE_HAS_QT4" = "yes"; then
   AC_SUBST(QT4_PREFIX)
 fi
 
+PKG_CHECK_MODULES(QT5, [Qt5Gui >= 5.0, Qt5Core >= 5.0],
+			[SCIM_BRIDGE_HAS_QT5=yes],
+			[SCIM_BRIDGE_HAS_QT5=no])
+
+if test "$SCIM_BRIDGE_HAS_QT5" = "yes"; then
+  if test -z "$QT5_PREFIX"; then
+    QT5_PREFIX=`$PKG_CONFIG --variable=prefix Qt5Core`
+  fi
+  AC_SUBST(QT5_PREFIX)
+fi
+
 # Check if we should build scim-bridge-clutter-immodule
 PKG_CHECK_MODULES(CLUTTER, clutter-0.9 clutter-imcontext-0.1,
            [SCIM_BRIDGE_HAS_CLUTTER=yes],
@@ -189,6 +200,10 @@ AC_ARG_ENABLE(qt4-immodule,
 	      [AS_HELP_STRING([--enable-qt4-immodule], [build Qt4 IM module])], , 
 		  enable_qt4_immodule=yes)
 
+AC_ARG_ENABLE(qt5-immodule,
+	      [AS_HELP_STRING([--enable-qt5-immodule], [build Qt5 IM module])], , 
+		  enable_qt5_immodule=yes)
+
 AC_ARG_ENABLE(clutter-immodule,
 	      [AS_HELP_STRING([--enable-clutter-immodule], [build CLUTTER IM module])], , )
 
@@ -270,6 +285,15 @@ else
   enable_qt4_immodule=no
 fi
 
+if test "$enable_qt5_immodule" = "yes" -a "$SCIM_BRIDGE_HAS_QT5" = "yes"; then
+  SCIM_BRIDGE_BUILD_QT5_IMMODULE=1
+  SCIM_BRIDGE_BUILD_IMMODULE=1
+  enable_immodule=yes
+else
+  SCIM_BRIDGE_BUILD_QT5_IMMODULE=0
+  enable_qt5_immodule=no
+fi
+
 if test "$enable_clutter_immodule" = "yes"; then
   SCIM_BRIDGE_BUILD_CLUTTER_IMMODULE=1
   SCIM_BRIDGE_BUILD_IMMODULE=1
@@ -306,6 +330,9 @@ AM_CONDITIONAL(SCIM_BRIDGE_BUILD_QT3_IMMODULE,
 AM_CONDITIONAL(SCIM_BRIDGE_BUILD_QT4_IMMODULE,
 		[test "$enable_qt4_immodule" = "yes"])
 
+AM_CONDITIONAL(SCIM_BRIDGE_BUILD_QT5_IMMODULE,
+		[test "$enable_qt5_immodule" = "yes"])
+
 AM_CONDITIONAL(SCIM_BRIDGE_BUILD_CLUTTER_IMMODULE,
 		[test "$enable_clutter_immodule" = "yes"])
 
@@ -319,6 +346,7 @@ AC_SUBST(SCIM_BRIDGE_BUILD_GTK3_IMMODULE)
 AC_SUBST(SCIM_BRIDGE_BUILD_GTK4_IMMODULE)
 AC_SUBST(SCIM_BRIDGE_BUILD_QT3_IMMODULE)
 AC_SUBST(SCIM_BRIDGE_BUILD_QT4_IMMODULE)
+AC_SUBST(SCIM_BRIDGE_BUILD_QT5_IMMODULE)
 AC_SUBST(SCIM_BRIDGE_BUILD_CLUTTER_IMMODULE)
 AC_SUBST(SCIM_BRIDGE_BUILD_IMMODULE)
 
@@ -357,7 +385,7 @@ AC_SUBST(SCIM_LOCALDIR)
 ##                      Output files.                    ##
 ###########################################################
 AC_SUBST(ac_aux_dir)
-AC_CONFIG_FILES([Makefile common/Makefile agent/Makefile client-common/Makefile client-gtk/gtk2/Makefile client-gtk/gtk3/Makefile client-qt/qt3/Makefile client-qt/qt4/Makefile client-clutter/Makefile tests/Makefile doc/Makefile])
+AC_CONFIG_FILES([Makefile common/Makefile agent/Makefile client-common/Makefile client-gtk/gtk2/Makefile client-gtk/gtk3/Makefile client-qt/qt3/Makefile client-qt/qt4/Makefile client-qt/qt5/Makefile client-clutter/Makefile tests/Makefile doc/Makefile])
 
 AC_OUTPUT
 
@@ -378,6 +406,7 @@ Module options:
   Build GTK4 IMModule      $enable_gtk4_immodule
   Build QT3 IMModule       $enable_qt3_immodule
   Build QT4 IMModule       $enable_qt4_immodule
+  Build QT5 IMModule       $enable_qt5_immodule
   Build CLUTTER IMModule   $enable_clutter_immodule
 ])
 
diff --git a/utils/Makefile.am b/utils/Makefile.am
index c77ea65..e835ecb 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -55,7 +55,8 @@ libscim_gtkutils@SCIM_EPOCH@_la_LDFLAGS= -version-info $(SCIM_CURRENT):$(SCIM_RE
 				  -export-dynamic \
 				  @LIBTOOL_EXPORT_OPTIONS@ \
 				  @LTLIBINTL@ \
-				  @GTK_LIBS@ 
+				  @GTK_LIBS@ \
+				  @X_LIBS@
 
 libscim_gtkutils@SCIM_EPOCH@_la_LIBADD= $(top_builddir)/src/libscim@SCIM_EPOCH@.la $(X11_UTILS)
 
-- 
2.37.3