ibus IM support for the xcb backend

Test code to check input methods using the ibus backend
used on e.g. ubuntu. The IM code is not very sophisticated,
but enough to test that things are working.

Reviewed-by: Jørgen Lind
bb10
Lars Knoll 2011-06-22 10:01:14 +02:00
parent 0584424d5c
commit 80eb461360
18 changed files with 1141 additions and 3 deletions

View File

@ -0,0 +1,11 @@
QT += dbus
SOURCES += $$PWD/qibusplatforminputcontext.cpp \
$$PWD/qibusproxy.cpp \
$$PWD/qibusinputcontextproxy.cpp \
$$PWD/qibustypes.cpp
HEADERS += $$PWD/qibusplatforminputcontext.h \
$$PWD/qibusproxy.h \
$$PWD/qibusinputcontextproxy.h \
$$PWD/qibustypes.h

View File

@ -0,0 +1,80 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.IBus.InputContext">
<method name="ProcessKeyEvent">
<arg name="keyval" direction="in" type="u"/>
<arg name="keycode" direction="in" type="u"/>
<arg name="state" direction="in" type="u"/>
<arg name="handled" direction="out" type="b"/>
</method>
<method name="SetCursorLocation">
<arg name="x" direction="in" type="i"/>
<arg name="y" direction="in" type="i"/>
<arg name="w" direction="in" type="i"/>
<arg name="h" direction="in" type="i"/>
</method>
<method name="FocusIn"/>
<method name="FocusOut"/>
<method name="Reset"/>
<method name="Enable"/>
<method name="Disable"/>
<method name="IsEnabled">
<arg name="enable" direction="out" type="b"/>
</method>
<method name="SetCapabilities">
<arg name="caps" direction="in" type="u"/>
</method>
<method name="PropertyActivate">
<arg name="name" direction="in" type="s"/>
<arg name="state" direction="in" type="i"/>
</method>
<method name="SetEngine">
<arg name="name" direction="in" type="s"/>
</method>
<method name="GetEngine">
<arg name="desc" direction="out" type="v"/>
</method>
<method name="Destroy"/>
<signal name="CommitText">
<arg name="text" type="v"/>
</signal>
<signal name="Enabled"/>
<signal name="Disabled"/>
<signal name="ForwardKeyEvent">
<arg name="keyval" type="u"/>
<arg name="keycode" type="u"/>
<arg name="state" type="u"/>
</signal>
<signal name="UpdatePreeditText">
<arg name="text" type="v"/>
<arg name="cursor_pos" type="u"/>
<arg name="visible" type="b"/>
</signal>
<signal name="ShowPreeditText"/>
<signal name="HidePreeditText"/>
<signal name="UpdateAuxiliaryText">
<arg name="text" type="v"/>
<arg name="visible" type="b"/>
</signal>
<signal name="ShowAuxiliaryText"/>
<signal name="HideAuxiliaryText"/>
<signal name="UpdateLookupTable">
<arg name="table" type="v"/>
<arg name="visible" type="b"/>
</signal>
<signal name="ShowLookupTable"/>
<signal name="HideLookupTable"/>
<signal name="PageUpLookupTable"/>
<signal name="PageDownLookupTable"/>
<signal name="CursorUpLookupTable"/>
<signal name="CursorDownLookupTable"/>
<signal name="RegisterProperties">
<arg name="props" type="v"/>
</signal>
<signal name="UpdateProperty">
<arg name="prop" type="v"/>
</signal>
</interface>
</node>

View File

@ -0,0 +1,30 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.IBus">
<method name="GetAddress">
<arg name="address" direction="out" type="s"/>
</method>
<method name="CreateInputContext">
<arg name="name" direction="in" type="s"/>
<arg name="context" direction="out" type="o"/>
</method>
<method name="RegisterComponent">
<arg name="components" direction="in" type="v"/>
</method>
<method name="ListEngines">
<arg name="engines" direction="out" type="av"/>
</method>
<method name="ListActiveEngines">
<arg name="engines" direction="out" type="av"/>
</method>
<method name="Exit">
<arg name="restart" direction="in" type="b"/>
</method>
<method name="Ping">
<arg name="data" direction="in" type="v"/>
<arg name="data" direction="out" type="v"/>
</method>
</interface>
</node>

View File

@ -0,0 +1,26 @@
/*
* This file was generated by qdbusxml2cpp version 0.7
* Command line was: qdbusxml2cpp -N -p qibusinputcontextproxy -c QIBusInputContextProxy interfaces/org.freedesktop.IBus.InputContext.xml
*
* qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "qibusinputcontextproxy.h"
/*
* Implementation of interface class QIBusInputContextProxy
*/
QIBusInputContextProxy::QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
QIBusInputContextProxy::~QIBusInputContextProxy()
{
}

View File

@ -0,0 +1,144 @@
/*
* This file was generated by qdbusxml2cpp version 0.7
* Command line was: qdbusxml2cpp -N -p qibusinputcontextproxy -c QIBusInputContextProxy interfaces/org.freedesktop.IBus.InputContext.xml
*
* qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef QIBUSINPUTCONTEXTPROXY_H_1308831153
#define QIBUSINPUTCONTEXTPROXY_H_1308831153
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface org.freedesktop.IBus.InputContext
*/
class QIBusInputContextProxy: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.freedesktop.IBus.InputContext"; }
public:
QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~QIBusInputContextProxy();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> Destroy()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("Destroy"), argumentList);
}
inline QDBusPendingReply<> Disable()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("Disable"), argumentList);
}
inline QDBusPendingReply<> Enable()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("Enable"), argumentList);
}
inline QDBusPendingReply<> FocusIn()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("FocusIn"), argumentList);
}
inline QDBusPendingReply<> FocusOut()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("FocusOut"), argumentList);
}
inline QDBusPendingReply<QDBusVariant> GetEngine()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("GetEngine"), argumentList);
}
inline QDBusPendingReply<bool> IsEnabled()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("IsEnabled"), argumentList);
}
inline QDBusPendingReply<bool> ProcessKeyEvent(uint keyval, uint keycode, uint state)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(keyval) << QVariant::fromValue(keycode) << QVariant::fromValue(state);
return asyncCallWithArgumentList(QLatin1String("ProcessKeyEvent"), argumentList);
}
inline QDBusPendingReply<> PropertyActivate(const QString &name, int state)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(name) << QVariant::fromValue(state);
return asyncCallWithArgumentList(QLatin1String("PropertyActivate"), argumentList);
}
inline QDBusPendingReply<> Reset()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("Reset"), argumentList);
}
inline QDBusPendingReply<> SetCapabilities(uint caps)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(caps);
return asyncCallWithArgumentList(QLatin1String("SetCapabilities"), argumentList);
}
inline QDBusPendingReply<> SetCursorLocation(int x, int y, int w, int h)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y) << QVariant::fromValue(w) << QVariant::fromValue(h);
return asyncCallWithArgumentList(QLatin1String("SetCursorLocation"), argumentList);
}
inline QDBusPendingReply<> SetEngine(const QString &name)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(name);
return asyncCallWithArgumentList(QLatin1String("SetEngine"), argumentList);
}
Q_SIGNALS: // SIGNALS
void CommitText(const QDBusVariant &text);
void CursorDownLookupTable();
void CursorUpLookupTable();
void Disabled();
void Enabled();
void ForwardKeyEvent(uint keyval, uint keycode, uint state);
void HideAuxiliaryText();
void HideLookupTable();
void HidePreeditText();
void PageDownLookupTable();
void PageUpLookupTable();
void RegisterProperties(const QDBusVariant &props);
void ShowAuxiliaryText();
void ShowLookupTable();
void ShowPreeditText();
void UpdateAuxiliaryText(const QDBusVariant &text, bool visible);
void UpdateLookupTable(const QDBusVariant &table, bool visible);
void UpdatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible);
void UpdateProperty(const QDBusVariant &prop);
};
#endif

View File

@ -0,0 +1,301 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qibusplatforminputcontext.h"
#include <QtDebug>
#include <QTextCharFormat>
#include <QGuiApplication>
#include <qevent.h>
#include "qibusproxy.h"
#include "qibusinputcontextproxy.h"
#include "qibustypes.h"
#include <sys/types.h>
#include <signal.h>
#include <QtDBus>
class QIBusPlatformInputContextPrivate
{
public:
QIBusPlatformInputContextPrivate();
~QIBusPlatformInputContextPrivate()
{
delete context;
delete bus;
delete connection;
}
static QDBusConnection *createConnection();
QDBusConnection *connection;
QIBusProxy *bus;
QIBusInputContextProxy *context;
bool valid;
};
QIBusPlatformInputContext::QIBusPlatformInputContext ()
: d(new QIBusPlatformInputContextPrivate())
{
connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant)));
connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool)));
}
QIBusPlatformInputContext::~QIBusPlatformInputContext (void)
{
delete d;
}
void QIBusPlatformInputContext::mouseHandler (int x, QMouseEvent *event)
{
QPlatformInputContext::mouseHandler (x, event);
if (!d->valid)
return;
}
void QIBusPlatformInputContext::reset()
{
QPlatformInputContext::reset();
if (!d->valid)
return;
d->context->Reset();
}
void QIBusPlatformInputContext::update()
{
QPlatformInputContext::update();
if (!d->valid)
return;
QObject *o = focusObject();
if (!o)
return;
QInputMethodQueryEvent query(Qt::ImMicroFocus);
QGuiApplication::sendEvent(o, &query);
QRect r = query.value().toRect();
if(r.isValid()) {
qDebug() << "mocroFocus" << r;
d->context->SetCursorLocation(r.x(), r.y(), r.width(), r.height());
}
}
void QIBusPlatformInputContext::setFocusObject(QObject *object)
{
QPlatformInputContext::setFocusObject(object);
if (!d->valid)
return;
qDebug() << "setFocusObject" << object;
if (object)
d->context->FocusIn();
else
d->context->FocusOut();
}
void QIBusPlatformInputContext::commitText(const QDBusVariant &text)
{
const QDBusArgument arg = text.variant().value<QDBusArgument>();
QIBusText t;
qDebug() << arg.currentSignature();
t.fromDBusArgument(arg);
qDebug() << "commit text:" << t.text;
QInputMethodEvent event;
event.setCommitString(t.text);
QCoreApplication::sendEvent(focusObject(), &event);
}
void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint cursorPos, bool visible)
{
const QDBusArgument arg = text.variant().value<QDBusArgument>();
QIBusText t;
t.fromDBusArgument(arg);
qDebug() << "preedit text:" << t.text;
QList<QInputMethodEvent::Attribute> attributes = t.attributes.imAttributes();
attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, visible ? 1 : 0, QVariant());
QInputMethodEvent event(t.text, attributes);
QCoreApplication::sendEvent(focusObject(), &event);
}
/* Kernel keycode -> X keycode table */
static const unsigned int keycode_table[256] = {
0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 76, 79, 80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 111, 221, 94, 95, 96, 211, 128, 127, 129, 208, 131, 126,
108, 109, 112, 111, 113, 181, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107,
239, 160, 174, 176, 222, 157, 123, 110, 139, 134, 209, 210, 133, 115, 116, 117,
232, 133, 134, 135, 140, 248, 191, 192, 122, 188, 245, 158, 161, 193, 223, 227,
198, 199, 200, 147, 159, 151, 178, 201, 146, 203, 166, 236, 230, 235, 234, 233,
163, 204, 253, 153, 162, 144, 164, 177, 152, 190, 208, 129, 130, 231, 209, 210,
136, 220, 143, 246, 251, 137, 138, 182, 183, 184, 93, 184, 247, 132, 170, 219,
249, 205, 207, 149, 150, 154, 155, 167, 168, 169, 171, 172, 173, 165, 175, 179,
180, 0, 185, 186, 187, 118, 119, 120, 121, 229, 194, 195, 196, 197, 148, 202,
101, 212, 237, 214, 215, 216, 217, 218, 228, 142, 213, 240, 241, 242, 243, 244,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
bool
QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, bool press)
{
if (!d->valid)
return false;
if (!press)
return false;
keycode -= 8; // ###
QDBusReply<bool> reply = d->context->ProcessKeyEvent(keyval, keycode, state);
// qDebug() << "x11FilterEvent return" << reply.value();
return reply.value();
}
QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
: connection(createConnection()),
bus(0),
context(0),
valid(false)
{
if (!connection->isConnected()) {
qDebug() << "not connected";
return;
}
bus = new QIBusProxy(QLatin1String("org.freedesktop.IBus"),
QLatin1String("/org/freedesktop/IBus"),
*connection);
if (!bus->isValid()) {
qDebug() << "invalid bus";
return;
}
QDBusReply<QDBusObjectPath> ic = bus->CreateInputContext(QLatin1String("QIBusInputContext"));
if (!ic.isValid()) {
qDebug() << "CreateInputContext failed";
return;
}
context = new QIBusInputContextProxy(QLatin1String("org.freedesktop.IBus"), ic.value().path(), *connection);
if (!context->isValid()) {
qDebug() << "invalid input context";
return;
}
enum Capabilities {
IBUS_CAP_PREEDIT_TEXT = 1 << 0,
IBUS_CAP_AUXILIARY_TEXT = 1 << 1,
IBUS_CAP_LOOKUP_TABLE = 1 << 2,
IBUS_CAP_FOCUS = 1 << 3,
IBUS_CAP_PROPERTY = 1 << 4,
IBUS_CAP_SURROUNDING_TEXT = 1 << 5,
};
context->SetCapabilities(IBUS_CAP_PREEDIT_TEXT|IBUS_CAP_FOCUS);
qDebug() << ">>>> valid!";
valid = true;
}
QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
{
QByteArray display(getenv("DISPLAY"));
QByteArray host = "unix";
QByteArray displayNumber = "0";
int pos = display.indexOf(':');
if (pos > 0)
host = display.left(pos);
++pos;
int pos2 = display.indexOf('.', pos);
if (pos2 > 0)
displayNumber = display.mid(pos, pos2 - pos);
qDebug() << "host=" << host << "displayNumber" << displayNumber;
QFile file(QDir::homePath() + QLatin1String("/.config/ibus/bus/") +
QLatin1String(QDBusConnection::localMachineId()) +
QLatin1Char('-') + QString::fromLocal8Bit(host) + QLatin1Char('-') + QString::fromLocal8Bit(displayNumber));
if (!file.exists()) {
qDebug() << "ibus config file does not exist";
return 0;
}
file.open(QFile::ReadOnly);
QByteArray address;
int pid = -1;
while (!file.atEnd()) {
QByteArray line = file.readLine().trimmed();
if (line.startsWith('#'))
continue;
if (line.startsWith("IBUS_ADDRESS="))
address = line.mid(sizeof("IBUS_ADDRESS=") - 1);
if (line.startsWith("IBUS_DAEMON_PID="))
pid = line.mid(sizeof("IBUS_DAEMON_PID=") - 1).toInt();
}
qDebug() << "IBUS_ADDRESS=" << address << "PID=" << pid;
if (address.isEmpty() || pid < 0 || kill(pid, 0) != 0)
return 0;
return new QDBusConnection(QDBusConnection::connectToBus(QString::fromLatin1(address), QLatin1String("QIBusProxy")));
}

View File

@ -0,0 +1,71 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QIBUSPLATFORMINPUTCONTEXT_H
#define QIBUSPLATFORMINPUTCONTEXT_H
#include <QPlatformInputContext>
class QIBusPlatformInputContextPrivate;
class QDBusVariant;
class QIBusPlatformInputContext : public QObject, public QPlatformInputContext
{
Q_OBJECT
public:
QIBusPlatformInputContext();
~QIBusPlatformInputContext();
void mouseHandler(int x, QMouseEvent *event);
void reset(void);
void update(void);
void setFocusObject(QObject *object);
bool x11FilterEvent(uint keyval, uint keycode, uint state, bool press);
public Q_SLOTS:
void commitText(const QDBusVariant &text);
void updatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible);
private:
QIBusPlatformInputContextPrivate *d;
};
#endif

View File

@ -0,0 +1,26 @@
/*
* This file was generated by qdbusxml2cpp version 0.7
* Command line was: qdbusxml2cpp -N -p qibusproxy -c QIBusProxy interfaces/org.freedesktop.IBus.xml
*
* qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "qibusproxy.h"
/*
* Implementation of interface class QIBusProxy
*/
QIBusProxy::QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
QIBusProxy::~QIBusProxy()
{
}

View File

@ -0,0 +1,88 @@
/*
* This file was generated by qdbusxml2cpp version 0.7
* Command line was: qdbusxml2cpp -N -p qibusproxy -c QIBusProxy interfaces/org.freedesktop.IBus.xml
*
* qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef QIBUSPROXY_H_1308831142
#define QIBUSPROXY_H_1308831142
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface org.freedesktop.IBus
*/
class QIBusProxy: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.freedesktop.IBus"; }
public:
QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~QIBusProxy();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<QDBusObjectPath> CreateInputContext(const QString &name)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(name);
return asyncCallWithArgumentList(QLatin1String("CreateInputContext"), argumentList);
}
inline QDBusPendingReply<> Exit(bool restart)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(restart);
return asyncCallWithArgumentList(QLatin1String("Exit"), argumentList);
}
inline QDBusPendingReply<QString> GetAddress()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("GetAddress"), argumentList);
}
inline QDBusPendingReply<QVariantList> ListActiveEngines()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("ListActiveEngines"), argumentList);
}
inline QDBusPendingReply<QVariantList> ListEngines()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("ListEngines"), argumentList);
}
inline QDBusPendingReply<QDBusVariant> Ping(const QDBusVariant &data)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(data);
return asyncCallWithArgumentList(QLatin1String("Ping"), argumentList);
}
inline QDBusPendingReply<> RegisterComponent(const QDBusVariant &components)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(components);
return asyncCallWithArgumentList(QLatin1String("RegisterComponent"), argumentList);
}
Q_SIGNALS: // SIGNALS
};
#endif

View File

@ -0,0 +1,209 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qibustypes.h"
#include <qtextformat.h>
#include <QtDBus>
QIBusSerializable::QIBusSerializable()
{
}
QIBusSerializable::~QIBusSerializable()
{
}
void QIBusSerializable::fromDBusArgument(const QDBusArgument &arg)
{
arg >> name;
arg.beginMap();
while (!arg.atEnd()) {
arg.beginMapEntry();
QString key;
QDBusVariant value;
arg >> key;
arg >> value;
arg.endMapEntry();
attachments[key] = value.variant().value<QDBusArgument>();
}
arg.endMap();
}
QIBusAttribute::QIBusAttribute()
: type(Invalid),
value(0),
start(0),
end(0)
{
}
QIBusAttribute::~QIBusAttribute()
{
}
void QIBusAttribute::fromDBusArgument(const QDBusArgument &arg)
{
// qDebug() << "QIBusAttribute::fromDBusArgument()" << arg.currentSignature();
arg.beginStructure();
QIBusSerializable::fromDBusArgument(arg);
quint32 t;
arg >> t;
type = (Type)t;
arg >> value;
arg >> start;
arg >> end;
arg.endStructure();
}
QTextFormat QIBusAttribute::format() const
{
QTextCharFormat fmt;
switch (type) {
case Invalid:
break;
case Underline: {
QTextCharFormat::UnderlineStyle style = QTextCharFormat::NoUnderline;
switch (value) {
case UnderlineNone:
break;
case UnderlineSingle:
style = QTextCharFormat::SingleUnderline;
break;
case UnderlineDouble:
style = QTextCharFormat::DashUnderline;
break;
case UnderlineLow:
style = QTextCharFormat::DashDotLine;
break;
case UnderlineError:
style = QTextCharFormat::WaveUnderline;
fmt.setUnderlineColor(Qt::red);
break;
}
fmt.setUnderlineStyle(style);
break;
}
case Foreground:
fmt.setForeground(QColor(value));
break;
case Background:
fmt.setBackground(QColor(value));
break;
}
return fmt;
}
QIBusAttributeList::QIBusAttributeList()
{
}
QIBusAttributeList::~QIBusAttributeList()
{
}
void QIBusAttributeList::fromDBusArgument(const QDBusArgument &arg)
{
// qDebug() << "QIBusAttributeList::fromDBusArgument()" << arg.currentSignature();
arg.beginStructure();
QIBusSerializable::fromDBusArgument(arg);
arg.beginArray();
while(!arg.atEnd()) {
QDBusVariant var;
arg >> var;
QIBusAttribute attr;
attr.fromDBusArgument(var.variant().value<QDBusArgument>());
attributes.append(attr);
}
arg.endArray();
arg.endStructure();
}
QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const
{
QList<QInputMethodEvent::Attribute> imAttrs;
for (int i = 0; i < attributes.size(); ++i) {
const QIBusAttribute &attr = attributes.at(i);
imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, attr.start, attr.end - attr.start, attr.format());
}
return imAttrs;
}
QIBusText::QIBusText()
{
}
QIBusText::~QIBusText()
{
}
void QIBusText::fromDBusArgument(const QDBusArgument &arg)
{
// qDebug() << "QIBusText::fromDBusArgument()" << arg.currentSignature();
arg.beginStructure();
QIBusSerializable::fromDBusArgument(arg);
arg >> text;
QDBusVariant variant;
arg >> variant;
attributes.fromDBusArgument(variant.variant().value<QDBusArgument>());
arg.endStructure();
}

View File

@ -0,0 +1,116 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QIBUSTYPES_H
#define QIBUSTYPES_H
#include <qvector.h>
#include <qevent.h>
class QDBusArgument;
class QIBusSerializable
{
public:
QIBusSerializable();
virtual ~QIBusSerializable();
virtual void fromDBusArgument(const QDBusArgument &arg);
QString name;
QHash<QString, QDBusArgument> attachments;
};
class QIBusAttribute : public QIBusSerializable
{
public:
enum Type {
Invalid = 0,
Underline = 1,
Foreground = 2,
Background = 3,
};
enum Underline {
UnderlineNone = 0,
UnderlineSingle = 1,
UnderlineDouble = 2,
UnderlineLow = 3,
UnderlineError = 4,
};
QIBusAttribute();
~QIBusAttribute();
void fromDBusArgument(const QDBusArgument &arg);
QTextFormat format() const;
Type type;
quint32 value;
quint32 start;
quint32 end;
};
class QIBusAttributeList : public QIBusSerializable
{
public:
QIBusAttributeList();
~QIBusAttributeList();
void fromDBusArgument(const QDBusArgument &arg);
QList<QInputMethodEvent::Attribute> imAttributes() const;
QVector<QIBusAttribute> attributes;
};
class QIBusText : public QIBusSerializable
{
public:
QIBusText();
~QIBusText();
void fromDBusArgument(const QDBusArgument &arg);
QString text;
QIBusAttributeList attributes;
};
#endif

View File

@ -0,0 +1,3 @@
unix {
include($$PWD/ibus/ibus.pri)
}

View File

@ -27,4 +27,4 @@ include(fb_base/fb_base.pri)
include(fontdatabases/fontdatabases.pri)
include(glxconvenience/glxconvenience.pri)
include(printersupport/printersupport.pri)
#include(inputmethods/inputmethods.pri)
include(inputmethods/inputmethods.pri)

View File

@ -71,6 +71,11 @@
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#endif
#define XCB_USE_IBUS
#if defined(XCB_USE_IBUS)
#include "QtPlatformSupport/qibusplatforminputcontext.h"
#endif
QXcbIntegration::QXcbIntegration()
: m_connection(new QXcbConnection), m_printerSupport(new QGenericUnixPrinterSupport)
{
@ -79,6 +84,8 @@ QXcbIntegration::QXcbIntegration()
m_fontDatabase = new QGenericUnixFontDatabase();
m_nativeInterface = new QXcbNativeInterface;
m_inputContext = 0;
}
QXcbIntegration::~QXcbIntegration()
@ -141,6 +148,11 @@ QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const
{
QAbstractEventDispatcher *eventDispatcher = createUnixEventDispatcher();
m_connection->setEventDispatcher(eventDispatcher);
#ifdef XCB_USE_IBUS
// A bit hacky to do this here, but we need an eventloop before we can instantiate
// the input context.
const_cast<QXcbIntegration *>(this)->m_inputContext = new QIBusPlatformInputContext;
#endif
return eventDispatcher;
}
@ -318,3 +330,8 @@ QPlatformDrag *QXcbIntegration::drag() const
{
return m_connection->drag();
}
QPlatformInputContext *QXcbIntegration::inputContext() const
{
return m_inputContext;
}

View File

@ -76,6 +76,8 @@ public:
QPlatformClipboard *clipboard() const;
QPlatformDrag *drag() const;
QPlatformInputContext *inputContext() const;
private:
bool hasOpenGL() const;
QList<QPlatformScreen *> m_screens;
@ -84,6 +86,8 @@ private:
QPlatformFontDatabase *m_fontDatabase;
QPlatformNativeInterface *m_nativeInterface;
QPlatformPrinterSupport *m_printerSupport;
QPlatformInputContext *m_inputContext;
};
QT_END_NAMESPACE

View File

@ -46,8 +46,14 @@
#include <X11/keysym.h>
#include <QtGui/QWindowSystemInterface>
#include <QtCore/QTextCodec>
#include <private/qguiapplication_p.h>
#include <stdio.h>
#define XCB_USE_IBUS
#if defined(XCB_USE_IBUS)
#include "QtPlatformSupport/qibusplatforminputcontext.h"
#endif
#ifndef XK_ISO_Left_Tab
#define XK_ISO_Left_Tab 0xFE20
#endif
@ -1023,6 +1029,11 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
QByteArray chars;
xcb_keysym_t sym = lookupString(window, state, code, type, &chars);
QIBusPlatformInputContext *ic = static_cast<QIBusPlatformInputContext *>(QGuiApplicationPrivate::platformIntegration()->inputContext());
if (ic && ic->x11FilterEvent(sym, code, state, type == QEvent::KeyPress))
return;
Qt::KeyboardModifiers modifiers;
int qtcode = 0;
int count = chars.count();

View File

@ -84,5 +84,8 @@ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
CONFIG += qpa/genericunixfontdatabase
QT += dbus
LIBS += -ldbus-1
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target

View File

@ -11190,7 +11190,6 @@ void QWidget::setShortcutAutoRepeat(int id, bool enable)
*/
void QWidget::updateMicroFocus()
{
#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_OS_SYMBIAN))
Q_D(QWidget);
// and optimization to update input context only it has already been created.
if (d->assignedInputContext() || qApp->d_func()->inputContext) {
@ -11198,7 +11197,6 @@ void QWidget::updateMicroFocus()
if (ic)
ic->update();
}
#endif
#ifndef QT_NO_ACCESSIBILITY
if (isVisible()) {
// ##### is this correct