added fcitx inputcontext plugin for linux version

This commit is contained in:
John Preston 2015-08-13 18:09:04 +03:00
parent 869194f16a
commit efa62ece72
46 changed files with 16732 additions and 20 deletions

View File

@ -6,7 +6,7 @@ Source code is published under GPL v3, license is available [here](https://githu
###Supported systems
* Windows XP - Windows 8.1 (**not** RT)
* Windows XP - Windows 10 (**not** RT)
* Mac OS X 10.8 - Mac OS X 10.10
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
* Ubuntu 12.04 - Ubuntu 14.04

View File

@ -763,7 +763,9 @@ void SettingsInner::keyPressEvent(QKeyEvent *e) {
App::wnd()->showLayer(box);
from = size;
break;
} else if (qsl("debugmode").startsWith(str) || qsl("testmode").startsWith(str)) {
} else if (str == qstr("loadlang")) {
chooseCustomLang();
} else if (qsl("debugmode").startsWith(str) || qsl("testmode").startsWith(str) || qsl("loadlang").startsWith(str)) {
break;
}
++from;
@ -1167,25 +1169,29 @@ void SettingsInner::onTelegramFAQ() {
QDesktopServices::openUrl(qsl("https://telegram.org/faq#general"));
}
void SettingsInner::chooseCustomLang() {
QString file;
QByteArray arr;
if (filedialogGetOpenFile(file, arr, qsl("Choose language .strings file"), qsl("Language files (*.strings)"))) {
_testlang = QFileInfo(file).absoluteFilePath();
LangLoaderPlain loader(_testlang, LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_continue));
if (loader.errors().isEmpty()) {
LangLoaderResult result = loader.found();
QString text = result.value(lng_sure_save_language, langOriginal(lng_sure_save_language)),
save = result.value(lng_continue, langOriginal(lng_continue)),
cancel = result.value(lng_cancel, langOriginal(lng_cancel));
ConfirmBox *box = new ConfirmBox(text, save, cancel);
connect(box, SIGNAL(confirmed()), this, SLOT(onSaveTestLang()));
App::wnd()->showLayer(box);
} else {
App::wnd()->showLayer(new ConfirmBox("Custom lang failed :(\n\nError: " + loader.errors(), true, lang(lng_close)));
}
}
}
void SettingsInner::onChangeLanguage() {
if ((_changeLanguage.clickModifiers() & Qt::ShiftModifier) && (_changeLanguage.clickModifiers() & Qt::AltModifier)) {
QString file;
QByteArray arr;
if (filedialogGetOpenFile(file, arr, qsl("Choose language .strings file"), qsl("Language files (*.strings)"))) {
_testlang = QFileInfo(file).absoluteFilePath();
LangLoaderPlain loader(_testlang, LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_continue));
if (loader.errors().isEmpty()) {
LangLoaderResult result = loader.found();
QString text = result.value(lng_sure_save_language, langOriginal(lng_sure_save_language)),
save = result.value(lng_continue, langOriginal(lng_continue)),
cancel = result.value(lng_cancel, langOriginal(lng_cancel));
ConfirmBox *box = new ConfirmBox(text, save, cancel);
connect(box, SIGNAL(confirmed()), this, SLOT(onSaveTestLang()));
App::wnd()->showLayer(box);
} else {
App::wnd()->showLayer(new ConfirmBox("Custom lang failed :(\n\nError: " + loader.errors(), true, lang(lng_close)));
}
}
chooseCustomLang();
} else {
App::wnd()->showLayer(new LanguageBox());
}

View File

@ -78,6 +78,8 @@ public:
void showAll();
void chooseCustomLang();
void updateChatBackground();
void needBackgroundUpdate(bool tile);

View File

@ -36,5 +36,6 @@ Q_IMPORT_PLUGIN(QWebpPlugin)
#elif defined Q_OS_LINUX
Q_IMPORT_PLUGIN(QComposePlatformInputContextPlugin)
Q_IMPORT_PLUGIN(QIbusPlatformInputContextPlugin)
Q_IMPORT_PLUGIN(QFcitxPlatformInputContextPlugin)
Q_IMPORT_PLUGIN(QWebpPlugin)
#endif

View File

@ -313,7 +313,9 @@ INCLUDEPATH += "/usr/include/libdbusmenu-glib-0.4"
LIBS += -lcrypto -lssl -lz -ldl -llzma -lexif -lopenal -lavformat -lavcodec -lswresample -lavutil -lopus
LIBS += ./../../../Libraries/QtStatic/qtbase/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.a \
./../../../Libraries/QtStatic/qtbase/plugins/platforminputcontexts/libibusplatforminputcontextplugin.a
./../../../Libraries/QtStatic/qtbase/plugins/platforminputcontexts/libibusplatforminputcontextplugin.a \
./../../../Libraries/QtStatic/qtbase/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.a
LIBS += /usr/local/lib/libxkbcommon.a
RESOURCES += \
./SourceFiles/telegram.qrc \

View File

@ -0,0 +1,29 @@
TARGET = composeplatforminputcontextplugin
PLUGIN_TYPE = platforminputcontexts
PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin
load(qt_plugin)
QT += gui-private
DEFINES += X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"'
SOURCES += $$PWD/qcomposeplatforminputcontextmain.cpp \
$$PWD/qcomposeplatforminputcontext.cpp \
$$PWD/generator/qtablegenerator.cpp \
HEADERS += $$PWD/qcomposeplatforminputcontext.h \
$$PWD/generator/qtablegenerator.h \
# libxkbcommon
contains(QT_CONFIG, xkbcommon-qt): {
# dont't need x11 dependency for compose key plugin
QT_CONFIG -= use-xkbcommon-x11support
# include(../../../3rdparty/xkbcommon.pri)
} else {
# LIBS += $$QMAKE_LIBS_XKBCOMMON
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
}
OTHER_FILES += $$PWD/compose.json

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
{
"Keys": [ "fcitx" ]
}

View File

@ -0,0 +1,38 @@
TARGET = fcitxplatforminputcontextplugin
PLUGIN_TYPE = platforminputcontexts
PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QFcitxPlatformInputContextPlugin
load(qt_plugin)
QT += dbus gui-private
SOURCES += $$PWD/fcitxqtconnection.cpp \
$$PWD/fcitxqtformattedpreedit.cpp \
$$PWD/fcitxqtinputcontextproxy.cpp \
$$PWD/fcitxqtinputmethoditem.cpp \
$$PWD/fcitxqtinputmethodproxy.cpp \
$$PWD/fcitxqtkeyboardlayout.cpp \
$$PWD/fcitxqtkeyboardproxy.cpp \
$$PWD/keyuni.cpp \
$$PWD/main.cpp \
$$PWD/qfcitxplatforminputcontext.cpp \
$$PWD/utils.cpp
HEADERS += $$PWD/fcitxqtconnection.h \
$$PWD/fcitxqtconnection_p.h \
$$PWD/fcitxqtdbusaddons_export.h \
$$PWD/fcitxqtdbusaddons_version.h \
$$PWD/fcitxqtformattedpreedit.h \
$$PWD/fcitxqtinputcontextproxy.h \
$$PWD/fcitxqtinputmethoditem.h \
$$PWD/fcitxqtinputmethodproxy.h \
$$PWD/fcitxqtkeyboardlayout.h \
$$PWD/fcitxqtkeyboardproxy.h \
$$PWD/keydata.h \
$$PWD/keyserver_x11.h \
$$PWD/keyuni.h \
$$PWD/main.h \
$$PWD/qfcitxplatforminputcontext.h \
$$PWD/utils.h
OTHER_FILES += $$PWD/fcitx.jsn

View File

@ -0,0 +1,369 @@
/***************************************************************************
* Copyright (C) 2012~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "fcitxqtconnection_p.h"
#include <QDBusConnection>
#include <QDBusServiceWatcher>
#include <QDBusReply>
#include <QDBusConnectionInterface>
#include <QDebug>
#include <QFile>
#include <QTimer>
#include <QDir>
#include <signal.h>
#include <errno.h>
// utils function in fcitx-utils and fcitx-config
bool _pid_exists(pid_t pid) {
if (pid <= 0)
return 0;
return !(kill(pid, 0) && (errno == ESRCH));
}
FcitxQtConnection::FcitxQtConnection(QObject* parent): QObject(parent)
,d_ptr(new FcitxQtConnectionPrivate(this))
{
}
void FcitxQtConnection::startConnection()
{
Q_D(FcitxQtConnection);
if (!d->m_initialized) {
d->initialize();
d->createConnection();
}
}
void FcitxQtConnection::endConnection()
{
Q_D(FcitxQtConnection);
d->cleanUp();
d->finalize();
d->m_connectedOnce = false;
}
bool FcitxQtConnection::autoReconnect()
{
Q_D(FcitxQtConnection);
return d->m_autoReconnect;
}
void FcitxQtConnection::setAutoReconnect(bool a)
{
Q_D(FcitxQtConnection);
d->m_autoReconnect = a;
}
QDBusConnection* FcitxQtConnection::connection()
{
Q_D(FcitxQtConnection);
return d->m_connection;
}
const QString& FcitxQtConnection::serviceName()
{
Q_D(FcitxQtConnection);
return d->m_serviceName;
}
bool FcitxQtConnection::isConnected()
{
Q_D(FcitxQtConnection);
return d->isConnected();
}
FcitxQtConnection::~FcitxQtConnection()
{
}
FcitxQtConnectionPrivate::FcitxQtConnectionPrivate(FcitxQtConnection* conn) : QObject(conn)
,q_ptr(conn)
,m_displayNumber(-1)
,m_serviceName(QString("%1-%2").arg("org.fcitx.Fcitx").arg(displayNumber()))
,m_connection(0)
,m_serviceWatcher(new QDBusServiceWatcher(conn))
,m_watcher(new QFileSystemWatcher(this))
,m_autoReconnect(true)
,m_connectedOnce(false)
,m_initialized(false)
{
}
FcitxQtConnectionPrivate::~FcitxQtConnectionPrivate()
{
if (m_connection)
delete m_connection;
}
void FcitxQtConnectionPrivate::initialize() {
m_serviceWatcher->setConnection(QDBusConnection::sessionBus());
m_serviceWatcher->addWatchedService(m_serviceName);
QFileInfo info(socketFile());
QDir dir(info.path());
if (!dir.exists()) {
QDir rt(QDir::root());
rt.mkpath(info.path());
}
m_watcher->addPath(info.path());
if (info.exists()) {
m_watcher->addPath(info.filePath());
}
connect(m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(socketFileChanged()));
connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(socketFileChanged()));
m_initialized = true;
}
void FcitxQtConnectionPrivate::finalize() {
m_serviceWatcher->removeWatchedService(m_serviceName);
m_watcher->removePaths(m_watcher->files());
m_watcher->removePaths(m_watcher->directories());
m_watcher->disconnect(SIGNAL(fileChanged(QString)));
m_watcher->disconnect(SIGNAL(directoryChanged(QString)));
m_initialized = false;
}
void FcitxQtConnectionPrivate::socketFileChanged() {
QFileInfo info(socketFile());
if (info.exists()) {
if (m_watcher->files().indexOf(info.filePath()) == -1)
m_watcher->addPath(info.filePath());
}
QString addr = address();
if (addr.isNull())
return;
cleanUp();
createConnection();
}
QByteArray FcitxQtConnectionPrivate::localMachineId()
{
#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
return QDBusConnection::localMachineId();
#else
QFile file1("/var/lib/dbus/machine-id");
QFile file2("/etc/machine-id");
QFile* fileToRead = NULL;
if (file1.open(QIODevice::ReadOnly)) {
fileToRead = &file1;
}
else if (file2.open(QIODevice::ReadOnly)) {
fileToRead = &file2;
}
if (fileToRead) {
QByteArray result = fileToRead->readLine(1024);
fileToRead->close();
result = result.trimmed();
if (!result.isEmpty())
return result;
}
return "machine-id";
#endif
}
int FcitxQtConnectionPrivate::displayNumber() {
if (m_displayNumber < 0) {
QByteArray displayNumber("0");
QByteArray display(qgetenv("DISPLAY"));
int pos = display.indexOf(':');
if (pos >= 0) {
++pos;
int pos2 = display.indexOf('.', pos);
if (pos2 > 0) {
displayNumber = display.mid(pos, pos2 - pos);
} else {
displayNumber = display.mid(pos);
}
}
bool ok;
int d = displayNumber.toInt(&ok);
if (ok) {
m_displayNumber = d;
} else {
m_displayNumber = 0;
}
}
return m_displayNumber;
}
const QString& FcitxQtConnectionPrivate::socketFile()
{
if (!m_socketFile.isEmpty())
return m_socketFile;
QString filename = QString("%1-%2").arg(QString::fromLatin1(QDBusConnection::localMachineId())).arg(displayNumber());
QString home = QString::fromLocal8Bit(qgetenv("XDG_CONFIG_HOME"));
if (home.isEmpty()) {
home = QDir::homePath().append(QLatin1Literal("/.config"));
}
m_socketFile = QString("%1/fcitx/dbus/%2").arg(home).arg(filename);
return m_socketFile;
}
QString FcitxQtConnectionPrivate::address()
{
QString addr;
QByteArray addrVar = qgetenv("FCITX_DBUS_ADDRESS");
if (!addrVar.isNull())
return QString::fromLocal8Bit(addrVar);
QFile file(socketFile());
if (!file.open(QIODevice::ReadOnly))
return QString();
const int BUFSIZE = 1024;
char buffer[BUFSIZE];
size_t sz = file.read(buffer, BUFSIZE);
file.close();
if (sz == 0)
return QString();
char* p = buffer;
while(*p)
p++;
size_t addrlen = p - buffer;
if (sz != addrlen + 2 * sizeof(pid_t) + 1)
return QString();
/* skip '\0' */
p++;
pid_t *ppid = (pid_t*) p;
pid_t daemonpid = ppid[0];
pid_t fcitxpid = ppid[1];
if (!_pid_exists(daemonpid)
|| !_pid_exists(fcitxpid))
return QString();
addr = QLatin1String(buffer);
return addr;
}
void FcitxQtConnectionPrivate::createConnection() {
if (m_connectedOnce && !m_autoReconnect) {
return;
}
m_serviceWatcher->disconnect(SIGNAL(serviceOwnerChanged(QString,QString,QString)));
QString addr = address();
if (!addr.isNull()) {
QDBusConnection connection(QDBusConnection::connectToBus(addr, "fcitx"));
if (connection.isConnected()) {
// qDebug() << "create private";
m_connection = new QDBusConnection(connection);
}
else
QDBusConnection::disconnectFromBus("fcitx");
}
if (!m_connection) {
QDBusConnection* connection = new QDBusConnection(QDBusConnection::sessionBus());
connect(m_serviceWatcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(imChanged(QString,QString,QString)));
QDBusReply<bool> registered = connection->interface()->isServiceRegistered(m_serviceName);
if (!registered.isValid() || !registered.value()) {
delete connection;
}
else {
m_connection = connection;
}
}
Q_Q(FcitxQtConnection);
if (m_connection) {
m_connection->connect ("org.freedesktop.DBus.Local",
"/org/freedesktop/DBus/Local",
"org.freedesktop.DBus.Local",
"Disconnected",
this,
SLOT (dbusDisconnected ()));
m_connectedOnce = true;
emit q->connected();
}
}
void FcitxQtConnectionPrivate::dbusDisconnected()
{
cleanUp();
createConnection();
}
void FcitxQtConnectionPrivate::imChanged(const QString& service, const QString& oldowner, const QString& newowner)
{
if (service == m_serviceName) {
/* old die */
if (oldowner.length() > 0 || newowner.length() > 0)
cleanUp();
/* new rise */
if (newowner.length() > 0) {
QTimer::singleShot(100, this, SLOT(newServiceAppear()));
}
}
}
void FcitxQtConnectionPrivate::cleanUp()
{
Q_Q(FcitxQtConnection);
bool doemit = false;
QDBusConnection::disconnectFromBus("fcitx");
if (m_connection) {
delete m_connection;
m_connection = 0;
doemit = true;
}
if (!m_autoReconnect && m_connectedOnce)
finalize();
/* we want m_connection and finalize being called before the signal
* thus isConnected will return false in slot
* and startConnection can be called in slot
*/
if (doemit)
emit q->disconnected();
}
bool FcitxQtConnectionPrivate::isConnected()
{
return m_connection && m_connection->isConnected();
}
void FcitxQtConnectionPrivate::newServiceAppear() {
if (!isConnected()) {
cleanUp();
createConnection();
}
}

View File

@ -0,0 +1,111 @@
/***************************************************************************
* Copyright (C) 2012~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef FCITXQTCONNECTION_H
#define FCITXQTCONNECTION_H
#include "fcitxqtdbusaddons_export.h"
#include <QtCore/QObject>
class QDBusConnection;
class FcitxQtConnectionPrivate;
/**
* dbus connection to fcitx
**/
class FCITXQTDBUSADDONS_EXPORT FcitxQtConnection : public QObject {
Q_OBJECT
Q_PROPERTY(bool autoReconnect READ autoReconnect WRITE setAutoReconnect)
Q_PROPERTY(bool connected READ isConnected)
Q_PROPERTY(QDBusConnection* connection READ connection)
Q_PROPERTY(QString serviceName READ serviceName)
public:
/**
* create a new connection
*
* @param parent
**/
explicit FcitxQtConnection(QObject* parent = 0);
/**
* destroy the connection
**/
virtual ~FcitxQtConnection();
/**
* the connection will not start to work until you call this function
* you may want to connect to the signal before you call this function
**/
void startConnection();
void endConnection();
/**
* automatically reconnect if fcitx disappeared
*
* @param a ...
* @return void
**/
void setAutoReconnect(bool a);
/**
* check this connection is doing automatical reconnect or not
*
* default value is true
**/
bool autoReconnect();
/**
* return the current dbus connection to fcitx, notice, the object return
* by this function might be deteled if fcitx disappear, or might return 0
* if fcitx is not running
*
* @return QDBusConnection*
**/
QDBusConnection* connection();
/**
* current fcitx dbus service name, can be used for create DBus proxy
*
* @return service name
**/
const QString& serviceName();
/**
* check its connected or not
**/
bool isConnected();
Q_SIGNALS:
/**
* this signal will be emitted upon fcitx appears
**/
void connected();
/**
* this signal will be emitted upon fcitx disappears
*
* it will come with connected in pair
**/
void disconnected();
private:
FcitxQtConnectionPrivate * const d_ptr;
Q_DECLARE_PRIVATE(FcitxQtConnection);
};
#endif // FCITXCONNECTION_H

View File

@ -0,0 +1,68 @@
/***************************************************************************
* Copyright (C) 2012~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef FCITXQTCONNECTION_P_H
#define FCITXQTCONNECTION_P_H
#include "fcitxqtconnection.h"
#include <QtCore/QWeakPointer>
#include <QtCore/QFileSystemWatcher>
class QDBusConnection;
class QDBusServiceWatcher;
class FcitxQtConnectionPrivate : public QObject {
Q_OBJECT
public:
FcitxQtConnectionPrivate(FcitxQtConnection* conn);
virtual ~FcitxQtConnectionPrivate();
FcitxQtConnection * const q_ptr;
Q_DECLARE_PUBLIC(FcitxQtConnection);
private Q_SLOTS:
void imChanged(const QString& service, const QString& oldowner, const QString& newowner);
void dbusDisconnected();
void cleanUp();
void newServiceAppear();
void socketFileChanged();
private:
bool isConnected();
static QByteArray localMachineId();
const QString& socketFile();
void createConnection();
QString address();
int displayNumber();
void initialize();
void finalize();
int m_displayNumber;
QString m_serviceName;
QDBusConnection* m_connection;
QDBusServiceWatcher* m_serviceWatcher;
QFileSystemWatcher* m_watcher;
QString m_socketFile;
bool m_autoReconnect;
bool m_connectedOnce;
bool m_initialized;
};
#endif // FCITXCONNECTION_P_H

View File

@ -0,0 +1,41 @@
#ifndef FCITXQTDBUSADDONS_EXPORT_H
#define FCITXQTDBUSADDONS_EXPORT_H
#ifdef FCITXQTDBUSADDONS_STATIC_DEFINE
# define FCITXQTDBUSADDONS_EXPORT
# define FCITXQTDBUSADDONS_NO_EXPORT
#else
# ifndef FCITXQTDBUSADDONS_EXPORT
# ifdef FcitxQt5DBusAddons_EXPORTS
/* We are building this library */
# define FCITXQTDBUSADDONS_EXPORT __attribute__((visibility("default")))
# else
/* We are using this library */
# define FCITXQTDBUSADDONS_EXPORT __attribute__((visibility("default")))
# endif
# endif
# ifndef FCITXQTDBUSADDONS_NO_EXPORT
# define FCITXQTDBUSADDONS_NO_EXPORT __attribute__((visibility("hidden")))
# endif
#endif
#ifndef FCITXQTDBUSADDONS_DEPRECATED
# define FCITXQTDBUSADDONS_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef FCITXQTDBUSADDONS_DEPRECATED_EXPORT
# define FCITXQTDBUSADDONS_DEPRECATED_EXPORT FCITXQTDBUSADDONS_EXPORT FCITXQTDBUSADDONS_DEPRECATED
#endif
#ifndef FCITXQTDBUSADDONS_DEPRECATED_NO_EXPORT
# define FCITXQTDBUSADDONS_DEPRECATED_NO_EXPORT FCITXQTDBUSADDONS_NO_EXPORT FCITXQTDBUSADDONS_DEPRECATED
#endif
#define DEFINE_NO_DEPRECATED 0
#if DEFINE_NO_DEPRECATED
# define FCITXQTDBUSADDONS_NO_DEPRECATED
#endif
#endif

View File

@ -0,0 +1,11 @@
#ifndef FCITXQT5DBUSADDONS_VERSION_H
#define FCITXQT5DBUSADDONS_VERSION_H
#define FCITXQT5DBUSADDONS_VERSION_STRING "1.0.0"
#define FCITXQT5DBUSADDONS_VERSION_MAJOR 1
#define FCITXQT5DBUSADDONS_VERSION_MINOR 0
#define FCITXQT5DBUSADDONS_VERSION_PATCH 0
#define FCITXQT5DBUSADDONS_VERSION ((1<<16)|(0<<8)|(0))
#endif

View File

@ -0,0 +1,78 @@
/***************************************************************************
* Copyright (C) 2012~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <QDBusMetaType>
#include "fcitxqtformattedpreedit.h"
void FcitxQtFormattedPreedit::registerMetaType()
{
qRegisterMetaType<FcitxQtFormattedPreedit>("FcitxQtFormattedPreedit");
qDBusRegisterMetaType<FcitxQtFormattedPreedit>();
qRegisterMetaType<FcitxQtFormattedPreeditList>("FcitxQtFormattedPreeditList");
qDBusRegisterMetaType<FcitxQtFormattedPreeditList>();
}
qint32 FcitxQtFormattedPreedit::format() const
{
return m_format;
}
const QString& FcitxQtFormattedPreedit::string() const
{
return m_string;
}
void FcitxQtFormattedPreedit::setFormat(qint32 format)
{
m_format = format;
}
void FcitxQtFormattedPreedit::setString(const QString& str)
{
m_string = str;
}
bool FcitxQtFormattedPreedit::operator==(const FcitxQtFormattedPreedit& preedit) const
{
return (preedit.m_format == m_format) && (preedit.m_string == m_string);
}
FCITXQTDBUSADDONS_EXPORT
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtFormattedPreedit& preedit)
{
argument.beginStructure();
argument << preedit.string();
argument << preedit.format();
argument.endStructure();
return argument;
}
FCITXQTDBUSADDONS_EXPORT
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtFormattedPreedit& preedit)
{
QString str;
qint32 format;
argument.beginStructure();
argument >> str >> format;
argument.endStructure();
preedit.setString(str);
preedit.setFormat(format);
return argument;
}

View File

@ -0,0 +1,51 @@
/***************************************************************************
* Copyright (C) 2012~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef FCITX_QT_FORMATTED_PREEDIT_H
#define FCITX_QT_FORMATTED_PREEDIT_H
#include "fcitxqtdbusaddons_export.h"
#include <QtCore/QMetaType>
#include <QtDBus/QDBusArgument>
class FCITXQTDBUSADDONS_EXPORT FcitxQtFormattedPreedit {
public:
const QString& string() const;
qint32 format() const;
void setString(const QString& str);
void setFormat(qint32 format);
static void registerMetaType();
bool operator ==(const FcitxQtFormattedPreedit& preedit) const;
private:
QString m_string;
qint32 m_format;
};
typedef QList<FcitxQtFormattedPreedit> FcitxQtFormattedPreeditList;
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtFormattedPreedit& im);
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtFormattedPreedit& im);
Q_DECLARE_METATYPE(FcitxQtFormattedPreedit)
Q_DECLARE_METATYPE(FcitxQtFormattedPreeditList)
#endif

View File

@ -0,0 +1,26 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -N -p fcitxqtinputcontextproxy -c FcitxQtInputContextProxy interfaces/org.fcitx.Fcitx.InputContext.xml -i fcitxqtformattedpreedit.h -i fcitxqt_export.h
*
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc 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 "fcitxqtinputcontextproxy.h"
/*
* Implementation of interface class FcitxQtInputContextProxy
*/
FcitxQtInputContextProxy::FcitxQtInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
FcitxQtInputContextProxy::~FcitxQtInputContextProxy()
{
}

View File

@ -0,0 +1,136 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -N -p fcitxqtinputcontextproxy -c FcitxQtInputContextProxy interfaces/org.fcitx.Fcitx.InputContext.xml -i fcitxqtformattedpreedit.h -i fcitxqt_export.h
*
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef FCITXQTINPUTCONTEXTPROXY_H_1409252990
#define FCITXQTINPUTCONTEXTPROXY_H_1409252990
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
#include "fcitxqtformattedpreedit.h"
#include "fcitxqtdbusaddons_export.h"
/*
* Proxy class for interface org.fcitx.Fcitx.InputContext
*/
class FCITXQTDBUSADDONS_EXPORT FcitxQtInputContextProxy: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.fcitx.Fcitx.InputContext"; }
public:
FcitxQtInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~FcitxQtInputContextProxy();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> CloseIC()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("CloseIC"), argumentList);
}
inline QDBusPendingReply<> DestroyIC()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("DestroyIC"), argumentList);
}
inline QDBusPendingReply<> EnableIC()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("EnableIC"), 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<> MouseEvent(int x)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(x);
return asyncCallWithArgumentList(QLatin1String("MouseEvent"), argumentList);
}
inline QDBusPendingReply<int> ProcessKeyEvent(uint keyval, uint keycode, uint state, int type, uint time)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(keyval) << QVariant::fromValue(keycode) << QVariant::fromValue(state) << QVariant::fromValue(type) << QVariant::fromValue(time);
return asyncCallWithArgumentList(QLatin1String("ProcessKeyEvent"), argumentList);
}
inline QDBusPendingReply<> Reset()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("Reset"), argumentList);
}
inline QDBusPendingReply<> SetCapacity(uint caps)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(caps);
return asyncCallWithArgumentList(QLatin1String("SetCapacity"), argumentList);
}
inline QDBusPendingReply<> SetCursorLocation(int x, int y)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y);
return asyncCallWithArgumentList(QLatin1String("SetCursorLocation"), argumentList);
}
inline QDBusPendingReply<> SetCursorRect(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("SetCursorRect"), argumentList);
}
inline QDBusPendingReply<> SetSurroundingText(const QString &text, uint cursor, uint anchor)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(text) << QVariant::fromValue(cursor) << QVariant::fromValue(anchor);
return asyncCallWithArgumentList(QLatin1String("SetSurroundingText"), argumentList);
}
inline QDBusPendingReply<> SetSurroundingTextPosition(uint cursor, uint anchor)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(cursor) << QVariant::fromValue(anchor);
return asyncCallWithArgumentList(QLatin1String("SetSurroundingTextPosition"), argumentList);
}
Q_SIGNALS: // SIGNALS
void CloseIM();
void CommitString(const QString &str);
void DeleteSurroundingText(int offset, uint nchar);
void EnableIM();
void ForwardKey(uint keyval, uint state, int type);
void UpdateClientSideUI(const QString &auxup, const QString &auxdown, const QString &preedit, const QString &candidateword, const QString &imname, int cursorpos);
void UpdateFormattedPreedit(FcitxQtFormattedPreeditList str, int cursorpos);
};
#endif

View File

@ -0,0 +1,95 @@
/***************************************************************************
* Copyright (C) 2011~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
// Qt
#include <QDBusArgument>
#include <QDBusMetaType>
// self
#include "fcitxqtinputmethoditem.h"
bool FcitxQtInputMethodItem::enabled() const
{
return m_enabled;
}
const QString& FcitxQtInputMethodItem::langCode() const
{
return m_langCode;
}
const QString& FcitxQtInputMethodItem::name() const
{
return m_name;
}
const QString& FcitxQtInputMethodItem::uniqueName() const
{
return m_uniqueName;
}
void FcitxQtInputMethodItem::setEnabled(bool enable)
{
m_enabled = enable;
}
void FcitxQtInputMethodItem::setLangCode(const QString& lang)
{
m_langCode = lang;
}
void FcitxQtInputMethodItem::setName(const QString& name)
{
m_name = name;
}
void FcitxQtInputMethodItem::setUniqueName(const QString& name)
{
m_uniqueName = name;
}
void FcitxQtInputMethodItem::registerMetaType()
{
qRegisterMetaType<FcitxQtInputMethodItem>("FcitxQtInputMethodItem");
qDBusRegisterMetaType<FcitxQtInputMethodItem>();
qRegisterMetaType<FcitxQtInputMethodItemList>("FcitxQtInputMethodItemList");
qDBusRegisterMetaType<FcitxQtInputMethodItemList>();
}
FCITXQTDBUSADDONS_EXPORT
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtInputMethodItem& im)
{
argument.beginStructure();
argument << im.name();
argument << im.uniqueName();
argument << im.langCode();
argument << im.enabled();
argument.endStructure();
return argument;
}
FCITXQTDBUSADDONS_EXPORT
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtInputMethodItem& im)
{
QString name;
QString uniqueName;
QString langCode;
bool enabled;
argument.beginStructure();
argument >> name >> uniqueName >> langCode >> enabled;
argument.endStructure();
im.setName(name);
im.setUniqueName(uniqueName);
im.setLangCode(langCode);
im.setEnabled(enabled);
return argument;
}

View File

@ -0,0 +1,64 @@
/***************************************************************************
* Copyright (C) 2011~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef FCITX_QT_INPUT_METHOD_ITEM_H
#define FCITX_QT_INPUT_METHOD_ITEM_H
#include "fcitxqtdbusaddons_export.h"
// Qt
#include <QtCore/QString>
#include <QtCore/QMetaType>
#include <QtDBus/QDBusArgument>
class FCITXQTDBUSADDONS_EXPORT FcitxQtInputMethodItem
{
public:
const QString& name() const;
const QString& uniqueName() const;
const QString& langCode() const;
bool enabled() const;
void setName(const QString& name);
void setUniqueName(const QString& name);
void setLangCode(const QString& name);
void setEnabled(bool name);
static void registerMetaType();
inline bool operator < (const FcitxQtInputMethodItem& im) const {
if (m_enabled == true && im.m_enabled == false)
return true;
return false;
}
private:
QString m_name;
QString m_uniqueName;
QString m_langCode;
bool m_enabled;
};
typedef QList<FcitxQtInputMethodItem> FcitxQtInputMethodItemList;
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtInputMethodItem& im);
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtInputMethodItem& im);
Q_DECLARE_METATYPE(FcitxQtInputMethodItem)
Q_DECLARE_METATYPE(FcitxQtInputMethodItemList)
#endif

View File

@ -0,0 +1,26 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -N -p fcitxqtinputmethodproxy -c FcitxQtInputMethodProxy interfaces/org.fcitx.Fcitx.InputMethod.xml -i fcitxqtinputmethoditem.h -i fcitxqt_export.h
*
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc 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 "fcitxqtinputmethodproxy.h"
/*
* Implementation of interface class FcitxQtInputMethodProxy
*/
FcitxQtInputMethodProxy::FcitxQtInputMethodProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
FcitxQtInputMethodProxy::~FcitxQtInputMethodProxy()
{
}

View File

@ -0,0 +1,217 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -N -p fcitxqtinputmethodproxy -c FcitxQtInputMethodProxy interfaces/org.fcitx.Fcitx.InputMethod.xml -i fcitxqtinputmethoditem.h -i fcitxqt_export.h
*
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef FCITXQTINPUTMETHODPROXY_H_1409252990
#define FCITXQTINPUTMETHODPROXY_H_1409252990
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
#include "fcitxqtinputmethoditem.h"
#include "fcitxqtdbusaddons_export.h"
/*
* Proxy class for interface org.fcitx.Fcitx.InputMethod
*/
class FCITXQTDBUSADDONS_EXPORT FcitxQtInputMethodProxy: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.fcitx.Fcitx.InputMethod"; }
public:
FcitxQtInputMethodProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~FcitxQtInputMethodProxy();
Q_PROPERTY(QString CurrentIM READ currentIM WRITE setCurrentIM)
inline QString currentIM() const
{ return qvariant_cast< QString >(property("CurrentIM")); }
inline void setCurrentIM(const QString &value)
{ setProperty("CurrentIM", QVariant::fromValue(value)); }
Q_PROPERTY(FcitxQtInputMethodItemList IMList READ iMList WRITE setIMList)
inline FcitxQtInputMethodItemList iMList() const
{ return qvariant_cast< FcitxQtInputMethodItemList >(property("IMList")); }
inline void setIMList(FcitxQtInputMethodItemList value)
{ setProperty("IMList", QVariant::fromValue(value)); }
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> ActivateIM()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("ActivateIM"), argumentList);
}
inline QDBusPendingReply<> Configure()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("Configure"), argumentList);
}
inline QDBusPendingReply<> ConfigureAddon(const QString &addon)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(addon);
return asyncCallWithArgumentList(QLatin1String("ConfigureAddon"), argumentList);
}
inline QDBusPendingReply<> ConfigureIM(const QString &im)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(im);
return asyncCallWithArgumentList(QLatin1String("ConfigureIM"), argumentList);
}
inline QDBusPendingReply<int, uint, uint, uint, uint> CreateIC()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("CreateIC"), argumentList);
}
inline QDBusReply<int> CreateIC(uint &keyval1, uint &state1, uint &keyval2, uint &state2)
{
QList<QVariant> argumentList;
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("CreateIC"), argumentList);
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 5) {
keyval1 = qdbus_cast<uint>(reply.arguments().at(1));
state1 = qdbus_cast<uint>(reply.arguments().at(2));
keyval2 = qdbus_cast<uint>(reply.arguments().at(3));
state2 = qdbus_cast<uint>(reply.arguments().at(4));
}
return reply;
}
inline QDBusPendingReply<int, bool, uint, uint, uint, uint> CreateICv2(const QString &appname)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(appname);
return asyncCallWithArgumentList(QLatin1String("CreateICv2"), argumentList);
}
inline QDBusReply<int> CreateICv2(const QString &appname, bool &enable, uint &keyval1, uint &state1, uint &keyval2, uint &state2)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(appname);
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("CreateICv2"), argumentList);
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 6) {
enable = qdbus_cast<bool>(reply.arguments().at(1));
keyval1 = qdbus_cast<uint>(reply.arguments().at(2));
state1 = qdbus_cast<uint>(reply.arguments().at(3));
keyval2 = qdbus_cast<uint>(reply.arguments().at(4));
state2 = qdbus_cast<uint>(reply.arguments().at(5));
}
return reply;
}
inline QDBusPendingReply<int, bool, uint, uint, uint, uint> CreateICv3(const QString &appname, int pid)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(appname) << QVariant::fromValue(pid);
return asyncCallWithArgumentList(QLatin1String("CreateICv3"), argumentList);
}
inline QDBusReply<int> CreateICv3(const QString &appname, int pid, bool &enable, uint &keyval1, uint &state1, uint &keyval2, uint &state2)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(appname) << QVariant::fromValue(pid);
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("CreateICv3"), argumentList);
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 6) {
enable = qdbus_cast<bool>(reply.arguments().at(1));
keyval1 = qdbus_cast<uint>(reply.arguments().at(2));
state1 = qdbus_cast<uint>(reply.arguments().at(3));
keyval2 = qdbus_cast<uint>(reply.arguments().at(4));
state2 = qdbus_cast<uint>(reply.arguments().at(5));
}
return reply;
}
inline QDBusPendingReply<> Exit()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("Exit"), argumentList);
}
inline QDBusPendingReply<QString> GetCurrentIM()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("GetCurrentIM"), argumentList);
}
inline QDBusPendingReply<int> GetCurrentState()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("GetCurrentState"), argumentList);
}
inline QDBusPendingReply<QString> GetCurrentUI()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("GetCurrentUI"), argumentList);
}
inline QDBusPendingReply<QString> GetIMAddon(const QString &im)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(im);
return asyncCallWithArgumentList(QLatin1String("GetIMAddon"), argumentList);
}
inline QDBusPendingReply<> InactivateIM()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("InactivateIM"), argumentList);
}
inline QDBusPendingReply<> ReloadAddonConfig(const QString &addon)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(addon);
return asyncCallWithArgumentList(QLatin1String("ReloadAddonConfig"), argumentList);
}
inline QDBusPendingReply<> ReloadConfig()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("ReloadConfig"), argumentList);
}
inline QDBusPendingReply<> ResetIMList()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("ResetIMList"), argumentList);
}
inline QDBusPendingReply<> Restart()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("Restart"), argumentList);
}
inline QDBusPendingReply<> SetCurrentIM(const QString &im)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(im);
return asyncCallWithArgumentList(QLatin1String("SetCurrentIM"), argumentList);
}
inline QDBusPendingReply<> ToggleIM()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("ToggleIM"), argumentList);
}
Q_SIGNALS: // SIGNALS
};
#endif

View File

@ -0,0 +1,100 @@
/***************************************************************************
* Copyright (C) 2011~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
// Qt
#include <QDBusArgument>
#include <QDBusMetaType>
// self
#include "fcitxqtkeyboardlayout.h"
const QString& FcitxQtKeyboardLayout::layout() const
{
return m_layout;
}
const QString& FcitxQtKeyboardLayout::langCode() const
{
return m_langCode;
}
const QString& FcitxQtKeyboardLayout::name() const
{
return m_name;
}
const QString& FcitxQtKeyboardLayout::variant() const
{
return m_variant;
}
void FcitxQtKeyboardLayout::setLayout(const QString& layout)
{
m_layout = layout;
}
void FcitxQtKeyboardLayout::setLangCode(const QString& lang)
{
m_langCode = lang;
}
void FcitxQtKeyboardLayout::setName(const QString& name)
{
m_name = name;
}
void FcitxQtKeyboardLayout::setVariant(const QString& variant)
{
m_variant = variant;
}
void FcitxQtKeyboardLayout::registerMetaType()
{
qRegisterMetaType<FcitxQtKeyboardLayout>("FcitxQtKeyboardLayout");
qDBusRegisterMetaType<FcitxQtKeyboardLayout>();
qRegisterMetaType<FcitxQtKeyboardLayoutList>("FcitxQtKeyboardLayoutList");
qDBusRegisterMetaType<FcitxQtKeyboardLayoutList>();
}
FCITXQTDBUSADDONS_EXPORT
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtKeyboardLayout& layout)
{
argument.beginStructure();
argument << layout.layout();
argument << layout.variant();
argument << layout.name();
argument << layout.langCode();
argument.endStructure();
return argument;
}
FCITXQTDBUSADDONS_EXPORT
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtKeyboardLayout& layout)
{
QString l;
QString variant;
QString name;
QString langCode;
argument.beginStructure();
argument >> l >> variant >> name >> langCode;
argument.endStructure();
layout.setLayout(l);
layout.setVariant(variant);
layout.setName(name);
layout.setLangCode(langCode);
return argument;
}

View File

@ -0,0 +1,58 @@
/***************************************************************************
* Copyright (C) 2011~2012 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef FCITX_QT_KEYBOARD_LAYOUT_H
#define FCITX_QT_KEYBOARD_LAYOUT_H
#include "fcitxqtdbusaddons_export.h"
// Qt
#include <QtCore/QString>
#include <QtCore/QMetaType>
#include <QtDBus/QDBusArgument>
class FCITXQTDBUSADDONS_EXPORT FcitxQtKeyboardLayout
{
public:
const QString& layout() const;
const QString& variant() const;
const QString& name() const;
const QString& langCode() const;
void setLayout(const QString& layout);
void setLangCode(const QString& lang);
void setName(const QString& name);
void setVariant(const QString& variant);
static void registerMetaType();
private:
QString m_layout;
QString m_variant;
QString m_name;
QString m_langCode;
};
typedef QList<FcitxQtKeyboardLayout> FcitxQtKeyboardLayoutList;
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtKeyboardLayout& l);
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtKeyboardLayout& l);
Q_DECLARE_METATYPE(FcitxQtKeyboardLayout)
Q_DECLARE_METATYPE(FcitxQtKeyboardLayoutList)
#endif

View File

@ -0,0 +1,26 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -N -p fcitxqtkeyboardproxy -c FcitxQtKeyboardProxy interfaces/org.fcitx.Fcitx.Keyboard.xml -i fcitxqtkeyboardlayout.h -i fcitxqt_export.h
*
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc 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 "fcitxqtkeyboardproxy.h"
/*
* Implementation of interface class FcitxQtKeyboardProxy
*/
FcitxQtKeyboardProxy::FcitxQtKeyboardProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
FcitxQtKeyboardProxy::~FcitxQtKeyboardProxy()
{
}

View File

@ -0,0 +1,74 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -N -p fcitxqtkeyboardproxy -c FcitxQtKeyboardProxy interfaces/org.fcitx.Fcitx.Keyboard.xml -i fcitxqtkeyboardlayout.h -i fcitxqt_export.h
*
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef FCITXQTKEYBOARDPROXY_H_1409252990
#define FCITXQTKEYBOARDPROXY_H_1409252990
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
#include "fcitxqtkeyboardlayout.h"
#include "fcitxqtdbusaddons_export.h"
/*
* Proxy class for interface org.fcitx.Fcitx.Keyboard
*/
class FCITXQTDBUSADDONS_EXPORT FcitxQtKeyboardProxy: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.fcitx.Fcitx.Keyboard"; }
public:
FcitxQtKeyboardProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~FcitxQtKeyboardProxy();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<QString, QString> GetLayoutForIM(const QString &im)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(im);
return asyncCallWithArgumentList(QLatin1String("GetLayoutForIM"), argumentList);
}
inline QDBusReply<QString> GetLayoutForIM(const QString &im, QString &variant)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(im);
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("GetLayoutForIM"), argumentList);
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) {
variant = qdbus_cast<QString>(reply.arguments().at(1));
}
return reply;
}
inline QDBusPendingReply<FcitxQtKeyboardLayoutList> GetLayouts()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("GetLayouts"), argumentList);
}
inline QDBusPendingReply<> SetLayoutForIM(const QString &im, const QString &layout, const QString &variant)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(im) << QVariant::fromValue(layout) << QVariant::fromValue(variant);
return asyncCallWithArgumentList(QLatin1String("SetLayoutForIM"), argumentList);
}
Q_SIGNALS: // SIGNALS
};
#endif

View File

@ -0,0 +1,81 @@
<!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.fcitx.Fcitx.InputContext">
<method name="EnableIC">
</method>
<method name="CloseIC">
</method>
<method name="FocusIn">
</method>
<method name="FocusOut">
</method>
<method name="Reset">
</method>
<method name="MouseEvent">
<arg name="x" direction="in" type="i" />
</method>
<method name="SetCursorLocation">
<arg name="x" direction="in" type="i"/>
<arg name="y" direction="in" type="i"/>
</method>
<method name="SetCursorRect">
<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="SetCapacity">
<arg name="caps" direction="in" type="u"/>
</method>
<method name="SetSurroundingText">
<arg name="text" direction="in" type="s"/>
<arg name="cursor" direction="in" type="u"/>
<arg name="anchor" direction="in" type="u"/>
</method>
<method name="SetSurroundingTextPosition">
<arg name="cursor" direction="in" type="u"/>
<arg name="anchor" direction="in" type="u"/>
</method>
<method name="DestroyIC">
</method>
<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="type" direction="in" type="i"/>
<arg name="time" direction="in" type="u"/>
<arg name="ret" direction="out" type="i"/>
</method>
<signal name="EnableIM">
</signal>
<signal name="CloseIM">
</signal>
<signal name="CommitString">
<arg name="str" type="s"/>
</signal>
<signal name="UpdateFormattedPreedit">
<arg name="str" type="a(si)" />
<arg name="cursorpos" type="i"/>
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="FcitxQtFormattedPreeditList" />
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="FcitxQtFormattedPreeditList" />
</signal>
<signal name="UpdateClientSideUI">
<arg name="auxup" type="s"/>
<arg name="auxdown" type="s"/>
<arg name="preedit" type="s"/>
<arg name="candidateword" type="s"/>
<arg name="imname" type="s"/>
<arg name="cursorpos" type="i"/>
</signal>
<signal name="ForwardKey">
<arg name="keyval" type="u"/>
<arg name="state" type="u"/>
<arg name="type" type="i"/>
</signal>
<signal name="DeleteSurroundingText">
<arg name="offset" type="i"/>
<arg name="nchar" type="u"/>
</signal>
</interface>
</node>

View File

@ -0,0 +1,81 @@
<!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.fcitx.Fcitx.InputMethod">
<method name="CreateIC">
<arg name="icid" direction="out" type="i"/>
<arg name="keyval1" direction="out" type="u"/>
<arg name="state1" direction="out" type="u"/>
<arg name="keyval2" direction="out" type="u"/>
<arg name="state2" direction="out" type="u"/>
</method>
<method name="CreateICv2">
<arg name="appname" direction="in" type="s"/>
<arg name="icid" direction="out" type="i"/>
<arg name="enable" direction="out" type="b"/>
<arg name="keyval1" direction="out" type="u"/>
<arg name="state1" direction="out" type="u"/>
<arg name="keyval2" direction="out" type="u"/>
<arg name="state2" direction="out" type="u"/>
</method>
<method name="CreateICv3">
<arg name="appname" direction="in" type="s"/>
<arg name="pid" direction="in" type="i"/>
<arg name="icid" direction="out" type="i"/>
<arg name="enable" direction="out" type="b"/>
<arg name="keyval1" direction="out" type="u"/>
<arg name="state1" direction="out" type="u"/>
<arg name="keyval2" direction="out" type="u"/>
<arg name="state2" direction="out" type="u"/>
</method>
<method name="Exit">
</method>
<method name="GetCurrentIM">
<arg name="im" direction="out" type="s"/>
</method>
<method name="SetCurrentIM">
<arg name="im" direction="in" type="s"/>
</method>
<method name="ReloadConfig">
</method>
<method name="ReloadAddonConfig">
<arg name="addon" direction="in" type="s"/>
</method>
<method name="Restart">
</method>
<method name="Configure">
</method>
<method name="ConfigureAddon">
<arg name="addon" direction="in" type="s"/>
</method>
<method name="ConfigureIM">
<arg name="im" direction="in" type="s"/>
</method>
<method name="GetCurrentUI">
<arg name="addon" direction="out" type="s"/>
</method>
<method name="GetIMAddon">
<arg name="im" direction="in" type="s"/>
<arg name="addon" direction="out" type="s"/>
</method>
<method name="ActivateIM">
</method>
<method name="InactivateIM">
</method>
<method name="ToggleIM">
</method>
<method name="ResetIMList">
</method>
<method name="GetCurrentState">
<arg name="state" direction="out" type="i"/>
</method>
<property access="readwrite" type="a(sssb)" name="IMList">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
<annotation name="com.trolltech.QtDBus.QtTypeName" value="FcitxQtInputMethodItemList" />
<annotation name="org.qtproject.QtDBus.QtTypeName" value="FcitxQtInputMethodItemList" />
</property>
<property access="readwrite" type="s" name="CurrentIM">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
</property>
</interface>
</node>

View File

@ -0,0 +1,20 @@
<!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.fcitx.Fcitx.Keyboard">
<method name="GetLayouts">
<arg name="layouts" direction="out" type="a(ssss)"/>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="FcitxQtKeyboardLayoutList" />
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="FcitxQtKeyboardLayoutList" />
</method>
<method name="GetLayoutForIM">
<arg name="im" direction="in" type="s"/>
<arg name="layout" direction="out" type="s"/>
<arg name="variant" direction="out" type="s"/>
</method>
<method name="SetLayoutForIM">
<arg name="im" direction="in" type="s"/>
<arg name="layout" direction="in" type="s"/>
<arg name="variant" direction="in" type="s"/>
</method>
</interface>
</node>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,173 @@
/*
Copyright (C) 2001 Ellis Whitehead <ellis@kde.org>
Win32 port:
Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KEYSERVER_X11_H
#define KEYSERVER_X11_H
#include <X11/keysym.h>
struct TransKey {
int keySymQt;
uint keySymX;
};
static const TransKey g_rgQtToSymX[] = {
{ Qt::Key_Escape, XK_Escape },
{ Qt::Key_Tab, XK_Tab },
{ Qt::Key_Backtab, XK_ISO_Left_Tab },
{ Qt::Key_Backspace, XK_BackSpace },
{ Qt::Key_Return, XK_Return },
{ Qt::Key_Enter, XK_KP_Enter },
{ Qt::Key_Insert, XK_Insert },
{ Qt::Key_Delete, XK_Delete },
{ Qt::Key_Pause, XK_Pause },
#ifdef sun
{ Qt::Key_Print, XK_F22 },
#else
{ Qt::Key_Print, XK_Print },
#endif
{ Qt::Key_SysReq, XK_Sys_Req },
{ Qt::Key_Home, XK_Home },
{ Qt::Key_End, XK_End },
{ Qt::Key_Left, XK_Left },
{ Qt::Key_Up, XK_Up },
{ Qt::Key_Right, XK_Right },
{ Qt::Key_Down, XK_Down },
//{ Qt::Key_Shift, 0 },
//{ Qt::Key_Control, 0 },
//{ Qt::Key_Meta, 0 },
//{ Qt::Key_Alt, 0 },
{ Qt::Key_CapsLock, XK_Caps_Lock },
{ Qt::Key_NumLock, XK_Num_Lock },
{ Qt::Key_ScrollLock, XK_Scroll_Lock },
{ Qt::Key_F1, XK_F1 },
{ Qt::Key_F2, XK_F2 },
{ Qt::Key_F3, XK_F3 },
{ Qt::Key_F4, XK_F4 },
{ Qt::Key_F5, XK_F5 },
{ Qt::Key_F6, XK_F6 },
{ Qt::Key_F7, XK_F7 },
{ Qt::Key_F8, XK_F8 },
{ Qt::Key_F9, XK_F9 },
{ Qt::Key_F10, XK_F10 },
{ Qt::Key_F11, XK_F11 },
{ Qt::Key_F12, XK_F12 },
{ Qt::Key_F13, XK_F13 },
{ Qt::Key_F14, XK_F14 },
{ Qt::Key_F15, XK_F15 },
{ Qt::Key_F16, XK_F16 },
{ Qt::Key_F17, XK_F17 },
{ Qt::Key_F18, XK_F18 },
{ Qt::Key_F19, XK_F19 },
{ Qt::Key_F20, XK_F20 },
{ Qt::Key_F21, XK_F21 },
{ Qt::Key_F22, XK_F22 },
{ Qt::Key_F23, XK_F23 },
{ Qt::Key_F24, XK_F24 },
{ Qt::Key_F25, XK_F25 },
{ Qt::Key_F26, XK_F26 },
{ Qt::Key_F27, XK_F27 },
{ Qt::Key_F28, XK_F28 },
{ Qt::Key_F29, XK_F29 },
{ Qt::Key_F30, XK_F30 },
{ Qt::Key_F31, XK_F31 },
{ Qt::Key_F32, XK_F32 },
{ Qt::Key_F33, XK_F33 },
{ Qt::Key_F34, XK_F34 },
{ Qt::Key_F35, XK_F35 },
{ Qt::Key_Super_L, XK_Super_L },
{ Qt::Key_Super_R, XK_Super_R },
{ Qt::Key_Menu, XK_Menu },
{ Qt::Key_Hyper_L, XK_Hyper_L },
{ Qt::Key_Hyper_R, XK_Hyper_R },
{ Qt::Key_Help, XK_Help },
{ '/', XK_KP_Divide },
{ '*', XK_KP_Multiply },
{ '-', XK_KP_Subtract },
{ '+', XK_KP_Add },
{ Qt::Key_Return, XK_KP_Enter },
{Qt::Key_Multi_key, XK_Multi_key},
{Qt::Key_Codeinput, XK_Codeinput},
{Qt::Key_SingleCandidate, XK_SingleCandidate},
{Qt::Key_MultipleCandidate, XK_MultipleCandidate},
{Qt::Key_PreviousCandidate, XK_PreviousCandidate},
{Qt::Key_Mode_switch, XK_Mode_switch},
{Qt::Key_Kanji, XK_Kanji},
{Qt::Key_Muhenkan, XK_Muhenkan},
{Qt::Key_Henkan, XK_Henkan},
{Qt::Key_Romaji, XK_Romaji},
{Qt::Key_Hiragana, XK_Hiragana},
{Qt::Key_Katakana, XK_Katakana},
{Qt::Key_Hiragana_Katakana, XK_Hiragana_Katakana},
{Qt::Key_Zenkaku, XK_Zenkaku},
{Qt::Key_Hankaku, XK_Hankaku},
{Qt::Key_Zenkaku_Hankaku, XK_Zenkaku_Hankaku},
{Qt::Key_Touroku, XK_Touroku},
{Qt::Key_Massyo, XK_Massyo},
{Qt::Key_Kana_Lock, XK_Kana_Lock},
{Qt::Key_Kana_Shift, XK_Kana_Shift},
{Qt::Key_Eisu_Shift, XK_Eisu_Shift},
{Qt::Key_Eisu_toggle, XK_Eisu_toggle},
{Qt::Key_Hangul, XK_Hangul},
{Qt::Key_Hangul_Start, XK_Hangul_Start},
{Qt::Key_Hangul_End, XK_Hangul_End},
{Qt::Key_Hangul_Hanja, XK_Hangul_Hanja},
{Qt::Key_Hangul_Jamo, XK_Hangul_Jamo},
{Qt::Key_Hangul_Romaja, XK_Hangul_Romaja},
{Qt::Key_Hangul_Jeonja, XK_Hangul_Jeonja},
{Qt::Key_Hangul_Banja, XK_Hangul_Banja},
{Qt::Key_Hangul_PreHanja, XK_Hangul_PreHanja},
{Qt::Key_Hangul_PostHanja, XK_Hangul_PostHanja},
{Qt::Key_Hangul_Special, XK_Hangul_Special},
};
#include <qstring.h>
inline int map_sym_to_qt(uint keySym)
{
if (keySym < 0x1000) {
if (keySym >= 'a' && keySym <= 'z')
return QChar(keySym).toUpper().unicode();
return keySym;
}
#ifdef Q_WS_WIN
if (keySym < 0x3000)
return keySym;
#else
if (keySym < 0x3000)
return keySym | Qt::UNICODE_ACCEL;
for (uint i = 0; i < sizeof(g_rgQtToSymX) / sizeof(TransKey); i++)
if (g_rgQtToSymX[i].keySymX == keySym)
return g_rgQtToSymX[i].keySymQt;
#endif
return Qt::Key_unknown;
}
static bool symToKeyQt(uint keySym, int& keyQt)
{
keyQt = map_sym_to_qt(keySym);
return (keyQt != Qt::Key_unknown);
}
#endif

View File

@ -0,0 +1,56 @@
/***************************************************************************
* Copyright (C) 2012~2013 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <stdint.h>
#include "keyuni.h"
#include "keydata.h"
uint32_t
FcitxKeySymToUnicode (uint32_t keyval)
{
int min = 0;
int max = sizeof (gdk_keysym_to_unicode_tab) / sizeof(gdk_keysym_to_unicode_tab[0]) - 1;
int mid;
/* First check for Latin-1 characters (1:1 mapping) */
if ((keyval >= 0x0020 && keyval <= 0x007e) ||
(keyval >= 0x00a0 && keyval <= 0x00ff))
return keyval;
/* Also check for directly encoded 24-bit UCS characters:
*/
if ((keyval & 0xff000000) == 0x01000000)
return keyval & 0x00ffffff;
/* binary search in table */
while (max >= min) {
mid = (min + max) / 2;
if (gdk_keysym_to_unicode_tab[mid].keysym < keyval)
min = mid + 1;
else if (gdk_keysym_to_unicode_tab[mid].keysym > keyval)
max = mid - 1;
else {
/* found it */
return gdk_keysym_to_unicode_tab[mid].ucs;
}
}
/* No matching Unicode value found */
return 0;
}

View File

@ -0,0 +1,29 @@
/***************************************************************************
* Copyright (C) 2012~2013 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef KEYUNI_H
#define KEYUNI_H
#include <qglobal.h>
quint32
FcitxKeySymToUnicode (quint32 keyval);
#endif // KEYUNI_H

View File

@ -0,0 +1,35 @@
/***************************************************************************
* Copyright (C) 2012~2013 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "main.h"
QStringList QFcitxPlatformInputContextPlugin::keys() const
{
return QStringList(QStringLiteral("fcitx"));
}
QFcitxPlatformInputContext *QFcitxPlatformInputContextPlugin::create(const QString& system, const QStringList& paramList)
{
Q_UNUSED(paramList);
if (system.compare(system, QStringLiteral("fcitx"), Qt::CaseInsensitive) == 0)
return new QFcitxPlatformInputContext;
return 0;
}

View File

@ -0,0 +1,37 @@
/***************************************************************************
* Copyright (C) 2012~2013 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef MAIN_H
#define MAIN_H
#include <qpa/qplatforminputcontextplugin_p.h>
#include <QtCore/QStringList>
#include "qfcitxplatforminputcontext.h"
class QFcitxPlatformInputContextPlugin : public QPlatformInputContextPlugin
{
Q_OBJECT
public:
Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE "fcitx.json")
QStringList keys() const;
QFcitxPlatformInputContext *create(const QString& system, const QStringList& paramList);
};
#endif // MAIN_H

View File

@ -0,0 +1,770 @@
/***************************************************************************
* Copyright (C) 2011~2013 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <QKeyEvent>
#include <QDBusConnection>
#include <QGuiApplication>
#include <QInputMethod>
#include <QTextCharFormat>
#include <QPalette>
#include <QWindow>
#include <qpa/qplatformscreen.h>
#include <qpa/qplatformcursor.h>
#include <qpa/qwindowsysteminterface.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include "keyserver_x11.h"
#include "qfcitxplatforminputcontext.h"
#include "fcitxqtinputcontextproxy.h"
#include "fcitxqtinputmethodproxy.h"
#include "fcitxqtconnection.h"
#include "keyuni.h"
#include "utils.h"
static bool key_filtered = false;
static bool
get_boolean_env(const char *name,
bool defval)
{
const char *value = getenv(name);
if (value == NULL)
return defval;
if (strcmp(value, "") == 0 ||
strcmp(value, "0") == 0 ||
strcmp(value, "false") == 0 ||
strcmp(value, "False") == 0 ||
strcmp(value, "FALSE") == 0)
return false;
return true;
}
static inline const char*
get_locale()
{
const char* locale = getenv("LC_ALL");
if (!locale)
locale = getenv("LC_CTYPE");
if (!locale)
locale = getenv("LANG");
if (!locale)
locale = "C";
return locale;
}
struct xkb_context* _xkb_context_new_helper()
{
struct xkb_context* context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (context) {
xkb_context_set_log_level(context, XKB_LOG_LEVEL_CRITICAL);
}
return context;
}
QFcitxPlatformInputContext::QFcitxPlatformInputContext() :
m_connection(new FcitxQtConnection(this)),
m_improxy(0),
m_n_compose(0),
m_cursorPos(0),
m_useSurroundingText(false),
m_syncMode(true),
m_lastWId(0),
m_destroy(false),
m_xkbContext(_xkb_context_new_helper()),
m_xkbComposeTable(m_xkbContext ? xkb_compose_table_new_from_locale(m_xkbContext.data(), get_locale(), XKB_COMPOSE_COMPILE_NO_FLAGS) : 0),
m_xkbComposeState(m_xkbComposeTable ? xkb_compose_state_new(m_xkbComposeTable.data(), XKB_COMPOSE_STATE_NO_FLAGS) : 0)
{
FcitxQtFormattedPreedit::registerMetaType();
memset(m_compose_buffer, 0, sizeof(uint) * (MAX_COMPOSE_LEN + 1));
connect(m_connection, SIGNAL(connected()), this, SLOT(connected()));
connect(m_connection, SIGNAL(disconnected()), this, SLOT(cleanUp()));
m_connection->startConnection();
}
QFcitxPlatformInputContext::~QFcitxPlatformInputContext()
{
m_destroy = true;
cleanUp();
}
void QFcitxPlatformInputContext::connected()
{
if (!m_connection->isConnected())
return;
// qDebug() << "create Input Context" << m_connection->name();
if (m_improxy) {
delete m_improxy;
m_improxy = 0;
}
m_improxy = new FcitxQtInputMethodProxy(m_connection->serviceName(), QLatin1String("/inputmethod"), *m_connection->connection(), this);
QWindow* w = qApp->focusWindow();
if (w)
createICData(w);
}
void QFcitxPlatformInputContext::cleanUp()
{
for(QHash<WId, FcitxQtICData *>::const_iterator i = m_icMap.constBegin(),
e = m_icMap.constEnd(); i != e; ++i) {
FcitxQtICData* data = i.value();
if (data->proxy)
delete data->proxy;
}
m_icMap.clear();
if (m_improxy) {
delete m_improxy;
m_improxy = 0;
}
if (!m_destroy) {
commitPreedit();
}
}
bool QFcitxPlatformInputContext::isValid() const
{
return true;
}
void QFcitxPlatformInputContext::invokeAction(QInputMethod::Action action, int cursorPosition)
{
if (action == QInputMethod::Click
&& (cursorPosition <= 0 || cursorPosition >= m_preedit.length())
)
{
// qDebug() << action << cursorPosition;
commitPreedit();
}
}
void QFcitxPlatformInputContext::commitPreedit()
{
QObject *input = qApp->focusObject();
if (!input)
return;
if (m_commitPreedit.length() <= 0)
return;
QInputMethodEvent e;
e.setCommitString(m_commitPreedit);
QCoreApplication::sendEvent(input, &e);
m_commitPreedit.clear();
}
void QFcitxPlatformInputContext::reset()
{
commitPreedit();
FcitxQtInputContextProxy* proxy = validIC();
if (proxy)
proxy->Reset();
if (m_xkbComposeState) {
xkb_compose_state_reset(m_xkbComposeState.data());
}
QPlatformInputContext::reset();
}
void QFcitxPlatformInputContext::update(Qt::InputMethodQueries queries )
{
QWindow* window = qApp->focusWindow();
FcitxQtInputContextProxy* proxy = validICByWindow(window);
if (!proxy)
return;
FcitxQtICData* data = m_icMap.value(window->winId());
QInputMethod *method = qApp->inputMethod();
QObject *input = qApp->focusObject();
if (!input)
return;
QInputMethodQueryEvent query(queries);
QGuiApplication::sendEvent(input, &query);
if (queries & Qt::ImCursorRectangle) {
cursorRectChanged();
}
if (queries & Qt::ImHints) {
Qt::InputMethodHints hints = Qt::InputMethodHints(query.value(Qt::ImHints).toUInt());
#define CHECK_HINTS(_HINTS, _CAPACITY) \
if (hints & _HINTS) \
addCapacity(data, _CAPACITY); \
else \
removeCapacity(data, _CAPACITY);
CHECK_HINTS(Qt::ImhNoAutoUppercase, CAPACITY_NOAUTOUPPERCASE)
CHECK_HINTS(Qt::ImhPreferNumbers, CAPACITY_NUMBER)
CHECK_HINTS(Qt::ImhPreferUppercase, CAPACITY_UPPERCASE)
CHECK_HINTS(Qt::ImhPreferLowercase, CAPACITY_LOWERCASE)
CHECK_HINTS(Qt::ImhNoPredictiveText, CAPACITY_NO_SPELLCHECK)
CHECK_HINTS(Qt::ImhDigitsOnly, CAPACITY_DIGIT)
CHECK_HINTS(Qt::ImhFormattedNumbersOnly, CAPACITY_NUMBER)
CHECK_HINTS(Qt::ImhUppercaseOnly, CAPACITY_UPPERCASE)
CHECK_HINTS(Qt::ImhLowercaseOnly, CAPACITY_LOWERCASE)
CHECK_HINTS(Qt::ImhDialableCharactersOnly, CAPACITY_DIALABLE)
CHECK_HINTS(Qt::ImhEmailCharactersOnly, CAPACITY_EMAIL)
}
bool setSurrounding = false;
do {
if (!m_useSurroundingText)
break;
if (!((queries & Qt::ImSurroundingText) && (queries & Qt::ImCursorPosition)))
break;
if (data->capacity.testFlag(CAPACITY_PASSWORD))
break;
QVariant var = query.value(Qt::ImSurroundingText);
QVariant var1 = query.value(Qt::ImCursorPosition);
QVariant var2 = query.value(Qt::ImAnchorPosition);
if (!var.isValid() || !var1.isValid())
break;
QString text = var.toString();
/* we don't want to waste too much memory here */
#define SURROUNDING_THRESHOLD 4096
if (text.length() < SURROUNDING_THRESHOLD) {
if (_utf8_check_string(text.toUtf8().data())) {
addCapacity(data, CAPACITY_SURROUNDING_TEXT);
int cursor = var1.toInt();
int anchor;
if (var2.isValid())
anchor = var2.toInt();
else
anchor = cursor;
if (data->surroundingText != text) {
data->surroundingText = text;
proxy->SetSurroundingText(text, cursor, anchor);
}
else {
if (data->surroundingAnchor != anchor ||
data->surroundingCursor != cursor)
proxy->SetSurroundingTextPosition(cursor, anchor);
}
data->surroundingCursor = cursor;
data->surroundingAnchor = anchor;
setSurrounding = true;
}
}
if (!setSurrounding) {
data->surroundingAnchor = -1;
data->surroundingCursor = -1;
data->surroundingText = QString::null;
removeCapacity(data, CAPACITY_SURROUNDING_TEXT);
}
} while(0);
}
void QFcitxPlatformInputContext::commit()
{
QPlatformInputContext::commit();
}
void QFcitxPlatformInputContext::setFocusObject(QObject* object)
{
FcitxQtInputContextProxy* proxy = validICByWId(m_lastWId);
if (proxy) {
proxy->FocusOut();
}
QWindow *window = qApp->focusWindow();
if (window) {
m_lastWId = window->winId();
} else {
m_lastWId = 0;
return;
}
proxy = validICByWindow(window);
if (proxy)
proxy->FocusIn();
else {
FcitxQtICData* data = m_icMap.value(window->winId());
if (!data) {
createICData(window);
return;
}
}
}
void QFcitxPlatformInputContext::windowDestroyed(QObject* object)
{
/* access QWindow is not possible here, so we use our own map to do so */
WId wid = m_windowToWidMap.take(object);
if (!wid)
return;
FcitxQtICData* data = m_icMap.take(wid);
if (!data)
return;
delete data;
// qDebug() << "Window Destroyed and we destroy IC correctly, horray!";
}
void QFcitxPlatformInputContext::cursorRectChanged()
{
QWindow *inputWindow = qApp->focusWindow();
if (!inputWindow)
return;
FcitxQtInputContextProxy* proxy = validICByWindow(inputWindow);
if (!proxy)
return;
FcitxQtICData* data = m_icMap.value(inputWindow->winId());
QRect r = qApp->inputMethod()->cursorRectangle().toRect();
if(!r.isValid())
return;
r.moveTopLeft(inputWindow->mapToGlobal(r.topLeft()));
qreal scale = inputWindow->devicePixelRatio();
if (data->rect != r) {
data->rect = r;
proxy->SetCursorRect(r.x() * scale, r.y() * scale,
r.width() * scale, r.height() * scale);
}
}
void QFcitxPlatformInputContext::createInputContext(WId w)
{
if (!m_connection->isConnected())
return;
// qDebug() << "create Input Context" << m_connection->connection()->name();
if (m_improxy) {
delete m_improxy;
m_improxy = NULL;
}
m_improxy = new FcitxQtInputMethodProxy(m_connection->serviceName(), QLatin1String("/inputmethod"), *m_connection->connection(), this);
if (!m_improxy->isValid())
return;
QFileInfo info(QCoreApplication::applicationFilePath());
QDBusPendingReply< int, bool, uint, uint, uint, uint > result = m_improxy->CreateICv3(info.fileName(), QCoreApplication::applicationPid());
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(result);
watcher->setProperty("wid", (qulonglong) w);
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(createInputContextFinished(QDBusPendingCallWatcher*)));
}
void QFcitxPlatformInputContext::createInputContextFinished(QDBusPendingCallWatcher* watcher)
{
WId w = watcher->property("wid").toULongLong();
FcitxQtICData* data = m_icMap.value(w);
if (!data)
return;
QDBusPendingReply< int, bool, uint, uint, uint, uint > result = *watcher;
do {
if (result.isError()) {
break;
}
if (!m_connection->isConnected())
break;
int id = qdbus_cast<int>(result.argumentAt(0));
QString path = QString("/inputcontext_%1").arg(id);
if (data->proxy) {
delete data->proxy;
}
data->proxy = new FcitxQtInputContextProxy(m_connection->serviceName(), path, *m_connection->connection(), this);
connect(data->proxy, SIGNAL(CommitString(QString)), this, SLOT(commitString(QString)));
connect(data->proxy, SIGNAL(ForwardKey(uint, uint, int)), this, SLOT(forwardKey(uint, uint, int)));
connect(data->proxy, SIGNAL(UpdateFormattedPreedit(FcitxQtFormattedPreeditList,int)), this, SLOT(updateFormattedPreedit(FcitxQtFormattedPreeditList,int)));
connect(data->proxy, SIGNAL(DeleteSurroundingText(int,uint)), this, SLOT(deleteSurroundingText(int,uint)));
if (data->proxy->isValid()) {
QWindow* window = qApp->focusWindow();
if (window && window->winId() == w)
data->proxy->FocusIn();
}
QFlags<FcitxCapacityFlags> flag;
flag |= CAPACITY_PREEDIT;
flag |= CAPACITY_FORMATTED_PREEDIT;
flag |= CAPACITY_CLIENT_UNFOCUS_COMMIT;
m_useSurroundingText = get_boolean_env("FCITX_QT_ENABLE_SURROUNDING_TEXT", true);
if (m_useSurroundingText)
flag |= CAPACITY_SURROUNDING_TEXT;
/*
* event loop will cause some problem, so we tries to use async way.
*/
m_syncMode = get_boolean_env("FCITX_QT_USE_SYNC", false);
addCapacity(data, flag, true);
} while(0);
delete watcher;
}
void QFcitxPlatformInputContext::updateCapacity(FcitxQtICData* data)
{
if (!data->proxy || !data->proxy->isValid())
return;
QDBusPendingReply< void > result = data->proxy->SetCapacity((uint) data->capacity);
}
void QFcitxPlatformInputContext::commitString(const QString& str)
{
m_cursorPos = 0;
m_preeditList.clear();
m_commitPreedit.clear();
QObject *input = qApp->focusObject();
if (!input)
return;
QInputMethodEvent event;
event.setCommitString(str);
QCoreApplication::sendEvent(input, &event);
}
void QFcitxPlatformInputContext::updateFormattedPreedit(const FcitxQtFormattedPreeditList& preeditList, int cursorPos)
{
QObject *input = qApp->focusObject();
if (!input)
return;
if (cursorPos == m_cursorPos && preeditList == m_preeditList)
return;
m_preeditList = preeditList;
m_cursorPos = cursorPos;
QString str, commitStr;
int pos = 0;
QList<QInputMethodEvent::Attribute> attrList;
Q_FOREACH(const FcitxQtFormattedPreedit& preedit, preeditList)
{
str += preedit.string();
if (!(preedit.format() & MSG_DONOT_COMMIT_WHEN_UNFOCUS))
commitStr += preedit.string();
QTextCharFormat format;
if ((preedit.format() & MSG_NOUNDERLINE) == 0) {
format.setUnderlineStyle(QTextCharFormat::DashUnderline);
}
if (preedit.format() & MSG_HIGHLIGHT) {
QBrush brush;
QPalette palette;
palette = QGuiApplication::palette();
format.setBackground(QBrush(QColor(palette.color(QPalette::Active, QPalette::Highlight))));
format.setForeground(QBrush(QColor(palette.color(QPalette::Active, QPalette::HighlightedText))));
}
attrList.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, pos, preedit.string().length(), format));
pos += preedit.string().length();
}
QByteArray array = str.toUtf8();
array.truncate(cursorPos);
cursorPos = QString::fromUtf8(array).length();
attrList.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, 1, 0));
m_preedit = str;
m_commitPreedit = commitStr;
QInputMethodEvent event(str, attrList);
QCoreApplication::sendEvent(input, &event);
update(Qt::ImCursorRectangle);
}
void QFcitxPlatformInputContext::deleteSurroundingText(int offset, uint nchar)
{
QObject *input = qApp->focusObject();
if (!input)
return;
QInputMethodEvent event;
event.setCommitString("", offset, nchar);
QCoreApplication::sendEvent(input, &event);
}
void QFcitxPlatformInputContext::forwardKey(uint keyval, uint state, int type)
{
QObject *input = qApp->focusObject();
if (input != NULL) {
key_filtered = true;
QKeyEvent *keyevent = createKeyEvent(keyval, state, type);
QCoreApplication::sendEvent(input, keyevent);
delete keyevent;
key_filtered = false;
}
}
void QFcitxPlatformInputContext::createICData(QWindow* w)
{
FcitxQtICData* data = m_icMap.value(w->winId());
if (!data) {
data = new FcitxQtICData;
m_icMap[w->winId()] = data;
m_windowToWidMap[w] = w->winId();
connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*)));
}
createInputContext(w->winId());
}
QKeyEvent* QFcitxPlatformInputContext::createKeyEvent(uint keyval, uint state, int type)
{
Qt::KeyboardModifiers qstate = Qt::NoModifier;
int count = 1;
if (state & FcitxKeyState_Alt) {
qstate |= Qt::AltModifier;
count ++;
}
if (state & FcitxKeyState_Shift) {
qstate |= Qt::ShiftModifier;
count ++;
}
if (state & FcitxKeyState_Ctrl) {
qstate |= Qt::ControlModifier;
count ++;
}
int key;
symToKeyQt(keyval, key);
QKeyEvent* keyevent = new QKeyEvent(
(type == FCITX_PRESS_KEY) ? (QEvent::KeyPress) : (QEvent::KeyRelease),
key,
qstate,
QString(),
false,
count
);
return keyevent;
}
bool QFcitxPlatformInputContext::filterEvent(const QEvent* event)
{
do {
if (event->type() != QEvent::KeyPress && event->type() != QEvent::KeyRelease) {
break;
}
const QKeyEvent* keyEvent = static_cast<const QKeyEvent*>(event);
quint32 keyval = keyEvent->nativeVirtualKey();
quint32 keycode = keyEvent->nativeScanCode();
quint32 state = keyEvent->nativeModifiers();
bool press = keyEvent->type() == QEvent::KeyPress;
if (key_filtered) {
break;
}
if (!inputMethodAccepted())
break;
QObject *input = qApp->focusObject();
if (!input) {
break;
}
FcitxQtInputContextProxy* proxy = validICByWindow(qApp->focusWindow());
if (!proxy) {
if (filterEventFallback(keyval, keycode, state, press)) {
return true;
} else {
break;
}
}
proxy->FocusIn();
QDBusPendingReply< int > reply = proxy->ProcessKeyEvent(keyval,
keycode,
state,
(press) ? FCITX_PRESS_KEY : FCITX_RELEASE_KEY,
QDateTime::currentDateTime().toTime_t());
if (Q_UNLIKELY(m_syncMode)) {
reply.waitForFinished();
if (!m_connection->isConnected() || !reply.isFinished() || reply.isError() || reply.value() <= 0) {
if (filterEventFallback(keyval, keycode, state, press)) {
return true;
} else {
break;
}
} else {
update(Qt::ImCursorRectangle);
return true;
}
}
else {
ProcessKeyWatcher* watcher = new ProcessKeyWatcher(*keyEvent, qApp->focusWindow(), reply, this);
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
this, SLOT(processKeyEventFinished(QDBusPendingCallWatcher*)));
return true;
}
} while(0);
return QPlatformInputContext::filterEvent(event);
}
void QFcitxPlatformInputContext::processKeyEventFinished(QDBusPendingCallWatcher* w)
{
ProcessKeyWatcher* watcher = static_cast<ProcessKeyWatcher*>(w);
QDBusPendingReply< int > result(*watcher);
bool filtered = false;
QWindow* window = watcher->window();
// if window is already destroyed, we can only throw this event away.
if (!window) {
return;
}
const QKeyEvent& keyEvent = watcher->event();
// use same variable name as in QXcbKeyboard::handleKeyEvent
QEvent::Type type = keyEvent.type();
int qtcode = keyEvent.key();
Qt::KeyboardModifiers modifiers = keyEvent.modifiers();
quint32 code = keyEvent.nativeScanCode();
quint32 sym = keyEvent.nativeVirtualKey();
quint32 state = keyEvent.nativeModifiers();
QString string = keyEvent.text();
bool isAutoRepeat = keyEvent.isAutoRepeat();
ulong time = keyEvent.timestamp();
if (result.isError() || result.value() <= 0) {
filtered = filterEventFallback(sym, code, state, type == QEvent::KeyPress);
} else {
filtered = true;
}
if (!result.isError()) {
update(Qt::ImCursorRectangle);
}
if (!filtered) {
// copied from QXcbKeyboard::handleKeyEvent()
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
const QPoint pos = window->mapFromGlobal(globalPos); QWindowSystemInterface::handleContextMenuEvent(window, false, pos, globalPos, modifiers);
}
QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
code, sym, state, string, isAutoRepeat);
}
delete watcher;
}
bool QFcitxPlatformInputContext::filterEventFallback(uint keyval, uint keycode, uint state, bool press)
{
Q_UNUSED(keycode);
if (processCompose(keyval, state, (press) ? FCITX_PRESS_KEY : FCITX_RELEASE_KEY)) {
return true;
}
return false;
}
FcitxQtInputContextProxy* QFcitxPlatformInputContext::validIC()
{
if (m_icMap.isEmpty()) {
return 0;
}
QWindow* window = qApp->focusWindow();
return validICByWindow(window);
}
FcitxQtInputContextProxy* QFcitxPlatformInputContext::validICByWId(WId wid)
{
if (m_icMap.isEmpty()) {
return 0;
}
FcitxQtICData* icData = m_icMap.value(wid);
if (!icData)
return 0;
if (icData->proxy.isNull()) {
return 0;
} else if (icData->proxy->isValid()) {
return icData->proxy.data();
}
return 0;
}
FcitxQtInputContextProxy* QFcitxPlatformInputContext::validICByWindow(QWindow* w)
{
if (!w) {
return 0;
}
if (m_icMap.isEmpty()) {
return 0;
}
return validICByWId(w->winId());
}
bool QFcitxPlatformInputContext::processCompose(uint keyval, uint state, FcitxKeyEventType event)
{
Q_UNUSED(state);
if (!m_xkbComposeTable || event == FCITX_RELEASE_KEY)
return false;
struct xkb_compose_state* xkbComposeState = m_xkbComposeState.data();
enum xkb_compose_feed_result result = xkb_compose_state_feed(xkbComposeState, keyval);
if (result == XKB_COMPOSE_FEED_IGNORED) {
return false;
}
enum xkb_compose_status status = xkb_compose_state_get_status(xkbComposeState);
if (status == XKB_COMPOSE_NOTHING) {
return 0;
} else if (status == XKB_COMPOSE_COMPOSED) {
char buffer[] = {'\0', '\0', '\0', '\0', '\0', '\0', '\0'};
int length = xkb_compose_state_get_utf8(xkbComposeState, buffer, sizeof(buffer));
xkb_compose_state_reset(xkbComposeState);
if (length != 0) {
commitString(QString::fromUtf8(buffer));
}
} else if (status == XKB_COMPOSE_CANCELLED) {
xkb_compose_state_reset(xkbComposeState);
}
return true;
}
// kate: indent-mode cstyle; space-indent on; indent-width 0;

View File

@ -0,0 +1,269 @@
/***************************************************************************
* Copyright (C) 2012~2013 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef QFCITXPLATFORMINPUTCONTEXT_H
#define QFCITXPLATFORMINPUTCONTEXT_H
#include <qpa/qplatforminputcontext.h>
#include <QWindow>
#include <QKeyEvent>
#include <QDBusConnection>
#include <QDBusServiceWatcher>
#include <QPointer>
#include <QFileSystemWatcher>
#include <QRect>
#include <xkbcommon/xkbcommon-compose.h>
#include "fcitxqtformattedpreedit.h"
#include "fcitxqtinputcontextproxy.h"
#define MAX_COMPOSE_LEN 7
class FcitxQtConnection;
class QFileSystemWatcher;
enum FcitxKeyEventType {
FCITX_PRESS_KEY,
FCITX_RELEASE_KEY
};
enum FcitxCapacityFlags {
CAPACITY_NONE = 0,
CAPACITY_CLIENT_SIDE_UI = (1 << 0),
CAPACITY_PREEDIT = (1 << 1),
CAPACITY_CLIENT_SIDE_CONTROL_STATE = (1 << 2),
CAPACITY_PASSWORD = (1 << 3),
CAPACITY_FORMATTED_PREEDIT = (1 << 4),
CAPACITY_CLIENT_UNFOCUS_COMMIT = (1 << 5),
CAPACITY_SURROUNDING_TEXT = (1 << 6),
CAPACITY_EMAIL = (1 << 7),
CAPACITY_DIGIT = (1 << 8),
CAPACITY_UPPERCASE = (1 << 9),
CAPACITY_LOWERCASE = (1 << 10),
CAPACITY_NOAUTOUPPERCASE = (1 << 11),
CAPACITY_URL = (1 << 12),
CAPACITY_DIALABLE = (1 << 13),
CAPACITY_NUMBER = (1 << 14),
CAPACITY_NO_ON_SCREEN_KEYBOARD = (1 << 15),
CAPACITY_SPELLCHECK = (1 << 16),
CAPACITY_NO_SPELLCHECK = (1 << 17),
CAPACITY_WORD_COMPLETION = (1 << 18),
CAPACITY_UPPERCASE_WORDS = (1 << 19),
CAPACITY_UPPERCASE_SENTENCES = (1 << 20),
CAPACITY_ALPHA = (1 << 21),
CAPACITY_NAME = (1 << 22)
} ;
/** message type and flags */
enum FcitxMessageType {
MSG_TYPE_FIRST = 0,
MSG_TYPE_LAST = 6,
MSG_TIPS = 0, /**< Hint Text */
MSG_INPUT = 1, /**< User Input */
MSG_INDEX = 2, /**< Index Number */
MSG_FIRSTCAND = 3, /**< First candidate */
MSG_USERPHR = 4, /**< User Phrase */
MSG_CODE = 5, /**< Typed character */
MSG_OTHER = 6, /**< Other Text */
MSG_NOUNDERLINE = (1 << 3), /**< backward compatible, no underline is a flag */
MSG_HIGHLIGHT = (1 << 4), /**< highlight the preedit */
MSG_DONOT_COMMIT_WHEN_UNFOCUS = (1 << 5), /**< backward compatible */
MSG_REGULAR_MASK = 0x7 /**< regular color type mask */
};
enum FcitxKeyState {
FcitxKeyState_None = 0,
FcitxKeyState_Shift = 1 << 0,
FcitxKeyState_CapsLock = 1 << 1,
FcitxKeyState_Ctrl = 1 << 2,
FcitxKeyState_Alt = 1 << 3,
FcitxKeyState_Alt_Shift = FcitxKeyState_Alt | FcitxKeyState_Shift,
FcitxKeyState_Ctrl_Shift = FcitxKeyState_Ctrl | FcitxKeyState_Shift,
FcitxKeyState_Ctrl_Alt = FcitxKeyState_Ctrl | FcitxKeyState_Alt,
FcitxKeyState_Ctrl_Alt_Shift = FcitxKeyState_Ctrl | FcitxKeyState_Alt | FcitxKeyState_Shift,
FcitxKeyState_NumLock = 1 << 4,
FcitxKeyState_Super = 1 << 6,
FcitxKeyState_ScrollLock = 1 << 7,
FcitxKeyState_MousePressed = 1 << 8,
FcitxKeyState_HandledMask = 1 << 24,
FcitxKeyState_IgnoredMask = 1 << 25,
FcitxKeyState_Super2 = 1 << 26,
FcitxKeyState_Hyper = 1 << 27,
FcitxKeyState_Meta = 1 << 28,
FcitxKeyState_UsedMask = 0x5c001fff
};
struct FcitxQtICData {
FcitxQtICData() : capacity(0), proxy(0), surroundingAnchor(-1), surroundingCursor(-1) {}
~FcitxQtICData() {
if (proxy && proxy->isValid()) {
proxy->DestroyIC();
delete proxy;
}
}
QFlags<FcitxCapacityFlags> capacity;
QPointer<FcitxQtInputContextProxy> proxy;
QRect rect;
QString surroundingText;
int surroundingAnchor;
int surroundingCursor;
};
class ProcessKeyWatcher : public QDBusPendingCallWatcher
{
Q_OBJECT
public:
ProcessKeyWatcher(const QKeyEvent& event, QWindow* window, const QDBusPendingCall &call, QObject *parent = 0) :
QDBusPendingCallWatcher(call, parent)
,m_event(event.type(), event.key(), event.modifiers(),
event.nativeScanCode(), event.nativeVirtualKey(), event.nativeModifiers(),
event.text(), event.isAutoRepeat(), event.count())
,m_window(window)
{
}
virtual ~ProcessKeyWatcher() {
}
const QKeyEvent& event() {
return m_event;
}
QWindow* window() {
return m_window.data();
}
private:
QKeyEvent m_event;
QPointer<QWindow> m_window;
};
struct XkbContextDeleter
{
static inline void cleanup(struct xkb_context* pointer)
{
if (pointer) xkb_context_unref(pointer);
}
};
struct XkbComposeTableDeleter
{
static inline void cleanup(struct xkb_compose_table* pointer)
{
if (pointer) xkb_compose_table_unref(pointer);
}
};
struct XkbComposeStateDeleter
{
static inline void cleanup(struct xkb_compose_state* pointer)
{
if (pointer) xkb_compose_state_unref(pointer);
}
};
class FcitxQtInputMethodProxy;
class QFcitxPlatformInputContext : public QPlatformInputContext
{
Q_OBJECT
public:
QFcitxPlatformInputContext();
virtual ~QFcitxPlatformInputContext();
virtual bool filterEvent(const QEvent* event);
virtual bool isValid() const;
virtual void invokeAction(QInputMethod::Action , int cursorPosition);
virtual void reset();
virtual void commit();
virtual void update(Qt::InputMethodQueries quries );
virtual void setFocusObject(QObject* object);
public Q_SLOTS:
void cursorRectChanged();
void commitString(const QString& str);
void updateFormattedPreedit(const FcitxQtFormattedPreeditList& preeditList, int cursorPos);
void deleteSurroundingText(int offset, uint nchar);
void forwardKey(uint keyval, uint state, int type);
void createInputContextFinished(QDBusPendingCallWatcher* watcher);
void connected();
void cleanUp();
void windowDestroyed(QObject* object);
private:
void createInputContext(WId w);
bool processCompose(uint keyval, uint state, FcitxKeyEventType event);
bool checkAlgorithmically();
bool checkCompactTable(const struct _FcitxComposeTableCompact *table);
QKeyEvent* createKeyEvent(uint keyval, uint state, int type);
void addCapacity(FcitxQtICData* data, QFlags<FcitxCapacityFlags> capacity, bool forceUpdate = false)
{
QFlags< FcitxCapacityFlags > newcaps = data->capacity | capacity;
if (data->capacity != newcaps || forceUpdate) {
data->capacity = newcaps;
updateCapacity(data);
}
}
void removeCapacity(FcitxQtICData* data, QFlags<FcitxCapacityFlags> capacity, bool forceUpdate = false)
{
QFlags< FcitxCapacityFlags > newcaps = data->capacity & (~capacity);
if (data->capacity != newcaps || forceUpdate) {
data->capacity = newcaps;
updateCapacity(data);
}
}
void updateCapacity(FcitxQtICData* data);
void commitPreedit();
void createICData(QWindow* w);
FcitxQtInputContextProxy* validIC();
FcitxQtInputContextProxy* validICByWindow(QWindow* window);
FcitxQtInputContextProxy* validICByWId(WId wid);
bool filterEventFallback(uint keyval, uint keycode, uint state, bool press);
FcitxQtInputMethodProxy* m_improxy;
uint m_compose_buffer[MAX_COMPOSE_LEN + 1];
int m_n_compose;
QString m_preedit;
QString m_commitPreedit;
FcitxQtFormattedPreeditList m_preeditList;
int m_cursorPos;
bool m_useSurroundingText;
bool m_syncMode;
FcitxQtConnection* m_connection;
QString m_lastSurroundingText;
int m_lastSurroundingAnchor;
int m_lastSurroundingCursor;
QHash<WId, FcitxQtICData*> m_icMap;
QHash<QObject*, WId> m_windowToWidMap;
WId m_lastWId;
bool m_destroy;
QScopedPointer<struct xkb_context, XkbContextDeleter> m_xkbContext;
QScopedPointer<struct xkb_compose_table, XkbComposeTableDeleter> m_xkbComposeTable;
QScopedPointer<struct xkb_compose_state, XkbComposeStateDeleter> m_xkbComposeState;
private slots:
void processKeyEventFinished(QDBusPendingCallWatcher*);
};
#endif // QFCITXPLATFORMINPUTCONTEXT_H

View File

@ -0,0 +1,177 @@
/***************************************************************************
* Copyright (C) 2012~2013 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "utils.h"
/** check utf8 character */
#define ISUTF8_CB(c) (((c)&0xc0) == 0x80)
#define CONT(i) ISUTF8_CB(in[i])
#define VAL(i, s) ((in[i]&0x3f) << s)
#define UTF8_LENGTH(Char) \
((Char) < 0x80 ? 1 : \
((Char) < 0x800 ? 2 : \
((Char) < 0x10000 ? 3 : \
((Char) < 0x200000 ? 4 : \
((Char) < 0x4000000 ? 5 : 6)))))
#define UNICODE_VALID(Char) \
((Char) < 0x110000 && \
(((Char) & 0xFFFFF800) != 0xD800) && \
((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
((Char) & 0xFFFE) != 0xFFFE)
int
_utf8_get_char_extended(const char *s,
int max_len)
{
const unsigned char*p = (const unsigned char*)s;
int i, len;
unsigned int wc = (unsigned char) * p;
if (wc < 0x80) {
return wc;
} else if (wc < 0xc0) {
return (unsigned int) - 1;
} else if (wc < 0xe0) {
len = 2;
wc &= 0x1f;
} else if (wc < 0xf0) {
len = 3;
wc &= 0x0f;
} else if (wc < 0xf8) {
len = 4;
wc &= 0x07;
} else if (wc < 0xfc) {
len = 5;
wc &= 0x03;
} else if (wc < 0xfe) {
len = 6;
wc &= 0x01;
} else {
return (unsigned int) - 1;
}
if (max_len >= 0 && len > max_len) {
for (i = 1; i < max_len; i++) {
if ((((unsigned char *)p)[i] & 0xc0) != 0x80)
return (unsigned int) - 1;
}
return (unsigned int) - 2;
}
for (i = 1; i < len; ++i) {
unsigned int ch = ((unsigned char *)p)[i];
if ((ch & 0xc0) != 0x80) {
if (ch)
return (unsigned int) - 1;
else
return (unsigned int) - 2;
}
wc <<= 6;
wc |= (ch & 0x3f);
}
if (UTF8_LENGTH(wc) != len)
return (unsigned int) - 1;
return wc;
}
int _utf8_get_char_validated(const char *p,
int max_len)
{
int result;
if (max_len == 0)
return -2;
result = _utf8_get_char_extended(p, max_len);
if (result & 0x80000000)
return result;
else if (!UNICODE_VALID(result))
return -1;
else
return result;
}
char *
_utf8_get_char(const char *i, uint32_t *chr)
{
const unsigned char* in = (const unsigned char *)i;
if (!(in[0] & 0x80)) {
*(chr) = *(in);
return (char *)in + 1;
}
/* 2-byte, 0x80-0x7ff */
if ((in[0] & 0xe0) == 0xc0 && CONT(1)) {
*chr = ((in[0] & 0x1f) << 6) | VAL(1, 0);
return (char *)in + 2;
}
/* 3-byte, 0x800-0xffff */
if ((in[0] & 0xf0) == 0xe0 && CONT(1) && CONT(2)) {
*chr = ((in[0] & 0xf) << 12) | VAL(1, 6) | VAL(2, 0);
return (char *)in + 3;
}
/* 4-byte, 0x10000-0x1FFFFF */
if ((in[0] & 0xf8) == 0xf0 && CONT(1) && CONT(2) && CONT(3)) {
*chr = ((in[0] & 0x7) << 18) | VAL(1, 12) | VAL(2, 6) | VAL(3, 0);
return (char *)in + 4;
}
/* 5-byte, 0x200000-0x3FFFFFF */
if ((in[0] & 0xfc) == 0xf8 && CONT(1) && CONT(2) && CONT(3) && CONT(4)) {
*chr = ((in[0] & 0x3) << 24) | VAL(1, 18) | VAL(2, 12) | VAL(3, 6) | VAL(4, 0);
return (char *)in + 5;
}
/* 6-byte, 0x400000-0x7FFFFFF */
if ((in[0] & 0xfe) == 0xfc && CONT(1) && CONT(2) && CONT(3) && CONT(4) && CONT(5)) {
*chr = ((in[0] & 0x1) << 30) | VAL(1, 24) | VAL(2, 18) | VAL(3, 12) | VAL(4, 6) | VAL(5, 0);
return (char *)in + 6;
}
*chr = *in;
return (char *)in + 1;
}
int _utf8_check_string(const char *s)
{
while (*s) {
uint32_t chr;
if (_utf8_get_char_validated(s, 6) < 0)
return 0;
s = _utf8_get_char(s, &chr);
}
return 1;
}

View File

@ -0,0 +1,35 @@
/***************************************************************************
* Copyright (C) 2012~2013 by CSSlayer *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef UTILS_H
#define UTILS_H
#include <stdint.h>
int
_utf8_get_char_extended(const char *s,
int max_len);
int _utf8_get_char_validated(const char *p,
int max_len);
char *
_utf8_get_char(const char *i, uint32_t *chr);
int _utf8_check_string(const char *s);
#endif // UTILS_H

View File

@ -0,0 +1,98 @@
/*
* Copyright © 2012 Daniel Stone
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Daniel Stone <daniel@fooishbar.org>
*/
#ifndef _XKBCOMMON_COMPAT_H
#define _XKBCOMMON_COMPAT_H
/**
* Renamed keymap API.
*/
#define xkb_group_index_t xkb_layout_index_t
#define xkb_group_mask_t xkb_layout_mask_t
#define xkb_map_compile_flags xkb_keymap_compile_flags
#define XKB_GROUP_INVALID XKB_LAYOUT_INVALID
#define XKB_STATE_DEPRESSED \
(XKB_STATE_MODS_DEPRESSED | XKB_STATE_LAYOUT_DEPRESSED)
#define XKB_STATE_LATCHED \
(XKB_STATE_MODS_LATCHED | XKB_STATE_LAYOUT_LATCHED)
#define XKB_STATE_LOCKED \
(XKB_STATE_MODS_LOCKED | XKB_STATE_LAYOUT_LOCKED)
#define XKB_STATE_EFFECTIVE \
(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED | \
XKB_STATE_MODS_EFFECTIVE | XKB_STATE_LAYOUT_EFFECTIVE)
#define xkb_map_new_from_names(context, names, flags) \
xkb_keymap_new_from_names(context, names, flags)
#define xkb_map_new_from_file(context, file, format, flags) \
xkb_keymap_new_from_file(context, file, format, flags)
#define xkb_map_new_from_string(context, string, format, flags) \
xkb_keymap_new_from_string(context, string, format, flags)
#define xkb_map_get_as_string(keymap) \
xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1)
#define xkb_map_ref(keymap) xkb_keymap_ref(keymap)
#define xkb_map_unref(keymap) xkb_keymap_unref(keymap)
#define xkb_map_num_mods(keymap) xkb_keymap_num_mods(keymap)
#define xkb_map_mod_get_name(keymap, idx) xkb_keymap_mod_get_name(keymap, idx)
#define xkb_map_mod_get_index(keymap, str) xkb_keymap_mod_get_index(keymap, str)
#define xkb_key_mod_index_is_consumed(state, key, mod) \
xkb_state_mod_index_is_consumed(state, key, mod)
#define xkb_key_mod_mask_remove_consumed(state, key, modmask) \
xkb_state_mod_mask_remove_consumed(state, key, modmask)
#define xkb_map_num_groups(keymap) xkb_keymap_num_layouts(keymap)
#define xkb_key_num_groups(keymap, key) \
xkb_keymap_num_layouts_for_key(keymap, key)
#define xkb_map_group_get_name(keymap, idx) \
xkb_keymap_layout_get_name(keymap, idx)
#define xkb_map_group_get_index(keymap, str) \
xkb_keymap_layout_get_index(keymap, str)
#define xkb_map_num_leds(keymap) xkb_keymap_num_leds(keymap)
#define xkb_map_led_get_name(keymap, idx) xkb_keymap_led_get_name(keymap, idx)
#define xkb_map_led_get_index(keymap, str) \
xkb_keymap_led_get_index(keymap, str)
#define xkb_key_repeats(keymap, key) xkb_keymap_key_repeats(keymap, key)
#define xkb_key_get_syms(state, key, syms_out) \
xkb_state_key_get_syms(state, key, syms_out)
#define xkb_state_group_name_is_active(state, name, type) \
xkb_state_layout_name_is_active(state, name, type)
#define xkb_state_group_index_is_active(state, idx, type) \
xkb_state_layout_index_is_active(state, idx, type)
#define xkb_state_serialize_group(state, component) \
xkb_state_serialize_layout(state, component)
#define xkb_state_get_map(state) xkb_state_get_keymap(state)
/* Not needed anymore, since there's NO_FLAGS. */
#define XKB_MAP_COMPILE_PLACEHOLDER XKB_KEYMAP_COMPILE_NO_FLAGS
#define XKB_MAP_COMPILE_NO_FLAGS XKB_KEYMAP_COMPILE_NO_FLAGS
#endif

View File

@ -0,0 +1,488 @@
/*
* Copyright © 2013 Ran Benita
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _XKBCOMMON_COMPOSE_H
#define _XKBCOMMON_COMPOSE_H
#include <xkbcommon/xkbcommon.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file
* libxkbcommon Compose API - support for Compose and dead-keys.
*/
/**
* @defgroup compose Compose and dead-keys support
* Support for Compose and dead-keys.
* @since 0.5.0
*
* @{
*/
/**
* @page compose-overview Overview
* @parblock
*
* Compose and dead-keys are a common feature of many keyboard input
* systems. They extend the range of the keysysm that can be produced
* directly from a keyboard by using a sequence of key strokes, instead
* of just one.
*
* Here are some example sequences, in the libX11 Compose file format:
*
* <dead_acute> <a> : "á" aacute # LATIN SMALL LETTER A WITH ACUTE
* <Multi_key> <A> <T> : "@" at # COMMERCIAL AT
*
* When the user presses a key which produces the `<dead_acute>` keysym,
* nothing initially happens (thus the key is dubbed a "dead-key"). But
* when the user enters `<a>`, "á" is "composed", in place of "a". If
* instead the user had entered a keysym which does not follow
* `<dead_acute>` in any compose sequence, the sequence is said to be
* "cancelled".
*
* Compose files define many such sequences. For a description of the
* common file format for Compose files, see the Compose(5) man page.
*
* A successfuly-composed sequence has two results: a keysym and a UTF-8
* string. At least one of the two is defined for each sequence. If only
* a keysym is given, the keysym's string representation is used for the
* result string (using xkb_keysym_to_utf8()).
*
* This library provides low-level support for Compose file parsing and
* processing. Higher-level APIs (such as libX11's `Xutf8LookupString`(3))
* may be built upon it, or it can be used directly.
*
* @endparblock
*/
/**
* @page compose-conflicting Conflicting Sequences
* @parblock
*
* To avoid ambiguity, a sequence is not allowed to be a prefix of another.
* In such a case, the conflict is resolved thus:
*
* 1. A longer sequence overrides a shorter one.
* 2. An equal sequence overrides an existing one.
* 3. A shorter sequence does not override a longer one.
*
* Sequences of length 1 are allowed.
*
* @endparblock
*/
/**
* @page compose-cancellation Cancellation Behavior
* @parblock
*
* What should happen when a sequence is cancelled? For example, consider
* there are only the above sequences, and the input keysyms are
* `<dead_acute> <b>`. There are a few approaches:
*
* 1. Swallow the cancelling keysym; that is, no keysym is produced.
* This is the approach taken by libX11.
* 2. Let the cancelling keysym through; that is, `<b>` is produced.
* 3. Replay the entire sequence; that is, `<dead_acute> <b>` is produced.
* This is the approach taken by Microsoft Windows (approximately;
* instead of `<dead_acute>`, the underlying key is used. This is
* difficult to simulate with XKB keymaps).
*
* You can program whichever approach best fits users' expectations.
*
* @endparblock
*/
/**
* @struct xkb_compose_table
* Opaque Compose table object.
*
* The compose table holds the definitions of the Compose sequences, as
* gathered from Compose files. It is immutable.
*/
struct xkb_compose_table;
/**
* @struct xkb_compose_state
* Opaque Compose state object.
*
* The compose state maintains state for compose sequence matching, such
* as which possible sequences are being matched, and the position within
* these sequences. It acts as a simple state machine wherein keysyms are
* the input, and composed keysyms and strings are the output.
*
* The compose state is usually associated with a keyboard device.
*/
struct xkb_compose_state;
/** Flags affecting Compose file compilation. */
enum xkb_compose_compile_flags {
/** Do not apply any flags. */
XKB_COMPOSE_COMPILE_NO_FLAGS = 0
};
/** The recognized Compose file formats. */
enum xkb_compose_format {
/** The classic libX11 Compose text format, described in Compose(5). */
XKB_COMPOSE_FORMAT_TEXT_V1 = 1
};
/**
* @page compose-locale Compose Locale
* @parblock
*
* Compose files are locale dependent:
* - Compose files are written for a locale, and the locale is used when
* searching for the appropriate file to use.
* - Compose files may reference the locale internally, with directives
* such as \%L.
*
* As such, functions like xkb_compose_table_new_from_locale() require
* a `locale` parameter. This will usually be the current locale (see
* locale(7) for more details). You may also want to allow the user to
* explicitly configure it, so he can use the Compose file of a given
* locale, but not use that locale for other things.
*
* You may query the current locale as follows:
* @code
* const char *locale;
* locale = setlocale(LC_CTYPE, NULL);
* @endcode
*
* This will only give useful results if the program had previously set
* the current locale using setlocale(3), with `LC_CTYPE` or `LC_ALL`
* and a non-NULL argument.
*
* If you prefer not to use the locale system of the C runtime library,
* you may nevertheless obtain the user's locale directly using
* environment variables, as described in locale(7). For example,
* @code
* locale = getenv("LC_ALL");
* if (!locale)
* locale = getenv("LC_CTYPE");
* if (!locale)
* locale = getenv("LANG");
* if (!locale)
* locale = "C";
* @endcode
*
* Note that some locales supported by the C standard library may not
* have a Compose file assigned.
*
* @endparblock
*/
/**
* Create a compose table for a given locale.
*
* The locale is used for searching the file-system for an appropriate
* Compose file. The search order is described in Compose(5). It is
* affected by the following environment variables:
*
* 1. `XCOMPOSEFILE` - see Compose(5).
* 2. `HOME` - see Compose(5).
* 3. `XLOCALEDIR` - if set, used as the base directory for the system's
* X locale files, e.g. `/usr/share/X11/locale`, instead of the
* preconfigured directory.
*
* @param context
* The library context in which to create the compose table.
* @param locale
* The current locale. See @ref compose-locale.
* @param flags
* Optional flags for the compose table, or 0.
*
* @returns A compose table for the given locale, or NULL if the
* compilation failed or a Compose file was not found.
*
* @memberof xkb_compose_table
*/
struct xkb_compose_table *
xkb_compose_table_new_from_locale(struct xkb_context *context,
const char *locale,
enum xkb_compose_compile_flags flags);
/**
* Create a new compose table from a Compose file.
*
* @param context
* The library context in which to create the compose table.
* @param file
* The Compose file to compile.
* @param locale
* The current locale. See @ref compose-locale.
* @param format
* The text format of the Compose file to compile.
* @param flags
* Optional flags for the compose table, or 0.
*
* @returns A compose table compiled from the given file, or NULL if
* the compilation failed.
*
* @memberof xkb_compose_table
*/
struct xkb_compose_table *
xkb_compose_table_new_from_file(struct xkb_context *context,
FILE *file,
const char *locale,
enum xkb_compose_format format,
enum xkb_compose_compile_flags flags);
/**
* Create a new compose table from a memory buffer.
*
* This is just like xkb_compose_table_new_from_file(), but instead of
* a file, gets the table as one enormous string.
*
* @see xkb_compose_table_new_from_file()
* @memberof xkb_compose_table
*/
struct xkb_compose_table *
xkb_compose_table_new_from_buffer(struct xkb_context *context,
const char *buffer, size_t length,
const char *locale,
enum xkb_compose_format format,
enum xkb_compose_compile_flags flags);
/**
* Take a new reference on a compose table.
*
* @returns The passed in object.
*
* @memberof xkb_compose_table
*/
struct xkb_compose_table *
xkb_compose_table_ref(struct xkb_compose_table *table);
/**
* Release a reference on a compose table, and possibly free it.
*
* @param table The object. If it is NULL, this function does nothing.
*
* @memberof xkb_compose_table
*/
void
xkb_compose_table_unref(struct xkb_compose_table *table);
/** Flags for compose state creation. */
enum xkb_compose_state_flags {
/** Do not apply any flags. */
XKB_COMPOSE_STATE_NO_FLAGS = 0
};
/**
* Create a new compose state object.
*
* @param table
* The compose table the state will use.
* @param flags
* Optional flags for the compose state, or 0.
*
* @returns A new compose state, or NULL on failure.
*
* @memberof xkb_compose_state
*/
struct xkb_compose_state *
xkb_compose_state_new(struct xkb_compose_table *table,
enum xkb_compose_state_flags flags);
/**
* Take a new reference on a compose state object.
*
* @returns The passed in object.
*
* @memberof xkb_compose_state
*/
struct xkb_compose_state *
xkb_compose_state_ref(struct xkb_compose_state *state);
/**
* Release a reference on a compose state object, and possibly free it.
*
* @param state The object. If NULL, do nothing.
*
* @memberof xkb_compose_state
*/
void
xkb_compose_state_unref(struct xkb_compose_state *state);
/**
* Get the compose table which a compose state object is using.
*
* @returns The compose table which was passed to xkb_compose_state_new()
* when creating this state object.
*
* This function does not take a new reference on the compose table; you
* must explicitly reference it yourself if you plan to use it beyond the
* lifetime of the state.
*
* @memberof xkb_compose_state
*/
struct xkb_compose_table *
xkb_compose_state_get_compose_table(struct xkb_compose_state *state);
/** Status of the Compose sequence state machine. */
enum xkb_compose_status {
/** The initial state; no sequence has started yet. */
XKB_COMPOSE_NOTHING,
/** In the middle of a sequence. */
XKB_COMPOSE_COMPOSING,
/** A complete sequence has been matched. */
XKB_COMPOSE_COMPOSED,
/** The last sequence was cancelled due to an unmatched keysym. */
XKB_COMPOSE_CANCELLED
};
/** The effect of a keysym fed to xkb_compose_state_feed(). */
enum xkb_compose_feed_result {
/** The keysym had no effect - it did not affect the status. */
XKB_COMPOSE_FEED_IGNORED,
/** The keysym started, advanced or cancelled a sequence. */
XKB_COMPOSE_FEED_ACCEPTED
};
/**
* Feed one keysym to the Compose sequence state machine.
*
* This function can advance into a compose sequence, cancel a sequence,
* start a new sequence, or do nothing in particular. The resulting
* status may be observed with xkb_compose_state_get_status().
*
* Some keysyms, such as keysyms for modifier keys, are ignored - they
* have no effect on the status or otherwise.
*
* The following is a description of the possible status transitions, in
* the format CURRENT STATUS => NEXT STATUS, given a non-ignored input
* keysym `keysym`:
*
@verbatim
NOTHING or CANCELLED or COMPOSED =>
NOTHING if keysym does not start a sequence.
COMPOSING if keysym starts a sequence.
COMPOSED if keysym starts and terminates a single-keysym sequence.
COMPOSING =>
COMPOSING if keysym advances any of the currently possible
sequences but does not terminate any of them.
COMPOSED if keysym terminates one of the currently possible
sequences.
CANCELLED if keysym does not advance any of the currently
possible sequences.
@endverbatim
*
* The current Compose formats do not support multiple-keysyms.
* Therefore, if you are using a function such as xkb_state_key_get_syms()
* and it returns more than one keysym, consider feeding XKB_KEY_NoSymbol
* instead.
*
* @param state
* The compose state object.
* @param keysym
* A keysym, usually obtained after a key-press event, with a
* function such as xkb_state_key_get_one_sym().
*
* @returns Whether the keysym was ignored. This is useful, for example,
* if you want to keep a record of the sequence matched thus far.
*
* @memberof xkb_compose_state
*/
enum xkb_compose_feed_result
xkb_compose_state_feed(struct xkb_compose_state *state,
xkb_keysym_t keysym);
/**
* Reset the Compose sequence state machine.
*
* The status is set to XKB_COMPOSE_NOTHING, and the current sequence
* is discarded.
*
* @memberof xkb_compose_state
*/
void
xkb_compose_state_reset(struct xkb_compose_state *state);
/**
* Get the current status of the compose state machine.
*
* @see xkb_compose_status
* @memberof xkb_compose_state
**/
enum xkb_compose_status
xkb_compose_state_get_status(struct xkb_compose_state *state);
/**
* Get the result Unicode/UTF-8 string for a composed sequence.
*
* See @ref compose-overview for more details. This function is only
* useful when the status is XKB_COMPOSE_COMPOSED.
*
* @param[in] state
* The compose state.
* @param[out] buffer
* A buffer to write the string into.
* @param[in] size
* Size of the buffer.
*
* @warning If the buffer passed is too small, the string is truncated
* (though still NUL-terminated).
*
* @returns
* The number of bytes required for the string, excluding the NUL byte.
* If the sequence is not complete, or does not have a viable result
* string, returns 0, and sets `buffer` to the empty string (if possible).
* @returns
* You may check if truncation has occurred by comparing the return value
* with the size of `buffer`, similarly to the `snprintf`(3) function.
* You may safely pass NULL and 0 to `buffer` and `size` to find the
* required size (without the NUL-byte).
*
* @memberof xkb_compose_state
**/
int
xkb_compose_state_get_utf8(struct xkb_compose_state *state,
char *buffer, size_t size);
/**
* Get the result keysym for a composed sequence.
*
* See @ref compose-overview for more details. This function is only
* useful when the status is XKB_COMPOSE_COMPOSED.
*
* @returns The result keysym. If the sequence is not complete, or does
* not specify a result keysym, returns XKB_KEY_NoSymbol.
*
* @memberof xkb_compose_state
**/
xkb_keysym_t
xkb_compose_state_get_one_sym(struct xkb_compose_state *state);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _XKBCOMMON_COMPOSE_H */

View File

@ -0,0 +1,45 @@
/*
* Copyright © 2012 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Daniel Stone <daniel@fooishbar.org>
*/
#ifndef _XKBCOMMON_NAMES_H
#define _XKBCOMMON_NAMES_H
/**
* @file
* @brief Predefined names for common modifiers and LEDs.
*/
#define XKB_MOD_NAME_SHIFT "Shift"
#define XKB_MOD_NAME_CAPS "Lock"
#define XKB_MOD_NAME_CTRL "Control"
#define XKB_MOD_NAME_ALT "Mod1"
#define XKB_MOD_NAME_NUM "Mod2"
#define XKB_MOD_NAME_LOGO "Mod4"
#define XKB_LED_NAME_CAPS "Caps Lock"
#define XKB_LED_NAME_NUM "Num Lock"
#define XKB_LED_NAME_SCROLL "Scroll Lock"
#endif

View File

@ -0,0 +1,244 @@
/*
* Copyright © 2013 Ran Benita
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _XKBCOMMON_X11_H
#define _XKBCOMMON_X11_H
#include <xcb/xcb.h>
#include <xkbcommon/xkbcommon.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file
* libxkbcommon-x11 API - Additional X11 support for xkbcommon.
*/
/**
* @defgroup x11 X11 support
* Additional X11 support for xkbcommon.
* @since 0.4.0
*
* @{
*/
/**
* @page x11-overview Overview
* @parblock
*
* The xkbcommon-x11 module provides a means for creating an xkb_keymap
* corresponding to the currently active keymap on the X server. To do
* so, it queries the XKB X11 extension using the xcb-xkb library. It
* can be used as a replacement for Xlib's keyboard handling.
*
* Following is an example workflow using xkbcommon-x11. A complete
* example may be found in the test/interactive-x11.c file in the
* xkbcommon source repository. On startup:
*
* 1. Connect to the X server using xcb_connect().
* 2. Setup the XKB X11 extension. You can do this either by using the
* xcb_xkb_use_extension() request directly, or by using the
* xkb_x11_setup_xkb_extension() helper function.
*
* The XKB extension supports using separate keymaps and states for
* different keyboard devices. The devices are identified by an integer
* device ID and are managed by another X11 extension, XInput (or its
* successor, XInput2). The original X11 protocol only had one keyboard
* device, called the "core keyboard", which is still supported as a
* "virtual device".
*
* 3. We will use the core keyboard as an example. To get its device ID,
* use either the xcb_xkb_get_device_info() request directly, or the
* xkb_x11_get_core_keyboard_device_id() helper function.
* 4. Create an initial xkb_keymap for this device, using the
* xkb_x11_keymap_new_from_device() function.
* 5. Create an initial xkb_state for this device, using the
* xkb_x11_state_new_from_device() function.
*
* @note At this point, you may consider setting various XKB controls and
* XKB per-client flags. For example, enabling detectable autorepeat: \n
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat
*
* Next, you need to react to state changes (e.g. a modifier was pressed,
* the layout was changed) and to keymap changes (e.g. a tool like xkbcomp,
* setxkbmap or xmodmap was used):
*
* 6. Select to listen to at least the following XKB events:
* NewKeyboardNotify, MapNotify, StateNotify; using the
* xcb_xkb_select_events_aux() request.
* 7. When NewKeyboardNotify or MapNotify are received, recreate the
* xkb_keymap and xkb_state as described above.
* 8. When StateNotify is received, update the xkb_state accordingly
* using the xkb_state_update_mask() function.
*
* @note It is also possible to use the KeyPress/KeyRelease @p state
* field to find the effective modifier and layout state, instead of
* using XkbStateNotify: \n
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Computing_A_State_Field_from_an_XKB_State
* \n However, XkbStateNotify is more accurate.
*
* @note There is no need to call xkb_state_update_key(); the state is
* already synchronized.
*
* Finally, when a key event is received, you can use ordinary xkbcommon
* functions, like xkb_state_key_get_one_sym() and xkb_state_key_get_utf8(),
* as you normally would.
*
* @endparblock
*/
/**
* The minimal compatible major version of the XKB X11 extension which
* this library can use.
*/
#define XKB_X11_MIN_MAJOR_XKB_VERSION 1
/**
* The minimal compatible minor version of the XKB X11 extension which
* this library can use (for the minimal major version).
*/
#define XKB_X11_MIN_MINOR_XKB_VERSION 0
/** Flags for the xkb_x11_setup_xkb_extension() function. */
enum xkb_x11_setup_xkb_extension_flags {
/** Do not apply any flags. */
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS = 0
};
/**
* Setup the XKB X11 extension for this X client.
*
* The xkbcommon-x11 library uses various XKB requests. Before doing so,
* an X client must notify the server that it will be using the extension.
* This function (or an XCB equivalent) must be called before any other
* function in this library is used.
*
* Some X servers may not support or disable the XKB extension. If you
* want to support such servers, you need to use a different fallback.
*
* You may call this function several times; it is idempotent.
*
* @param connection
* An XCB connection to the X server.
* @param major_xkb_version
* See @p minor_xkb_version.
* @param minor_xkb_version
* The XKB extension version to request. To operate correctly, you
* must have (major_xkb_version, minor_xkb_version) >=
* (XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION),
* though this is not enforced.
* @param flags
* Optional flags, or 0.
* @param[out] major_xkb_version_out
* See @p minor_xkb_version_out.
* @param[out] minor_xkb_version_out
* Backfilled with the compatible XKB extension version numbers picked
* by the server. Can be NULL.
* @param[out] base_event_out
* Backfilled with the XKB base (also known as first) event code, needed
* to distinguish XKB events. Can be NULL.
* @param[out] base_error_out
* Backfilled with the XKB base (also known as first) error code, needed
* to distinguish XKB errors. Can be NULL.
*
* @returns 1 on success, or 0 on failure.
*/
int
xkb_x11_setup_xkb_extension(xcb_connection_t *connection,
uint16_t major_xkb_version,
uint16_t minor_xkb_version,
enum xkb_x11_setup_xkb_extension_flags flags,
uint16_t *major_xkb_version_out,
uint16_t *minor_xkb_version_out,
uint8_t *base_event_out,
uint8_t *base_error_out);
/**
* Get the keyboard device ID of the core X11 keyboard.
*
* @param connection An XCB connection to the X server.
*
* @returns A device ID which may be used with other xkb_x11_* functions,
* or -1 on failure.
*/
int32_t
xkb_x11_get_core_keyboard_device_id(xcb_connection_t *connection);
/**
* Create a keymap from an X11 keyboard device.
*
* This function queries the X server with various requests, fetches the
* details of the active keymap on a keyboard device, and creates an
* xkb_keymap from these details.
*
* @param context
* The context in which to create the keymap.
* @param connection
* An XCB connection to the X server.
* @param device_id
* An XInput 1 device ID (in the range 0-255) with input class KEY.
* Passing values outside of this range is an error.
* @param flags
* Optional flags for the keymap, or 0.
*
* @returns A keymap retrieved from the X server, or NULL on failure.
*
* @memberof xkb_keymap
*/
struct xkb_keymap *
xkb_x11_keymap_new_from_device(struct xkb_context *context,
xcb_connection_t *connection,
int32_t device_id,
enum xkb_keymap_compile_flags flags);
/**
* Create a new keyboard state object from an X11 keyboard device.
*
* This function is the same as xkb_state_new(), only pre-initialized
* with the state of the device at the time this function is called.
*
* @param keymap
* The keymap for which to create the state.
* @param connection
* An XCB connection to the X server.
* @param device_id
* An XInput 1 device ID (in the range 0-255) with input class KEY.
* Passing values outside of this range is an error.
*
* @returns A new keyboard state object, or NULL on failure.
*
* @memberof xkb_state
*/
struct xkb_state *
xkb_x11_state_new_from_device(struct xkb_keymap *keymap,
xcb_connection_t *connection,
int32_t device_id);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _XKBCOMMON_X11_H */

View File

@ -0,0 +1,10 @@
TEMPLATE = subdirs
qtHaveModule(dbus) {
!mac:!win32:SUBDIRS += fcitx
!mac:!win32:SUBDIRS += ibus
}
contains(QT_CONFIG, xcb-plugin): SUBDIRS += compose