summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-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/qwaylandwindow.cpp4
-rw-r--r--src/plugins/platforms/wayland/wayland_sha1.txt2
-rw-r--r--src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanager-client-protocol.h68
-rw-r--r--src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp33
-rw-r--r--src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.h5
-rw-r--r--src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-protocol.c16
9 files changed, 278 insertions, 52 deletions
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index f3e2e9fb94..1314eda012 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -311,7 +311,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 7f3737613f..c1e2325766 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/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index 2376df55c9..f685dae729 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -146,8 +146,8 @@ void QWaylandWindow::newSurfaceCreated()
{
if (mBuffer) {
wl_surface_attach(mSurface,mBuffer->buffer(),0,0);
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
- wl_surface_damage(mSurface,0,0,mBuffer->size().width(),mBuffer->size().height());
+ // do not damage the surface here, as this leads to graphical corruptions in the compositor until
+ // the first frame has been rendered
}
}
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
diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanager-client-protocol.h b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanager-client-protocol.h
index 73673aef6f..e781b16c41 100644
--- a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanager-client-protocol.h
+++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanager-client-protocol.h
@@ -36,71 +36,67 @@ struct wl_client;
struct wl_windowmanager;
-struct wl_proxy;
-
-extern void
-wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);
-extern struct wl_proxy *
-wl_proxy_create(struct wl_proxy *factory,
- const struct wl_interface *interface);
-extern struct wl_proxy *
-wl_proxy_create_for_id(struct wl_display *display,
- const struct wl_interface *interface, uint32_t id);
-extern void
-wl_proxy_destroy(struct wl_proxy *proxy);
-
-extern int
-wl_proxy_add_listener(struct wl_proxy *proxy,
- void (**implementation)(void), void *data);
-
-extern void
-wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);
-
-extern void *
-wl_proxy_get_user_data(struct wl_proxy *proxy);
-
extern const struct wl_interface wl_windowmanager_interface;
-#define wl_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS 0
-#define wl_WINDOWMANAGER_AUTHENTICATE_WITH_TOKEN 1
+struct wl_windowmanager_listener {
+ void (*client_onscreen_visibility)(void *data,
+ struct wl_windowmanager *wl_windowmanager,
+ int visible);
+ void (*set_screen_rotation)(void *data,
+ struct wl_windowmanager *wl_windowmanager,
+ int rotation);
+};
+
+static inline int
+wl_windowmanager_add_listener(struct wl_windowmanager *wl_windowmanager,
+ const struct wl_windowmanager_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) wl_windowmanager,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS 0
+#define WL_WINDOWMANAGER_AUTHENTICATE_WITH_TOKEN 1
static inline struct wl_windowmanager *
-wl_windowmanager_create(struct wl_display *display, uint32_t id)
+wl_windowmanager_create(struct wl_display *display, uint32_t id, uint32_t version)
{
- return (struct wl_windowmanager *)
- wl_proxy_create_for_id(display, &wl_windowmanager_interface, id);
+ wl_display_bind(display, id, "wl_windowmanager", version);
+
+ return (struct wl_windowmanager *)
+ wl_proxy_create_for_id(display, &wl_windowmanager_interface, id);
}
static inline void
wl_windowmanager_set_user_data(struct wl_windowmanager *wl_windowmanager, void *user_data)
{
- wl_proxy_set_user_data((struct wl_proxy *) wl_windowmanager, user_data);
+ wl_proxy_set_user_data((struct wl_proxy *) wl_windowmanager, user_data);
}
static inline void *
wl_windowmanager_get_user_data(struct wl_windowmanager *wl_windowmanager)
{
- return wl_proxy_get_user_data((struct wl_proxy *) wl_windowmanager);
+ return wl_proxy_get_user_data((struct wl_proxy *) wl_windowmanager);
}
static inline void
wl_windowmanager_destroy(struct wl_windowmanager *wl_windowmanager)
{
- wl_proxy_destroy((struct wl_proxy *) wl_windowmanager);
+ wl_proxy_destroy((struct wl_proxy *) wl_windowmanager);
}
static inline void
wl_windowmanager_map_client_to_process(struct wl_windowmanager *wl_windowmanager, uint32_t processid)
{
- wl_proxy_marshal((struct wl_proxy *) wl_windowmanager,
- wl_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS, processid);
+ wl_proxy_marshal((struct wl_proxy *) wl_windowmanager,
+ WL_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS, processid);
}
static inline void
-wl_windowmanager_authenticate_with_token(struct wl_windowmanager *wl_windowmanager, const char *wl_authentication_token)
+wl_windowmanager_authenticate_with_token(struct wl_windowmanager *wl_windowmanager, const char *processid)
{
- wl_proxy_marshal((struct wl_proxy *) wl_windowmanager,
- wl_WINDOWMANAGER_AUTHENTICATE_WITH_TOKEN, wl_authentication_token);
+ wl_proxy_marshal((struct wl_proxy *) wl_windowmanager,
+ WL_WINDOWMANAGER_AUTHENTICATE_WITH_TOKEN, processid);
}
#ifdef __cplusplus
diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
index 4236f395cb..7390c52740 100644
--- a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
+++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
@@ -43,6 +43,15 @@
#include "qwaylandwindowmanager-client-protocol.h"
#include <stdint.h>
+#include <QDebug>
+#include <QEvent>
+#include <QtGui/QtEvents>
+#include <QCoreApplication>
+
+const struct wl_windowmanager_listener QWaylandWindowManagerIntegration::mWindowManagerListener = {
+ QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange,
+ QWaylandWindowManagerIntegration::wlHandleScreenOrientationChange,
+};
QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::createIntegration(QWaylandDisplay *waylandDisplay)
{
@@ -70,9 +79,12 @@ struct wl_windowmanager *QWaylandWindowManagerIntegration::windowManager() const
void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
{
+ Q_UNUSED(version);
if (strcmp(interface, "wl_windowmanager") == 0) {
QWaylandWindowManagerIntegration *integration = static_cast<QWaylandWindowManagerIntegration *>(data);
- integration->mWaylandWindowManager = wl_windowmanager_create(display, id);
+ integration->mWaylandWindowManager = wl_windowmanager_create(display, id, 1);
+
+ wl_windowmanager_add_listener(integration->mWaylandWindowManager, &mWindowManagerListener, integration);
}
}
@@ -90,3 +102,22 @@ void QWaylandWindowManagerIntegration::authenticateWithToken(const QByteArray &t
if (mWaylandWindowManager)
wl_windowmanager_authenticate_with_token(mWaylandWindowManager, authToken.constData());
}
+
+void QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(wl_windowmanager);
+ QEvent evt(visible != 0 ? QEvent::ApplicationActivated : QEvent::ApplicationDeactivated);
+
+ QCoreApplication::sendEvent(QCoreApplication::instance(), &evt);
+
+ qDebug() << "OnScreenVisibility" << (visible != 0);
+}
+
+void QWaylandWindowManagerIntegration::wlHandleScreenOrientationChange(void *data, struct wl_windowmanager *wl_windowmanager, int screenOrientation)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(wl_windowmanager);
+ QScreenOrientationChangeEvent event(screenOrientation);
+ QCoreApplication::sendEvent(QCoreApplication::instance(), &event);
+}
diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.h b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.h
index 0e3781dbe2..6b4658c7e1 100644
--- a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.h
+++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.h
@@ -62,9 +62,14 @@ private:
static void wlHandleListenerGlobal(wl_display *display, uint32_t id,
const char *interface, uint32_t version, void *data);
+ static void wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible);
+ static void wlHandleScreenOrientationChange(void *data, struct wl_windowmanager *wl_windowmanager, int screenOrientation);
private:
+
QWaylandDisplay *mWaylandDisplay;
struct wl_windowmanager *mWaylandWindowManager;
+
+ static const struct wl_windowmanager_listener mWindowManagerListener;
};
#endif // QWAYLANDWINDOWMANAGERINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-protocol.c b/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-protocol.c
index 0250801b1f..8125dec4d3 100644
--- a/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-protocol.c
+++ b/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-protocol.c
@@ -26,12 +26,18 @@
#include "wayland-util.h"
static const struct wl_message wl_windowmanager_requests[] = {
- { "map_client_to_process", "u" },
- { "authenticate_with_token", "s" },
+ { "map_client_to_process", "u", NULL },
+ { "authenticate_with_token", "s", NULL },
+};
+
+static const struct wl_message wl_windowmanager_events[] = {
+ { "client_onscreen_visibility", "i", NULL },
+ { "set_screen_rotation", "i", NULL },
};
WL_EXPORT const struct wl_interface wl_windowmanager_interface = {
- "wl_windowmanager", 1,
- ARRAY_LENGTH(wl_windowmanager_requests), wl_windowmanager_requests,
- 0, NULL,
+ "wl_windowmanager", 1,
+ ARRAY_LENGTH(wl_windowmanager_requests), wl_windowmanager_requests,
+ ARRAY_LENGTH(wl_windowmanager_events), wl_windowmanager_events,
};
+