summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2011-06-29 17:03:19 +0300
committerQt by Nokia <qt-info@nokia.com>2011-06-30 10:18:28 +0200
commit06d85c51fe062b3ae9431860aa9dedc860bf4681 (patch)
tree0018c4da1faf3cc90ef419309be04518b04fb0cd /src/plugins
parentc70869abc1cdfd263418575d440bffbb7321fa71 (diff)
Add touch event support to wayland plugin.
Change-Id: If4be4965ae4e9898f5afb756632aa0349bd9b149 Reviewed-on: http://codereview.qt.nokia.com/935 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp2
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp169
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.h31
-rw-r--r--src/plugins/platforms/wayland/wayland_sha1.txt2
4 files changed, 196 insertions, 8 deletions
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index 69ec6adc0c..26e0e8ebeb 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -309,7 +309,7 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id,
wl_shell_add_listener(mShell, &shellListener, this);
} else if (interface == "wl_input_device") {
QWaylandInputDevice *inputDevice =
- new QWaylandInputDevice(mDisplay, id);
+ new QWaylandInputDevice(this, id);
mInputDevices.append(inputDevice);
} else if (interface == "wl_selection_offer") {
QWaylandClipboard::instance(display)->createSelectionOffer(id);
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
index d1da57d81d..3c9afafada 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
@@ -45,10 +45,9 @@
#include "qwaylandwindow.h"
#include "qwaylandbuffer.h"
-#include <QWindowSystemInterface>
-
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/QPlatformWindow>
+#include <QDebug>
#include <unistd.h>
#include <fcntl.h>
@@ -58,13 +57,17 @@
#include <X11/keysym.h>
#endif
-QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
+//#define POINT_DEBUG
+
+QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display,
uint32_t id)
- : mDisplay(display)
- , mInputDevice(wl_input_device_create(display, id, 1))
+ : mQDisplay(display)
+ , mDisplay(display->wl_display())
+ , mInputDevice(wl_input_device_create(mDisplay, id, 1))
, mPointerFocus(NULL)
, mKeyboardFocus(NULL)
, mButtons(0)
+ , mTouchState(QEvent::TouchBegin)
{
wl_input_device_add_listener(mInputDevice,
&inputDeviceListener,
@@ -338,12 +341,168 @@ void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
#endif
}
+void QWaylandInputDevice::inputHandleTouchDown(void *data,
+ struct wl_input_device *wl_input_device,
+ uint32_t time,
+ int id,
+ int x,
+ int y)
+{
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ inputDevice->handleTouchPoint(id, x, y, Qt::TouchPointPressed);
+}
+
+void QWaylandInputDevice::inputHandleTouchUp(void *data,
+ struct wl_input_device *wl_input_device,
+ uint32_t time,
+ int id)
+{
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ inputDevice->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased);
+}
+
+void QWaylandInputDevice::inputHandleTouchMotion(void *data,
+ struct wl_input_device *wl_input_device,
+ uint32_t time,
+ int id,
+ int x,
+ int y)
+{
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ inputDevice->handleTouchPoint(id, x, y, Qt::TouchPointMoved);
+}
+
+void QWaylandInputDevice::handleTouchPoint(int id, int x, int y, Qt::TouchPointState state)
+{
+ QWindowSystemInterface::TouchPoint tp;
+
+ // Find out the coordinates for Released events.
+ bool coordsOk = false;
+ if (state == Qt::TouchPointReleased)
+ for (int i = 0; i < mPrevTouchPoints.count(); ++i)
+ if (mPrevTouchPoints.at(i).id == id) {
+ tp.area = mPrevTouchPoints.at(i).area;
+ coordsOk = true;
+ break;
+ }
+
+ if (!coordsOk) {
+ // x and y are surface relative.
+ // We need a global (screen) position.
+
+ QWaylandWindow *win = mPointerFocus;
+ if (!win)
+ win = mKeyboardFocus;
+#ifdef POINT_DEBUG
+ qDebug() << "surface relative coords" << x << y << "using window" << win;
+#endif
+ if (!win)
+ return;
+
+ QRect winRect = win->geometry();
+
+ // Get a normalized position (0..1).
+ const qreal nx = x / qreal(winRect.width());
+ const qreal ny = y / qreal(winRect.height());
+ tp.normalPosition = QPointF(nx, ny);
+
+ // Map to screen.
+ QPlatformScreen *screen = mQDisplay->screens().at(0);
+ QRect screenRect = screen->geometry();
+ x = int(nx * screenRect.width());
+ y = int(ny * screenRect.height());
+
+#ifdef POINT_DEBUG
+ qDebug() << "normalized position" << nx << ny
+ << "win rect" << winRect << "screen rect" << screenRect;
+ qDebug() << "mapped to screen position" << x << y;
+#endif
+
+ tp.area = QRectF(x, y, 1, 1);
+ }
+
+ tp.state = state;
+ tp.id = id;
+ tp.isPrimary = mTouchPoints.isEmpty();
+ tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1;
+ mTouchPoints.append(tp);
+}
+
+void QWaylandInputDevice::inputHandleTouchFrame(void *data, struct wl_input_device *wl_input_device)
+{
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ inputDevice->handleTouchFrame();
+}
+
+void QWaylandInputDevice::handleTouchFrame()
+{
+ // Copy all points, that are in the previous but not in the current list, as stationary.
+ for (int i = 0; i < mPrevTouchPoints.count(); ++i) {
+ const QWindowSystemInterface::TouchPoint &prevPoint(mPrevTouchPoints.at(i));
+ if (prevPoint.state == Qt::TouchPointReleased)
+ continue;
+ bool found = false;
+ for (int j = 0; j < mTouchPoints.count(); ++j)
+ if (mTouchPoints.at(j).id == prevPoint.id) {
+ found = true;
+ break;
+ }
+ if (!found) {
+ QWindowSystemInterface::TouchPoint p = prevPoint;
+ p.state = Qt::TouchPointStationary;
+ mTouchPoints.append(p);
+ }
+ }
+
+ if (mTouchPoints.isEmpty()) {
+ mPrevTouchPoints.clear();
+ return;
+ }
+
+#ifdef POINT_DEBUG
+ qDebug() << mTouchPoints.count() << "touchpoints, event type" << mTouchState;
+ for (int i = 0; i < mTouchPoints.count(); ++i)
+ qDebug() << " " << mTouchPoints[i].id << mTouchPoints[i].state << mTouchPoints[i].area;
+#endif
+
+ QWindowSystemInterface::handleTouchEvent(0, mTouchState, QTouchEvent::TouchScreen, mTouchPoints);
+
+ bool allReleased = true;
+ for (int i = 0; i < mTouchPoints.count(); ++i)
+ if (mTouchPoints.at(i).state != Qt::TouchPointReleased) {
+ allReleased = false;
+ break;
+ }
+
+ mPrevTouchPoints = mTouchPoints;
+ mTouchPoints.clear();
+
+ if (allReleased) {
+#ifdef POINT_DEBUG
+ qDebug() << mTouchPoints.count() << "touchpoints, event type" << QEvent::TouchEnd;
+#endif
+ QWindowSystemInterface::handleTouchEvent(0, QEvent::TouchEnd, QTouchEvent::TouchScreen, mTouchPoints);
+ mTouchState = QEvent::TouchBegin;
+ mPrevTouchPoints.clear();
+ } else if (mTouchState == QEvent::TouchBegin)
+ mTouchState = QEvent::TouchUpdate;
+}
+
+void QWaylandInputDevice::inputHandleTouchCancel(void *data, struct wl_input_device *wl_input_device)
+{
+}
+
const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = {
QWaylandInputDevice::inputHandleMotion,
QWaylandInputDevice::inputHandleButton,
QWaylandInputDevice::inputHandleKey,
QWaylandInputDevice::inputHandlePointerFocus,
QWaylandInputDevice::inputHandleKeyboardFocus,
+ QWaylandInputDevice::inputHandleTouchDown,
+ QWaylandInputDevice::inputHandleTouchUp,
+ QWaylandInputDevice::inputHandleTouchMotion,
+ QWaylandInputDevice::inputHandleTouchFrame,
+ QWaylandInputDevice::inputHandleTouchCancel
};
void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h
index e5be5bb8d2..008ecf144d 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.h
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h
@@ -48,21 +48,24 @@
#include <QObject>
#include <QtGui/QPlatformIntegration>
#include <QtGui/QPlatformScreen>
+#include <QWindowSystemInterface>
#include <wayland-client.h>
QT_BEGIN_NAMESPACE
class QWaylandWindow;
+class QWaylandDisplay;
class QWaylandInputDevice {
public:
- QWaylandInputDevice(struct wl_display *display, uint32_t id);
+ QWaylandInputDevice(QWaylandDisplay *display, uint32_t id);
void attach(QWaylandBuffer *buffer, int x, int y);
void handleWindowDestroyed(QWaylandWindow *window);
struct wl_input_device *wl_input_device() const { return mInputDevice; }
private:
+ QWaylandDisplay *mQDisplay;
struct wl_display *mDisplay;
struct wl_input_device *mInputDevice;
QWaylandWindow *mPointerFocus;
@@ -95,6 +98,32 @@ private:
uint32_t time,
struct wl_surface *surface,
struct wl_array *keys);
+ static void inputHandleTouchDown(void *data,
+ struct wl_input_device *wl_input_device,
+ uint32_t time,
+ int id,
+ int x,
+ int y);
+ static void inputHandleTouchUp(void *data,
+ struct wl_input_device *wl_input_device,
+ uint32_t time,
+ int id);
+ static void inputHandleTouchMotion(void *data,
+ struct wl_input_device *wl_input_device,
+ uint32_t time,
+ int id,
+ int x,
+ int y);
+ static void inputHandleTouchFrame(void *data,
+ struct wl_input_device *wl_input_device);
+ static void inputHandleTouchCancel(void *data,
+ struct wl_input_device *wl_input_device);
+
+ void handleTouchPoint(int id, int x, int y, Qt::TouchPointState state);
+ void handleTouchFrame();
+ QList<QWindowSystemInterface::TouchPoint> mTouchPoints;
+ QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints;
+ QEvent::Type mTouchState;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/wayland_sha1.txt b/src/plugins/platforms/wayland/wayland_sha1.txt
index a696e760d5..9596f7b0a8 100644
--- a/src/plugins/platforms/wayland/wayland_sha1.txt
+++ b/src/plugins/platforms/wayland/wayland_sha1.txt
@@ -1,3 +1,3 @@
This version of the Qt Wayland plugin is checked against the following sha1
from the Wayland repository:
-bfea3d6befdb688d5354e6f15a9400ea637febf9
+aa7bbb210b7121b9314993228960240358e9b123