summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorJan Arne Petersen <jan.petersen@kdab.com>2013-09-11 23:04:02 +0200
committerJørgen Lind <jorgen.lind@digia.com>2013-11-22 15:46:05 +0100
commit3194cb5c75a8a7e6deab8709fb9f39accc86b2af (patch)
tree39eb6020e9d6e10ec40a2041920b08c18585e705 /src/plugins/platforms
parentc83b4313b34b142750601ac95c10015bb9993ce8 (diff)
Add support for text protocol to platform plugin
Change-Id: I57b3efdc6f8200337afb58925b23896a8d8c7d1e Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandcursor.cpp5
-rw-r--r--src/plugins/platforms/wayland_common/qwaylanddisplay.cpp4
-rw-r--r--src/plugins/platforms/wayland_common/qwaylanddisplay.h4
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandinputcontext.cpp253
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandinputcontext.h103
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandintegration.cpp5
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandintegration.h2
-rw-r--r--src/plugins/platforms/wayland_common/wayland_common.pro7
8 files changed, 378 insertions, 5 deletions
diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp
index e0abba304..05ab6d496 100644
--- a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp
+++ b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp
@@ -133,6 +133,11 @@ void QWaylandDisplay::setCursor(struct wl_buffer *buffer, struct wl_cursor_image
}
}
+QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
+{
+ return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
+}
+
void QWaylandCursor::pointerEvent(const QMouseEvent &event)
{
mLastPos = event.globalPos();
diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp
index 12be111dd..9f2d58390 100644
--- a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp
@@ -61,6 +61,8 @@
#include "qwaylandtouch.h"
#include "qwaylandqtkey.h"
+#include "qwayland-text.h"
+
#include <QtCore/QAbstractEventDispatcher>
#include <QtGui/private/qguiapplication_p.h>
@@ -243,6 +245,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
mTouchExtension = new QWaylandTouchExtension(this, id);
} else if (interface == "qt_key_extension") {
mQtKeyExtension = new QWaylandQtKeyExtension(this, id);
+ } else if (interface == "wl_text_input_manager") {
+ mTextInputManager = new QtWayland::wl_text_input_manager(registry, id);
}
foreach (Listener l, mRegistryListeners)
diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.h b/src/plugins/platforms/wayland_common/qwaylanddisplay.h
index 6b2cc89d6..5916a5b41 100644
--- a/src/plugins/platforms/wayland_common/qwaylanddisplay.h
+++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.h
@@ -73,6 +73,7 @@ namespace QtWayland {
class qt_shell;
class qt_sub_surface_extension;
class qt_surface_extension;
+ class wl_text_input_manager;
}
typedef void (*RegistryListener)(void *data,
@@ -112,6 +113,7 @@ public:
QtWayland::wl_shell *shell() { return mShell; }
QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; }
+ QWaylandInputDevice *defaultInputDevice() const;
QWaylandInputDevice *lastKeyboardFocusInputDevice() const;
void setLastKeyboardFocusInputDevice(QWaylandInputDevice *device);
@@ -122,6 +124,7 @@ public:
QtWayland::qt_sub_surface_extension *subSurfaceExtension() const { return mSubSurfaceExtension; }
QtWayland::qt_output_extension *outputExtension() const { return mOutputExtension; }
QWaylandTouchExtension *touchExtension() const { return mTouchExtension; }
+ QtWayland::wl_text_input_manager *textInputManager() const { return mTextInputManager; }
/* wl_registry_add_listener does not add but rather sets a listener, so this function is used
* to enable many listeners at once. */
@@ -163,6 +166,7 @@ private:
QWaylandTouchExtension *mTouchExtension;
QWaylandQtKeyExtension *mQtKeyExtension;
QWaylandWindowManagerIntegration *mWindowManagerIntegration;
+ QtWayland::wl_text_input_manager *mTextInputManager;
QSocketNotifier *mReadNotifier;
int mFd;
diff --git a/src/plugins/platforms/wayland_common/qwaylandinputcontext.cpp b/src/plugins/platforms/wayland_common/qwaylandinputcontext.cpp
new file mode 100644
index 000000000..d7b2ca896
--- /dev/null
+++ b/src/plugins/platforms/wayland_common/qwaylandinputcontext.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandinputcontext.h"
+
+#include <QGuiApplication>
+#include <QWindow>
+#include <xkbcommon/xkbcommon.h>
+
+#include "qwaylanddisplay.h"
+#include "qwaylandinputdevice.h"
+#include "qwaylandwindow.h"
+
+QT_BEGIN_NAMESPACE
+
+static Qt::Key toQtKey(uint32_t sym)
+{
+ switch (static_cast<xkb_keysym_t>(sym)) {
+ case XKB_KEY_BackSpace:
+ return Qt::Key_Backspace;
+ case XKB_KEY_Return:
+ return Qt::Key_Return;
+ case XKB_KEY_Left:
+ return Qt::Key_Left;
+ case XKB_KEY_Up:
+ return Qt::Key_Up;
+ case XKB_KEY_Right:
+ return Qt::Key_Right;
+ case XKB_KEY_Down:
+ return Qt::Key_Down;
+ default:
+ return Qt::Key_unknown;
+ }
+}
+
+static QEvent::Type toQEventType(uint32_t state)
+{
+ switch (static_cast<wl_keyboard_key_state>(state)) {
+ default:
+ case WL_KEYBOARD_KEY_STATE_PRESSED:
+ return QEvent::KeyPress;
+ case WL_KEYBOARD_KEY_STATE_RELEASED:
+ return QEvent::KeyRelease;
+ }
+}
+
+QWaylandTextInput::QWaylandTextInput(struct ::wl_text_input *text_input)
+ : QtWayland::wl_text_input(text_input)
+ , m_commit()
+ , m_serial(0)
+ , m_resetSerial(0)
+{
+}
+
+QString QWaylandTextInput::commitString() const
+{
+ return m_commit;
+}
+
+void QWaylandTextInput::reset()
+{
+ wl_text_input::reset();
+ updateState();
+ m_resetSerial = m_serial;
+}
+
+void QWaylandTextInput::updateState()
+{
+ if (!QGuiApplication::focusObject())
+ return;
+
+ QInputMethodQueryEvent event(Qt::ImQueryAll);
+ QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
+
+ const QString &text = event.value(Qt::ImSurroundingText).toString();
+ const int cursor = event.value(Qt::ImCursorPosition).toInt();
+ const int anchor = event.value(Qt::ImAnchorPosition).toInt();
+
+ set_surrounding_text(text, text.leftRef(cursor).toUtf8().size(), text.leftRef(anchor).toUtf8().size());
+
+ commit_state(++m_serial);
+}
+
+void QWaylandTextInput::text_input_commit_string(uint32_t serial, const QString &text)
+{
+ if (!QGuiApplication::focusObject())
+ return;
+
+ QInputMethodEvent event;
+ event.setCommitString(text);
+ QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
+}
+
+void QWaylandTextInput::text_input_enter(wl_surface *)
+{
+ updateState();
+ m_resetSerial = m_serial;
+}
+
+void QWaylandTextInput::text_input_leave()
+{
+}
+
+void QWaylandTextInput::text_input_keysym(uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers)
+{
+ if (!QGuiApplication::focusObject())
+ return;
+
+ // TODO: Convert modifiers to Qt::KeyboardModifiers.
+ QKeyEvent event(toQEventType(state), toQtKey(sym), Qt::NoModifier);
+ QCoreApplication::sendEvent(qGuiApp->focusWindow(), &event);
+}
+
+QWaylandInputContext::QWaylandInputContext(QWaylandDisplay *display)
+ : QPlatformInputContext()
+ , mDisplay(display)
+ , mTextInput()
+{
+}
+
+bool QWaylandInputContext::isValid() const
+{
+ return mDisplay->textInputManager() != 0;
+}
+
+void QWaylandInputContext::reset()
+{
+ if (!ensureTextInput())
+ return;
+
+ mTextInput->reset();
+}
+
+void QWaylandInputContext::commit()
+{
+ if (!ensureTextInput())
+ return;
+
+ if (!QGuiApplication::focusObject())
+ return;
+
+ QInputMethodEvent event;
+ event.setCommitString(mTextInput->commitString());
+ QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
+
+ mTextInput->reset();
+}
+
+void QWaylandInputContext::update(Qt::InputMethodQueries queries)
+{
+ if (!ensureTextInput())
+ return;
+
+ mTextInput->updateState();
+}
+
+void QWaylandInputContext::invokeAction(QInputMethod::Action, int cursorPosition)
+{
+ if (!ensureTextInput())
+ return;
+
+ mTextInput->invoke_action(0, cursorPosition); // FIXME button, to UTF8 cursor position
+}
+
+void QWaylandInputContext::showInputPanel()
+{
+ if (!ensureTextInput())
+ return;
+
+ mTextInput->show_input_panel();
+}
+
+void QWaylandInputContext::hideInputPanel()
+{
+ if (!ensureTextInput())
+ return;
+
+ mTextInput->hide_input_panel();
+}
+
+bool QWaylandInputContext::isInputPanelVisible() const
+{
+ return false;
+}
+
+void QWaylandInputContext::setFocusObject(QObject *object)
+{
+ if (!ensureTextInput())
+ return;
+
+ if (!object) {
+ mTextInput->deactivate(mDisplay->defaultInputDevice()->wl_seat());
+ return;
+ }
+
+ QWindow *window = QGuiApplication::focusWindow();
+ if (!window || !window->handle())
+ return;
+
+ struct ::wl_surface *surface = static_cast<QWaylandWindow *>(window->handle())->object();
+ mTextInput->activate(mDisplay->defaultInputDevice()->wl_seat(), surface);
+}
+
+bool QWaylandInputContext::ensureTextInput()
+{
+ if (mTextInput)
+ return true;
+
+ if (!isValid())
+ return false;
+
+ mTextInput.reset(new QWaylandTextInput(mDisplay->textInputManager()->create_text_input()));
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/wayland_common/qwaylandinputcontext.h b/src/plugins/platforms/wayland_common/qwaylandinputcontext.h
new file mode 100644
index 000000000..43284eb9e
--- /dev/null
+++ b/src/plugins/platforms/wayland_common/qwaylandinputcontext.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDINPUTCONTEXT_H
+#define QWAYLANDINPUTCONTEXT_H
+
+#include <qpa/qplatforminputcontext.h>
+
+#include <qwayland-text.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandDisplay;
+
+class QWaylandTextInput : public QtWayland::wl_text_input
+{
+public:
+ QWaylandTextInput(struct ::wl_text_input *text_input);
+
+ QString commitString() const;
+
+ void reset();
+ void updateState();
+
+protected:
+ void text_input_commit_string(uint32_t serial, const QString &text) Q_DECL_OVERRIDE;
+ void text_input_enter(wl_surface *surface) Q_DECL_OVERRIDE;
+ void text_input_leave() Q_DECL_OVERRIDE;
+ void text_input_keysym(uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers);
+
+private:
+ QString m_commit;
+
+ uint32_t m_serial;
+ uint32_t m_resetSerial;
+};
+
+class QWaylandInputContext : public QPlatformInputContext
+{
+ Q_OBJECT
+public:
+ explicit QWaylandInputContext(QWaylandDisplay *display);
+
+ bool isValid() const Q_DECL_OVERRIDE;
+
+ void reset() Q_DECL_OVERRIDE;
+ void commit() Q_DECL_OVERRIDE;
+ void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE;
+ void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE;
+
+ void showInputPanel() Q_DECL_OVERRIDE;
+ void hideInputPanel() Q_DECL_OVERRIDE;
+ bool isInputPanelVisible() const Q_DECL_OVERRIDE;
+
+ void setFocusObject(QObject *object) Q_DECL_OVERRIDE;
+
+private:
+ bool ensureTextInput();
+
+ QWaylandDisplay *mDisplay;
+ QScopedPointer<QWaylandTextInput> mTextInput;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDINPUTCONTEXT_H
diff --git a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp
index 5160d66f0..78494b543 100644
--- a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp
@@ -42,6 +42,7 @@
#include "qwaylandintegration.h"
#include "qwaylanddisplay.h"
+#include "qwaylandinputcontext.h"
#include "qwaylandshmbackingstore.h"
#include "qwaylandshmwindow.h"
#include "qwaylandnativeinterface.h"
@@ -116,7 +117,7 @@ QWaylandIntegration::QWaylandIntegration()
foreach (QPlatformScreen *screen, mDisplay->screens())
screenAdded(screen);
- mInputContext = QPlatformInputContextFactory::create();
+ mInputContext.reset(new QWaylandInputContext(mDisplay));
}
QWaylandIntegration::~QWaylandIntegration()
@@ -209,7 +210,7 @@ QPlatformDrag *QWaylandIntegration::drag() const
QPlatformInputContext *QWaylandIntegration::inputContext() const
{
- return mInputContext;
+ return mInputContext.data();
}
QVariant QWaylandIntegration::styleHint(StyleHint hint) const
diff --git a/src/plugins/platforms/wayland_common/qwaylandintegration.h b/src/plugins/platforms/wayland_common/qwaylandintegration.h
index e9f8b73ad..9a6b7cd2c 100644
--- a/src/plugins/platforms/wayland_common/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland_common/qwaylandintegration.h
@@ -91,7 +91,7 @@ private:
QPlatformDrag *mDrag;
QWaylandDisplay *mDisplay;
QPlatformNativeInterface *mNativeInterface;
- QPlatformInputContext *mInputContext;
+ QScopedPointer<QPlatformInputContext> mInputContext;
QPlatformAccessibility *mAccessibility;
};
diff --git a/src/plugins/platforms/wayland_common/wayland_common.pro b/src/plugins/platforms/wayland_common/wayland_common.pro
index 45fc7ce6e..fc00c7c3e 100644
--- a/src/plugins/platforms/wayland_common/wayland_common.pro
+++ b/src/plugins/platforms/wayland_common/wayland_common.pro
@@ -26,7 +26,8 @@ SOURCES += qwaylandintegration.cpp \
../../../shared/qwaylandmimehelper.cpp \
qwaylanddecoration.cpp \
qwaylandeventthread.cpp\
- qwaylandwindowmanagerintegration.cpp
+ qwaylandwindowmanagerintegration.cpp \
+ qwaylandinputcontext.cpp
HEADERS += qwaylandintegration.h \
qwaylandnativeinterface.h \
@@ -52,7 +53,8 @@ HEADERS += qwaylandintegration.h \
../../../shared/qwaylandmimehelper.h \
qwaylanddecoration.h \
qwaylandeventthread.h \
- qwaylandwindowmanagerintegration.h
+ qwaylandwindowmanagerintegration.h \
+ qwaylandinputcontext.h
contains(DEFINES, QT_WAYLAND_GL_SUPPORT) {
SOURCES += qwaylandglintegration.cpp
@@ -67,6 +69,7 @@ WAYLANDCLIENTSOURCES += \
../../../extensions/touch-extension.xml \
../../../extensions/qtkey-extension.xml \
../../../extensions/windowmanager.xml \
+ ../../../3rdparty/protocol/text.xml \
PLUGIN_TYPE = platforms