summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.tests/qpa/wayland/wayland.cpp7
-rw-r--r--config.tests/qpa/wayland/wayland.pro6
-rwxr-xr-xconfigure5
-rw-r--r--src/plugins/platforms/platforms.pro4
-rw-r--r--src/plugins/platforms/wayland/main.cpp72
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp399
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h156
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindowsurface.cpp131
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindowsurface.h71
-rw-r--r--src/plugins/platforms/wayland/wayland.pro19
10 files changed, 870 insertions, 0 deletions
diff --git a/config.tests/qpa/wayland/wayland.cpp b/config.tests/qpa/wayland/wayland.cpp
new file mode 100644
index 0000000..40ff2cb
--- /dev/null
+++ b/config.tests/qpa/wayland/wayland.cpp
@@ -0,0 +1,7 @@
+#include "wayland-client.h"
+#include "wayland-glib.h"
+
+int main(int, char **)
+{
+ return 0;
+}
diff --git a/config.tests/qpa/wayland/wayland.pro b/config.tests/qpa/wayland/wayland.pro
new file mode 100644
index 0000000..83f5efe
--- /dev/null
+++ b/config.tests/qpa/wayland/wayland.pro
@@ -0,0 +1,6 @@
+SOURCES = client.cpp
+CONFIG -= qt
+
+QMAKE_CXXFLAGS += $$QT_CFLAGS_WAYLAND
+LIBS += $$QT_LIBS_WAYLAND -lfreetype -lfontconfig -lwayland-client
+
diff --git a/configure b/configure
index e3c0882..e1c41ec 100755
--- a/configure
+++ b/configure
@@ -6185,6 +6185,11 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
QMakeVar set QMAKE_LIBS_FONTCONFIG "$QT_LIBS_FONTCONFIG"
CFG_LIBFREETYPE=system
fi
+
+ if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/wayland "Wayland" $L_FLAGS $I_FLAGS $l_FLAGS; then
+ QT_CONFIG="$QT_CONFIG wayland"
+ fi
+
fi
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/mac/coreservices "CoreServices" $L_FLAGS $I_FLAGS $l_FLAGS $MAC_CONFIG_TEST_COMMANDLINE; then
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 26ccd44..57015e7 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -2,3 +2,7 @@ TEMPLATE = subdirs
SUBDIRS += minimal
+contains(QT_CONFIG, wayland) {
+ SUBDIRS += wayland
+}
+
diff --git a/src/plugins/platforms/wayland/main.cpp b/src/plugins/platforms/wayland/main.cpp
new file mode 100644
index 0000000..056cc64
--- /dev/null
+++ b/src/plugins/platforms/wayland/main.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QPlatformIntegrationPlugin>
+#include "qwaylandintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QWaylandIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "Wayland";
+ return list;
+}
+
+QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "wayland")
+ return new QWaylandIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(wayland, QWaylandIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
new file mode 100644
index 0000000..577dd28
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -0,0 +1,399 @@
+#include <QWindowSystemInterface>
+#include "qwaylandintegration.h"
+#include "qwaylandwindowsurface.h"
+#include "qfontconfigdatabase.h"
+
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/QPlatformWindow>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+extern "C" {
+#include <xf86drm.h>
+}
+
+struct wl_surface *QWaylandDisplay::createSurface()
+{
+ return wl_compositor_create_surface(mCompositor);
+}
+
+struct wl_buffer *QWaylandDisplay::createShmBuffer(int fd,
+ int width, int height,
+ uint32_t stride,
+ struct wl_visual *visual)
+{
+ return wl_shm_create_buffer(mShm, fd, width, height, stride, visual);
+}
+
+struct wl_visual *QWaylandDisplay::argbVisual()
+{
+ return wl_display_get_argb_visual(mDisplay);
+}
+
+void QWaylandDisplay::drmHandleDevice(void *data,
+ struct wl_drm *drm, const char *device)
+{
+ Q_UNUSED(drm);
+ QWaylandDisplay *qwd = (QWaylandDisplay *) data;
+
+ qwd->mDeviceName = strdup(device);
+}
+
+void QWaylandDisplay::drmHandleAuthenticated(void *data, struct wl_drm *drm)
+{
+ Q_UNUSED(drm);
+ QWaylandDisplay *qwd = (QWaylandDisplay *) data;
+
+ qwd->mAuthenticated = true;
+}
+
+const struct wl_drm_listener QWaylandDisplay::drmListener = {
+ QWaylandDisplay::drmHandleDevice,
+ QWaylandDisplay::drmHandleAuthenticated
+};
+
+void QWaylandDisplay::outputHandleGeometry(void *data,
+ struct wl_output *output,
+ int32_t width, int32_t height)
+{
+ Q_UNUSED(output);
+ QWaylandDisplay *qwd = (QWaylandDisplay *) data;
+ QWaylandScreen *screen;
+
+ screen = new QWaylandScreen();
+ screen->mGeometry = QRect(0, 0, width, height);
+ screen->mDepth = 32;
+ screen->mFormat = QImage::Format_ARGB32;
+ screen->mOutput = output;
+
+ qwd->mScreens.append(screen);
+}
+
+const struct wl_output_listener QWaylandDisplay::outputListener = {
+ QWaylandDisplay::outputHandleGeometry
+};
+
+class QWaylandInputDevice {
+public:
+ QWaylandInputDevice(struct wl_display *display, uint32_t id);
+
+private:
+ struct wl_display *mDisplay;
+ struct wl_input_device *mInputDevice;
+ struct wl_surface *mPointerFocus;
+ struct wl_surface *mKeyboardFocus;
+ static const struct wl_input_device_listener inputDeviceListener;
+ Qt::MouseButtons mButtons;
+ QPoint mSurfacePos;
+ QPoint mGlobalPos;
+
+ static void inputHandleMotion(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ int32_t x, int32_t y,
+ int32_t sx, int32_t sy);
+ static void inputHandleButton(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, uint32_t button, uint32_t state);
+ static void inputHandleKey(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, uint32_t key, uint32_t state);
+ static void inputHandlePointerFocus(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t sx, int32_t sy);
+ static void inputHandleKeyboardFocus(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ struct wl_array *keys);
+};
+
+QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
+ uint32_t id)
+ : mDisplay(display)
+ , mInputDevice(wl_input_device_create(display, id))
+ , mPointerFocus(NULL)
+ , mKeyboardFocus(NULL)
+ , mButtons(0)
+{
+ wl_input_device_add_listener(mInputDevice,
+ &inputDeviceListener,
+ this);
+ wl_input_device_set_user_data(mInputDevice, this);
+}
+
+void QWaylandInputDevice::inputHandleMotion(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ int32_t x, int32_t y,
+ int32_t surface_x, int32_t surface_y)
+{
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window =
+ (QWaylandWindow *) wl_surface_get_user_data(inputDevice->mPointerFocus);
+
+ inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
+ inputDevice->mGlobalPos = QPoint(x, y);
+ QWindowSystemInterface::handleMouseEvent(window->widget(),
+ time,
+ inputDevice->mSurfacePos,
+ inputDevice->mGlobalPos,
+ inputDevice->mButtons);
+}
+
+void QWaylandInputDevice::inputHandleButton(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, uint32_t button, uint32_t state)
+{
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window =
+ (QWaylandWindow *) wl_surface_get_user_data(inputDevice->mPointerFocus);
+ Qt::MouseButton qt_button;
+
+ switch (button) {
+ case 272:
+ qt_button = Qt::LeftButton;
+ break;
+ case 273:
+ qt_button = Qt::RightButton;
+ break;
+ case 274:
+ qt_button = Qt::MidButton;
+ break;
+ default:
+ return;
+ }
+
+ if (state)
+ inputDevice->mButtons |= qt_button;
+ else
+ inputDevice->mButtons &= ~qt_button;
+
+ QWindowSystemInterface::handleMouseEvent(window->widget(),
+ time,
+ inputDevice->mSurfacePos,
+ inputDevice->mGlobalPos,
+ inputDevice->mButtons);
+}
+
+void QWaylandInputDevice::inputHandleKey(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, uint32_t key, uint32_t state)
+{
+}
+
+void QWaylandInputDevice::inputHandlePointerFocus(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t sx, int32_t sy)
+{
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window;
+
+ if (inputDevice->mPointerFocus) {
+ window = (QWaylandWindow *)
+ wl_surface_get_user_data(inputDevice->mPointerFocus);
+ QWindowSystemInterface::handleLeaveEvent(window->widget());
+ inputDevice->mPointerFocus = NULL;
+ }
+
+ if (surface) {
+ window = (QWaylandWindow *) wl_surface_get_user_data(surface);
+ QWindowSystemInterface::handleEnterEvent(window->widget());
+ inputDevice->mPointerFocus = surface;
+ }
+}
+
+void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ struct wl_array *keys)
+{
+ QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
+ QWaylandWindow *window;
+
+ if (inputDevice->mKeyboardFocus) {
+ window = (QWaylandWindow *)
+ wl_surface_get_user_data(inputDevice->mKeyboardFocus);
+ inputDevice->mKeyboardFocus = NULL;
+ }
+
+ if (surface) {
+ window = (QWaylandWindow *) wl_surface_get_user_data(surface);
+ inputDevice->mKeyboardFocus = surface;
+ }
+}
+
+const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = {
+ QWaylandInputDevice::inputHandleMotion,
+ QWaylandInputDevice::inputHandleButton,
+ QWaylandInputDevice::inputHandleKey,
+ QWaylandInputDevice::inputHandlePointerFocus,
+ QWaylandInputDevice::inputHandleKeyboardFocus,
+};
+
+void QWaylandDisplay::displayHandleGlobal(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version, void *data)
+{
+ Q_UNUSED(version);
+ QWaylandDisplay *qwd = (QWaylandDisplay *) data;
+
+ if (strcmp(interface, "compositor") == 0) {
+ qwd->mCompositor = wl_compositor_create(display, id);
+ } else if (strcmp(interface, "drm") == 0) {
+ qwd->mDrm = wl_drm_create(display, id);
+ wl_drm_add_listener(qwd->mDrm, &drmListener, qwd);
+ } else if (strcmp(interface, "shm") == 0) {
+ qwd->mShm = wl_shm_create(display, id);
+ } else if (strcmp(interface, "output") == 0) {
+ struct wl_output *output = wl_output_create(display, id);
+ wl_output_add_listener(output, &outputListener, qwd);
+ } else if (strcmp(interface, "input_device") == 0) {
+ QWaylandInputDevice *inputDevice = new QWaylandInputDevice(display, id);
+ qwd->mInputDevices.append(inputDevice);
+ }
+}
+
+static void initial_roundtrip(void *data)
+{
+ bool *done = (bool *) data;
+
+ *done = true;
+}
+
+static const char socket_name[] = "\0wayland";
+
+void QWaylandDisplay::eventDispatcher(void)
+{
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+}
+
+int
+QWaylandDisplay::sourceUpdate(uint32_t mask, void *data)
+{
+ QWaylandDisplay *qwd = (QWaylandDisplay *) data;
+
+ /* FIXME: We get a callback here when we ask wl_display for the
+ * fd, but at that point we don't have the socket notifier as we
+ * need the fd to create that. We'll probably need to split that
+ * API into get_fd and set_update_func functions. */
+ if (qwd->mWriteNotifier == NULL)
+ return 0;
+
+ qwd->mWriteNotifier->setEnabled(mask & WL_DISPLAY_WRITABLE);
+
+ return 0;
+}
+
+void QWaylandDisplay::flushRequests(void)
+{
+ wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
+}
+
+QWaylandDisplay::QWaylandDisplay(void)
+ : mWriteNotifier(0)
+{
+ drm_magic_t magic;
+ bool done;
+
+ mDisplay = wl_display_create(socket_name, sizeof socket_name);
+ if (mDisplay == NULL) {
+ fprintf(stderr, "failed to create display: %m\n");
+ return;
+ }
+
+ wl_display_add_global_listener(mDisplay,
+ QWaylandDisplay::displayHandleGlobal, this);
+
+ /* Process connection events. */
+ wl_display_sync_callback(mDisplay, initial_roundtrip, &done);
+ wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
+ done = false;
+ while (!done)
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+
+ mFd = open(mDeviceName, O_RDWR);
+ if (mFd < 0) {
+ qWarning("drm open failed: %m\n");
+ return;
+ }
+
+ if (drmGetMagic(mFd, &magic)) {
+ qWarning("DRI2: failed to get drm magic");
+ return;
+ }
+
+ /* Wait for authenticated event */
+ wl_drm_authenticate(mDrm, magic);
+ wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
+ while (!mAuthenticated)
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+
+ int fd = wl_display_get_fd(mDisplay, sourceUpdate, this);
+ mReadNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
+ connect(mReadNotifier,
+ SIGNAL(activated(int)), this, SLOT(eventDispatcher()));
+
+ mWriteNotifier = new QSocketNotifier(fd, QSocketNotifier::Write, this);
+ connect(mWriteNotifier,
+ SIGNAL(activated(int)), this, SLOT(flushRequests()));
+ mWriteNotifier->setEnabled(false);
+}
+
+QWaylandDisplay::~QWaylandDisplay(void)
+{
+ close(mFd);
+ wl_display_destroy(mDisplay);
+}
+
+QWaylandIntegration::QWaylandIntegration()
+ : mFontDb(new QFontconfigDatabase())
+ , mDisplay(new QWaylandDisplay())
+{
+}
+
+QList<QPlatformScreen *>
+QWaylandIntegration::screens() const
+{
+ return mDisplay->screens();
+}
+
+QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type) const
+{
+ return new QRasterPixmapData(type);
+}
+
+QWaylandWindow::QWaylandWindow(QWidget *window, QWaylandDisplay *display)
+ : QPlatformWindow(window)
+ , mDisplay(display)
+{
+ mSurface = mDisplay->createSurface();
+ wl_surface_set_user_data(mSurface, this);
+}
+
+QWaylandWindow::~QWaylandWindow()
+{
+ /* mDisplay->destroySurface() */
+}
+
+QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QWaylandWindow(widget, mDisplay);
+}
+
+QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId winId) const
+{
+ Q_UNUSED(winId);
+ return new QWaylandWindowSurface(widget, mDisplay);
+}
+
+QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
new file mode 100644
index 0000000..d777175
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMINTEGRATION_WAYLAND_H
+#define QPLATFORMINTEGRATION_WAYLAND_H
+
+#include <QSocketNotifier>
+#include <QObject>
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+
+#include <wayland-client.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandInputDevice;
+
+class QWaylandDisplay : public QObject {
+ Q_OBJECT;
+
+public:
+ QWaylandDisplay(void);
+ ~QWaylandDisplay(void);
+
+ QList<QPlatformScreen *> screens() const { return mScreens; }
+ struct wl_surface *createSurface();
+ struct wl_buffer *createShmBuffer(int fd, int width, int height,
+ uint32_t stride,
+ struct wl_visual *visual);
+ struct wl_visual *argbVisual();
+
+public slots:
+ void eventDispatcher(void);
+ void flushRequests(void);
+
+private:
+ struct wl_display *mDisplay;
+ struct wl_compositor *mCompositor;
+ struct wl_drm *mDrm;
+ struct wl_shm *mShm;
+ char *mDeviceName;
+ int mFd;
+ bool mAuthenticated;
+ QList<QPlatformScreen *> mScreens;
+ QList<QWaylandInputDevice *> mInputDevices;
+ QSocketNotifier *mReadNotifier;
+ QSocketNotifier *mWriteNotifier;
+
+ static void displayHandleGlobal(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version, void *data);
+
+ static void drmHandleDevice(void *data,
+ struct wl_drm *drm, const char *device);
+ static void drmHandleAuthenticated(void *data, struct wl_drm *drm);
+
+ static void outputHandleGeometry(void *data,
+ struct wl_output *output,
+ int32_t width, int32_t height);
+
+ static int sourceUpdate(uint32_t mask, void *data);
+
+ static const struct wl_drm_listener drmListener;
+ static const struct wl_output_listener outputListener;
+};
+
+class QWaylandScreen : public QPlatformScreen
+{
+public:
+ QWaylandScreen() {}
+
+ QRect geometry() const { return mGeometry; }
+ int depth() const { return mDepth; }
+ QImage::Format format() const { return mFormat; }
+
+public:
+ QRect mGeometry;
+ int mDepth;
+ QImage::Format mFormat;
+ QSize mPhysicalSize;
+ struct wl_output *mOutput;
+};
+
+
+class QWaylandWindow : public QPlatformWindow
+{
+public:
+ QWaylandWindow(QWidget *window, QWaylandDisplay *display);
+ ~QWaylandWindow();
+ struct wl_surface *surface() { return mSurface; }
+
+private:
+ struct wl_surface *mSurface;
+ QWaylandDisplay *mDisplay;
+};
+
+class QWaylandIntegration : public QPlatformIntegration
+{
+public:
+ QWaylandIntegration();
+
+ QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
+ QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+
+ QList<QPlatformScreen *> screens() const;
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+private:
+ QPlatformFontDatabase *mFontDb;
+ QWaylandDisplay *mDisplay;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp b/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp
new file mode 100644
index 0000000..f0f5018
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandwindowsurface.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenVG module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandintegration.h"
+#include "qwaylandwindowsurface.h"
+#include <QtCore/qdebug.h>
+#include <QtGui/private/qapplication_p.h>
+
+#include <wayland-client.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+QT_BEGIN_NAMESPACE
+
+QWaylandWindowSurface::QWaylandWindowSurface(QWidget *window,
+ QWaylandDisplay *display)
+ : QWindowSurface(window)
+ , mImage(0)
+ , mDisplay(display)
+{
+ //qDebug() << "QWaylandWindowSurface::QWaylandWindowSurface:" << (long)this;
+}
+
+QWaylandWindowSurface::~QWaylandWindowSurface()
+{
+}
+
+QPaintDevice *QWaylandWindowSurface::paintDevice()
+{
+ //qDebug() << "QWaylandWindowSurface::paintDevice";
+ return mImage;
+}
+
+void QWaylandWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(offset);
+ QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
+ QVector<QRect> rects = region.rects();
+ const QRect *r;
+ int i;
+
+ for (i = 0; i < rects.size(); i++) {
+ r = &rects.at(i);
+ wl_surface_damage(ww->surface(),
+ r->x(), r->y(), r->width(), r->height());
+ }
+}
+
+void QWaylandWindowSurface::resize(const QSize &size)
+{
+ //qDebug() << "QWaylandWindowSurface::setGeometry:" << (long)this << rect;
+ QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
+ QWindowSurface::resize(size);
+ QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
+
+ if (mImage != NULL && mImage->size() == size)
+ return;
+
+ if (mImage != NULL) {
+ delete mImage;
+ munmap(mData, mSize);
+ }
+
+ mStride = size.width() * 4;
+ mSize = mStride * size.height();
+ char filename[] = "/tmp/wayland-shm-XXXXXX";
+ int fd = mkstemp(filename);
+ if (fd < 0)
+ qWarning("open %s failed: %s", filename, strerror(errno));
+ if (ftruncate(fd, mSize) < 0)
+ qWarning("ftruncate failed: %s", strerror(errno));
+ mData = (uchar *)
+ mmap(NULL, mSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ unlink(filename);
+
+ if (mData == (uchar *) MAP_FAILED)
+ qWarning("mmap /dev/zero failed: %s", strerror(errno));
+
+ mImage = new QImage(mData, size.width(), size.height(), mStride, format);
+
+ struct wl_buffer *buffer =
+ mDisplay->createShmBuffer(fd, size.width(), size.height(),
+ mStride, mDisplay->argbVisual());
+ wl_surface_attach(ww->surface(), buffer);
+ wl_surface_map(ww->surface(), 0, 0, size.width(), size.height());
+ wl_buffer_destroy(buffer);
+ close(fd);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.h b/src/plugins/platforms/wayland/qwaylandwindowsurface.h
new file mode 100644
index 0000000..1054c51
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandwindowsurface.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenVG module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSURFACE_WAYLAND_H
+#define QWINDOWSURFACE_WAYLAND_H
+
+#include <QtGui/private/qwindowsurface_p.h>
+
+#include <QtGui/QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandWindowSurface : public QWindowSurface
+{
+public:
+ QWaylandWindowSurface(QWidget *window, QWaylandDisplay *display);
+ ~QWaylandWindowSurface();
+
+ QPaintDevice *paintDevice();
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size);
+
+private:
+ QImage *mImage;
+ uchar *mData;
+ int mSize;
+ int mStride;
+ QWaylandDisplay *mDisplay;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
new file mode 100644
index 0000000..62ff4df
--- /dev/null
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -0,0 +1,19 @@
+TARGET = qwayland
+include(../../qpluginbase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+SOURCES = main.cpp \
+ qwaylandintegration.cpp \
+ qwaylandwindowsurface.cpp
+
+HEADERS = qwaylandintegration.h \
+ qwaylandwindowsurface.h
+
+INCLUDEPATH += /usr/include/libdrm
+LIBS += -lwayland-client -ldrm
+
+include (../fontdatabases/fontconfig/fontconfig.pri)
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target