diff options
author | Mamoru Komachi <usata@gentoo.org> | 2004-08-04 16:15:05 +0000 |
---|---|---|
committer | Mamoru Komachi <usata@gentoo.org> | 2004-08-04 16:15:05 +0000 |
commit | 690f79fd4f5e371d8244f18f90075c4ff836bd96 (patch) | |
tree | 24f87e99be98d57db35767d6cbfc115f3d7f190e /x11-libs/qt | |
parent | add fontconfig support, bug #40808 (Manifest recommit) (diff) | |
download | gentoo-2-690f79fd4f5e371d8244f18f90075c4ff836bd96.tar.gz gentoo-2-690f79fd4f5e371d8244f18f90075c4ff836bd96.tar.bz2 gentoo-2-690f79fd4f5e371d8244f18f90075c4ff836bd96.zip |
Added qt-immodule patch. Thanks to Ken Deeter <ktdeeter@alumni.princeton.edu>. This closes bug #55508.
Diffstat (limited to 'x11-libs/qt')
-rw-r--r-- | x11-libs/qt/ChangeLog | 9 | ||||
-rw-r--r-- | x11-libs/qt/files/digest-qt-3.3.2 | 1 | ||||
-rw-r--r-- | x11-libs/qt/files/qt-x11-immodule-bc-qt3.3.2-20040623.diff | 4414 | ||||
-rw-r--r-- | x11-libs/qt/qt-3.3.2.ebuild | 16 |
4 files changed, 4436 insertions, 4 deletions
diff --git a/x11-libs/qt/ChangeLog b/x11-libs/qt/ChangeLog index d5c69a7b94c3..8b105aa96db6 100644 --- a/x11-libs/qt/ChangeLog +++ b/x11-libs/qt/ChangeLog @@ -1,11 +1,16 @@ # ChangeLog for x11-libs/qt # Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/x11-libs/qt/ChangeLog,v 1.156 2004/07/27 03:03:39 tgall Exp $ +# $Header: /var/cvsroot/gentoo-x86/x11-libs/qt/ChangeLog,v 1.157 2004/08/04 16:15:05 usata Exp $ + + 05 Aug 2004; Mamoru KOMACHI <usata@gentoo.org> + +files/qt-x11-immodule-bc-qt3.3.2-20040623.diff, qt-3.3.2.ebuild: + Added qt-immodule patch. Thanks to Ken Deeter + <ktdeeter@alumni.princeton.edu>. This closes bug #55508. 26 Jul 2004; Tom Gall <tgall@gentoo.org> qt-3.3.2.ebuild: stable on ppc64 - 19 Jul 2004; Bryan Østergaard <kloeri@gentoo.org> qt-3.3.2.ebuild: + 19 Jul 2004; Bryan ƒŠstergaard <kloeri@gentoo.org> qt-3.3.2.ebuild: Stable on alpha. *qt-3.3.1-r2 (09 Jul 2004) diff --git a/x11-libs/qt/files/digest-qt-3.3.2 b/x11-libs/qt/files/digest-qt-3.3.2 index af9aa584b19a..644c0799e5ad 100644 --- a/x11-libs/qt/files/digest-qt-3.3.2 +++ b/x11-libs/qt/files/digest-qt-3.3.2 @@ -1 +1,2 @@ MD5 903cad618274ad84d7d13fd0027a6c3c qt-x11-free-3.3.2.tar.bz2 14434821 +MD5 653f15a063bc0886050570430f973c2a qt-x11-immodule-bc-qt3.3.2-20040623.diff 137699 diff --git a/x11-libs/qt/files/qt-x11-immodule-bc-qt3.3.2-20040623.diff b/x11-libs/qt/files/qt-x11-immodule-bc-qt3.3.2-20040623.diff new file mode 100644 index 000000000000..6f7918c39322 --- /dev/null +++ b/x11-libs/qt/files/qt-x11-immodule-bc-qt3.3.2-20040623.diff @@ -0,0 +1,4414 @@ +diff -urN qt-x11-free-3.3.2/configure qt-x11-immodule-bc/configure +--- qt-x11-free-3.3.2/configure 2004-04-01 01:40:12.000000000 +0900 ++++ qt-x11-immodule-bc/configure 2004-06-23 01:10:27.058123680 +0900 +@@ -217,7 +217,7 @@ + fi + + # licensed modules depend on type of commercial license +-MODULES="styles tools kernel widgets dialogs iconview workspace" ++MODULES="styles tools kernel widgets dialogs iconview workspace input" + [ "$PLATFORM_QWS" = "yes" ] && [ "$Products" = "qt-professional" ] && MODULES="$MODULES network" + [ "$Products" != "qt-professional" ] && MODULES="$MODULES network canvas table xml opengl sql" + CFG_MODULES_AVAILABLE=$MODULES +@@ -2999,7 +2999,7 @@ + # minimal-config small-config medium-config large-config full-config + # + # Modules: +-# styles tools kernel widgets dialogs iconview workspace ++# styles tools kernel widgets dialogs iconview workspace input + # + # Enterprise/Free edition modules: + # network canvas table xml opengl sql +@@ -3031,7 +3031,7 @@ + # X11 : xftnameunparse x11sm xinerama xcursor xrandr xrender xftfreetype xkb + # Embedded: embedded ft + # +-ALL_OPTIONS="styles tools kernel widgets dialogs iconview workspace network canvas table xml opengl sql stl" ++ALL_OPTIONS="styles tools kernel widgets dialogs iconview workspace input network canvas table xml opengl sql stl" + BUILD_CONFIG= + BUILD_OPTIONS= + +@@ -3045,7 +3045,7 @@ + BUILD_CONFIG="$config_option" + ;; + +- styles|tools|kernel|widgets|dialogs|iconview|workspace|network|canvas|table|xml|opengl|sql|stl) ++ styles|tools|kernel|widgets|dialogs|iconview|workspace|input|network|canvas|table|xml|opengl|sql|stl) + # these config options affect the Qt API/ABI. they should influence + # the generation of the buildkey, so we don't skip them + SKIP="no" +diff -urN qt-x11-free-3.3.2/src/input/qinputcontextfactory.cpp qt-x11-immodule-bc/src/input/qinputcontextfactory.cpp +--- qt-x11-free-3.3.2/src/input/qinputcontextfactory.cpp 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/input/qinputcontextfactory.cpp 2004-06-23 01:54:29.544404704 +0900 +@@ -0,0 +1,151 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** Implementation of QInputContextFactory class ++** ++** Created : 001103 ++** ++** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ++** ++** This file is part of the widgets module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition licenses may use this ++** file in accordance with the Qt Commercial License Agreement provided ++** with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++#include "qinputcontextinterface_p.h" // up here for GCC 2.7.* compatibility ++#include "qinputcontextfactory.h" ++ ++#ifndef QT_NO_IM ++ ++#include "qapplication.h" ++#include "qpopupmenu.h" ++#ifdef Q_WS_X11 ++#include "qximinputcontext_p.h" ++#endif ++ ++#ifdef QT_THREAD_SUPPORT ++#include <private/qmutexpool_p.h> ++#endif // QT_THREAD_SUPPORT ++ ++#include <stdlib.h> ++ ++#include "qcleanuphandler.h" ++#include <private/qpluginmanager_p.h> ++#ifndef QT_NO_COMPONENT ++ ++ ++static QPluginManager<QInputContextFactoryInterface> *manager = 0; ++static QSingleCleanupHandler< QPluginManager<QInputContextFactoryInterface> > cleanup_manager; ++ ++static void create_manager() ++{ ++ if( manager ) // already created ++ return; ++ ++#ifdef QT_THREAD_SUPPORT ++ // protect manager creation ++ QMutexLocker locker( qt_global_mutexpool ? ++ qt_global_mutexpool->get( &manager ) : 0); ++ ++ // we check the manager pointer again to make sure that another thread ++ // has not created the manager before us. ++ ++ if ( manager ) // already created ++ return; ++#endif ++ ++ manager = new QPluginManager<QInputContextFactoryInterface>( IID_QInputContextFactory, QApplication::libraryPaths(), "/input", FALSE ); ++ ++ Q_CHECK_PTR( manager ); ++ cleanup_manager.set( &manager ); ++} ++ ++#endif //QT_NO_COMPONENT ++ ++ ++/*! ++ This function generates InputMethod with the name which is in agreement ++ with key of the first argument. widget of the second argument is client ++ widget of QInputContext. ++*/ ++QInputContext *QInputContextFactory::create( const QString& key, QWidget *widget ) ++{ ++ QInputContext *ret = 0; ++ QString inputcontext = key; ++#ifdef Q_WS_X11 ++ if ( inputcontext == "XIM" ) { ++ ret = new QXIMInputContext( widget ); ++ ret->setHolderWidget( widget ); ++ } ++#endif ++ { } // Keep these here - they make the #ifdefery above work ++ ++#ifndef QT_NO_COMPONENT ++ if(!ret) { ++ // make sure the manager is created ++ create_manager(); ++ ++ QInterfacePtr<QInputContextFactoryInterface> iface; ++ manager->queryInterface( inputcontext, &iface ); ++ ++ if ( iface ) { ++ ret = iface->create( inputcontext ); ++#ifdef Q_WS_X11 ++ ret->setHolderWidget( widget ); ++#endif ++ } ++ } ++#endif ++ return ret; ++} ++ ++ ++/*! ++ This function returns the list of the names input methods. ++ Only input methods included in default and putted below ++ $QTDIR/plugins/input are listed. ++*/ ++#ifndef QT_NO_STRINGLIST ++QStringList QInputContextFactory::keys() ++{ ++ QStringList list; ++#ifndef QT_NO_COMPONENT ++ // make sure the manager is created ++ create_manager(); ++ ++ list = manager->featureList(); ++#endif //QT_NO_COMPONENT ++ ++#ifdef Q_WS_X11 ++ if ( !list.contains( "XIM" ) ) ++ list << "XIM"; ++#endif // Q_WS_X11 ++ ++ return list; ++} ++#endif // QT_NO_STRINGLIST ++ ++#endif // QT_NO_IM +diff -urN qt-x11-free-3.3.2/src/input/qinputcontextfactory.h qt-x11-immodule-bc/src/input/qinputcontextfactory.h +--- qt-x11-free-3.3.2/src/input/qinputcontextfactory.h 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/input/qinputcontextfactory.h 2004-06-23 01:10:27.059123528 +0900 +@@ -0,0 +1,60 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** Definition of QInputContextPlugin class ++** ++** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ++** ++** This file is part of the widgets module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ++** licenses may use this file in accordance with the Qt Commercial License ++** Agreement provided with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++#ifndef QINPUTCONTEXTFACTORY_H ++#define QINPUTCONTEXTFACTORY_H ++ ++#ifndef QT_H ++#include "qstringlist.h" ++#endif // QT_H ++ ++#ifndef QT_NO_IM ++ ++class QInputContext; ++class QPopupMenu; ++ ++ ++class Q_EXPORT QInputContextFactory ++{ ++public: ++#ifndef QT_NO_STRINGLIST ++ static QStringList keys(); ++#endif ++ static QInputContext *create( const QString&, QWidget*); // should be a toplevel widget ++ ++}; ++#endif //QT_NO_IM ++ ++#endif //QINPUTCONTEXTFACTORY_H +diff -urN qt-x11-free-3.3.2/src/input/qinputcontextinterface_p.h qt-x11-immodule-bc/src/input/qinputcontextinterface_p.h +--- qt-x11-free-3.3.2/src/input/qinputcontextinterface_p.h 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/input/qinputcontextinterface_p.h 2004-06-23 01:10:27.060123376 +0900 +@@ -0,0 +1,74 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** ... ++** ++** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ++** ++** This file is part of the widgets module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ++** licenses may use this file in accordance with the Qt Commercial License ++** Agreement provided with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++#ifndef QINPUTCONTEXTINTERFACE_P_H ++#define QINPUTCONTEXTINTERFACE_P_H ++ ++// ++// W A R N I N G ++// ------------- ++// ++// This file is not part of the Qt API. This header file may ++// change from version to version without notice, or even be ++// removed. ++// ++// We mean it. ++// ++// ++ ++#ifndef QT_H ++#include <private/qcom_p.h> ++#endif // QT_H ++ ++#ifndef QT_NO_IM ++#ifndef QT_NO_COMPONENT ++ ++class QWidget; ++class QInputContext; ++ ++// {6C2B9EDE-B63C-14c9-A729-3C7643739C4C} ++#ifndef IID_QInputContextFactory ++#define IID_QInputContextFactory QUuid(0x6c2b9ede, 0xb63c, 0x14c9, 0xa7, 0x29, 0x3c, 0x76, 0x43, 0x73, 0x9c, 0x4c) ++#endif ++ ++struct Q_EXPORT QInputContextFactoryInterface : public QFeatureListInterface ++{ ++ virtual QInputContext* create( const QString& inputcontext ) = 0; ++}; ++ ++#endif //QT_NO_COMPONENT ++#endif //QT_NO_IM ++ ++#endif //QINPUTCONTEXTINTERFACE_P_H +diff -urN qt-x11-free-3.3.2/src/input/qinputcontextplugin.cpp qt-x11-immodule-bc/src/input/qinputcontextplugin.cpp +--- qt-x11-free-3.3.2/src/input/qinputcontextplugin.cpp 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/input/qinputcontextplugin.cpp 2004-06-23 01:10:27.060123376 +0900 +@@ -0,0 +1,158 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** Implementation of QInputContextPlugin class ++** ++** Created : 010920 ++** ++** Copyright (C) 2001 Trolltech AS. All rights reserved. ++** ++** This file is part of the widgets module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ++** licenses may use this file in accordance with the Qt Commercial License ++** Agreement provided with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++#include "qinputcontextplugin.h" ++ ++#ifndef QT_NO_IM ++#ifndef QT_NO_COMPONENT ++ ++#include "qinputcontextinterface_p.h" ++ ++/*! ++ \class QInputContextPlugin qinputcontextplugin.h ++ \brief The QInputContextPlugin class provides an abstract base for custom QInputContext plugins. ++ \reentrant ++ \ingroup plugins ++ ++ The input context plugin is a simple plugin interface that makes it ++ easy to create custom input contexts that can be loaded dynamically ++ into applications. ++ ++ Writing a input context plugin is achieved by subclassing this base ++ class, reimplementing the pure virtual functions keys(), ++ create(), and exporting the class with the \c Q_EXPORT_PLUGIN macro. ++ See the \link plugins-howto.html Qt Plugins documentation \endlink ++ for details. ++*/ ++ ++/*! ++ \fn QStringList QInputContextPlugin::keys() const ++ ++ Returns the list of InputContext keys this plugin supports. ++ ++ These keys are usually the class names of the custom input context ++ that are implemented in the plugin. ++ ++ \sa create() ++*/ ++ ++/*! ++ \fn QInputContext* QInputContextPlugin::create( const QString& key ) ++ ++ Creates and returns a QInputContext object for the InputContext key \a key. ++ The InputContext key is usually the class name of the required input method. ++ ++ \sa keys() ++*/ ++ ++ ++ ++class QInputContextPluginPrivate : public QInputContextFactoryInterface ++{ ++public: ++ QInputContextPluginPrivate( QInputContextPlugin *p ) ++ : plugin( p ) ++ { ++ } ++ ++ virtual ~QInputContextPluginPrivate(); ++ ++ QRESULT queryInterface( const QUuid &iid, QUnknownInterface **iface ); ++ Q_REFCOUNT; ++ ++ QStringList featureList() const; ++ QInputContext *create( const QString &key ); ++ ++private: ++ QInputContextPlugin *plugin; ++}; ++ ++QRESULT QInputContextPluginPrivate::queryInterface( const QUuid &iid, QUnknownInterface **iface ) ++{ ++ *iface = 0; ++ ++ if ( iid == IID_QUnknown ) ++ *iface = this; ++ else if ( iid == IID_QFeatureList ) ++ *iface = this; ++ else if ( iid == IID_QInputContextFactory ) ++ *iface = this; ++ else ++ return QE_NOINTERFACE; ++ ++ (*iface)->addRef(); ++ return QS_OK; ++} ++ ++QInputContextPluginPrivate::~QInputContextPluginPrivate() ++{ ++ delete plugin; ++} ++ ++QStringList QInputContextPluginPrivate::featureList() const ++{ ++ return plugin->keys(); ++} ++ ++QInputContext *QInputContextPluginPrivate::create( const QString &key ) ++{ ++ return plugin->create( key ); ++} ++ ++ ++/*! ++ Constructs a InputContext plugin. This is invoked automatically by the ++ \c Q_EXPORT_PLUGIN macro. ++*/ ++QInputContextPlugin::QInputContextPlugin() ++ : QGPlugin( d = new QInputContextPluginPrivate( this ) ) ++{ ++} ++ ++/*! ++ Destroys the InputContext plugin. ++ ++ You never have to call this explicitly. Qt destroys a plugin ++ automatically when it is no longer used. ++*/ ++QInputContextPlugin::~QInputContextPlugin() ++{ ++ // don't delete d, as this is deleted by d ++} ++ ++#endif // QT_NO_COMPONENT ++#endif // QT_NO_IM +diff -urN qt-x11-free-3.3.2/src/input/qinputcontextplugin.h qt-x11-immodule-bc/src/input/qinputcontextplugin.h +--- qt-x11-free-3.3.2/src/input/qinputcontextplugin.h 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/input/qinputcontextplugin.h 2004-06-23 01:10:27.061123224 +0900 +@@ -0,0 +1,64 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** Definition of QInputContextPlugin class ++** ++** Created : 010920 ++** ++** Copyright (C) 2001 Trolltech AS. All rights reserved. ++** ++** This file is part of the tools module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ++** licenses may use this file in accordance with the Qt Commercial License ++** Agreement provided with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++#ifndef QINPUTCONTEXTPLUGIN_H ++#define QINPUTCONTEXTPLUGIN_H ++ ++#ifndef QT_H ++#include "qgplugin.h" ++#include "qstringlist.h" ++#endif // QT_H ++ ++#ifndef QT_NO_IM ++class QInputContext; ++class QInputContextPluginPrivate; ++ ++class Q_EXPORT QInputContextPlugin : public QGPlugin ++{ ++ Q_OBJECT ++public: ++ QInputContextPlugin(); ++ ~QInputContextPlugin(); ++ ++ virtual QStringList keys() const = 0; ++ virtual QInputContext *create( const QString &key ) = 0; ++ ++private: ++ QInputContextPluginPrivate *d; ++}; ++#endif // QT_NO_TEXTCODECPLUGIN ++#endif // QTEXTCODECPLUGIN_H +diff -urN qt-x11-free-3.3.2/src/input/qt_input.pri qt-x11-immodule-bc/src/input/qt_input.pri +--- qt-x11-free-3.3.2/src/input/qt_input.pri 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/input/qt_input.pri 2004-06-23 01:10:27.061123224 +0900 +@@ -0,0 +1,13 @@ ++# Qt inputcontext module ++ ++input { ++ INPUT_P = input ++ HEADERS +=$$INPUT_H/qinputcontextfactory.h \ ++ $$INPUT_P/qinputcontextinterface_p.h \ ++ $$INPUT_H/qinputcontextplugin.h \ ++ $$INPUT_H/qximinputcontext_p.h ++ SOURCES +=$$INPUT_CPP/qinputcontextfactory.cpp \ ++ $$INPUT_CPP/qinputcontextplugin.cpp \ ++ $$INPUT_CPP/qximinputcontext_x11.cpp ++ ++} +diff -urN qt-x11-free-3.3.2/src/input/qximinputcontext_p.h qt-x11-immodule-bc/src/input/qximinputcontext_p.h +--- qt-x11-free-3.3.2/src/input/qximinputcontext_p.h 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/input/qximinputcontext_p.h 2004-06-23 02:07:02.819889424 +0900 +@@ -0,0 +1,133 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** Definition of QXIMInputContext ++** ++** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ++** ++** This file is part of the kernel module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ++** licenses may use this file in accordance with the Qt Commercial License ++** Agreement provided with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++#ifndef QXIMINPUTCONTEXT_P_H ++#define QXIMINPUTCONTEXT_P_H ++ ++ ++// ++// W A R N I N G ++// ------------- ++// ++// This file is not part of the Qt API. It exists for the convenience ++// of internal files. This header file may change from version to version ++// without notice, or even be removed. ++// ++// We mean it. ++// ++// ++ ++#if !defined(Q_NO_IM) ++ ++#include "qglobal.h" ++#include <qinputcontext.h> ++#include <qfont.h> ++#include <qcstring.h> ++ ++class QKeyEvent; ++class QWidget; ++class QFont; ++class QString; ++ ++ ++#ifdef Q_WS_X11 ++#include "qarray.h" ++#include "qwindowdefs.h" ++#include <private/qt_x11_p.h> ++#endif ++ ++class QXIMInputContext : public QInputContext ++{ ++public: ++#ifdef Q_WS_X11 ++ QXIMInputContext( QWidget * ); // should be a toplevel widget ++ ~QXIMInputContext(); ++ ++ QString name(); ++ QCString language(); ++ ++ bool x11FilterEvent( QWidget *keywidget, XEvent *event ); ++ void reset(); ++ ++ void setFocus(); ++ void unsetFocus(); ++ void setMicroFocus( int x, int y, int w, int h, QFont *f = 0 ); ++ void mouseHandler( int x, QEvent::Type type, ++ Qt::ButtonState butoon, Qt::ButtonState state ); ++ ++ bool hasFocus() const; ++ bool isComposing() const; ++ void resetClientState(); ++ ++ void sendIMEvent( QEvent::Type type, ++ const QString &text = QString::null, ++ int cursorPosition = -1, int selLength = 0 ); ++ ++ static void init_xim(); ++ static void create_xim(); ++ static void close_xim(); ++ ++ void *ic; ++ QString composingText; ++ QFont font; ++ XFontSet fontset; ++ QMemArray<bool> selectedChars; ++ ++protected: ++ bool isPreeditRelocationEnabled(); ++ virtual bool isPreeditPreservationEnabled(); // not a QInputContext func ++ ++ QCString _language; ++ ++private: ++ void setComposePosition(int, int); ++ void setComposeArea(int, int, int, int); ++ void setXFontSet(const QFont &); ++ ++ int lookupString(XKeyEvent *, QCString &, KeySym *, Status *) const; ++ ++#endif // Q_WS_X11 ++}; ++ ++ ++inline QString QXIMInputContext::name() ++{ ++ return "XIM"; ++} ++ ++ ++#endif //Q_NO_IM ++ ++#endif // QXIMINPUTCONTEXT_P_H +diff -urN qt-x11-free-3.3.2/src/input/qximinputcontext_x11.cpp qt-x11-immodule-bc/src/input/qximinputcontext_x11.cpp +--- qt-x11-free-3.3.2/src/input/qximinputcontext_x11.cpp 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/input/qximinputcontext_x11.cpp 2004-06-23 02:10:35.916493816 +0900 +@@ -0,0 +1,895 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** Implementation of QXIMInputContext class ++** ++** Copyright (C) 2000-2003 Trolltech AS. All rights reserved. ++** ++** This file is part of the kernel module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ++** licenses for Unix/X11 may use this file in accordance with the Qt Commercial ++** License Agreement provided with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++ ++#include "qximinputcontext_p.h" ++ ++const int XKeyPress = KeyPress; ++const int XKeyRelease = KeyRelease; ++#undef KeyPress ++#undef KeyRelease ++ ++#if !defined(QT_NO_IM) ++ ++#include "qplatformdefs.h" ++ ++#include "qapplication.h" ++#include "qwidget.h" ++#include "qptrlist.h" ++#include "qintdict.h" ++#include "qtextcodec.h" ++#include "qlocale.h" ++ ++#include <stdlib.h> ++#include <limits.h> ++ ++#if !defined(QT_NO_XIM) ++ ++#define XK_MISCELLANY ++#define XK_LATIN1 ++#include <X11/keysymdef.h> ++ ++// #define QT_XIM_DEBUG ++ ++// from qapplication_x11.cpp ++static XIM qt_xim = 0; ++extern XIMStyle qt_xim_style; ++extern XIMStyle xim_preferred_style; ++extern char *ximServer; ++static bool isInitXIM = FALSE; ++static QPtrList<QXIMInputContext> *ximContextList = 0; ++#endif ++extern int composingKeycode; ++extern QTextCodec * input_mapper; ++ ++ ++#if !defined(QT_NO_XIM) ++ ++#if defined(Q_C_CALLBACKS) ++extern "C" { ++#endif // Q_C_CALLBACKS ++ ++ // These static functions should be rewritten as member of ++ // QXIMInputContext ++ ++#ifdef USE_X11R6_XIM ++ static void xim_create_callback(XIM /*im*/, ++ XPointer /*client_data*/, ++ XPointer /*call_data*/) ++ { ++ // qDebug("xim_create_callback"); ++ QXIMInputContext::create_xim(); ++ } ++ ++ static void xim_destroy_callback(XIM /*im*/, ++ XPointer /*client_data*/, ++ XPointer /*call_data*/) ++ { ++ // qDebug("xim_destroy_callback"); ++ QXIMInputContext::close_xim(); ++ Display *dpy = QPaintDevice::x11AppDisplay(); ++ XRegisterIMInstantiateCallback(dpy, 0, 0, 0, ++ (XIMProc) xim_create_callback, 0); ++ } ++ ++#endif // USE_X11R6_XIM ++ ++#if defined(Q_C_CALLBACKS) ++} ++#endif // Q_C_CALLBACKS ++ ++#endif // QT_NO_XIM ++ ++#ifndef QT_NO_XIM ++ ++/* The cache here is needed, as X11 leaks a few kb for every ++ XFreeFontSet call, so we avoid creating and deletion of fontsets as ++ much as possible ++*/ ++static XFontSet fontsetCache[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; ++static int fontsetRefCount = 0; ++ ++static const char * const fontsetnames[] = { ++ "-*-fixed-medium-r-*-*-16-*,-*-*-medium-r-*-*-16-*", ++ "-*-fixed-medium-i-*-*-16-*,-*-*-medium-i-*-*-16-*", ++ "-*-fixed-bold-r-*-*-16-*,-*-*-bold-r-*-*-16-*", ++ "-*-fixed-bold-i-*-*-16-*,-*-*-bold-i-*-*-16-*", ++ "-*-fixed-medium-r-*-*-24-*,-*-*-medium-r-*-*-24-*", ++ "-*-fixed-medium-i-*-*-24-*,-*-*-medium-i-*-*-24-*", ++ "-*-fixed-bold-r-*-*-24-*,-*-*-bold-r-*-*-24-*", ++ "-*-fixed-bold-i-*-*-24-*,-*-*-bold-i-*-*-24-*" ++}; ++ ++static XFontSet getFontSet( const QFont &f ) ++{ ++ int i = 0; ++ if (f.italic()) ++ i |= 1; ++ if (f.bold()) ++ i |= 2; ++ ++ if ( f.pointSize() > 20 ) ++ i += 4; ++ ++ if ( !fontsetCache[i] ) { ++ Display* dpy = QPaintDevice::x11AppDisplay(); ++ int missCount; ++ char** missList; ++ fontsetCache[i] = XCreateFontSet(dpy, fontsetnames[i], &missList, &missCount, 0); ++ if(missCount > 0) ++ XFreeStringList(missList); ++ if ( !fontsetCache[i] ) { ++ fontsetCache[i] = XCreateFontSet(dpy, "-*-fixed-*-*-*-*-16-*", &missList, &missCount, 0); ++ if(missCount > 0) ++ XFreeStringList(missList); ++ if ( !fontsetCache[i] ) ++ fontsetCache[i] = (XFontSet)-1; ++ } ++ } ++ return (fontsetCache[i] == (XFontSet)-1) ? 0 : fontsetCache[i]; ++} ++ ++ ++#ifdef Q_C_CALLBACKS ++extern "C" { ++#endif // Q_C_CALLBACKS ++ ++ static int xic_start_callback(XIC, XPointer client_data, XPointer) { ++ QXIMInputContext *qic = (QXIMInputContext *) client_data; ++ if (! qic) { ++#ifdef QT_XIM_DEBUG ++ qDebug("compose start: no qic"); ++#endif // QT_XIM_DEBUG ++ ++ return 0; ++ } ++ ++ qic->resetClientState(); ++ qic->sendIMEvent( QEvent::IMStart ); ++ ++#ifdef QT_XIM_DEBUG ++ qDebug("compose start"); ++#endif // QT_XIM_DEBUG ++ ++ return 0; ++ } ++ ++ static int xic_draw_callback(XIC, XPointer client_data, XPointer call_data) { ++ QXIMInputContext *qic = (QXIMInputContext *) client_data; ++ if (! qic) { ++#ifdef QT_XIM_DEBUG ++ qDebug("compose event: invalid compose event %p", qic); ++#endif // QT_XIM_DEBUG ++ ++ return 0; ++ } ++ ++ bool send_imstart = FALSE; ++ if( ! qic->isComposing() && qic->hasFocus() ) { ++ qic->resetClientState(); ++ send_imstart = TRUE; ++ } else if ( ! qic->isComposing() || ! qic->hasFocus() ) { ++#ifdef QT_XIM_DEBUG ++ qDebug( "compose event: invalid compose event composing=%d hasFocus=%d", ++ qic->isComposing(), qic->hasFocus() ); ++#endif // QT_XIM_DEBUG ++ ++ return 0; ++ } ++ ++ if ( send_imstart ) ++ qic->sendIMEvent( QEvent::IMStart ); ++ ++ XIMPreeditDrawCallbackStruct *drawstruct = ++ (XIMPreeditDrawCallbackStruct *) call_data; ++ XIMText *text = (XIMText *) drawstruct->text; ++ int cursor = drawstruct->caret, sellen = 0; ++ ++ if ( ! drawstruct->caret && ! drawstruct->chg_first && ++ ! drawstruct->chg_length && ! text ) { ++ if( qic->composingText.isEmpty() ) { ++#ifdef QT_XIM_DEBUG ++ qDebug( "compose emptied" ); ++#endif // QT_XIM_DEBUG ++ // if the composition string has been emptied, we need ++ // to send an IMEnd event ++ qic->sendIMEvent( QEvent::IMEnd ); ++ qic->resetClientState(); ++ // if the commit string has coming after here, IMStart ++ // will be sent dynamically ++ } ++ return 0; ++ } ++ ++ if (text) { ++ char *str = 0; ++ if (text->encoding_is_wchar) { ++ int l = wcstombs(NULL, text->string.wide_char, text->length); ++ if (l != -1) { ++ str = new char[l + 1]; ++ wcstombs(str, text->string.wide_char, l); ++ str[l] = 0; ++ } ++ } else ++ str = text->string.multi_byte; ++ ++ if (! str) ++ return 0; ++ ++ QString s = QString::fromLocal8Bit(str); ++ ++ if (text->encoding_is_wchar) ++ delete [] str; ++ ++ if (drawstruct->chg_length < 0) ++ qic->composingText.replace(drawstruct->chg_first, UINT_MAX, s); ++ else ++ qic->composingText.replace(drawstruct->chg_first, drawstruct->chg_length, s); ++ ++ if ( qic->selectedChars.size() < qic->composingText.length() ) { ++ // expand the selectedChars array if the compose string is longer ++ uint from = qic->selectedChars.size(); ++ qic->selectedChars.resize( qic->composingText.length() ); ++ for ( uint x = from; from < qic->selectedChars.size(); ++x ) ++ qic->selectedChars[x] = 0; ++ } ++ ++ uint x; ++ bool *p = qic->selectedChars.data() + drawstruct->chg_first; ++ // determine if the changed chars are selected based on text->feedback ++ for ( x = 0; x < s.length(); ++x ) ++ *p++ = ( text->feedback ? ( text->feedback[x] & XIMReverse ) : 0 ); ++ ++ // figure out where the selection starts, and how long it is ++ p = qic->selectedChars.data(); ++ bool started = FALSE; ++ for ( x = 0; x < qic->selectedChars.size(); ++x ) { ++ if ( started ) { ++ if ( *p ) ++sellen; ++ else break; ++ } else { ++ if ( *p ) { ++ cursor = x; ++ started = TRUE; ++ sellen = 1; ++ } ++ } ++ ++p; ++ } ++ } else { ++ if (drawstruct->chg_length == 0) ++ drawstruct->chg_length = -1; ++ ++ qic->composingText.remove(drawstruct->chg_first, drawstruct->chg_length); ++ bool qt_compose_emptied = qic->composingText.isEmpty(); ++ if ( qt_compose_emptied ) { ++#ifdef QT_XIM_DEBUG ++ qDebug( "compose emptied" ); ++#endif // QT_XIM_DEBUG ++ // if the composition string has been emptied, we need ++ // to send an IMEnd event ++ qic->sendIMEvent( QEvent::IMEnd ); ++ qic->resetClientState(); ++ // if the commit string has coming after here, IMStart ++ // will be sent dynamically ++ return 0; ++ } ++ } ++ ++ qic->sendIMEvent( QEvent::IMCompose, ++ qic->composingText, cursor, sellen ); ++ ++ return 0; ++ } ++ ++ static int xic_done_callback(XIC, XPointer client_data, XPointer) { ++ QXIMInputContext *qic = (QXIMInputContext *) client_data; ++ if (! qic) ++ return 0; ++ ++ // Don't send IMEnd here. QXIMInputContext::x11FilterEvent() ++ // handles IMEnd with commit string. ++#if 0 ++ if ( qic->isComposing() ) ++ qic->sendIMEvent( QEvent::IMEnd ); ++ qic->resetClientState(); ++#endif ++ ++ return 0; ++ } ++ ++#ifdef Q_C_CALLBACKS ++} ++#endif // Q_C_CALLBACKS ++ ++#endif // !QT_NO_XIM ++ ++ ++ ++QXIMInputContext::QXIMInputContext(QWidget *widget) ++ : QInputContext(), ic(0), fontset(0) ++{ ++ if(!isInitXIM) ++ QXIMInputContext::init_xim(); ++ ++#if !defined(QT_NO_XIM) ++ fontsetRefCount++; ++ if (! qt_xim) { ++ qWarning("QInputContext: no input method context available"); ++ return; ++ } ++ ++ if (! widget->isTopLevel()) { ++ qWarning("QInputContext: cannot create input context for non-toplevel widgets"); ++ return; ++ } ++ ++ XPoint spot; ++ XRectangle rect; ++ XVaNestedList preedit_attr = 0; ++ XIMCallback startcallback, drawcallback, donecallback; ++ ++ font = widget->font(); ++ fontset = getFontSet( font ); ++ ++ if (qt_xim_style & XIMPreeditArea) { ++ rect.x = 0; ++ rect.y = 0; ++ rect.width = widget->width(); ++ rect.height = widget->height(); ++ ++ preedit_attr = XVaCreateNestedList(0, ++ XNArea, &rect, ++ XNFontSet, fontset, ++ (char *) 0); ++ } else if (qt_xim_style & XIMPreeditPosition) { ++ spot.x = 1; ++ spot.y = 1; ++ ++ preedit_attr = XVaCreateNestedList(0, ++ XNSpotLocation, &spot, ++ XNFontSet, fontset, ++ (char *) 0); ++ } else if (qt_xim_style & XIMPreeditCallbacks) { ++ startcallback.client_data = (XPointer) this; ++ startcallback.callback = (XIMProc) xic_start_callback; ++ drawcallback.client_data = (XPointer) this; ++ drawcallback.callback = (XIMProc)xic_draw_callback; ++ donecallback.client_data = (XPointer) this; ++ donecallback.callback = (XIMProc) xic_done_callback; ++ ++ preedit_attr = XVaCreateNestedList(0, ++ XNPreeditStartCallback, &startcallback, ++ XNPreeditDrawCallback, &drawcallback, ++ XNPreeditDoneCallback, &donecallback, ++ (char *) 0); ++ } ++ ++ if (preedit_attr) { ++ ic = XCreateIC(qt_xim, ++ XNInputStyle, qt_xim_style, ++ XNClientWindow, widget->winId(), ++ XNPreeditAttributes, preedit_attr, ++ (char *) 0); ++ XFree(preedit_attr); ++ } else ++ ic = XCreateIC(qt_xim, ++ XNInputStyle, qt_xim_style, ++ XNClientWindow, widget->winId(), ++ (char *) 0); ++ ++ if (! ic) ++ qFatal("Failed to create XIM input context!"); ++ ++ // when resetting the input context, preserve the input state ++ (void) XSetICValues((XIC) ic, XNResetState, XIMPreserveState, (char *) 0); ++ ++ if( ! ximContextList ) ++ ximContextList = new QPtrList<QXIMInputContext>; ++ ximContextList->append( this ); ++#endif // !QT_NO_XIM ++} ++ ++ ++QXIMInputContext::~QXIMInputContext() ++{ ++ ++#if !defined(QT_NO_XIM) ++ if (ic) ++ XDestroyIC((XIC) ic); ++ ++ if ( --fontsetRefCount == 0 ) { ++ Display *dpy = QPaintDevice::x11AppDisplay(); ++ for ( int i = 0; i < 8; i++ ) { ++ if ( fontsetCache[i] && fontsetCache[i] != (XFontSet)-1 ) { ++ XFreeFontSet(dpy, fontsetCache[i]); ++ fontsetCache[i] = 0; ++ } ++ } ++ } ++ ++ if( ximContextList ) { ++ ximContextList->remove( this ); ++ if(ximContextList->isEmpty()) { ++ // Calling XCloseIM gives a Purify FMR error ++ // XCloseIM( qt_xim ); ++ // We prefer a less serious memory leak ++ if( qt_xim ) { ++ qt_xim = 0; ++ isInitXIM = FALSE; ++ } ++ ++ delete ximContextList; ++ ximContextList = 0; ++ } ++ } ++#endif // !QT_NO_XIM ++ ++ ic = 0; ++} ++ ++void QXIMInputContext::init_xim() ++{ ++#ifndef QT_NO_XIM ++ if(!isInitXIM) ++ isInitXIM = TRUE; ++ ++ qt_xim = 0; ++ QString ximServerName(ximServer); ++ if (ximServer) ++ ximServerName.prepend("@im="); ++ else ++ ximServerName = ""; ++ ++ if ( !XSupportsLocale() ) ++ qWarning("Qt: Locales not supported on X server"); ++ ++#ifdef USE_X11R6_XIM ++ else if ( XSetLocaleModifiers (ximServerName.ascii()) == 0 ) ++ qWarning( "Qt: Cannot set locale modifiers: %s", ++ ximServerName.ascii()); ++ else { ++ Display *dpy = QPaintDevice::x11AppDisplay(); ++ XRegisterIMInstantiateCallback(dpy, 0, 0, 0, ++ (XIMProc) xim_create_callback, 0); ++ } ++#else // !USE_X11R6_XIM ++ else if ( XSetLocaleModifiers ("") == 0 ) ++ qWarning("Qt: Cannot set locale modifiers"); ++ else ++ QXIMInputContext::create_xim(); ++#endif // USE_X11R6_XIM ++#endif // QT_NO_XIM ++} ++ ++ ++/*! \internal ++ Creates the application input method. ++ */ ++void QXIMInputContext::create_xim() ++{ ++#ifndef QT_NO_XIM ++ Display *appDpy = QPaintDevice::x11AppDisplay(); ++ qt_xim = XOpenIM( appDpy, 0, 0, 0 ); ++ if ( qt_xim ) { ++ ++#ifdef USE_X11R6_XIM ++ XIMCallback destroy; ++ destroy.callback = (XIMProc) xim_destroy_callback; ++ destroy.client_data = 0; ++ if ( XSetIMValues( qt_xim, XNDestroyCallback, &destroy, (char *) 0 ) != 0 ) ++ qWarning( "Xlib doesn't support destroy callback"); ++#endif // USE_X11R6_XIM ++ ++ XIMStyles *styles = 0; ++ XGetIMValues(qt_xim, XNQueryInputStyle, &styles, (char *) 0, (char *) 0); ++ if ( styles ) { ++ int i; ++ for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) { ++ if ( styles->supported_styles[i] == xim_preferred_style ) { ++ qt_xim_style = xim_preferred_style; ++ break; ++ } ++ } ++ // if the preferred input style couldn't be found, look for ++ // Nothing ++ for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) { ++ if ( styles->supported_styles[i] == (XIMPreeditNothing | ++ XIMStatusNothing) ) { ++ qt_xim_style = XIMPreeditNothing | XIMStatusNothing; ++ break; ++ } ++ } ++ // ... and failing that, None. ++ for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) { ++ if ( styles->supported_styles[i] == (XIMPreeditNone | ++ XIMStatusNone) ) { ++ qt_xim_style = XIMPreeditNone | XIMStatusNone; ++ break; ++ } ++ } ++ ++ // qDebug("QApplication: using im style %lx", qt_xim_style); ++ XFree( (char *)styles ); ++ } ++ ++ if ( qt_xim_style ) { ++ ++#ifdef USE_X11R6_XIM ++ XUnregisterIMInstantiateCallback(appDpy, 0, 0, 0, ++ (XIMProc) xim_create_callback, 0); ++#endif // USE_X11R6_XIM ++ ++ } else { ++ // Give up ++ qWarning( "No supported input style found." ++ " See InputMethod documentation."); ++ QXIMInputContext::close_xim(); ++ } ++ } ++#endif // QT_NO_XIM ++} ++ ++ ++/*! \internal ++ Closes the application input method. ++*/ ++void QXIMInputContext::close_xim() ++{ ++#ifndef QT_NO_XIM ++ QApplication::close_xim(); ++#endif // QT_NO_XIM ++} ++ ++ ++bool QXIMInputContext::x11FilterEvent( QWidget *keywidget, XEvent *event ) ++{ ++#ifndef QT_NO_XIM ++ int xkey_keycode = event->xkey.keycode; ++ if ( XFilterEvent( event, keywidget->topLevelWidget()->winId() ) ) { ++ composingKeycode = xkey_keycode; // ### not documented in xlib ++ ++ // Cancel of the composition is realizable even if ++ // follwing codes don't exist ++#if 0 ++ if ( event->type != XKeyPress || ! (qt_xim_style & XIMPreeditCallbacks) ) ++ return TRUE; ++ ++ /* ++ * The Solaris htt input method will transform a ClientMessage ++ * event into a filtered KeyPress event, in which case our ++ * keywidget is still zero. ++ */ ++ QETWidget *widget = (QETWidget*)QWidget::find( (WId)event->xany.window ); ++ if ( ! keywidget ) { ++ keywidget = (QETWidget*)QWidget::keyboardGrabber(); ++ if ( keywidget ) { ++ grabbed = TRUE; ++ } else { ++ if ( focus_widget ) ++ keywidget = (QETWidget*)focus_widget; ++ if ( !keywidget ) { ++ if ( qApp->inPopupMode() ) // no focus widget, see if we have a popup ++ keywidget = (QETWidget*) qApp->activePopupWidget(); ++ else if ( widget ) ++ keywidget = (QETWidget*)widget->topLevelWidget(); ++ } ++ } ++ } ++ ++ /* ++ if the composition string has been emptied, we need to send ++ an IMEnd event. however, we have no way to tell if the user ++ has cancelled input, or if the user has accepted the ++ composition. ++ ++ so, we have to look for the next keypress and see if it is ++ the 'commit' key press (keycode == 0). if it is, we deliver ++ an IMEnd event with the final text, otherwise we deliver an ++ IMEnd with empty text (meaning the user has cancelled the ++ input). ++ */ ++ if ( composing && focusWidget && qt_compose_emptied ) { ++ XEvent event2; ++ bool found = FALSE; ++ if ( XCheckTypedEvent( QPaintDevice::x11AppDisplay(), ++ XKeyPress, &event2 ) ) { ++ if ( event2.xkey.keycode == 0 ) { ++ // found a key event with the 'commit' string ++ found = TRUE; ++ XPutBackEvent( QPaintDevice::x11AppDisplay(), &event2 ); ++ } ++ } ++ ++ if ( !found ) { ++ // no key event, so the user must have cancelled the composition ++ QIMEvent endevent( QEvent::IMEnd, QString::null, -1 ); ++ QApplication::sendEvent( focusWidget, &endevent ); ++ ++ focusWidget = 0; ++ } ++ ++ qt_compose_emptied = FALSE; ++ } ++#endif ++ return TRUE; ++ } else if ( focusWidget() ) { ++ if ( event->type == XKeyPress && event->xkey.keycode == 0 ) { ++ // input method has sent us a commit string ++ QCString data(513); ++ KeySym sym; // unused ++ Status status; // unused ++ QString inputText; ++ int count = lookupString( &(event->xkey), data, &sym, &status ); ++ if ( count > 0 ) ++ inputText = input_mapper->toUnicode( data, count ); ++ ++ if ( ! ( qt_xim_style & XIMPreeditCallbacks ) || ! isComposing() ) { ++ // there is no composing state ++ sendIMEvent( QEvent::IMStart ); ++ } ++ ++ sendIMEvent( QEvent::IMEnd, inputText ); ++ resetClientState(); ++ ++ return TRUE; ++ } ++ } ++#endif // !QT_NO_XIM ++ ++ return FALSE; ++} ++ ++ ++void QXIMInputContext::sendIMEvent( QEvent::Type type, const QString &text, ++ int cursorPosition, int selLength ) ++{ ++ QInputContext::sendIMEvent( type, text, cursorPosition, selLength ); ++ if ( type == QEvent::IMCompose ) ++ composingText = text; ++} ++ ++ ++void QXIMInputContext::reset() ++{ ++#if !defined(QT_NO_XIM) ++ if ( focusWidget() && isComposing() && ! composingText.isNull() ) { ++#ifdef QT_XIM_DEBUG ++ qDebug("QXIMInputContext::reset: composing - sending IMEnd (empty) to %p", ++ focusWidget() ); ++#endif // QT_XIM_DEBUG ++ ++ QInputContext::reset(); ++ resetClientState(); ++ ++ char *mb = XmbResetIC((XIC) ic); ++ if (mb) ++ XFree(mb); ++ } ++#endif // !QT_NO_XIM ++} ++ ++ ++void QXIMInputContext::resetClientState() ++{ ++#if !defined(QT_NO_XIM) ++ composingText = QString::null; ++ if ( selectedChars.size() < 128 ) ++ selectedChars.resize( 128 ); ++ selectedChars.fill( 0 ); ++#endif // !QT_NO_XIM ++} ++ ++ ++bool QXIMInputContext::hasFocus() const ++{ ++ return ( focusWidget() != 0 ); ++} ++ ++ ++// to break access permission ++bool QXIMInputContext::isComposing() const ++{ ++ return QInputContext::isComposing(); ++} ++ ++void QXIMInputContext::setMicroFocus(int x, int y, int w, int h, QFont *f) ++{ ++ QWidget *widget = focusWidget(); ++ if ( qt_xim && widget ) { ++ QPoint p( x, y ); ++ QPoint p2 = widget->mapTo( widget->topLevelWidget(), QPoint( 0, 0 ) ); ++ p = widget->topLevelWidget()->mapFromGlobal( p ); ++ setXFontSet( f ? *f : widget->font() ); ++ setComposePosition(p.x(), p.y() + h); ++ setComposeArea(p2.x(), p2.y(), widget->width(), widget->height()); ++ } ++ ++} ++ ++void QXIMInputContext::mouseHandler( int x, QEvent::Type type, ++ Qt::ButtonState button, ++ Qt::ButtonState state ) ++{ ++ if ( type == QEvent::MouseButtonPress || ++ type == QEvent::MouseButtonDblClick ) { ++ // Don't reset Japanese input context here. Japanese input ++ // context sometimes contains a whole paragraph and has ++ // minutes of lifetime different to ephemeral one in other ++ // languages. The input context should be survived until ++ // focused again. ++ if ( ! isPreeditPreservationEnabled() ) ++ reset(); ++ } ++} ++ ++void QXIMInputContext::setComposePosition(int x, int y) ++{ ++#if !defined(QT_NO_XIM) ++ if (qt_xim && ic) { ++ XPoint point; ++ point.x = x; ++ point.y = y; ++ ++ XVaNestedList preedit_attr = ++ XVaCreateNestedList(0, ++ XNSpotLocation, &point, ++ ++ (char *) 0); ++ XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); ++ XFree(preedit_attr); ++ } ++#endif // !QT_NO_XIM ++} ++ ++ ++void QXIMInputContext::setComposeArea(int x, int y, int w, int h) ++{ ++#if !defined(QT_NO_XIM) ++ if (qt_xim && ic) { ++ XRectangle rect; ++ rect.x = x; ++ rect.y = y; ++ rect.width = w; ++ rect.height = h; ++ ++ XVaNestedList preedit_attr = XVaCreateNestedList(0, ++ XNArea, &rect, ++ ++ (char *) 0); ++ XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); ++ XFree(preedit_attr); ++ } ++#endif ++} ++ ++ ++void QXIMInputContext::setXFontSet(const QFont &f) ++{ ++#if !defined(QT_NO_XIM) ++ if (font == f) return; // nothing to do ++ font = f; ++ ++ XFontSet fs = getFontSet(font); ++ if (fontset == fs) return; // nothing to do ++ fontset = fs; ++ ++ XVaNestedList preedit_attr = XVaCreateNestedList(0, XNFontSet, fontset, (char *) 0); ++ XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); ++ XFree(preedit_attr); ++#else ++ Q_UNUSED( f ); ++#endif ++} ++ ++ ++int QXIMInputContext::lookupString(XKeyEvent *event, QCString &chars, ++ KeySym *key, Status *status) const ++{ ++ int count = 0; ++ ++#if !defined(QT_NO_XIM) ++ if (qt_xim && ic) { ++ count = XmbLookupString((XIC) ic, event, chars.data(), ++ chars.size(), key, status); ++ ++ if ((*status) == XBufferOverflow ) { ++ chars.resize(count + 1); ++ count = XmbLookupString((XIC) ic, event, chars.data(), ++ chars.size(), key, status); ++ } ++ } ++ ++#endif // QT_NO_XIM ++ ++ return count; ++} ++ ++void QXIMInputContext::setFocus() ++{ ++#if !defined(QT_NO_XIM) ++ if ( qt_xim && ic ) ++ XSetICFocus((XIC) ic); ++#endif // !QT_NO_XIM ++} ++ ++void QXIMInputContext::unsetFocus() ++{ ++#if !defined(QT_NO_XIM) ++ if (qt_xim && ic) ++ XUnsetICFocus((XIC) ic); ++#endif // !QT_NO_XIM ++ ++ // Don't reset Japanese input context here. Japanese input context ++ // sometimes contains a whole paragraph and has minutes of ++ // lifetime different to ephemeral one in other languages. The ++ // input context should be survived until focused again. ++ if ( ! isPreeditPreservationEnabled() ) ++ reset(); ++} ++ ++ ++bool QXIMInputContext::isPreeditRelocationEnabled() ++{ ++ return ( language() == "ja" ); ++} ++ ++ ++bool QXIMInputContext::isPreeditPreservationEnabled() ++{ ++ return ( language() == "ja" ); ++} ++ ++ ++QCString QXIMInputContext::language() ++{ ++#if !defined(QT_NO_XIM) ++ if ( qt_xim ) { ++ QLocale locale = QLocale( XLocaleOfIM( qt_xim ) ); ++ ++ if ( locale.language() == QLocale::Chinese ) { ++ // Chinese language should be formed as "zh_CN", "zh_TW", "zh_HK" ++ _language = locale.name(); ++ } else { ++ // other languages should be two-letter ISO 639 language code ++ _language = locale.name().left( 2 ); ++ } ++ } ++#endif ++ return _language; ++} ++ ++#endif //QT_NO_IM ++ +diff -urN qt-x11-free-3.3.2/src/kernel/qapplication.cpp qt-x11-immodule-bc/src/kernel/qapplication.cpp +--- qt-x11-free-3.3.2/src/kernel/qapplication.cpp 2004-04-19 18:36:11.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qapplication.cpp 2004-06-23 01:10:27.065122616 +0900 +@@ -3498,6 +3498,7 @@ + #ifdef Q_WS_WIN + QInputContext::accept( tmp ); + #endif ++ tmp->unfocusInputContext(); + QApplication::sendSpontaneousEvent( tmp, &out ); + } else if ( active_window ) { + QWidget *w = active_window->focusWidget(); +diff -urN qt-x11-free-3.3.2/src/kernel/qapplication_x11.cpp qt-x11-immodule-bc/src/kernel/qapplication_x11.cpp +--- qt-x11-free-3.3.2/src/kernel/qapplication_x11.cpp 2004-04-19 18:36:02.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qapplication_x11.cpp 2004-06-23 01:10:27.069122008 +0900 +@@ -89,7 +89,10 @@ + #include "qfileinfo.h" + + // Input method stuff - UNFINISHED +-#include "qinputcontext_p.h" ++#ifndef QT_NO_IM ++class QInputContext; ++#include "qinputcontext.h" ++#endif // QT_NO_IM + #include "qinternal_p.h" // shared double buffer cleanup + + #if defined(QT_THREAD_SUPPORT) +@@ -189,10 +192,9 @@ + static const char *mwGeometry = 0; // main widget geometry + static const char *mwTitle = 0; // main widget title + //Ming-Che 10/10 +-static char *ximServer = 0; // XIM Server will connect to ++char *ximServer = 0; // XIM Server will connect to + static bool mwIconic = FALSE; // main widget iconified + //Ming-Che 10/10 +-static bool noxim = FALSE; // connect to xim or not + static Display *appDpy = 0; // X11 application display + static char *appDpyName = 0; // X11 display name + static bool appForeignDpy = FALSE; // we didn't create display +@@ -386,15 +388,18 @@ + + + ++#if !defined(QT_NO_IM) ++QString defaultIM = "XIM"; // default input method's name ++#endif + #if !defined(QT_NO_XIM) +-XIM qt_xim = 0; ++//XIM qt_xim = 0; + XIMStyle qt_xim_style = 0; ++XIMStyle xim_preferred_style = 0; + static XIMStyle xim_default_style = XIMPreeditCallbacks | XIMStatusNothing; +-static XIMStyle xim_preferred_style = 0; + #endif + +-static int composingKeycode=0; +-static QTextCodec * input_mapper = 0; ++int composingKeycode=0; ++QTextCodec * input_mapper = 0; + + Q_EXPORT Time qt_x_time = CurrentTime; + Q_EXPORT Time qt_x_user_time = CurrentTime; +@@ -503,8 +508,7 @@ + void setWFlags( WFlags f ) { QWidget::setWFlags(f); } + void clearWFlags( WFlags f ) { QWidget::clearWFlags(f); } + bool translateMouseEvent( const XEvent * ); +- bool translateKeyEventInternal( const XEvent *, int& count, QString& text, int& state, char& ascii, int &code, +- QEvent::Type &type, bool willRepeat=FALSE ); ++ bool translateKeyEventInternal( const XEvent *, int& count, QString& text, int& state, char& ascii, int &code, QEvent::Type &type, bool willRepeat=FALSE, bool statefulTranslation=TRUE ); + bool translateKeyEvent( const XEvent *, bool grab ); + bool translatePaintEvent( const XEvent * ); + bool translateConfigEvent( const XEvent * ); +@@ -521,115 +525,27 @@ + + + // ************************************************************************ +-// X Input Method support ++// Input Method support + // ************************************************************************ + +-#if !defined(QT_NO_XIM) +- +-#if defined(Q_C_CALLBACKS) +-extern "C" { +-#endif // Q_C_CALLBACKS +- +-#ifdef USE_X11R6_XIM +- static void xim_create_callback(XIM /*im*/, +- XPointer /*client_data*/, +- XPointer /*call_data*/) +- { +- // qDebug("xim_create_callback"); +- QApplication::create_xim(); +- } +- +- static void xim_destroy_callback(XIM /*im*/, +- XPointer /*client_data*/, +- XPointer /*call_data*/) +- { +- // qDebug("xim_destroy_callback"); +- QApplication::close_xim(); +- XRegisterIMInstantiateCallback(appDpy, 0, 0, 0, +- (XIMProc) xim_create_callback, 0); +- } +- +-#endif // USE_X11R6_XIM +- +-#if defined(Q_C_CALLBACKS) +-} +-#endif // Q_C_CALLBACKS +- +-#endif // QT_NO_XIM +- +- + /*! \internal +- Creates the application input method. +- */ ++ Creates the application input method. ++*/ + void QApplication::create_xim() + { + #ifndef QT_NO_XIM +- qt_xim = XOpenIM( appDpy, 0, 0, 0 ); +- if ( qt_xim ) { +- +-#ifdef USE_X11R6_XIM +- XIMCallback destroy; +- destroy.callback = (XIMProc) xim_destroy_callback; +- destroy.client_data = 0; +- if ( XSetIMValues( qt_xim, XNDestroyCallback, &destroy, (char *) 0 ) != 0 ) +- qWarning( "Xlib dosn't support destroy callback"); +-#endif // USE_X11R6_XIM +- +- XIMStyles *styles = 0; +- XGetIMValues(qt_xim, XNQueryInputStyle, &styles, (char *) 0, (char *) 0); +- if ( styles ) { +- int i; +- for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) { +- if ( styles->supported_styles[i] == xim_preferred_style ) { +- qt_xim_style = xim_preferred_style; +- break; +- } +- } +- // if the preferred input style couldn't be found, look for +- // Nothing +- for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) { +- if ( styles->supported_styles[i] == (XIMPreeditNothing | +- XIMStatusNothing) ) { +- qt_xim_style = XIMPreeditNothing | XIMStatusNothing; +- break; +- } +- } +- // ... and failing that, None. +- for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) { +- if ( styles->supported_styles[i] == (XIMPreeditNone | +- XIMStatusNone) ) { +- qt_xim_style = XIMPreeditNone | XIMStatusNone; +- break; +- } +- } +- +- // qDebug("QApplication: using im style %lx", qt_xim_style); +- XFree( (char *)styles ); +- } +- +- if ( qt_xim_style ) { ++ if ( ! xim_preferred_style ) // no configured input style, use the default ++ xim_preferred_style = xim_default_style; ++#endif // QT_NO_XIM + +-#ifdef USE_X11R6_XIM +- XUnregisterIMInstantiateCallback(appDpy, 0, 0, 0, +- (XIMProc) xim_create_callback, 0); +-#endif // USE_X11R6_XIM +- +- QWidgetList *list= qApp->topLevelWidgets(); +- QWidgetListIt it(*list); +- QWidget * w; +- while( (w=it.current()) != 0 ) { +- ++it; +- w->createTLSysExtra(); +- } +- delete list; +- } else { +- // Give up +- qWarning( "No supported input style found." +- " See InputMethod documentation."); +- close_xim(); +- } ++ QWidgetList *list= qApp->topLevelWidgets(); ++ QWidgetListIt it(*list); ++ QWidget * w; ++ while( (w=it.current()) != 0 ) { ++ ++it; ++ w->createTLSysExtra(); + } +-#endif // QT_NO_XIM ++ delete list; + } + + +@@ -643,7 +559,10 @@ + // XCloseIM( qt_xim ); + // We prefer a less serious memory leak + +- qt_xim = 0; ++ // if ( qt_xim ) ++ // qt_xim = 0; ++ ++#endif // QT_NO_XIM + QWidgetList *list = qApp->topLevelWidgets(); + QWidgetListIt it(*list); + while(it.current()) { +@@ -651,7 +570,6 @@ + ++it; + } + delete list; +-#endif // QT_NO_XIM + } + + +@@ -1033,6 +951,13 @@ + xim_preferred_style = XIMPreeditArea | XIMStatusArea; + else if ( ximInputStyle == "root" ) + xim_preferred_style = XIMPreeditNothing | XIMStatusNothing; ++ ++ /* ++ The name of InputMethod set up as a default is acquired from ++ a configuration file. However, If not set up, "XIM" become ++ the name of default InputMethod. ++ */ ++ defaultIM = settings.readEntry( "/qt/DefaultInputMethod", QObject::trUtf8( "XIM" ) ); + #endif + + if (update_timestamp) { +@@ -1500,6 +1425,7 @@ + + #define XK_MISCELLANY + #define XK_LATIN1 ++#define XK_KOREAN + #include <X11/keysymdef.h> + + // ### This should be static but it isn't because of the friend declaration +@@ -1586,9 +1512,6 @@ + } else if ( arg == "-im" ) { + if ( ++i < argc ) + ximServer = argv[i]; +- } else if ( arg == "-noxim" ) { +- noxim=TRUE; +- // + } else if ( arg == "-iconic" ) { + mwIconic = !mwIconic; + } else if ( arg == "-ncols" ) { // xv and netscape use this name +@@ -2065,34 +1988,9 @@ + + qt_set_x11_resources( appFont, appFGCol, appBGCol, appBTNCol); + +-#ifndef QT_NO_XIM +- if ( ! xim_preferred_style ) // no configured input style, use the default +- xim_preferred_style = xim_default_style; +- +- qt_xim = 0; +- QString ximServerName(ximServer); +- if (ximServer) +- ximServerName.prepend("@im="); +- else +- ximServerName = ""; +- +- if ( !XSupportsLocale() ) +- qWarning("Qt: Locales not supported on X server"); +- +-#ifdef USE_X11R6_XIM +- else if ( XSetLocaleModifiers (ximServerName.ascii()) == 0 ) +- qWarning( "Qt: Cannot set locale modifiers: %s", +- ximServerName.ascii()); +- else if (! noxim) +- XRegisterIMInstantiateCallback(appDpy, 0, 0, 0, +- (XIMProc) xim_create_callback, 0); +-#else // !USE_X11R6_XIM +- else if ( XSetLocaleModifiers ("") == 0 ) +- qWarning("Qt: Cannot set locale modifiers"); +- else if (! noxim) +- QApplication::create_xim(); +-#endif // USE_X11R6_XIM +-#endif // QT_NO_XIM ++#if !defined(QT_NO_IM) ++ QApplication::create_xim(); ++#endif + + #if defined (QT_TABLET_SUPPORT) + int ndev, +@@ -2341,9 +2239,8 @@ + XCloseDevice( appDpy, devEraser ); + #endif + +-#if !defined(QT_NO_XIM) +- if ( qt_xim ) +- QApplication::close_xim(); ++#if !defined(QT_NO_IM) ++ QApplication::close_xim(); + #endif + + if ( qt_is_gui_used ) { +@@ -3198,77 +3095,45 @@ + } + } + +- int xkey_keycode = event->xkey.keycode; +- if ( XFilterEvent( event, +- keywidget ? keywidget->topLevelWidget()->winId() : None ) ) { +- if ( keywidget ) +- composingKeycode = xkey_keycode; // ### not documented in xlib +- +-#ifndef QT_NO_XIM +- if ( event->type != XKeyPress || ! (qt_xim_style & XIMPreeditCallbacks) ) +- return 1; +- +- /* +- * The Solaris htt input method will transform a ClientMessage +- * event into a filtered KeyPress event, in which case our +- * keywidget is still zero. +- */ +- if ( ! keywidget ) { +- keywidget = (QETWidget*)QWidget::keyboardGrabber(); +- if ( keywidget ) { +- grabbed = TRUE; +- } else { +- if ( focus_widget ) +- keywidget = (QETWidget*)focus_widget; +- if ( !keywidget ) { +- if ( inPopupMode() ) // no focus widget, see if we have a popup +- keywidget = (QETWidget*) activePopupWidget(); +- else if ( widget ) +- keywidget = (QETWidget*)widget->topLevelWidget(); +- } +- } +- } ++#ifndef QT_NO_IM ++ if( keywidget && keywidget->isEnabled() && keywidget->isInputMethodEnabled() ) { ++ if( ( event->type==XKeyPress || event->type==XKeyRelease ) && ++ sm_blockUserInput ) // block user interaction during session management ++ return TRUE; + +- /* +- if the composition string has been emptied, we need to send +- an IMEnd event. however, we have no way to tell if the user +- has cancelled input, or if the user has accepted the +- composition. +- +- so, we have to look for the next keypress and see if it is +- the 'commit' key press (keycode == 0). if it is, we deliver +- an IMEnd event with the final text, otherwise we deliver an +- IMEnd with empty text (meaning the user has cancelled the +- input). +- */ + QInputContext *qic = +- (QInputContext *) keywidget->topLevelWidget()->topData()->xic; +- extern bool qt_compose_emptied; // qinputcontext_x11.cpp +- if ( qic && qic->composing && qic->focusWidget && qt_compose_emptied ) { +- XEvent event2; +- bool found = FALSE; +- if ( XCheckTypedEvent( QPaintDevice::x11AppDisplay(), +- XKeyPress, &event2 ) ) { +- if ( event2.xkey.keycode == 0 ) { +- // found a key event with the 'commit' string +- found = TRUE; +- XPutBackEvent( QPaintDevice::x11AppDisplay(), &event2 ); +- } +- } ++ (QInputContext *) keywidget->topLevelWidget()->topData()->xic; ++ if( qic && qic->x11FilterEvent( keywidget, event ) ) ++ return TRUE; + +- if ( !found ) { +- // no key event, so the user must have cancelled the composition +- QIMEvent endevent( QEvent::IMEnd, QString::null, -1 ); +- QApplication::sendEvent( qic->focusWidget, &endevent ); ++ // filterEvent() accepts QEvent *event rather than preexpanded ++ // key event values. This is intended to pass other IM-related ++ // events in future. The IM-related events are supposed as ++ // QWheelEvent, QTabletEvent and so on. Other non IM-related ++ // events should not be forwarded to input contexts to prevent ++ // weird event handling. ++ if ( ( event->type == XKeyPress || event->type == XKeyRelease ) ) { ++ int code = -1; ++ int count = 0; ++ int state; ++ char ascii = 0; ++ QEvent::Type type; ++ QString text; ++ ++ keywidget->translateKeyEventInternal( event, count, text, ++ state, ascii, code, type, ++ FALSE, FALSE ); + +- qic->focusWidget = 0; +- } ++ QKeyEvent keyevent( type, code, ascii, state, text, FALSE, count ); + +- qt_compose_emptied = FALSE; ++ if( qic && qic->filterEvent( &keyevent ) ) ++ return TRUE; + } +-#endif // QT_NO_XIM +- +- return 1; ++ } else ++#endif // QT_NO_IM ++ { ++ if ( XFilterEvent( event, None ) ) ++ return TRUE; + } + + if ( qt_x11EventFilter(event) ) // send through app filter +@@ -3419,34 +3284,8 @@ + case XKeyRelease: + { + if ( keywidget && keywidget->isEnabled() ) { // should always exist +-#ifndef QT_NO_XIM +- QInputContext *qic = +- (QInputContext *) keywidget->topLevelWidget()->topData()->xic; +- +- if ((qt_xim_style & XIMPreeditCallbacks) && event->xkey.keycode == 0 && +- qic && qic->composing && qic->focusWidget) { +- // input method has sent us a commit string +- QCString data(513); +- KeySym sym; // unused +- Status status; // unused +- QString text; +- int count = qic->lookupString( &(event->xkey), data, +- &sym, &status ); +- if ( count > 0 ) +- text = input_mapper->toUnicode( data, count ); +- +- // qDebug( "sending IMEnd with %d chars", text.length() ); +- QIMEvent endevent( QEvent::IMEnd, text, -1 ); +- QApplication::sendEvent( qic->focusWidget, &endevent ); +- +- qic->focusWidget = 0; +- qic->text = QString::null; +- } else +-#endif // !QT_NO_XIM +- { +- // qDebug( "sending key event" ); +- keywidget->translateKeyEvent( event, grabbed ); +- } ++ // qDebug( "sending key event" ); ++ keywidget->translateKeyEvent( event, grabbed ); + } + break; + } +@@ -4733,6 +4572,61 @@ + XK_Help, Qt::Key_Help, + 0x1000FF74, Qt::Key_BackTab, // hardcoded HP backtab + ++ // International input method support keys ++ ++ // International & multi-key character composition ++ XK_Multi_key, Qt::Key_Multi_key, ++ XK_Codeinput, Qt::Key_Codeinput, ++ XK_SingleCandidate, Qt::Key_SingleCandidate, ++ XK_MultipleCandidate, Qt::Key_MultipleCandidate, ++ XK_PreviousCandidate, Qt::Key_PreviousCandidate, ++ ++ // Misc Functions ++ XK_Mode_switch, Qt::Key_Mode_switch, ++ //XK_script_switch, Qt::Key_script_switch, ++ ++ // Japanese keyboard support ++ XK_Kanji, Qt::Key_Kanji, ++ XK_Muhenkan, Qt::Key_Muhenkan, ++ //XK_Henkan_Mode, Qt::Key_Henkan_Mode, ++ XK_Henkan, Qt::Key_Henkan, ++ XK_Romaji, Qt::Key_Romaji, ++ XK_Hiragana, Qt::Key_Hiragana, ++ XK_Katakana, Qt::Key_Katakana, ++ XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana, ++ XK_Zenkaku, Qt::Key_Zenkaku, ++ XK_Hankaku, Qt::Key_Hankaku, ++ XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku, ++ XK_Touroku, Qt::Key_Touroku, ++ XK_Massyo, Qt::Key_Massyo, ++ XK_Kana_Lock, Qt::Key_Kana_Lock, ++ XK_Kana_Shift, Qt::Key_Kana_Shift, ++ XK_Eisu_Shift, Qt::Key_Eisu_Shift, ++ XK_Eisu_toggle, Qt::Key_Eisu_toggle, ++ //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou, ++ //XK_Zen_Koho, Qt::Key_Zen_Koho, ++ //XK_Mae_Koho, Qt::Key_Mae_Koho, ++ ++#ifdef XK_KOREAN ++ // Korean support ++ XK_Hangul, Qt::Key_Hangul, ++ XK_Hangul_Start, Qt::Key_Hangul_Start, ++ XK_Hangul_End, Qt::Key_Hangul_End, ++ XK_Hangul_Hanja, Qt::Key_Hangul_Hanja, ++ XK_Hangul_Jamo, Qt::Key_Hangul_Jamo, ++ XK_Hangul_Romaja, Qt::Key_Hangul_Romaja, ++ XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput, ++ XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja, ++ XK_Hangul_Banja, Qt::Key_Hangul_Banja, ++ XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja, ++ XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja, ++ XK_Hangul_SingleCandidate, Qt::Key_Hangul_SingleCandidate, ++ XK_Hangul_MultipleCandidate, Qt::Key_Hangul_MultipleCandidate, ++ XK_Hangul_PreviousCandidate, Qt::Key_Hangul_PreviousCandidate, ++ XK_Hangul_Special, Qt::Key_Hangul_Special, ++ //XK_Hangul_switch, Qt::Key_Hangul_switch, ++#endif // XK_KOREAN ++ + // Special multimedia keys + // currently only tested with MS internet keyboard + +@@ -4950,7 +4844,7 @@ + bool QETWidget::translateKeyEventInternal( const XEvent *event, int& count, + QString& text, + int& state, +- char& ascii, int& code, QEvent::Type &type, bool willRepeat ) ++ char& ascii, int& code, QEvent::Type &type, bool willRepeat, bool statefulTranslation ) + { + QTextCodec *mapper = input_mapper; + // some XmbLookupString implementations don't return buffer overflow correctly, +@@ -4999,6 +4893,11 @@ + + if ( type == QEvent::KeyPress ) { + bool mb=FALSE; ++ // commit string handling is done by ++ // QXIMInputContext::x11FilterEvent() and are passed to ++ // widgets via QIMEvent regardless of XIM style, so the ++ // following code is commented out. ++#if 0 + if ( qt_xim ) { + QTLWExtra* xd = tlw->topData(); + QInputContext *qic = (QInputContext *) xd->xic; +@@ -5007,6 +4906,7 @@ + count = qic->lookupString(&xkeyevent, chars, &key, &status); + } + } ++#endif + if ( !mb ) { + count = XLookupString( &xkeyevent, + chars.data(), chars.size(), &key, 0 ); +@@ -5090,7 +4990,7 @@ + state = translateButtonState( keystate ); + + static int directionKeyEvent = 0; +- if ( qt_use_rtl_extensions && type == QEvent::KeyRelease ) { ++ if ( qt_use_rtl_extensions && type == QEvent::KeyRelease && statefulTranslation ) { + if (directionKeyEvent == Key_Direction_R || directionKeyEvent == Key_Direction_L ) { + type = QEvent::KeyPress; + code = directionKeyEvent; +@@ -5108,7 +5008,7 @@ + // (to figure out whether the Ctrl modifier is held while Shift is pressed, + // or Shift is held while Ctrl is pressed) since the 'state' doesn't tell + // us whether the modifier held is Left or Right. +- if (qt_use_rtl_extensions && type == QEvent::KeyPress) ++ if ( qt_use_rtl_extensions && type == QEvent::KeyPress && statefulTranslation ) + if (key == XK_Control_L || key == XK_Control_R || key == XK_Shift_L || key == XK_Shift_R) { + if (!directionKeyEvent) + directionKeyEvent = key; +@@ -5176,7 +5076,7 @@ + chars[0] = 0; + } + +- if ( qt_use_rtl_extensions && type == QEvent::KeyPress ) { ++ if ( qt_use_rtl_extensions && type == QEvent::KeyPress && statefulTranslation ) { + if ( directionKeyEvent ) { + if ( key == XK_Shift_L && directionKeyEvent == XK_Control_L || + key == XK_Control_L && directionKeyEvent == XK_Shift_L ) { +@@ -5330,8 +5230,18 @@ + translateKeyEventInternal( event, count, text, state, ascii, code, type ); + } + ++#ifndef QT_NO_IM ++ QInputContext *qic = ++ (QInputContext *) topLevelWidget()->topData()->xic; ++#endif ++ + // compress keys + if ( !text.isEmpty() && testWState(WState_CompressKeys) && ++#ifndef QT_NO_IM ++ // input methods need discrete key events ++ // TODO: describe design decision ++ ! qic && ++#endif // QT_NO_IM + // do not compress keys if the key event we just got above matches + // one of the key ranges used to compute stopCompression + ! ( ( code >= Key_Escape && code <= Key_SysReq ) || +@@ -5419,7 +5329,13 @@ + + // autorepeat compression makes sense for all widgets (Windows + // does it automatically .... ) +- if ( event->type == XKeyPress && text.length() <= 1 ) { ++ if ( event->type == XKeyPress && text.length() <= 1 ++#ifndef QT_NO_IM ++ // input methods need discrete key events ++ // TODO: describe design decision ++ && ! qic ++#endif// QT_NO_IM ++ ) { + XEvent dummy; + + for (;;) { +diff -urN qt-x11-free-3.3.2/src/kernel/qinputcontext.cpp qt-x11-immodule-bc/src/kernel/qinputcontext.cpp +--- qt-x11-free-3.3.2/src/kernel/qinputcontext.cpp 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qinputcontext.cpp 2004-06-23 03:00:46.715782752 +0900 +@@ -0,0 +1,382 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** Implementation of QInputContext class ++** ++** Copyright (C) 2000-2003 Trolltech AS. All rights reserved. ++** ++** This file is part of the kernel module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ++** licenses for Unix/X11 may use this file in accordance with the Qt Commercial ++** License Agreement provided with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++//#define QT_NO_IM_PREEDIT_RELOCATION ++ ++#include "qinputcontext.h" ++ ++#ifndef QT_NO_IM ++ ++#include "qplatformdefs.h" ++ ++#include "qapplication.h" ++#include "qwidget.h" ++ ++#include <stdlib.h> ++#include <limits.h> ++ ++class QInputContextPrivate ++{ ++public: ++ QInputContextPrivate() ++ : holderWidget( 0 ), composingWidget( 0 ), hasFocus( FALSE ), ++ isComposing( FALSE ) ++#if !defined(QT_NO_IM_PREEDIT_RELOCATION) ++ , preeditString( QString::null ), ++ cursorPosition( -1 ), selLength ( 0 ) ++#endif ++ {} ++ ++ QWidget *holderWidget; // widget to which QInputContext instance belongs. ++ QWidget *composingWidget; ++ bool hasFocus; ++ bool isComposing; ++ ++ void updateComposingState( const QString &text, ++ int newCursorPosition, int newSelLength ) { ++#if !defined(QT_NO_IM_PREEDIT_RELOCATION) ++ preeditString = text; ++ cursorPosition = newCursorPosition; ++ selLength = newSelLength; ++#endif ++ } ++ ++ void resetComposingState() { ++ isComposing = FALSE; ++#if !defined(QT_NO_IM_PREEDIT_RELOCATION) ++ preeditString = QString::null; ++ cursorPosition = -1; ++ selLength = 0; ++#endif ++ } ++ ++#if !defined(QT_NO_IM_PREEDIT_RELOCATION) ++ QString preeditString; ++ int cursorPosition; ++ int selLength; ++#endif ++}; ++ ++ ++/*! ++ This constructor sets widget of the first argument to the ++ holderWidget, state of the second argument to the imState, ++ respectively. holderWidget is widget holding QInputContext ++ (itself). imState is state of InputMethod. ++*/ ++QInputContext::QInputContext() ++{ ++ d = new QInputContextPrivate; ++} ++ ++ ++QInputContext::~QInputContext() ++{ ++ delete d; ++} ++ ++QWidget* QInputContext::holderWidget() const ++{ ++ return d->holderWidget; ++} ++ ++void QInputContext::setHolderWidget( QWidget *w ) ++{ ++ d->holderWidget = w; ++} ++ ++QWidget* QInputContext::focusWidget() const ++{ ++ return d->hasFocus ? d->composingWidget : 0; ++} ++ ++ ++void QInputContext::setFocusWidget( QWidget *w ) ++{ ++ if ( w ) { ++ bool isFocusingBack = ( w == d->composingWidget ); ++ bool isPreeditRelocation = ( ! isFocusingBack && isComposing() && ++ d->composingWidget ); ++ // invoke sendIMEventInternal() rather than sendIMEvent() to ++ // avoid altering the composing state ++ if ( isPreeditRelocation == TRUE ) { ++ // clear preedit of previously focused text ++ // widget. preserved preedit may be exist even if ++ // isPreeditRelocationEnabled() == FALSE. ++ sendIMEventInternal( QEvent::IMEnd ); ++ } ++ d->composingWidget = w; // changes recipient of QIMEvent ++ if ( isPreeditRelocation == TRUE ) { ++#if !defined(QT_NO_IM_PREEDIT_RELOCATION) ++ if ( isPreeditRelocationEnabled() ) { ++ // copy preedit state to the widget that gaining focus ++ sendIMEventInternal( QEvent::IMStart ); ++ sendIMEventInternal( QEvent::IMCompose, d->preeditString, ++ d->cursorPosition, d->selLength ); ++ } else ++#endif ++ { ++ // reset input context when the shared context has ++ // focused on another text widget ++ reset(); ++ } ++ } ++ } ++ d->hasFocus = w ? TRUE : FALSE; ++} ++ ++ ++void QInputContext::releaseComposingWidget( QWidget *w ) ++{ ++ if ( d->composingWidget == w ) { ++ d->composingWidget = 0; ++ d->hasFocus = FALSE; ++ } ++} ++ ++bool QInputContext::isPreeditRelocationEnabled() ++{ ++ return FALSE; ++} ++ ++bool QInputContext::isComposing() const ++{ ++ return d->isComposing; ++} ++ ++ ++/*! ++ This function must be implemented in subclasses to handle key ++ input (except for input method used only on a specific ++ platform). If an event is filtered, it must return TRUE. ++ ++ keywidget is client widget into which a text is inputted. type ++ shows whether inputted event is KeyPress or KeyRelease. code show ++ inputted key code. state show keyboard modifiers (OR-ed together). ++ ++ In principle, only when composition is finished, the input is ++ committed by QIMEvent (IMEnd). Otherwise, the input set to ++ arguments, such as text, ascii, count, etc. The purpose of this ++ specification is to take adjustment with key compression. ++*/ ++bool QInputContext::filterEvent( QEvent *event ) ++{ ++ return FALSE; ++} ++ ++ ++void QInputContext::sendIMEventInternal( QEvent::Type type, ++ const QString &text, ++ int cursorPosition, int selLength ) ++{ ++#if defined(Q_WS_X11) ++ if ( ! d->composingWidget ) ++ return; ++#endif ++ ++ if ( type == QEvent::IMStart ) { ++ qDebug( "sending IMStart with %d chars to %p", ++ text.length(), d->composingWidget ); ++#if defined(Q_WS_X11) ++ QIMEvent event( type, text, cursorPosition ); ++ QApplication::sendEvent( d->composingWidget, &event ); ++#elif defined(Q_WS_QWS) ++ // just a placeholder for now ++ //qwsServer->sendIMEvent( QWSServer::IMCompose, ++ // text, cursorPosition, selLength ); ++#endif ++ } else if ( type == QEvent::IMEnd ) { ++ qDebug( "sending IMEnd with %d chars to %p, text=%s", ++ text.length(), d->composingWidget, ++ (const char*)text.local8Bit() ); ++#if defined(Q_WS_X11) ++ QIMEvent event( type, text, cursorPosition ); ++ QApplication::sendEvent( d->composingWidget, &event ); ++#elif defined(Q_WS_QWS) ++ //qwsServer->sendIMEvent( QWSServer::IMEnd, ++ // text, cursorPosition, selLength ); ++#endif ++ } else if ( type == QEvent::IMCompose ) { ++ qDebug( "sending IMCompose to %p with %d chars, cpos=%d, sellen=%d, text=%s", ++ d->composingWidget, ++ text.length(), cursorPosition, selLength, ++ (const char*)text.local8Bit() ); ++#if defined(Q_WS_X11) ++ QIMComposeEvent event( type, text, cursorPosition, selLength ); ++ QApplication::sendEvent( d->composingWidget, &event ); ++#elif defined(Q_WS_QWS) ++ //qwsServer->sendIMEvent( QWSServer::IMCompose, ++ // text, cursorPosition, selLength ); ++#endif ++ } ++} ++ ++ ++void QInputContext::sendIMEvent( QEvent::Type type, const QString &text, ++ int cursorPosition, int selLength ) ++{ ++#if defined(Q_WS_X11) ++ if ( !focusWidget() ) ++ return; ++#endif ++ ++ if ( type == QEvent::IMStart ) { ++ sendIMEventInternal( type, text, cursorPosition, selLength ); ++ d->isComposing = TRUE; ++ } else if ( type == QEvent::IMEnd ) { ++ d->resetComposingState(); ++ sendIMEventInternal( type, text, cursorPosition, selLength ); ++ } else if ( type == QEvent::IMCompose ) { ++ d->updateComposingState( text, cursorPosition, selLength ); ++ sendIMEventInternal( type, text, cursorPosition, selLength ); ++ } ++} ++ ++ ++ ++/*! ++ \fn void QInputContext::setFocus() ++ ++ This function must be implemented in subclasses to set focus. ++ ++ \sa unsetFocus() ++*/ ++void QInputContext::setFocus() ++{ ++ // focusWidget is already set by QWidget::focusInputContext() ++} ++ ++ ++/*! ++ \fn void QInputContext::unsetFocus() ++ ++ This function must be implemented in subclasses to unset focus. ++ ++ \sa setFocus() ++*/ ++void QInputContext::unsetFocus() ++{ ++ reset(); ++ // focusWidget is set to 0 after return by QWidget::unfocusInputContext() ++} ++ ++ ++/*! ++ \fn void QInputContext::setMicroFocus( int x, int y, int w, int h, QFont *f ) ++ ++ This function must be implemented in subclasses to handle ++ focusHint changes. ++ ++ x and y are cursor's positions. w is cursor's width, and h is ++ cursor's height. widget is client widget. f is a font on the ++ cursor's position. ++*/ ++void QInputContext::setMicroFocus( int x, int y, int w, int h, QFont *f ) ++{ ++} ++ ++ ++/*! ++ \fn void QWSInputMethod::mouseHandler( int x, int state ) ++ ++ Implemented in subclasses to handle mouse ++ presses/releases/doubleclicks/moves within the on-the-spot text. The ++ parameter \a x is the offset within the string that was sent with ++ the IMCompose event. \a state is either \c QEvent::MouseButtonPress ++ or \c QEvent::MouseButtonRelease or \c QEvent::MouseButtonDblClick ++ or \c QEvent::MouseButtonMove. The method interface is imported from ++ QWSInputMethod::mouseHandler() of Qt/Embedded 2.3.7 and extended for ++ desktop system. ++ */ ++void QInputContext::mouseHandler( int x, QEvent::Type type, ++ Qt::ButtonState button, ++ Qt::ButtonState state ) ++{ ++ // Default behavior for simple ephemeral input contexts. Some ++ // complex input contexts should not be reset here. ++ if ( type == QEvent::MouseButtonPress || ++ type == QEvent::MouseButtonDblClick ) ++ reset(); ++} ++ ++ ++/*! ++ Returns the font of the current input widget ++ */ ++QFont QInputContext::font() const ++{ ++ if ( !focusWidget() ) ++ return QApplication::font(); //### absolutely last resort ++ ++ return focusWidget()->font(); ++} ++ ++ ++/*! ++ \fn void QInputContext::reset() ++ ++ This function must be implemented in subclasses to reset the state ++ of the input method. ++*/ ++void QInputContext::reset() ++{ ++ if ( isComposing() ) ++ sendIMEvent( QEvent::IMEnd ); ++} ++ ++ ++/*! ++ \fn QString QInputContext::name() ++ ++ This function must be implemented in subclasses to return the name ++ of the input method. ++*/ ++QString QInputContext::name() ++{ ++} ++ ++ ++/*! ++ \fn QCString QInputContext::language() ++ ++ This function must be implemented in subclasses to return a ++ language code (e.g. "zh_CN", "zh_TW", "zh_HK", "ja", "ko", ...) of ++ the input method. ++*/ ++QCString QInputContext::language() ++{ ++} ++ ++#endif //Q_NO_IM +diff -urN qt-x11-free-3.3.2/src/kernel/qinputcontext.h qt-x11-immodule-bc/src/kernel/qinputcontext.h +--- qt-x11-free-3.3.2/src/kernel/qinputcontext.h 1970-01-01 09:00:00.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qinputcontext.h 2004-06-23 03:07:02.936588496 +0900 +@@ -0,0 +1,116 @@ ++/**************************************************************************** ++** $Id: qt-x11-immodule-bc-qt3.3.2-20040623.diff,v 1.1 2004/08/04 16:15:05 usata Exp $ ++** ++** Definition of QInputContext ++** ++** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ++** ++** This file is part of the kernel module of the Qt GUI Toolkit. ++** ++** This file may be distributed under the terms of the Q Public License ++** as defined by Trolltech AS of Norway and appearing in the file ++** LICENSE.QPL included in the packaging of this file. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ++** licenses may use this file in accordance with the Qt Commercial License ++** Agreement provided with the Software. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ++** information about Qt Commercial License Agreements. ++** See http://www.trolltech.com/qpl/ for QPL licensing information. ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++ ++#ifndef QINPUTCONTEXT_H ++#define QINPUTCONTEXT_H ++ ++#ifndef QT_NO_IM ++ ++#ifndef QT_H ++#include "qglobal.h" ++#include "qevent.h" ++#endif ++ ++class QWidget; ++class QFont; ++class QString; ++class QInputContextPrivate; ++ ++ ++/* ++ QInputContext holds the data which input method uses and offers ++ the function which input method has. And, in order to enable ++ useing each input method, it is necessary to inherit QInputContext ++ and to implement InputContext corresponding to it. ++*/ ++class QInputContext ++{ ++public: ++ QInputContext(); ++ virtual ~QInputContext(); ++ ++ virtual QString name(); ++ virtual QCString language(); ++ ++#if defined(Q_WS_X11) ++ virtual bool x11FilterEvent( QWidget *keywidget, XEvent *event ); ++#endif // Q_WS_X11 ++ virtual bool filterEvent( QEvent *event ); ++ virtual void reset(); ++ ++ virtual void setFocus(); ++ virtual void unsetFocus(); ++ virtual void setMicroFocus( int x, int y, int w, int h, QFont *f = 0 ); ++ virtual void mouseHandler( int x, QEvent::Type type, ++ Qt::ButtonState button, Qt::ButtonState state ); ++ virtual QFont font() const; ++ ++protected: ++#if defined(Q_WS_X11) ++ // not recommended to use these functions ++ QWidget *focusWidget() const; ++ QWidget *holderWidget() const; ++#endif ++ ++ bool isComposing() const; ++ virtual bool isPreeditRelocationEnabled(); ++ virtual void sendIMEvent( QEvent::Type type, ++ const QString &text = QString::null, ++ int cursorPosition = -1, int selLength = 0 ); ++ ++private: ++ void sendIMEventInternal( QEvent::Type type, ++ const QString &text = QString::null, ++ int cursorPosition = -1, int selLength = 0 ); ++#if defined(Q_WS_X11) ++ void setFocusWidget( QWidget *w ); ++ void setHolderWidget( QWidget *w ); ++ void releaseComposingWidget( QWidget *w ); ++#endif ++ ++ QInputContextPrivate *d; ++ ++ friend class QWidget; ++ friend class QInputContextFactory; ++ ++private: // Disabled copy constructor and operator= ++ QInputContext( const QInputContext & ); ++ QInputContext &operator=( const QInputContext & ); ++ ++}; ++ ++#endif //Q_NO_IM ++ ++#endif // QINPUTCONTEXT_H +diff -urN qt-x11-free-3.3.2/src/kernel/qinputcontext_x11.cpp qt-x11-immodule-bc/src/kernel/qinputcontext_x11.cpp +--- qt-x11-free-3.3.2/src/kernel/qinputcontext_x11.cpp 2004-04-19 18:36:08.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qinputcontext_x11.cpp 2004-06-23 01:10:27.072121552 +0900 +@@ -33,500 +33,37 @@ + ** + **********************************************************************/ + ++#include "qinputcontext.h" ++ ++#ifndef QT_NO_IM ++ + #include "qplatformdefs.h" + + #include "qapplication.h" + #include "qwidget.h" +-#include "qinputcontext_p.h" +- +-#include <stdlib.h> +-#include <limits.h> + ++#include "qt_x11_p.h" + +-bool qt_compose_emptied = FALSE; ++/*! ++ This function, only if input method is depending on X11, must be overridden ++ in subclasses. Otherwise, this function must not. + +-#if !defined(QT_NO_XIM) ++ By default, this function translates key code and keyboard modifiers from ++ the event which is the 2nd argument, and pass the value to QInputContext::filterEvent(). + +-#define XK_MISCELLANY +-#define XK_LATIN1 +-#include <X11/keysymdef.h> ++ keywidget is client widget into which a text is inputted. event is inputted XEvent. + +-// #define QT_XIM_DEBUG ++ In principle, only when composition is finished, the input is committed ++ by QIMEvent (IMEnd). Otherwise, the input set to arguments, such as code, ++ state, text, ascii, count, etc. The purpose of this specification is to ++ take adjustment with key compression. + +-// from qapplication_x11.cpp +-extern XIM qt_xim; +-extern XIMStyle qt_xim_style; +- +-/* The cache here is needed, as X11 leaks a few kb for every +- XFreeFontSet call, so we avoid creating and deletion of fontsets as +- much as possible ++ type shows whether inputted event is KeyPress or KeyRelease. code show ++ inputted key code. state show keyboard modifiers (OR-ed together). + */ +-static XFontSet fontsetCache[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +-static int fontsetRefCount = 0; +- +-static const char * const fontsetnames[] = { +- "-*-fixed-medium-r-*-*-16-*,-*-*-medium-r-*-*-16-*", +- "-*-fixed-medium-i-*-*-16-*,-*-*-medium-i-*-*-16-*", +- "-*-fixed-bold-r-*-*-16-*,-*-*-bold-r-*-*-16-*", +- "-*-fixed-bold-i-*-*-16-*,-*-*-bold-i-*-*-16-*", +- "-*-fixed-medium-r-*-*-24-*,-*-*-medium-r-*-*-24-*", +- "-*-fixed-medium-i-*-*-24-*,-*-*-medium-i-*-*-24-*", +- "-*-fixed-bold-r-*-*-24-*,-*-*-bold-r-*-*-24-*", +- "-*-fixed-bold-i-*-*-24-*,-*-*-bold-i-*-*-24-*" +-}; +- +-static XFontSet getFontSet( const QFont &f ) +-{ +- int i = 0; +- if (f.italic()) +- i |= 1; +- if (f.bold()) +- i |= 2; +- +- if ( f.pointSize() > 20 ) +- i += 4; +- +- if ( !fontsetCache[i] ) { +- Display* dpy = QPaintDevice::x11AppDisplay(); +- int missCount; +- char** missList; +- fontsetCache[i] = XCreateFontSet(dpy, fontsetnames[i], &missList, &missCount, 0); +- if(missCount > 0) +- XFreeStringList(missList); +- if ( !fontsetCache[i] ) { +- fontsetCache[i] = XCreateFontSet(dpy, "-*-fixed-*-*-*-*-16-*", &missList, &missCount, 0); +- if(missCount > 0) +- XFreeStringList(missList); +- if ( !fontsetCache[i] ) +- fontsetCache[i] = (XFontSet)-1; +- } +- } +- return (fontsetCache[i] == (XFontSet)-1) ? 0 : fontsetCache[i]; +-} +- +- +-#ifdef Q_C_CALLBACKS +-extern "C" { +-#endif // Q_C_CALLBACKS +- +- static int xic_start_callback(XIC, XPointer client_data, XPointer) { +- QInputContext *qic = (QInputContext *) client_data; +- if (! qic) { +-#ifdef QT_XIM_DEBUG +- qDebug("compose start: no qic"); +-#endif // QT_XIM_DEBUG +- +- return 0; +- } +- +- qic->composing = TRUE; +- qic->text = QString::null; +- qic->focusWidget = 0; +- +- if ( qic->selectedChars.size() < 128 ) +- qic->selectedChars.resize( 128 ); +- qic->selectedChars.fill( 0 ); +- +-#ifdef QT_XIM_DEBUG +- qDebug("compose start"); +-#endif // QT_XIM_DEBUG +- +- return 0; +- } +- +- static int xic_draw_callback(XIC, XPointer client_data, XPointer call_data) { +- QInputContext *qic = (QInputContext *) client_data; +- if (! qic) { +-#ifdef QT_XIM_DEBUG +- qDebug("compose event: invalid compose event %p", qic); +-#endif // QT_XIM_DEBUG +- +- return 0; +- } +- +- bool send_imstart = FALSE; +- if (qApp->focusWidget() != qic->focusWidget && qic->text.isEmpty()) { +- if (qic->focusWidget) { +-#ifdef QT_XIM_DEBUG +- qDebug( "sending IMEnd (empty) to %p", qic->focusWidget ); +-#endif // QT_XIM_DEBUG +- +- QIMEvent endevent(QEvent::IMEnd, QString::null, -1); +- QApplication::sendEvent(qic->focusWidget, &endevent); +- } +- +- qic->text = QString::null; +- qic->focusWidget = qApp->focusWidget(); +- qic->composing = FALSE; +- +- if ( qic->selectedChars.size() < 128 ) +- qic->selectedChars.resize( 128 ); +- qic->selectedChars.fill( 0 ); +- +- if (qic->focusWidget) { +- qic->composing = TRUE; +- send_imstart = TRUE; +- } +- } +- +- if (! qic->composing || ! qic->focusWidget) { +-#ifdef QT_XIM_DEBUG +- qDebug("compose event: invalid compose event %d %p", +- qic->composing, qic->focusWidget); +-#endif // QT_XIM_DEBUG +- +- return 0; +- } +- +- if ( send_imstart ) { +-#ifdef QT_XIM_DEBUG +- qDebug( "sending IMStart to %p", qic->focusWidget ); +-#endif // QT_XIM_DEBUG +- +- qt_compose_emptied = FALSE; +- QIMEvent startevent(QEvent::IMStart, QString::null, -1); +- QApplication::sendEvent(qic->focusWidget, &startevent); +- } +- +- XIMPreeditDrawCallbackStruct *drawstruct = +- (XIMPreeditDrawCallbackStruct *) call_data; +- XIMText *text = (XIMText *) drawstruct->text; +- int cursor = drawstruct->caret, sellen = 0; +- +- if ( ! drawstruct->caret && ! drawstruct->chg_first && +- ! drawstruct->chg_length && ! text ) { +- // nothing to do +- return 0; +- } +- +- if (text) { +- char *str = 0; +- if (text->encoding_is_wchar) { +- int l = wcstombs(NULL, text->string.wide_char, text->length); +- if (l != -1) { +- str = new char[l + 1]; +- wcstombs(str, text->string.wide_char, l); +- str[l] = 0; +- } +- } else +- str = text->string.multi_byte; +- +- if (! str) +- return 0; +- +- QString s = QString::fromLocal8Bit(str); +- +- if (text->encoding_is_wchar) +- delete [] str; +- +- if (drawstruct->chg_length < 0) +- qic->text.replace(drawstruct->chg_first, UINT_MAX, s); +- else +- qic->text.replace(drawstruct->chg_first, drawstruct->chg_length, s); +- +- if ( qic->selectedChars.size() < qic->text.length() ) { +- // expand the selectedChars array if the compose string is longer +- uint from = qic->selectedChars.size(); +- qic->selectedChars.resize( qic->text.length() ); +- for ( uint x = from; from < qic->selectedChars.size(); ++x ) +- qic->selectedChars[x] = 0; +- } +- +- uint x; +- bool *p = qic->selectedChars.data() + drawstruct->chg_first; +- // determine if the changed chars are selected based on text->feedback +- for ( x = 0; x < s.length(); ++x ) +- *p++ = ( text->feedback ? ( text->feedback[x] & XIMReverse ) : 0 ); +- +- // figure out where the selection starts, and how long it is +- p = qic->selectedChars.data(); +- bool started = FALSE; +- for ( x = 0; x < qic->selectedChars.size(); ++x ) { +- if ( started ) { +- if ( *p ) ++sellen; +- else break; +- } else { +- if ( *p ) { +- cursor = x; +- started = TRUE; +- sellen = 1; +- } +- } +- ++p; +- } +- } else { +- if (drawstruct->chg_length == 0) +- drawstruct->chg_length = -1; +- +- qic->text.remove(drawstruct->chg_first, drawstruct->chg_length); +- qt_compose_emptied = qic->text.isEmpty(); +- if ( qt_compose_emptied ) { +-#ifdef QT_XIM_DEBUG +- qDebug( "compose emptied" ); +-#endif // QT_XIM_DEBUG +- +- // don't send an empty compose, since we will send an IMEnd with +- // either the correct compose text (or null text if the user has +- // cancelled the compose or deleted all chars). +- return 0; +- } +- } +- +-#ifdef QT_XIM_DEBUG +- qDebug( "sending IMCompose to %p with %d chars", +- qic->focusWidget, qic->text.length() ); +-#endif // QT_XIM_DEBUG +- +- QIMComposeEvent event( QEvent::IMCompose, qic->text, cursor, sellen ); +- QApplication::sendEvent(qic->focusWidget, &event); +- return 0; +- } +- +- static int xic_done_callback(XIC, XPointer client_data, XPointer) { +- QInputContext *qic = (QInputContext *) client_data; +- if (! qic) +- return 0; +- +- if (qic->composing && qic->focusWidget) { +-#ifdef QT_XIM_DEBUG +- qDebug( "sending IMEnd (empty) to %p", qic->focusWidget ); +-#endif // QT_XIM_DEBUG +- +- QIMEvent event(QEvent::IMEnd, QString::null, -1); +- QApplication::sendEvent(qic->focusWidget, &event); +- } +- +- qic->composing = FALSE; +- qic->focusWidget = 0; +- +- if ( qic->selectedChars.size() < 128 ) +- qic->selectedChars.resize( 128 ); +- qic->selectedChars.fill( 0 ); +- +- return 0; +- } +- +-#ifdef Q_C_CALLBACKS +-} +-#endif // Q_C_CALLBACKS +- +-#endif // !QT_NO_XIM +- +- +- +-QInputContext::QInputContext(QWidget *widget) +- : ic(0), focusWidget(0), composing(FALSE), fontset(0) +-{ +-#if !defined(QT_NO_XIM) +- fontsetRefCount++; +- if (! qt_xim) { +- qWarning("QInputContext: no input method context available"); +- return; +- } +- +- if (! widget->isTopLevel()) { +- qWarning("QInputContext: cannot create input context for non-toplevel widgets"); +- return; +- } +- +- XPoint spot; +- XRectangle rect; +- XVaNestedList preedit_attr = 0; +- XIMCallback startcallback, drawcallback, donecallback; +- +- font = widget->font(); +- fontset = getFontSet( font ); +- +- if (qt_xim_style & XIMPreeditArea) { +- rect.x = 0; +- rect.y = 0; +- rect.width = widget->width(); +- rect.height = widget->height(); +- +- preedit_attr = XVaCreateNestedList(0, +- XNArea, &rect, +- XNFontSet, fontset, +- (char *) 0); +- } else if (qt_xim_style & XIMPreeditPosition) { +- spot.x = 1; +- spot.y = 1; +- +- preedit_attr = XVaCreateNestedList(0, +- XNSpotLocation, &spot, +- XNFontSet, fontset, +- (char *) 0); +- } else if (qt_xim_style & XIMPreeditCallbacks) { +- startcallback.client_data = (XPointer) this; +- startcallback.callback = (XIMProc) xic_start_callback; +- drawcallback.client_data = (XPointer) this; +- drawcallback.callback = (XIMProc)xic_draw_callback; +- donecallback.client_data = (XPointer) this; +- donecallback.callback = (XIMProc) xic_done_callback; +- +- preedit_attr = XVaCreateNestedList(0, +- XNPreeditStartCallback, &startcallback, +- XNPreeditDrawCallback, &drawcallback, +- XNPreeditDoneCallback, &donecallback, +- (char *) 0); +- } +- +- if (preedit_attr) { +- ic = XCreateIC(qt_xim, +- XNInputStyle, qt_xim_style, +- XNClientWindow, widget->winId(), +- XNPreeditAttributes, preedit_attr, +- (char *) 0); +- XFree(preedit_attr); +- } else +- ic = XCreateIC(qt_xim, +- XNInputStyle, qt_xim_style, +- XNClientWindow, widget->winId(), +- (char *) 0); +- +- if (! ic) +- qFatal("Failed to create XIM input context!"); +- +- // when resetting the input context, preserve the input state +- (void) XSetICValues((XIC) ic, XNResetState, XIMPreserveState, (char *) 0); +-#endif // !QT_NO_XIM +-} +- +- +-QInputContext::~QInputContext() +-{ +- +-#if !defined(QT_NO_XIM) +- if (ic) +- XDestroyIC((XIC) ic); +- +- if ( --fontsetRefCount == 0 ) { +- Display *dpy = QPaintDevice::x11AppDisplay(); +- for ( int i = 0; i < 8; i++ ) { +- if ( fontsetCache[i] && fontsetCache[i] != (XFontSet)-1 ) { +- XFreeFontSet(dpy, fontsetCache[i]); +- fontsetCache[i] = 0; +- } +- } +- } +- +-#endif // !QT_NO_XIM +- +- ic = 0; +- focusWidget = 0; +- composing = FALSE; +-} +- +- +-void QInputContext::reset() +-{ +-#if !defined(QT_NO_XIM) +- if (focusWidget && composing && ! text.isNull()) { +-#ifdef QT_XIM_DEBUG +- qDebug("QInputContext::reset: composing - sending IMEnd (empty) to %p", +- focusWidget); +-#endif // QT_XIM_DEBUG +- +- QIMEvent endevent(QEvent::IMEnd, QString::null, -1); +- QApplication::sendEvent(focusWidget, &endevent); +- focusWidget = 0; +- text = QString::null; +- if ( selectedChars.size() < 128 ) +- selectedChars.resize( 128 ); +- selectedChars.fill( 0 ); +- +- char *mb = XmbResetIC((XIC) ic); +- if (mb) +- XFree(mb); +- } +-#endif // !QT_NO_XIM +-} +- +- +-void QInputContext::setComposePosition(int x, int y) +-{ +-#if !defined(QT_NO_XIM) +- if (qt_xim && ic) { +- XPoint point; +- point.x = x; +- point.y = y; +- +- XVaNestedList preedit_attr = +- XVaCreateNestedList(0, +- XNSpotLocation, &point, +- +- (char *) 0); +- XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); +- XFree(preedit_attr); +- } +-#endif // !QT_NO_XIM +-} +- +- +-void QInputContext::setComposeArea(int x, int y, int w, int h) ++bool QInputContext::x11FilterEvent( QWidget *keywidget, XEvent *event ) + { +-#if !defined(QT_NO_XIM) +- if (qt_xim && ic) { +- XRectangle rect; +- rect.x = x; +- rect.y = y; +- rect.width = w; +- rect.height = h; +- +- XVaNestedList preedit_attr = XVaCreateNestedList(0, +- XNArea, &rect, +- +- (char *) 0); +- XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); +- XFree(preedit_attr); +- } +-#endif ++ return FALSE; + } + +- +-int QInputContext::lookupString(XKeyEvent *event, QCString &chars, +- KeySym *key, Status *status) const +-{ +- int count = 0; +- +-#if !defined(QT_NO_XIM) +- if (qt_xim && ic) { +- count = XmbLookupString((XIC) ic, event, chars.data(), +- chars.size(), key, status); +- +- if ((*status) == XBufferOverflow ) { +- chars.resize(count + 1); +- count = XmbLookupString((XIC) ic, event, chars.data(), +- chars.size(), key, status); +- } +- } +- +-#endif // QT_NO_XIM +- +- return count; +-} +- +-void QInputContext::setFocus() +-{ +-#if !defined(QT_NO_XIM) +- if (qt_xim && ic) +- XSetICFocus((XIC) ic); +-#endif // !QT_NO_XIM +-} +- +-void QInputContext::setXFontSet(const QFont &f) +-{ +-#if !defined(QT_NO_XIM) +- if (font == f) return; // nothing to do +- font = f; +- +- XFontSet fs = getFontSet(font); +- if (fontset == fs) return; // nothing to do +- fontset = fs; +- +- XVaNestedList preedit_attr = XVaCreateNestedList(0, XNFontSet, fontset, (char *) 0); +- XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0); +- XFree(preedit_attr); +-#else +- Q_UNUSED( f ); +-#endif +-} ++#endif //Q_NO_IM +diff -urN qt-x11-free-3.3.2/src/kernel/qnamespace.h qt-x11-immodule-bc/src/kernel/qnamespace.h +--- qt-x11-free-3.3.2/src/kernel/qnamespace.h 2004-04-19 18:36:09.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qnamespace.h 2004-06-23 01:10:27.073121400 +0900 +@@ -397,6 +397,61 @@ + Key_Help = 0x1058, + Key_Direction_L = 0x1059, + Key_Direction_R = 0x1060, ++ ++ // International input method support (X keycode - 0xEE00) ++ // Only interesting if you are writing your own input method ++ ++ // International & multi-key character composition ++ Key_Multi_key = 0x1120, // Multi-key character compose ++ Key_Codeinput = 0x1137, ++ Key_SingleCandidate = 0x113c, ++ Key_MultipleCandidate = 0x113d, ++ Key_PreviousCandidate = 0x113e, ++ ++ // Misc Functions ++ Key_Mode_switch = 0x117e, // Character set switch ++ //Key_script_switch = 0x117e, // Alias for mode_switch ++ ++ // Japanese keyboard support ++ Key_Kanji = 0x1121, // Kanji, Kanji convert ++ Key_Muhenkan = 0x1122, // Cancel Conversion ++ //Key_Henkan_Mode = 0x1123, // Start/Stop Conversion ++ Key_Henkan = 0x1123, // Alias for Henkan_Mode ++ Key_Romaji = 0x1124, // to Romaji ++ Key_Hiragana = 0x1125, // to Hiragana ++ Key_Katakana = 0x1126, // to Katakana ++ Key_Hiragana_Katakana = 0x1127, // Hiragana/Katakana toggle ++ Key_Zenkaku = 0x1128, // to Zenkaku ++ Key_Hankaku = 0x1129, // to Hankaku ++ Key_Zenkaku_Hankaku = 0x112a, // Zenkaku/Hankaku toggle ++ Key_Touroku = 0x112b, // Add to Dictionary ++ Key_Massyo = 0x112c, // Delete from Dictionary ++ Key_Kana_Lock = 0x112d, // Kana Lock ++ Key_Kana_Shift = 0x112e, // Kana Shift ++ Key_Eisu_Shift = 0x112f, // Alphanumeric Shift ++ Key_Eisu_toggle = 0x1130, // Alphanumeric toggle ++ //Key_Kanji_Bangou = 0x1137, // Codeinput ++ //Key_Zen_Koho = 0x113d, // Multiple/All Candidate(s) ++ //Key_Mae_Koho = 0x113e, // Previous Candidate ++ ++ // Korean support ++ Key_Hangul = 0x1131, // Hangul start/stop(toggle) ++ Key_Hangul_Start = 0x1132, // Hangul start ++ Key_Hangul_End = 0x1133, // Hangul end, English start ++ Key_Hangul_Hanja = 0x1134, // Start Hangul->Hanja Conversion ++ Key_Hangul_Jamo = 0x1135, // Hangul Jamo mode ++ Key_Hangul_Romaja = 0x1136, // Hangul Romaja mode ++ Key_Hangul_Codeinput = 0x1137, // Hangul code input mode ++ Key_Hangul_Jeonja = 0x1138, // Jeonja mode ++ Key_Hangul_Banja = 0x1139, // Banja mode ++ Key_Hangul_PreHanja = 0x113a, // Pre Hanja conversion ++ Key_Hangul_PostHanja = 0x113b, // Post Hanja conversion ++ Key_Hangul_SingleCandidate = 0x113c, // Single candidate ++ Key_Hangul_MultipleCandidate = 0x113d, // Multiple candidate ++ Key_Hangul_PreviousCandidate = 0x113e, // Previous candidate ++ Key_Hangul_Special = 0x113f, // Special symbols ++ //Key_Hangul_switch = 0x117e, // Alias for mode_switch ++ + Key_Space = 0x20, // 7 bit printable ASCII + Key_Any = Key_Space, + Key_Exclam = 0x21, +diff -urN qt-x11-free-3.3.2/src/kernel/qrichtext.cpp qt-x11-immodule-bc/src/kernel/qrichtext.cpp +--- qt-x11-free-3.3.2/src/kernel/qrichtext.cpp 2004-04-19 18:36:05.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qrichtext.cpp 2004-06-23 01:10:27.077120792 +0900 +@@ -657,7 +657,7 @@ + pop(); + } + +-bool QTextCursor::place( const QPoint &p, QTextParagraph *s, bool link ) ++bool QTextCursor::place( const QPoint &p, QTextParagraph *s, bool link, bool loosePlacing, bool matchBetweenCharacters ) + { + QPoint pos( p ); + QRect r; +@@ -675,7 +675,7 @@ + str = s; + if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() ) + break; +- if ( !s->next() ) { ++ if ( loosePlacing == TRUE && !s->next() ) { + #ifdef Q_WS_MACX + pos.setX( s->rect().x() + s->rect().width() ); + #endif +@@ -716,7 +716,7 @@ + if ( pos.x() < x ) + pos.setX( x + 1 ); + int cw; +- int curpos = s->length()-1; ++ int curpos = -1; + int dist = 10000000; + bool inCustom = FALSE; + while ( i < nextLine ) { +@@ -738,14 +738,21 @@ + cpos += cw; + int d = cpos - pos.x(); + bool dm = d < 0 ? !chr->rightToLeft : chr->rightToLeft; +- if ( (QABS( d ) < dist || (dist == d && dm == TRUE )) && para->string()->validCursorPosition( i ) ) { ++ if ( ( matchBetweenCharacters == TRUE && (QABS( d ) < dist || (dist == d && dm == TRUE )) && para->string()->validCursorPosition( i ) ) || ++ ( matchBetweenCharacters == FALSE && ( d == 0 || dm == TRUE ) ) ) { + dist = QABS( d ); +- if ( !link || pos.x() >= x + chr->x ) ++ if ( !link || ( pos.x() >= x + chr->x && ( loosePlacing == TRUE || pos.x() < cpos ) ) ) + curpos = i; + } + } + i++; + } ++ if ( curpos == -1 ) { ++ if ( loosePlacing == TRUE ) ++ curpos = s->length()-1; ++ else ++ return FALSE; ++ } + setIndex( curpos ); + + #ifndef QT_NO_TEXTCUSTOMITEM +@@ -4828,6 +4835,9 @@ + tmpw = fullSelectionWidth - xleft; + painter.fillRect( xleft, y, tmpw, h, color ); + painter.drawText( xstart, y + baseLine, str, start, len, dir ); ++ // draw preedit's underline ++ if (selection == QTextDocument::IMCompositionText) ++ painter.drawLine(xstart, y + baseLine + 1, xstart + w, y + baseLine + 1); + if (selStart != start || selEnd != start + len || selWrap) + painter.restore(); + } +diff -urN qt-x11-free-3.3.2/src/kernel/qrichtext_p.h qt-x11-immodule-bc/src/kernel/qrichtext_p.h +--- qt-x11-free-3.3.2/src/kernel/qrichtext_p.h 2004-04-19 18:36:05.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qrichtext_p.h 2004-06-23 01:10:27.078120640 +0900 +@@ -358,7 +358,8 @@ + int totalOffsetY() const; // total document offset + + bool place( const QPoint &pos, QTextParagraph *s ) { return place( pos, s, FALSE ); } +- bool place( const QPoint &pos, QTextParagraph *s, bool link ); ++ bool place( const QPoint &pos, QTextParagraph *s, bool link ) { return place( pos, s, link, TRUE, TRUE ); } ++ bool place( const QPoint &pos, QTextParagraph *s, bool link, bool loosePlacing, bool matchBetweenCharacters ); + void restoreState(); + + +diff -urN qt-x11-free-3.3.2/src/kernel/qt_kernel.pri qt-x11-immodule-bc/src/kernel/qt_kernel.pri +--- qt-x11-free-3.3.2/src/kernel/qt_kernel.pri 2003-12-08 23:44:24.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qt_kernel.pri 2004-06-23 01:10:27.079120488 +0900 +@@ -34,7 +34,6 @@ + $$KERNEL_H/qimage.h \ + $$KERNEL_P/qimageformatinterface_p.h \ + $$KERNEL_H/qimageformatplugin.h \ +- $$KERNEL_P/qinputcontext_p.h \ + $$KERNEL_H/qkeycode.h \ + $$KERNEL_H/qkeysequence.h \ + $$KERNEL_H/qlayout.h \ +@@ -99,6 +98,12 @@ + $$KERNEL_CPP/qfontengine_p.h \ + $$KERNEL_CPP/qtextlayout_p.h + ++ unix:x11 { ++ HEADERS += $$KERNEL_H/qinputcontext.h ++ } else { ++ HEADERS += $$KERNEL_P/qinputcontext_p.h ++ } ++ + win32:SOURCES += $$KERNEL_CPP/qapplication_win.cpp \ + $$KERNEL_CPP/qclipboard_win.cpp \ + $$KERNEL_CPP/qcolor_win.cpp \ +@@ -130,6 +135,7 @@ + $$KERNEL_CPP/qdesktopwidget_x11.cpp \ + $$KERNEL_CPP/qeventloop_x11.cpp \ + $$KERNEL_CPP/qfont_x11.cpp \ ++ $$KERNEL_CPP/qinputcontext.cpp \ + $$KERNEL_CPP/qinputcontext_x11.cpp \ + $$KERNEL_CPP/qmotifdnd_x11.cpp \ + $$KERNEL_CPP/qpixmap_x11.cpp \ +diff -urN qt-x11-free-3.3.2/src/kernel/qwidget.cpp qt-x11-immodule-bc/src/kernel/qwidget.cpp +--- qt-x11-free-3.3.2/src/kernel/qwidget.cpp 2004-04-19 18:36:08.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qwidget.cpp 2004-06-23 01:10:27.081120184 +0900 +@@ -3282,8 +3282,24 @@ + if ( isActiveWindow() ) { + QWidget * prev = qApp->focus_widget; + if ( prev ) { +- if ( prev != this ) ++ // This part is never executed when Q_WS_X11? Preceding XFocusOut ++ // had already reset focus_widget when received XFocusIn ++ ++ // Don't reset input context explicitly here. Whether reset or not ++ // when focusing out is a responsibility of input methods. For ++ // example, Japanese input context should not be reset here. The ++ // context sometimes contains a whole paragraph and has minutes of ++ // lifetime different to ephemeral one in other languages. The ++ // input context should be survived until focused again. So we ++ // delegate the responsibility to input context via ++ // unfocusInputContext(). ++ if ( prev != this ) { ++#if 0 + prev->resetInputContext(); ++#else ++ prev->unfocusInputContext(); ++#endif ++ } + } + #if defined(Q_WS_WIN) + else { +@@ -3291,9 +3307,7 @@ + } + #endif + qApp->focus_widget = this; +-#if defined(Q_WS_X11) + focusInputContext(); +-#endif + + #if defined(Q_WS_WIN) + if ( !topLevelWidget()->isPopup() ) +@@ -3341,6 +3355,7 @@ + focusProxy()->clearFocus(); + return; + } else if ( hasFocus() ) { ++ unfocusInputContext(); + QWidget* w = qApp->focusWidget(); + // clear active focus + qApp->focus_widget = 0; +@@ -4661,7 +4676,13 @@ + break; + + case QEvent::MouseButtonPress: ++ // Don't reset input context here. Whether reset or not is ++ // a responsibility of input method. reset() will be ++ // called by mouseHandler() of input method if necessary ++ // via mousePressEvent() of text widgets. ++#if 0 + resetInputContext(); ++#endif + mousePressEvent( (QMouseEvent*)e ); + if ( ! ((QMouseEvent*)e)->isAccepted() ) + return FALSE; +diff -urN qt-x11-free-3.3.2/src/kernel/qwidget.h qt-x11-immodule-bc/src/kernel/qwidget.h +--- qt-x11-free-3.3.2/src/kernel/qwidget.h 2004-04-19 18:36:06.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qwidget.h 2004-06-23 01:10:27.082120032 +0900 +@@ -536,6 +536,9 @@ + int metric( int ) const; + + void resetInputContext(); ++ void sendMouseEventToInputContext( int x, QEvent::Type type, ++ Qt::ButtonState button, ++ Qt::ButtonState state ); + + virtual void create( WId = 0, bool initializeWindow = TRUE, + bool destroyOldWindow = TRUE ); +@@ -573,6 +576,7 @@ + void createInputContext(); + void destroyInputContext(); + void focusInputContext(); ++ void unfocusInputContext(); + void checkChildrenDnd(); + #elif defined(Q_WS_MAC) + uint own_id : 1, macDropEnabled : 1; +diff -urN qt-x11-free-3.3.2/src/kernel/qwidget_x11.cpp qt-x11-immodule-bc/src/kernel/qwidget_x11.cpp +--- qt-x11-free-3.3.2/src/kernel/qwidget_x11.cpp 2004-04-19 18:36:07.000000000 +0900 ++++ qt-x11-immodule-bc/src/kernel/qwidget_x11.cpp 2004-06-23 01:10:27.084119728 +0900 +@@ -61,11 +61,11 @@ + bool qt_wstate_iconified( WId ); + void qt_updated_rootinfo(); + +-#ifndef QT_NO_XIM +-#include "qinputcontext_p.h" ++#ifndef QT_NO_IM ++#include "qinputcontext.h" ++#include "qinputcontextfactory.h" + +-extern XIM qt_xim; +-extern XIMStyle qt_xim_style; ++extern QString defaultIM; + #endif + + // Paint event clipping magic +@@ -940,22 +940,18 @@ + void QWidget::setMicroFocusHint(int x, int y, int width, int height, + bool text, QFont *f ) + { +-#ifndef QT_NO_XIM ++#ifndef QT_NO_IM + if ( text ) { + QWidget* tlw = topLevelWidget(); + QTLWExtra *topdata = tlw->topData(); + + // trigger input context creation if it hasn't happened already + createInputContext(); +- QInputContext *qic = (QInputContext *) topdata->xic; + +- if ( qt_xim && qic ) { +- QPoint p( x, y ); +- QPoint p2 = mapTo( topLevelWidget(), QPoint( 0, 0 ) ); +- p = mapTo( topLevelWidget(), p); +- qic->setXFontSet( f ? *f : fnt ); +- qic->setComposePosition(p.x(), p.y() + height); +- qic->setComposeArea(p2.x(), p2.y(), this->width(), this->height()); ++ QInputContext *qic = (QInputContext *) topdata->xic; ++ if(qic) { ++ QPoint gp = mapToGlobal( QPoint( x, y ) ); ++ qic->setMicroFocus(gp.x(), gp.y(), width, height, f); + } + } + #endif +@@ -1424,16 +1420,8 @@ + QWidget *tlw = topLevelWidget(); + if ( tlw->isVisible() && !tlw->topData()->embedded && !qt_deferred_map_contains(tlw) ) { + XSetInputFocus( x11Display(), tlw->winId(), RevertToNone, qt_x_time); +- +-#ifndef QT_NO_XIM +- // trigger input context creation if it hasn't happened already +- createInputContext(); +- +- if (tlw->topData()->xic) { +- QInputContext *qic = (QInputContext *) tlw->topData()->xic; +- qic->setFocus(); +- } +-#endif ++ // tlw->focusInputContext(); ++ focusInputContext(); + } + } + +@@ -2625,62 +2613,81 @@ + } + + ++/*! ++ \internal ++ This is an internal function, you should never call this. ++ ++ This function is called when generating InputContext ++ according to a configuration of default InputMethod. ++ (e.g. when setMicroFocusHint() and so on is executed.) ++ ++ InputContext is generated only when isInputMethodEnabled() ++ return TRUE. ++*/ + void QWidget::createInputContext() + { ++ if( !isInputMethodEnabled() ) ++ return; ++ + QWidget *tlw = topLevelWidget(); + QTLWExtra *topdata = tlw->topData(); + +-#ifndef QT_NO_XIM +- if (qt_xim) { +- if (! topdata->xic) { +- QInputContext *qic = new QInputContext(tlw); +- topdata->xic = (void *) qic; +- } +- } else +-#endif // QT_NO_XIM +- { +- // qDebug("QWidget::createInputContext: no xim"); +- topdata->xic = 0; +- } ++#ifndef QT_NO_IM ++ if (! topdata->xic) { ++ // InputContext corresponding to the name of default ++ // InputMethod of the Application in present is generated. ++ QInputContext *qic = QInputContextFactory::create(defaultIM, tlw); ++ ++ topdata->xic = (void *) qic; ++ } ++#endif // QT_NO_IM + } + + + void QWidget::destroyInputContext() + { +-#ifndef QT_NO_XIM ++#ifndef QT_NO_IM + QInputContext *qic = (QInputContext *) extra->topextra->xic; +- delete qic; +-#endif // QT_NO_XIM ++ if(qic) ++ delete qic; ++ ++#endif // QT_NO_IM + extra->topextra->xic = 0; + } + + + /*! +- This function is called when the user finishes input composition, +- e.g. changes focus to another widget, moves the cursor, etc. ++ This function is called when text widgets need to be neutral state to ++ execute text operations properly. See qlineedit.cpp and qtextedit.cpp as ++ example. Ordinary reset such as along with changes focus to another ++ widget, moves the cursor, etc, is implicitly handled via ++ unfocusInputContext() because whether reset or not when such situation is ++ a responsibility of input methods. For example, Japanese input context ++ should not be reset when focus out. The context sometimes contains a whole ++ paragraph and has minutes of lifetime different to ephemeral one in other ++ languages. The input context should be survived until focused again. So we ++ delegate the responsibility to the input context via unfocusInputContext(). + */ + void QWidget::resetInputContext() + { +-#ifndef QT_NO_XIM +- if (qt_xim_style & XIMPreeditCallbacks) { +- QWidget *tlw = topLevelWidget(); +- QTLWExtra *topdata = tlw->topData(); ++#ifndef QT_NO_IM ++ QWidget *tlw = topLevelWidget(); ++ QTLWExtra *topdata = tlw->topData(); + +- // trigger input context creation if it hasn't happened already +- createInputContext(); ++ // trigger input context creation if it hasn't happened already ++ createInputContext(); + +- if (topdata->xic) { +- QInputContext *qic = (QInputContext *) topdata->xic; +- qic->reset(); +- } ++ if (topdata->xic) { ++ QInputContext *qic = (QInputContext *) topdata->xic; ++ qic->reset(); + } +-#endif // QT_NO_XIM ++#endif // QT_NO_IM + } + + + void QWidget::focusInputContext() + { +-#ifndef QT_NO_XIM ++#ifndef QT_NO_IM + QWidget *tlw = topLevelWidget(); + QTLWExtra *topdata = tlw->topData(); + +@@ -2689,11 +2696,56 @@ + + if (topdata->xic) { + QInputContext *qic = (QInputContext *) topdata->xic; ++ ++ if( qic->focusWidget() != this) ++ qic->setFocusWidget( this ); + qic->setFocus(); + } +-#endif // QT_NO_XIM ++#endif // QT_NO_IM + } + ++ ++void QWidget::unfocusInputContext() ++{ ++#ifndef QT_NO_IM ++ QWidget *tlw = topLevelWidget(); ++ QTLWExtra *topdata = tlw->topData(); ++ ++ // trigger input context creation if it hasn't happened already ++ createInputContext(); ++ ++ if (topdata->xic) { ++ QInputContext *qic = (QInputContext *) topdata->xic; ++ ++ // may be caused reset() in some input methods ++ qic->unsetFocus(); ++ qic->setFocusWidget( 0 ); ++ } ++#endif // QT_NO_IM ++} ++ ++ ++void QWidget::sendMouseEventToInputContext( int x, QEvent::Type type, ++ Qt::ButtonState button, ++ Qt::ButtonState state ) ++{ ++#ifndef QT_NO_IM ++ QWidget *tlw = topLevelWidget(); ++ QTLWExtra *topdata = tlw->topData(); ++ ++ // trigger input context creation if it hasn't happened already ++ createInputContext(); ++ ++ if (topdata->xic) { ++ QInputContext *qic = (QInputContext *) topdata->xic; ++ ++ // may be causing reset() in some input methods ++ qic->mouseHandler( x, type, button, state ); ++ } ++#endif // QT_NO_IM ++} ++ ++ + void QWidget::setWindowOpacity(double) + { + } +diff -urN qt-x11-free-3.3.2/src/qt.pro qt-x11-immodule-bc/src/qt.pro +--- qt-x11-free-3.3.2/src/qt.pro 2004-03-01 19:20:58.000000000 +0900 ++++ qt-x11-immodule-bc/src/qt.pro 2004-06-23 01:10:27.085119576 +0900 +@@ -37,6 +37,7 @@ + TOOLS_CPP = tools + CODECS_CPP = codecs + WORKSPACE_CPP = workspace ++INPUT_CPP = input + XML_CPP = xml + STYLES_CPP = styles + EMBEDDED_CPP = embedded +@@ -54,6 +55,7 @@ + TOOLS_H = $$TOOLS_CPP + CODECS_H = $$CODECS_CPP + WORKSPACE_H = $$WORKSPACE_CPP ++ #INPUT_H = $$INPUT_CPP + XML_H = $$XML_CPP + CANVAS_H = $$CANVAS_CPP + STYLES_H = $$STYLES_CPP +@@ -70,6 +72,7 @@ + TOOLS_H = $$WIN_ALL_H + CODECS_H = $$WIN_ALL_H + WORKSPACE_H = $$WIN_ALL_H ++ #INPUT_H = $$WIN_ALL_H + XML_H = $$WIN_ALL_H + CANVAS_H = $$WIN_ALL_H + STYLES_H = $$WIN_ALL_H +@@ -98,6 +101,7 @@ + TOOLS_H = $$TOOLS_CPP + CODECS_H = $$CODECS_CPP + WORKSPACE_H = $$WORKSPACE_CPP ++ INPUT_H = $$INPUT_CPP + XML_H = $$XML_CPP + STYLES_H = $$STYLES_CPP + !embedded:!mac:CONFIG += x11 x11inc +@@ -112,7 +116,7 @@ + EMBEDDED_H = $$EMBEDDED_CPP + } + +-DEPENDPATH += ;$$NETWORK_H;$$KERNEL_H;$$WIDGETS_H;$$SQL_H;$$TABLE_H;$$DIALOGS_H; ++DEPENDPATH += ;$$NETWORK_H;$$KERNEL_H;$$WIDGETS_H;$$INPUT_H;$$SQL_H;$$TABLE_H;$$DIALOGS_H; + DEPENDPATH += $$ICONVIEW_H;$$OPENGL_H;$$TOOLS_H;$$CODECS_H;$$WORKSPACE_H;$$XML_H; + DEPENDPATH += $$CANVAS_H;$$STYLES_H + embedded:DEPENDPATH += ;$$EMBEDDED_H +@@ -147,6 +151,7 @@ + include($$DIALOGS_CPP/qt_dialogs.pri) + include($$ICONVIEW_CPP/qt_iconview.pri) + include($$WORKSPACE_CPP/qt_workspace.pri) ++include($$INPUT_CPP/qt_input.pri) + include($$NETWORK_CPP/qt_network.pri) + include($$CANVAS_CPP/qt_canvas.pri) + include($$TABLE_CPP/qt_table.pri) +diff -urN qt-x11-free-3.3.2/src/widgets/qlineedit.cpp qt-x11-immodule-bc/src/widgets/qlineedit.cpp +--- qt-x11-free-3.3.2/src/widgets/qlineedit.cpp 2004-04-19 18:36:19.000000000 +0900 ++++ qt-x11-immodule-bc/src/widgets/qlineedit.cpp 2004-06-23 01:10:27.087119272 +0900 +@@ -245,12 +245,17 @@ + + // input methods + int imstart, imend, imselstart, imselend; ++ bool composeMode() const { return preeditLength(); } ++ bool hasIMSelection() const { return imSelectionLength(); } ++ int preeditLength() const { return ( imend - imstart ); } ++ int imSelectionLength() const { return ( imselend - imselstart ); } + + // complex text layout + QTextLayout textLayout; + void updateTextLayout(); + void moveCursor( int pos, bool mark = FALSE ); + void setText( const QString& txt ); ++ int xToPosInternal( int x, QTextItem::CursorPosition ) const; + int xToPos( int x, QTextItem::CursorPosition = QTextItem::BetweenCharacters ) const; + inline int visualAlignment() const { return alignment ? alignment : int( isRightToLeft() ? AlignRight : AlignLeft ); } + QRect cursorRect() const; +@@ -1411,6 +1416,8 @@ + */ + void QLineEdit::mousePressEvent( QMouseEvent* e ) + { ++ if ( sendMouseEventToInputContext( e ) ) ++ return; + if ( e->button() == RightButton ) + return; + if ( d->tripleClickTimer && ( e->pos() - d->tripleClick ).manhattanLength() < +@@ -1440,7 +1447,8 @@ + */ + void QLineEdit::mouseMoveEvent( QMouseEvent * e ) + { +- ++ if ( sendMouseEventToInputContext( e ) ) ++ return; + #ifndef QT_NO_CURSOR + if ( ( e->state() & MouseButtonMask ) == 0 ) { + if ( !d->readOnly && d->dragEnabled +@@ -1469,6 +1477,8 @@ + */ + void QLineEdit::mouseReleaseEvent( QMouseEvent* e ) + { ++ if ( sendMouseEventToInputContext( e ) ) ++ return; + #ifndef QT_NO_DRAGANDDROP + if ( e->button() == LeftButton ) { + if ( d->dndTimer ) { +@@ -1495,6 +1505,8 @@ + */ + void QLineEdit::mouseDoubleClickEvent( QMouseEvent* e ) + { ++ if ( sendMouseEventToInputContext( e ) ) ++ return; + if ( e->button() == Qt::LeftButton ) { + deselect(); + d->cursor = d->xToPos( e->pos().x() ); +@@ -1763,6 +1775,33 @@ + e->ignore(); + } + ++ ++/*! ++ This function is not intended as polymorphic usage. Just a shared code ++ fragment that calls QWidget::sendMouseEventToInputContext() as easy for this ++ class. ++ */ ++bool QLineEdit::sendMouseEventToInputContext( QMouseEvent *e ) ++{ ++#ifndef QT_NO_IM ++ if ( d->composeMode() ) { ++ int cursor = d->xToPosInternal( e->pos().x(), QTextItem::OnCharacters ); ++ int mousePos = cursor - d->imstart; ++ if ( mousePos >= 0 && mousePos < d->preeditLength() ) { ++ QWidget::sendMouseEventToInputContext( mousePos, e->type(), ++ e->button(), e->state() ); ++ } else if ( e->type() != QEvent::MouseMove ) { ++ // send button events on out of preedit ++ QWidget::sendMouseEventToInputContext( -1, e->type(), ++ e->button(), e->state() ); ++ } ++ return TRUE; ++ } ++#endif ++ return FALSE; ++} ++ ++ + /*! \reimp + */ + void QLineEdit::imStartEvent( QIMEvent *e ) +@@ -1788,7 +1827,16 @@ + d->imend = d->imstart + e->text().length(); + d->imselstart = d->imstart + e->cursorPos(); + d->imselend = d->imselstart + e->selectionLength(); ++#if 0 + d->cursor = e->selectionLength() ? d->imend : d->imselend; ++#else ++ // Cursor placement code is changed for Asian input method that ++ // shows candidate window. This behavior is same as Qt/E 2.3.7 ++ // which supports Asian input methods. Asian input methods need ++ // start point of IM selection text to place candidate window as ++ // adjacent to the selection text. ++ d->cursor = d->imselstart; ++#endif + d->updateTextLayout(); + update(); + } +@@ -1822,6 +1870,8 @@ + } + if( !hasSelectedText() || style().styleHint( QStyle::SH_BlinkCursorWhenTextSelected ) ) + d->setCursorVisible( TRUE ); ++ if ( d->hasIMSelection() ) ++ d->cursor = d->imselstart; + d->updateMicroFocusHint(); + } + +@@ -1898,6 +1948,14 @@ + } else if ( widthUsed - d->hscroll < lineRect.width() ) { + d->hscroll = widthUsed - lineRect.width() + 1; + } ++ // This updateMicroFocusHint() is corresponding to update() at ++ // IMCompose event. Although the function is invoked from various ++ // other points, some situations such as "candidate selection on ++ // AlignHCenter'ed text" need this invocation because ++ // updateMicroFocusHint() requires updated contentsRect(), and ++ // there are no other chances in such situation that invoke the ++ // function. ++ d->updateMicroFocusHint(); + // the y offset is there to keep the baseline constant in case we have script changes in the text. + QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->ascent-fm.ascent()); + +@@ -1938,7 +1996,7 @@ + } + + // input method edit area +- if ( d->imstart < d->imend && (last >= d->imstart && first < d->imend ) ) { ++ if ( d->composeMode() && (last >= d->imstart && first < d->imend ) ) { + QRect highlight = QRect( QPoint( tix + ti.cursorToX( QMAX( d->imstart - first, 0 ) ), lineRect.top() ), + QPoint( tix + ti.cursorToX( QMIN( d->imend - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize(); + p->save(); +@@ -1951,11 +2009,16 @@ + imCol.setHsv( h1, s1, ( v1 + v2 ) / 2 ); + p->fillRect( highlight, imCol ); + p->drawTextItem( topLeft, ti, textflags ); ++ // draw preedit's underline ++ if (d->imend - d->imstart > 0) { ++ p->setPen( cg.text() ); ++ p->drawLine( highlight.bottomLeft(), highlight.bottomRight() ); ++ } + p->restore(); + } + + // input method selection +- if ( d->imselstart < d->imselend && (last >= d->imselstart && first < d->imselend ) ) { ++ if ( d->hasIMSelection() && (last >= d->imselstart && first < d->imselend ) ) { + QRect highlight = QRect( QPoint( tix + ti.cursorToX( QMAX( d->imselstart - first, 0 ) ), lineRect.top() ), + QPoint( tix + ti.cursorToX( QMIN( d->imselend - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize(); + p->save(); +@@ -1982,7 +2045,11 @@ + } + + // draw cursor +- if ( d->cursorVisible && !supressCursor ) { ++ // ++ // Asian users regard IM selection text as cursor on candidate ++ // selection phase of input method, so ordinary cursor should be ++ // invisible if IM selection text exists. ++ if ( d->cursorVisible && !supressCursor && !d->hasIMSelection() ) { + QPoint from( topLeft.x() + cix, lineRect.top() ); + QPoint to = from + QPoint( 0, lineRect.height() ); + p->drawLine( from, to ); +@@ -2090,6 +2157,10 @@ + void QLineEdit::contextMenuEvent( QContextMenuEvent * e ) + { + #ifndef QT_NO_POPUPMENU ++#ifndef QT_NO_IM ++ if ( d->composeMode() ) ++ return; ++#endif + d->separate(); + + QGuardedPtr<QPopupMenu> popup = createPopupMenu(); +@@ -2274,7 +2345,7 @@ + textLayout.endLine(0, 0, Qt::AlignLeft|Qt::SingleLine, &ascent); + } + +-int QLineEditPrivate::xToPos( int x, QTextItem::CursorPosition betweenOrOn ) const ++int QLineEditPrivate::xToPosInternal( int x, QTextItem::CursorPosition betweenOrOn ) const + { + x-= q->contentsRect().x() - hscroll + innerMargin; + for ( int i = 0; i < textLayout.numItems(); ++i ) { +@@ -2283,7 +2354,13 @@ + if ( x >= tir.left() && x <= tir.right() ) + return ti.xToCursor( x - tir.x(), betweenOrOn ) + ti.from(); + } +- return x < 0 ? 0 : text.length(); ++ return x < 0 ? -1 : text.length(); ++} ++ ++int QLineEditPrivate::xToPos( int x, QTextItem::CursorPosition betweenOrOn ) const ++{ ++ int pos = xToPosInternal( x, betweenOrOn ); ++ return ( pos < 0 ) ? 0 : pos; + } + + +diff -urN qt-x11-free-3.3.2/src/widgets/qlineedit.h qt-x11-immodule-bc/src/widgets/qlineedit.h +--- qt-x11-free-3.3.2/src/widgets/qlineedit.h 2004-04-19 18:36:18.000000000 +0900 ++++ qt-x11-immodule-bc/src/widgets/qlineedit.h 2004-06-23 01:10:27.087119272 +0900 +@@ -196,6 +196,7 @@ + void dropEvent( QDropEvent * ); + #endif + void contextMenuEvent( QContextMenuEvent * ); ++ bool sendMouseEventToInputContext( QMouseEvent *e ); + virtual QPopupMenu *createPopupMenu(); + void windowActivationChange( bool ); + #ifndef QT_NO_COMPAT +diff -urN qt-x11-free-3.3.2/src/widgets/qtextedit.cpp qt-x11-immodule-bc/src/widgets/qtextedit.cpp +--- qt-x11-free-3.3.2/src/widgets/qtextedit.cpp 2004-04-19 18:36:18.000000000 +0900 ++++ qt-x11-immodule-bc/src/widgets/qtextedit.cpp 2004-06-23 01:10:27.091118664 +0900 +@@ -107,6 +107,8 @@ + int id[ 7 ]; + int preeditStart; + int preeditLength; ++ bool composeMode() const { return ( preeditLength > 0 ); } ++ + uint ensureCursorVisibleInShowEvent : 1; + uint tabChangesFocus : 1; + QString scrollToAnchor; // used to deferr scrollToAnchor() until the show event when we are resized +@@ -1080,6 +1082,10 @@ + l += v; + } + } ++ ++ // This invocation is required to follow dragging of active window ++ // by the showed candidate window. ++ updateMicroFocusHint(); + } + + /*! +@@ -1554,6 +1560,35 @@ + } + + /*! ++ This function is not intended as polymorphic usage. Just a shared code ++ fragment that calls QWidget::sendMouseEventToInputContext() as easy for this ++ class. ++ */ ++bool QTextEdit::sendMouseEventToInputContext( QMouseEvent *e ) ++{ ++#ifndef QT_NO_IM ++ if ( d->composeMode() ) { ++ QTextCursor c( doc ); ++ if ( c.place( e->pos(), doc->firstParagraph(), FALSE, FALSE, FALSE ) ) { ++ int mousePos = c.index() - d->preeditStart; ++ if ( cursor->globalY() == c.globalY() && ++ mousePos >= 0 && mousePos < d->preeditLength ) { ++ QWidget::sendMouseEventToInputContext( mousePos, e->type(), ++ e->button(), e->state() ); ++ } ++ } else if ( e->type() != QEvent::MouseMove ) { ++ // send button events on out of preedit ++ QWidget::sendMouseEventToInputContext( -1, e->type(), ++ e->button(), e->state() ); ++ } ++ return TRUE; ++ } ++#endif ++ return FALSE; ++} ++ ++ ++/*! + \reimp + */ + void QTextEdit::imStartEvent( QIMEvent *e ) +@@ -1581,10 +1616,16 @@ + doc->removeSelection( QTextDocument::IMCompositionText ); + doc->removeSelection( QTextDocument::IMSelectionText ); + +- if ( d->preeditLength > 0 && cursor->paragraph() ) ++ if ( d->composeMode() && cursor->paragraph() ) + cursor->paragraph()->remove( d->preeditStart, d->preeditLength ); + cursor->setIndex( d->preeditStart ); +- insert( e->text() ); ++ ++ int sellen = e->selectionLength(); ++ uint insertionFlags = CheckNewLines | RemoveSelected | AsIMCompositionText; ++ if ( sellen > 0 ) { ++ insertionFlags |= WithIMSelection; ++ } ++ insert( e->text(), insertionFlags ); + d->preeditLength = e->text().length(); + + cursor->setIndex( d->preeditStart + d->preeditLength ); +@@ -1595,17 +1636,28 @@ + + cursor->setIndex( d->preeditStart + e->cursorPos() ); + +- int sellen = e->selectionLength(); + if ( sellen > 0 ) { + cursor->setIndex( d->preeditStart + e->cursorPos() + sellen ); + c = *cursor; + cursor->setIndex( d->preeditStart + e->cursorPos() ); + doc->setSelectionStart( QTextDocument::IMSelectionText, *cursor ); + doc->setSelectionEnd( QTextDocument::IMSelectionText, c ); ++#if 0 ++ // Disabled for Asian input method that shows candidate ++ // window. This behavior is same as Qt/E 2.3.7 which supports ++ // Asian input methods. Asian input methods need start point ++ // of IM selection text to place candidate window as adjacent ++ // to the selection text. + cursor->setIndex( d->preeditStart + d->preeditLength ); ++#endif + } + + repaintChanged(); ++ ++ // microFocusHint is required to place candidate window for Asian ++ // input methods. Cursor position and IM selection text are ++ // updated by the event. ++ updateMicroFocusHint(); + } + + /*! +@@ -1618,10 +1670,12 @@ + return; + } + ++ qWarning( "receiving IMEnd with %d chars", e->text().length() ); ++ + doc->removeSelection( QTextDocument::IMCompositionText ); + doc->removeSelection( QTextDocument::IMSelectionText ); + +- if ( d->preeditLength > 0 && cursor->paragraph() ) ++ if ( d->composeMode() && cursor->paragraph() ) + cursor->paragraph()->remove( d->preeditStart, d->preeditLength ); + if ( d->preeditStart >= 0 ) { + cursor->setIndex( d->preeditStart ); +@@ -2113,6 +2167,13 @@ + isReadOnly() ) + return; + ++ // Asian users regard selection text as cursor on candidate ++ // selection phase of input method, so ordinary cursor should be ++ // invisible if IM selection text exists. ++ if ( doc->hasSelection( QTextDocument::IMSelectionText ) ) { ++ visible = FALSE; ++ } ++ + QPainter p( viewport() ); + QRect r( cursor->topParagraph()->rect() ); + cursor->paragraph()->setChanged( TRUE ); +@@ -2187,6 +2248,9 @@ + } + #endif + ++ if ( sendMouseEventToInputContext( e ) ) ++ return; ++ + if ( d->trippleClickTimer->isActive() && + ( e->globalPos() - d->trippleClickPoint ).manhattanLength() < + QApplication::startDragDistance() ) { +@@ -2292,7 +2356,9 @@ + return; + } + #endif +- if ( mousePressed ) { ++ if ( sendMouseEventToInputContext( e ) ) { ++ // running through intended to avoid cursor vanishing ++ } else if ( mousePressed ) { + #ifndef QT_NO_DRAGANDDROP + if ( mightStartDrag ) { + dragStartTimer->stop(); +@@ -2345,7 +2411,7 @@ + + void QTextEdit::contentsMouseReleaseEvent( QMouseEvent * e ) + { +- if ( !inDoubleClick ) { // could be the release of a dblclick ++ if ( !inDoubleClick && !d->composeMode() ) { // could be the release of a dblclick + int para = 0; + int index = charAt( e->pos(), ¶ ); + emit clicked( para, index ); +@@ -2356,6 +2422,8 @@ + return; + } + #endif ++ if ( sendMouseEventToInputContext( e ) ) ++ return; + QTextCursor oldCursor = *cursor; + if ( scrollTimer->isActive() ) + scrollTimer->stop(); +@@ -2448,7 +2516,7 @@ + + void QTextEdit::contentsMouseDoubleClickEvent( QMouseEvent * e ) + { +- if ( e->button() != Qt::LeftButton ) { ++ if ( e->button() != Qt::LeftButton && !d->composeMode() ) { + e->ignore(); + return; + } +@@ -2479,6 +2547,9 @@ + } else + #endif + { ++ if ( sendMouseEventToInputContext( e ) ) ++ return; ++ + QTextCursor c1 = *cursor; + QTextCursor c2 = *cursor; + #if defined(Q_OS_MAC) +@@ -2653,10 +2724,15 @@ + */ + void QTextEdit::contentsContextMenuEvent( QContextMenuEvent *e ) + { ++ e->accept(); ++#ifndef QT_NO_IM ++ if ( d->composeMode() ) ++ return; ++#endif ++ + clearUndoRedo(); + mousePressed = FALSE; + +- e->accept(); + #ifndef QT_NO_POPUPMENU + QPopupMenu *popup = createPopupMenu( e->pos() ); + if ( !popup ) +@@ -2802,8 +2878,15 @@ + void QTextEdit::updateMicroFocusHint() + { + QTextCursor c( *cursor ); ++#if 0 ++ // Disabled for Asian input method that shows candidate ++ // window. This behavior is same as Qt/E 2.3.7 which supports ++ // Asian input methods. Asian input methods need start point of IM ++ // selection text to place candidate window as adjacent to the ++ // selection text. + if ( d->preeditStart != -1 ) + c.setIndex( d->preeditStart ); ++#endif + + if ( hasFocus() || viewport()->hasFocus() ) { + int h = c.paragraph()->lineHeightOfChar( cursor->index() ); +@@ -2968,6 +3051,8 @@ + bool indent = insertionFlags & RedoIndentation; + bool checkNewLine = insertionFlags & CheckNewLines; + bool removeSelected = insertionFlags & RemoveSelected; ++ bool imComposition = insertionFlags & AsIMCompositionText; ++ bool imSelection = insertionFlags & WithIMSelection; + QString txt( text ); + drawCursor( FALSE ); + if ( !isReadOnly() && doc->hasSelection( QTextDocument::Standard ) && removeSelected ) +@@ -3001,7 +3086,10 @@ + formatMore(); + repaintChanged(); + ensureCursorVisible(); +- drawCursor( TRUE ); ++ // Asian users regard selection text as cursor on candidate ++ // selection phase of input method, so ordinary cursor should be ++ // invisible if IM selection text exists. ++ drawCursor( !imSelection ); + + if ( undoEnabled && !isReadOnly() ) { + undoRedoInfo.d->text += txt; +@@ -3023,7 +3111,13 @@ + doc->setSelectionEnd( QTextDocument::Standard, *cursor ); + repaintChanged(); + } +- updateMicroFocusHint(); ++ // updateMicroFocusHint() should not be invoked here when this ++ // function is invoked from imComposeEvent() because cursor ++ // postion is incorrect yet. imComposeEvent() invokes ++ // updateMicroFocusHint() later. ++ if ( !imComposition ) { ++ updateMicroFocusHint(); ++ } + setModified(); + emit textChanged(); + } +diff -urN qt-x11-free-3.3.2/src/widgets/qtextedit.h qt-x11-immodule-bc/src/widgets/qtextedit.h +--- qt-x11-free-3.3.2/src/widgets/qtextedit.h 2004-04-19 18:36:18.000000000 +0900 ++++ qt-x11-immodule-bc/src/widgets/qtextedit.h 2004-06-23 01:10:27.092118512 +0900 +@@ -211,7 +211,9 @@ + enum TextInsertionFlags { + RedoIndentation = 0x0001, + CheckNewLines = 0x0002, +- RemoveSelected = 0x0004 ++ RemoveSelected = 0x0004, ++ AsIMCompositionText = 0x0008, // internal use ++ WithIMSelection = 0x0010 // internal use + }; + + QTextEdit( const QString& text, const QString& context = QString::null, +@@ -439,6 +441,7 @@ + void contentsDropEvent( QDropEvent *e ); + #endif + void contentsContextMenuEvent( QContextMenuEvent *e ); ++ bool sendMouseEventToInputContext( QMouseEvent *e ); + bool focusNextPrevChild( bool next ); + QTextDocument *document() const; + QTextCursor *textCursor() const; +diff -urN qt-x11-free-3.3.2/tools/qtconfig/mainwindow.cpp qt-x11-immodule-bc/tools/qtconfig/mainwindow.cpp +--- qt-x11-free-3.3.2/tools/qtconfig/mainwindow.cpp 2003-12-08 18:49:15.000000000 +0900 ++++ qt-x11-immodule-bc/tools/qtconfig/mainwindow.cpp 2004-06-23 01:10:27.093118360 +0900 +@@ -27,6 +27,7 @@ + #include <qapplication.h> + #include <qcombobox.h> + #include <qstylefactory.h> ++#include <qinputcontextfactory.h> + #include <qobjectlist.h> + #include <qfontdatabase.h> + #include <qlineedit.h> +@@ -362,9 +363,50 @@ + + #ifdef Q_WS_X11 + inputStyle->setCurrentText( settings.readEntry( "/qt/XIMInputStyle", trUtf8( "On The Spot" ) ) ); ++ ++ ++ /* ++ This code makes it possible to set up default InputMethod. ++ ++ The list of names of InputMethod which can be used is acquired ++ using QInputContextFactory::keys(). And it is set to inputMethodCombo ++ which displays the list of InputMethod. ++ */ ++ QStringList inputmethods = QInputContextFactory::keys(); ++ inputmethods.sort(); ++ inputMethodCombo->insertStringList(inputmethods); ++ ++ /* ++ InputMethod set up as a default in the past is chosen. ++ If nothing is set up, default InputMethod in the platform is chosen. ++ */ ++ QString currentIM = settings.readEntry("/qt/DefaultInputMethod"); ++ if (currentIM.isNull()) ++ currentIM = "XIM"; // default InputMethod is XIM in X11. ++ { ++ int s = 0; ++ QStringList::Iterator imIt = inputmethods.begin(); ++ while (imIt != inputmethods.end()) { ++ if (*imIt == currentIM) ++ break; ++ s++; ++ imIt++; ++ } ++ ++ // set up Selected InputMethod. ++ if (s < inputMethodCombo->count()) { ++ inputMethodCombo->setCurrentItem(s); ++ } else { ++ // we give up. But, probably this code is not executed. ++ inputMethodCombo->insertItem("Unknown"); ++ inputMethodCombo->setCurrentItem(inputMethodCombo->count() - 1); ++ } ++ } + #else + inputStyle->hide(); + inputStyleLabel->hide(); ++ inputMethodCombo->hide(); ++ inputMethodLabel->hide(); + #endif + + fontembeddingcheckbox->setChecked( settings.readBoolEntry("/qt/embedFonts", TRUE) ); +@@ -443,6 +485,8 @@ + else if ( style == trUtf8( "Root" ) ) + str = "Root"; + settings.writeEntry( "/qt/XIMInputStyle", inputStyle->currentText() ); ++ ++ settings.writeEntry("/qt/DefaultInputMethod", inputMethodCombo->currentText()); + #endif + + QStringList effects; +diff -urN qt-x11-free-3.3.2/tools/qtconfig/mainwindowbase.ui qt-x11-immodule-bc/tools/qtconfig/mainwindowbase.ui +--- qt-x11-free-3.3.2/tools/qtconfig/mainwindowbase.ui 2003-11-12 05:01:02.000000000 +0900 ++++ qt-x11-immodule-bc/tools/qtconfig/mainwindowbase.ui 2004-06-23 01:10:27.094118208 +0900 +@@ -1016,6 +1016,19 @@ + <number>0</number> + </property> + </widget> ++ <widget class="QLabel"> ++ <property name="name"> ++ <cstring>inputMethodLabel</cstring> ++ </property> ++ <property name="text"> ++ <string>Default Input Method:</string> ++ </property> ++ </widget> ++ <widget class="QComboBox"> ++ <property name="name"> ++ <cstring>inputMethodCombo</cstring> ++ </property> ++ </widget> + <spacer> + <property name="name"> + <cstring>spacer5</cstring> +@@ -1029,7 +1042,7 @@ + <property name="sizeHint"> + <size> + <width>20</width> +- <height>40</height> ++ <height>30</height> + </size> + </property> + </spacer> +@@ -1705,6 +1718,12 @@ + <slot>somethingModified()</slot> + </connection> + <connection> ++ <sender>inputMethodCombo</sender> ++ <signal>activated(int)</signal> ++ <receiver>MainWindowBase</receiver> ++ <slot>somethingModified()</slot> ++ </connection> ++ <connection> + <sender>gstylecombo</sender> + <signal>activated(const QString&)</signal> + <receiver>MainWindowBase</receiver> diff --git a/x11-libs/qt/qt-3.3.2.ebuild b/x11-libs/qt/qt-3.3.2.ebuild index a289ccd55805..35560a16c20d 100644 --- a/x11-libs/qt/qt-3.3.2.ebuild +++ b/x11-libs/qt/qt-3.3.2.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/x11-libs/qt/qt-3.3.2.ebuild,v 1.12 2004/07/27 03:03:39 tgall Exp $ +# $Header: /var/cvsroot/gentoo-x86/x11-libs/qt/qt-3.3.2.ebuild,v 1.13 2004/08/04 16:15:05 usata Exp $ inherit eutils @@ -13,7 +13,7 @@ SRC_URI="ftp://ftp.trolltech.com/qt/source/qt-x11-${SRCTYPE}-${PV}.tar.bz2" LICENSE="QPL-1.0 | GPL-2" SLOT="3" KEYWORDS="x86 alpha ppc amd64 sparc hppa ~mips ppc64" -IUSE="cups debug doc firebird gif icc ipv6 mysql nas odbc opengl postgres sqlite xinerama zlib" +IUSE="cups debug doc firebird gif icc ipv6 mysql nas odbc opengl postgres sqlite xinerama zlib cjk" DEPEND="virtual/x11 virtual/xft media-libs/libpng media-libs/jpeg media-libs/libmng @@ -49,6 +49,18 @@ src_unpack() { epatch ${FILESDIR}/qt-no-rpath-uic.patch + if use cjk ; then + epatch ${FILESDIR}/qt-x11-immodule-bc-qt3.3.2-20040623.diff + pushd include/ + ln -s ../src/kernel/qinputcontext.h . + ln -s ../src/input/qinputcontextfactory.h . + ln -s ../src/input/qinputcontextplugin.h . + cd private/ + ln -s ../../src/input/qinputcontextinterface_p.h . + ln -s ../../src/input/qximinputcontext_p.h . + popd + fi + # mips requires this patch to pass a CFLAG to gcc/g++ (which passes it to the assembler). # It tells the assembler to relax branches on mips, otherwise we get build errors. use mips && epatch ${FILESDIR}/${P}-mips-relax-branches.patch |