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>
This commit is contained in:
parent
c70869abc1
commit
06d85c51fe
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,3 @@
|
||||
This version of the Qt Wayland plugin is checked against the following sha1
|
||||
from the Wayland repository:
|
||||
bfea3d6befdb688d5354e6f15a9400ea637febf9
|
||||
aa7bbb210b7121b9314993228960240358e9b123
|
||||
|
Loading…
Reference in New Issue
Block a user