From a2d208c04a7db02f260be5b3e0ea82c769f69c0c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B8rgen=20Lind?= Date: Mon, 10 Jan 2011 15:48:20 +0100 Subject: [PATCH] Lighthouse:Wayland Moving some logic into files --- src/plugins/platforms/wayland/qwaylandcursor.cpp | 180 ++++++++ src/plugins/platforms/wayland/qwaylandcursor.h | 62 +++ src/plugins/platforms/wayland/qwaylanddisplay.cpp | 306 +++++++++++++ src/plugins/platforms/wayland/qwaylanddisplay.h | 125 ++++++ .../platforms/wayland/qwaylanddrmsurface.cpp | 4 +- .../platforms/wayland/qwaylandglcontext.cpp | 10 +- src/plugins/platforms/wayland/qwaylandglcontext.h | 72 +++ .../platforms/wayland/qwaylandinputdevice.cpp | 8 +- .../platforms/wayland/qwaylandintegration.cpp | 482 +-------------------- .../platforms/wayland/qwaylandintegration.h | 145 +------ src/plugins/platforms/wayland/qwaylandscreen.cpp | 43 ++ src/plugins/platforms/wayland/qwaylandscreen.h | 64 +++ .../platforms/wayland/qwaylandshmsurface.cpp | 3 +- src/plugins/platforms/wayland/qwaylandwindow.cpp | 113 +++++ src/plugins/platforms/wayland/qwaylandwindow.h | 80 ++++ .../platforms/wayland/qwaylandwindowsurface.h | 2 - src/plugins/platforms/wayland/wayland.pro | 13 +- 17 files changed, 1081 insertions(+), 631 deletions(-) create mode 100644 src/plugins/platforms/wayland/qwaylandcursor.cpp create mode 100644 src/plugins/platforms/wayland/qwaylandcursor.h create mode 100644 src/plugins/platforms/wayland/qwaylanddisplay.cpp create mode 100644 src/plugins/platforms/wayland/qwaylanddisplay.h create mode 100644 src/plugins/platforms/wayland/qwaylandglcontext.h create mode 100644 src/plugins/platforms/wayland/qwaylandscreen.cpp create mode 100644 src/plugins/platforms/wayland/qwaylandscreen.h create mode 100644 src/plugins/platforms/wayland/qwaylandwindow.cpp create mode 100644 src/plugins/platforms/wayland/qwaylandwindow.h diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp new file mode 100644 index 0000000..2a1e9a9 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "qwaylandcursor.h" + +#include "qwaylanddisplay.h" +#include "qwaylandwindowsurface.h" +#include "qwaylandinputdevice.h" + +#include + +#define DATADIR "/usr/share" + +static const struct pointer_image { + const char *filename; + int hotspot_x, hotspot_y; +} pointer_images[] = { + /* FIXME: Half of these are wrong... */ + /* Qt::ArrowCursor */ + { DATADIR "/wayland/left_ptr.png", 10, 5 }, + /* Qt::UpArrowCursor */ + { DATADIR "/wayland/top_side.png", 18, 8 }, + /* Qt::CrossCursor */ + { DATADIR "/wayland/top_side.png", 18, 8 }, + /* Qt::WaitCursor */ + { DATADIR "/wayland/top_side.png", 18, 8 }, + /* Qt::IBeamCursor */ + { DATADIR "/wayland/xterm.png", 15, 15 }, + /* Qt::SizeVerCursor */ + { DATADIR "/wayland/top_side.png", 18, 8 }, + /* Qt::SizeHorCursor */ + { DATADIR "/wayland/bottom_left_corner.png", 6, 30 }, + /* Qt::SizeBDiagCursor */ + { DATADIR "/wayland/bottom_right_corner.png", 28, 28 }, + /* Qt::SizeFDiagCursor */ + { DATADIR "/wayland/bottom_side.png", 16, 20 }, + /* Qt::SizeAllCursor */ + { DATADIR "/wayland/left_side.png", 10, 20 }, + /* Qt::BlankCursor */ + { DATADIR "/wayland/right_side.png", 30, 19 }, + /* Qt::SplitVCursor */ + { DATADIR "/wayland/sb_v_double_arrow.png", 15, 15 }, + /* Qt::SplitHCursor */ + { DATADIR "/wayland/sb_h_double_arrow.png", 15, 15 }, + /* Qt::PointingHandCursor */ + { DATADIR "/wayland/hand2.png", 14, 8 }, + /* Qt::ForbiddenCursor */ + { DATADIR "/wayland/top_right_corner.png", 26, 8 }, + /* Qt::WhatsThisCursor */ + { DATADIR "/wayland/top_right_corner.png", 26, 8 }, + /* Qt::BusyCursor */ + { DATADIR "/wayland/top_right_corner.png", 26, 8 }, + /* Qt::OpenHandCursor */ + { DATADIR "/wayland/hand1.png", 18, 11 }, + /* Qt::ClosedHandCursor */ + { DATADIR "/wayland/grabbing.png", 20, 17 }, + /* Qt::DragCopyCursor */ + { DATADIR "/wayland/dnd-copy.png", 13, 13 }, + /* Qt::DragMoveCursor */ + { DATADIR "/wayland/dnd-move.png", 13, 13 }, + /* Qt::DragLinkCursor */ + { DATADIR "/wayland/dnd-link.png", 13, 13 }, +}; + +void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget) +{ + const struct pointer_image *p; + + if (widget == NULL) + return; + + p = NULL; + + switch (cursor->shape()) { + case Qt::ArrowCursor: + p = &pointer_images[cursor->shape()]; + break; + case Qt::UpArrowCursor: + case Qt::CrossCursor: + case Qt::WaitCursor: + break; + case Qt::IBeamCursor: + p = &pointer_images[cursor->shape()]; + break; + case Qt::SizeVerCursor: /* 5 */ + case Qt::SizeHorCursor: + case Qt::SizeBDiagCursor: + case Qt::SizeFDiagCursor: + case Qt::SizeAllCursor: + case Qt::BlankCursor: /* 10 */ + break; + case Qt::SplitVCursor: + case Qt::SplitHCursor: + case Qt::PointingHandCursor: + p = &pointer_images[cursor->shape()]; + break; + case Qt::ForbiddenCursor: + case Qt::WhatsThisCursor: /* 15 */ + case Qt::BusyCursor: + break; + case Qt::OpenHandCursor: + case Qt::ClosedHandCursor: + case Qt::DragCopyCursor: + case Qt::DragMoveCursor: /* 20 */ + case Qt::DragLinkCursor: + p = &pointer_images[cursor->shape()]; + break; + + default: + case Qt::BitmapCursor: + break; + } + + if (!p) { + p = &pointer_images[0]; + qWarning("unhandled cursor %d", cursor->shape()); + } + + QImageReader reader(p->filename); + + if (mBuffer == NULL || mBuffer->mImage.size() != reader.size()) { + if (mBuffer) + delete mBuffer; + + mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(), + QImage::Format_ARGB32); + } + + reader.read(&mBuffer->mImage); + + mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y); +} + +void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y) +{ + /* Qt doesn't tell us which input device we should set the cursor + * for, so set it for all devices. */ + for (int i = 0; i < mInputDevices.count(); i++) { + QWaylandInputDevice *inputDevice = mInputDevices.at(i); + inputDevice->attach(buffer, x, y); + } +} diff --git a/src/plugins/platforms/wayland/qwaylandcursor.h b/src/plugins/platforms/wayland/qwaylandcursor.h new file mode 100644 index 0000000..8c9d263 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandcursor.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 QWAYLANDCURSOR_H +#define QWAYLANDCURSOR_H + +#include + +class QWaylandShmBuffer; +class QWaylandDisplay; + +class QWaylandCursor : QPlatformCursor { +public: + QWaylandCursor(QWaylandDisplay *display, + QPlatformScreen *screen) + : QPlatformCursor(screen) + , mBuffer(0), mDisplay(display) { } + + void changeCursor(QCursor *cursor, QWidget *widget); + QWaylandShmBuffer *mBuffer; + QWaylandDisplay *mDisplay; +}; + +#endif // QWAYLANDCURSOR_H diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp new file mode 100644 index 0000000..8446777 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -0,0 +1,306 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "qwaylanddisplay.h" + +#include "qwaylandwindow.h" +#include "qwaylandscreen.h" +#include "qwaylandcursor.h" +#include "qwaylandinputdevice.h" + +#include +#include +#include + +extern "C" { +#include +} + +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_buffer *QWaylandDisplay::createDrmBuffer(int name, + int width, int height, + uint32_t stride, + struct wl_visual *visual) +{ + return wl_drm_create_buffer(mDrm, name, width, height, stride, visual); +} + +struct wl_visual *QWaylandDisplay::rgbVisual() +{ + return wl_display_get_rgb_visual(mDisplay); +} + +struct wl_visual *QWaylandDisplay::argbVisual() +{ + return wl_display_get_argb_visual(mDisplay); +} + +struct wl_visual *QWaylandDisplay::argbPremultipliedVisual() +{ + return wl_display_get_premultiplied_argb_visual(mDisplay); +} + +void QWaylandDisplay::drmHandleDevice(void *data, + struct wl_drm *drm, const char *device) +{ + Q_UNUSED(drm); + QWaylandDisplay *qwd = (QWaylandDisplay *) data; + drm_magic_t magic; + + qwd->mDeviceName = strdup(device); + + qwd->mFd = open(qwd->mDeviceName, O_RDWR); + if (qwd->mFd < 0) { + qWarning("drm open failed: %m"); + return; + } + + if (drmGetMagic(qwd->mFd, &magic)) { + qWarning("DRI2: failed to get drm magic"); + return; + } + + wl_drm_authenticate(qwd->mDrm, magic); +} + +void QWaylandDisplay::drmHandleAuthenticated(void *data, struct wl_drm *drm) +{ + Q_UNUSED(drm); + QWaylandDisplay *qwd = (QWaylandDisplay *) data; + EGLint major, minor; + const char *extensions; + + qwd->mEglDisplay = eglGetDRMDisplayMESA(qwd->mFd); + if (qwd->mEglDisplay == NULL) { + qWarning("failed to create display"); + return; + } + + if (!eglInitialize(qwd->mEglDisplay, &major, &minor)) { + qWarning("failed to initialize display"); + qwd->mEglDisplay = NULL; + return; + } + + extensions = eglQueryString(qwd->mEglDisplay, EGL_EXTENSIONS); + if (!strstr(extensions, "EGL_KHR_surfaceless_gles2")) { + qWarning("EGL_KHR_surfaceless_opengles2 not available"); + eglTerminate(qwd->mEglDisplay); + qwd->mEglDisplay = NULL; + return; + } +} + +const struct wl_drm_listener QWaylandDisplay::drmListener = { + QWaylandDisplay::drmHandleDevice, + QWaylandDisplay::drmHandleAuthenticated +}; + +void QWaylandDisplay::shellHandleConfigure(void *data, struct wl_shell *shell, + uint32_t time, uint32_t edges, + struct wl_surface *surface, + int32_t width, int32_t height) +{ + Q_UNUSED(data); + Q_UNUSED(shell); + Q_UNUSED(time); + Q_UNUSED(edges); + QWaylandWindow *ww = (QWaylandWindow *) wl_surface_get_user_data(surface); + + ww->configure(time, edges, 0, 0, width, height); +} + +const struct wl_shell_listener QWaylandDisplay::shellListener = { + QWaylandDisplay::shellHandleConfigure, +}; + +void QWaylandDisplay::outputHandleGeometry(void *data, + struct wl_output *output, + int32_t x, int32_t y, + int32_t width, int32_t height) +{ + Q_UNUSED(output); + QWaylandDisplay *qwd = (QWaylandDisplay *) data; + QWaylandScreen *screen; + + screen = new QWaylandScreen(); + screen->mGeometry = QRect(x, y, width, height); + screen->mDepth = 32; + screen->mFormat = QImage::Format_ARGB32_Premultiplied; + screen->mOutput = output; + + new QWaylandCursor(qwd, screen); + + qwd->mScreens.append(screen); +} + +const struct wl_output_listener QWaylandDisplay::outputListener = { + QWaylandDisplay::outputHandleGeometry +}; + +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, "shell") == 0) { + qwd->mShell = wl_shell_create(display, id); + wl_shell_add_listener(qwd->mShell, &shellListener, qwd); + } 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 roundtripCallback(void *data) +{ + bool *done = (bool *) data; + + *done = true; +} + +static void forceRoundtrip(struct wl_display *display) +{ + bool done; + + wl_display_sync_callback(display, roundtripCallback, &done); + wl_display_iterate(display, WL_DISPLAY_WRITABLE); + done = false; + while (!done) + wl_display_iterate(display, WL_DISPLAY_READABLE); +} + +static const char *socket_name = NULL; + +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) +{ + mDisplay = wl_display_connect(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_iterate(mDisplay, WL_DISPLAY_READABLE); + if (!mShm || !mDeviceName) + forceRoundtrip(mDisplay); + + /* Force a roundtrip to finish the drm authentication so we + * initialize EGL before proceeding */ + forceRoundtrip(mDisplay); + if (mEglDisplay == NULL) + qDebug("EGL not available"); + else + qDebug("EGL initialized"); + + 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); +} diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h new file mode 100644 index 0000000..7d989a9 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 QWAYLANDDISPLAY_H +#define QWAYLANDDISPLAY_H + +#include + +#include + +#define MESA_EGL_NO_X11_HEADERS +#define EGL_EGLEXT_PROTOTYPES +#include +#include + +class QWaylandInputDevice; +class QSocketNotifier; +class QWaylandBuffer; +class QPlatformScreen; + +class QWaylandDisplay : public QObject { + Q_OBJECT; + +public: + QWaylandDisplay(void); + ~QWaylandDisplay(void); + + QList 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_buffer *createDrmBuffer(int name, int width, int height, + uint32_t stride, + struct wl_visual *visual); + struct wl_visual *rgbVisual(); + struct wl_visual *argbVisual(); + struct wl_visual *argbPremultipliedVisual(); + EGLDisplay eglDisplay() { return mEglDisplay; } + + void setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y); + +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; + struct wl_shell *mShell; + char *mDeviceName; + int mFd; + QList mScreens; + QList mInputDevices; + QSocketNotifier *mReadNotifier; + QSocketNotifier *mWriteNotifier; + EGLDisplay mEglDisplay; + + 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 x, int32_t y, + int32_t width, int32_t height); + + static void shellHandleConfigure(void *data, struct wl_shell *shell, + uint32_t time, uint32_t edges, + struct wl_surface *surface, + 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; + static const struct wl_shell_listener shellListener; +}; + +#endif // QWAYLANDDISPLAY_H diff --git a/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp b/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp index cb4445c..1a7683e 100644 --- a/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp @@ -49,8 +49,10 @@ #include #include -#include "qwaylandintegration.h" +#include "qwaylanddisplay.h" #include "qwaylandwindowsurface.h" +#include "qwaylandwindow.h" +#include "qwaylandscreen.h" #include #include diff --git a/src/plugins/platforms/wayland/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/qwaylandglcontext.cpp index 264da2e..24abcf8 100644 --- a/src/plugins/platforms/wayland/qwaylandglcontext.cpp +++ b/src/plugins/platforms/wayland/qwaylandglcontext.cpp @@ -1,7 +1,8 @@ -#define GL_GLEXT_PROTOTYPES -#include -#include +#include "qwaylandglcontext.h" +#include "qwaylanddisplay.h" +#include "qwaylandwindow.h" +#include "qwaylandwindowsurface.h" #include "qfontconfigdatabase.h" #include @@ -19,9 +20,6 @@ #include #include -#include "qwaylandintegration.h" -#include "qwaylandwindowsurface.h" - #include #include diff --git a/src/plugins/platforms/wayland/qwaylandglcontext.h b/src/plugins/platforms/wayland/qwaylandglcontext.h new file mode 100644 index 0000000..6e3c108 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandglcontext.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 QWAYLANDGLCONTEXT_H +#define QWAYLANDGLCONTEXT_H + +#include + +class QWaylandDisplay; +class QWaylandWindow; + +#define GL_GLEXT_PROTOTYPES +#include +#include + +class QWaylandGLContext : public QPlatformGLContext { +public: + QWaylandGLContext(QWaylandDisplay *wd, QWaylandWindow *window, const QPlatformWindowFormat &format); + ~QWaylandGLContext(); + void makeCurrent(); + void doneCurrent(); + void swapBuffers(); + void* getProcAddress(const QString&); + QPlatformWindowFormat platformWindowFormat() const { return mFormat; } + +private: + QPlatformWindowFormat mFormat; + QWaylandDisplay *mDisplay; + QWaylandWindow *mWindow; + GLuint parentFbo, parentRbo; +}; + + +#endif // QWAYLANDGLCONTEXT_H diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 6d489b6..77c5815 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -1,6 +1,10 @@ -#include +#include "qwaylandinputdevice.h" + #include "qwaylandintegration.h" #include "qwaylandwindowsurface.h" +#include "qwaylandwindow.h" + +#include #include #include @@ -51,7 +55,7 @@ void QWaylandInputDevice::inputHandleMotion(void *data, time, inputDevice->mSurfacePos, inputDevice->mGlobalPos, - inputDevice->mButtons); + inputDevice->mButtons); } void QWaylandInputDevice::inputHandleButton(void *data, diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 61f696c..a6fdc2e 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -1,419 +1,17 @@ -#include "qfontconfigdatabase.h" - -#include -#include -#include -#include - -#include - -#include -#include - #include "qwaylandintegration.h" -#include "qwaylandwindowsurface.h" - -#include -#include - -extern "C" { -#include -} - -class QWaylandCursor : QPlatformCursor { -public: - QWaylandCursor(QWaylandDisplay *display, - QPlatformScreen *screen) - : QPlatformCursor(screen) - , mBuffer(0), mDisplay(display) { } - - void changeCursor(QCursor *cursor, QWidget *widget); - QWaylandShmBuffer *mBuffer; - QWaylandDisplay *mDisplay; -}; - -#define DATADIR "/usr/share" - -static const struct pointer_image { - const char *filename; - int hotspot_x, hotspot_y; -} pointer_images[] = { - /* FIXME: Half of these are wrong... */ - /* Qt::ArrowCursor */ - { DATADIR "/wayland/left_ptr.png", 10, 5 }, - /* Qt::UpArrowCursor */ - { DATADIR "/wayland/top_side.png", 18, 8 }, - /* Qt::CrossCursor */ - { DATADIR "/wayland/top_side.png", 18, 8 }, - /* Qt::WaitCursor */ - { DATADIR "/wayland/top_side.png", 18, 8 }, - /* Qt::IBeamCursor */ - { DATADIR "/wayland/xterm.png", 15, 15 }, - /* Qt::SizeVerCursor */ - { DATADIR "/wayland/top_side.png", 18, 8 }, - /* Qt::SizeHorCursor */ - { DATADIR "/wayland/bottom_left_corner.png", 6, 30 }, - /* Qt::SizeBDiagCursor */ - { DATADIR "/wayland/bottom_right_corner.png", 28, 28 }, - /* Qt::SizeFDiagCursor */ - { DATADIR "/wayland/bottom_side.png", 16, 20 }, - /* Qt::SizeAllCursor */ - { DATADIR "/wayland/left_side.png", 10, 20 }, - /* Qt::BlankCursor */ - { DATADIR "/wayland/right_side.png", 30, 19 }, - /* Qt::SplitVCursor */ - { DATADIR "/wayland/sb_v_double_arrow.png", 15, 15 }, - /* Qt::SplitHCursor */ - { DATADIR "/wayland/sb_h_double_arrow.png", 15, 15 }, - /* Qt::PointingHandCursor */ - { DATADIR "/wayland/hand2.png", 14, 8 }, - /* Qt::ForbiddenCursor */ - { DATADIR "/wayland/top_right_corner.png", 26, 8 }, - /* Qt::WhatsThisCursor */ - { DATADIR "/wayland/top_right_corner.png", 26, 8 }, - /* Qt::BusyCursor */ - { DATADIR "/wayland/top_right_corner.png", 26, 8 }, - /* Qt::OpenHandCursor */ - { DATADIR "/wayland/hand1.png", 18, 11 }, - /* Qt::ClosedHandCursor */ - { DATADIR "/wayland/grabbing.png", 20, 17 }, - /* Qt::DragCopyCursor */ - { DATADIR "/wayland/dnd-copy.png", 13, 13 }, - /* Qt::DragMoveCursor */ - { DATADIR "/wayland/dnd-move.png", 13, 13 }, - /* Qt::DragLinkCursor */ - { DATADIR "/wayland/dnd-link.png", 13, 13 }, -}; - -void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget) -{ - const struct pointer_image *p; - - if (widget == NULL) - return; - - p = NULL; - - switch (cursor->shape()) { - case Qt::ArrowCursor: - p = &pointer_images[cursor->shape()]; - break; - case Qt::UpArrowCursor: - case Qt::CrossCursor: - case Qt::WaitCursor: - break; - case Qt::IBeamCursor: - p = &pointer_images[cursor->shape()]; - break; - case Qt::SizeVerCursor: /* 5 */ - case Qt::SizeHorCursor: - case Qt::SizeBDiagCursor: - case Qt::SizeFDiagCursor: - case Qt::SizeAllCursor: - case Qt::BlankCursor: /* 10 */ - break; - case Qt::SplitVCursor: - case Qt::SplitHCursor: - case Qt::PointingHandCursor: - p = &pointer_images[cursor->shape()]; - break; - case Qt::ForbiddenCursor: - case Qt::WhatsThisCursor: /* 15 */ - case Qt::BusyCursor: - break; - case Qt::OpenHandCursor: - case Qt::ClosedHandCursor: - case Qt::DragCopyCursor: - case Qt::DragMoveCursor: /* 20 */ - case Qt::DragLinkCursor: - p = &pointer_images[cursor->shape()]; - break; - - default: - case Qt::BitmapCursor: - break; - } - - if (!p) { - p = &pointer_images[0]; - qWarning("unhandled cursor %d", cursor->shape()); - } - - QImageReader reader(p->filename); - - if (mBuffer == NULL || mBuffer->mImage.size() != reader.size()) { - if (mBuffer) - delete mBuffer; - - mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(), - QImage::Format_ARGB32); - } - - reader.read(&mBuffer->mImage); - - mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y); -} - -void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y) -{ - /* Qt doesn't tell us which input device we should set the cursor - * for, so set it for all devices. */ - for (int i = 0; i < mInputDevices.count(); i++) { - QWaylandInputDevice *inputDevice = mInputDevices.at(i); - inputDevice->attach(buffer, x, y); - } -} - -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_buffer *QWaylandDisplay::createDrmBuffer(int name, - int width, int height, - uint32_t stride, - struct wl_visual *visual) -{ - return wl_drm_create_buffer(mDrm, name, width, height, stride, visual); -} - -struct wl_visual *QWaylandDisplay::rgbVisual() -{ - return wl_display_get_rgb_visual(mDisplay); -} - -struct wl_visual *QWaylandDisplay::argbVisual() -{ - return wl_display_get_argb_visual(mDisplay); -} - -struct wl_visual *QWaylandDisplay::argbPremultipliedVisual() -{ - return wl_display_get_premultiplied_argb_visual(mDisplay); -} - -void QWaylandDisplay::drmHandleDevice(void *data, - struct wl_drm *drm, const char *device) -{ - Q_UNUSED(drm); - QWaylandDisplay *qwd = (QWaylandDisplay *) data; - drm_magic_t magic; - - qwd->mDeviceName = strdup(device); - - qwd->mFd = open(qwd->mDeviceName, O_RDWR); - if (qwd->mFd < 0) { - qWarning("drm open failed: %m"); - return; - } - - if (drmGetMagic(qwd->mFd, &magic)) { - qWarning("DRI2: failed to get drm magic"); - return; - } - - wl_drm_authenticate(qwd->mDrm, magic); -} - -void QWaylandDisplay::drmHandleAuthenticated(void *data, struct wl_drm *drm) -{ - Q_UNUSED(drm); - QWaylandDisplay *qwd = (QWaylandDisplay *) data; - EGLint major, minor; - const char *extensions; - - qwd->mEglDisplay = eglGetDRMDisplayMESA(qwd->mFd); - if (qwd->mEglDisplay == NULL) { - qWarning("failed to create display"); - return; - } - - if (!eglInitialize(qwd->mEglDisplay, &major, &minor)) { - qWarning("failed to initialize display"); - qwd->mEglDisplay = NULL; - return; - } - - extensions = eglQueryString(qwd->mEglDisplay, EGL_EXTENSIONS); - if (!strstr(extensions, "EGL_KHR_surfaceless_gles2")) { - qWarning("EGL_KHR_surfaceless_opengles2 not available"); - eglTerminate(qwd->mEglDisplay); - qwd->mEglDisplay = NULL; - return; - } -} - -const struct wl_drm_listener QWaylandDisplay::drmListener = { - QWaylandDisplay::drmHandleDevice, - QWaylandDisplay::drmHandleAuthenticated -}; - -void QWaylandDisplay::shellHandleConfigure(void *data, struct wl_shell *shell, - uint32_t time, uint32_t edges, - struct wl_surface *surface, - int32_t width, int32_t height) -{ - Q_UNUSED(data); - Q_UNUSED(shell); - Q_UNUSED(time); - Q_UNUSED(edges); - QWaylandWindow *ww = (QWaylandWindow *) wl_surface_get_user_data(surface); - - ww->configure(time, edges, 0, 0, width, height); -} -const struct wl_shell_listener QWaylandDisplay::shellListener = { - QWaylandDisplay::shellHandleConfigure, -}; - -void QWaylandDisplay::outputHandleGeometry(void *data, - struct wl_output *output, - int32_t x, int32_t y, - int32_t width, int32_t height) -{ - Q_UNUSED(output); - QWaylandDisplay *qwd = (QWaylandDisplay *) data; - QWaylandScreen *screen; - - screen = new QWaylandScreen(); - screen->mGeometry = QRect(x, y, width, height); - screen->mDepth = 32; - screen->mFormat = QImage::Format_ARGB32_Premultiplied; - screen->mOutput = output; - - new QWaylandCursor(qwd, screen); - - qwd->mScreens.append(screen); -} - -const struct wl_output_listener QWaylandDisplay::outputListener = { - QWaylandDisplay::outputHandleGeometry -}; - -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, "shell") == 0) { - qwd->mShell = wl_shell_create(display, id); - wl_shell_add_listener(qwd->mShell, &shellListener, qwd); - } 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 roundtripCallback(void *data) -{ - bool *done = (bool *) data; - - *done = true; -} - -static void forceRoundtrip(struct wl_display *display) -{ - bool done; - - wl_display_sync_callback(display, roundtripCallback, &done); - wl_display_iterate(display, WL_DISPLAY_WRITABLE); - done = false; - while (!done) - wl_display_iterate(display, WL_DISPLAY_READABLE); -} - -static const char *socket_name = NULL; - -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) -{ - mDisplay = wl_display_connect(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_iterate(mDisplay, WL_DISPLAY_READABLE); - if (!mShm || !mDeviceName) - forceRoundtrip(mDisplay); - - /* Force a roundtrip to finish the drm authentication so we - * initialize EGL before proceeding */ - forceRoundtrip(mDisplay); - if (mEglDisplay == NULL) - qDebug("EGL not available"); - else - qDebug("EGL initialized"); +#include "qwaylanddisplay.h" +#include "qwaylandwindowsurface.h" +#include "qwaylandwindow.h" - int fd = wl_display_get_fd(mDisplay, sourceUpdate, this); - mReadNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); - connect(mReadNotifier, - SIGNAL(activated(int)), this, SLOT(eventDispatcher())); +#include "qfontconfigdatabase.h" - mWriteNotifier = new QSocketNotifier(fd, QSocketNotifier::Write, this); - connect(mWriteNotifier, - SIGNAL(activated(int)), this, SLOT(flushRequests())); - mWriteNotifier->setEnabled(false); -} +#include +#include +#include -QWaylandDisplay::~QWaylandDisplay(void) -{ - close(mFd); - wl_display_destroy(mDisplay); -} +#include +#include QWaylandIntegration::QWaylandIntegration(bool useOpenGL) : mFontDb(new QFontconfigDatabase()) @@ -435,69 +33,7 @@ QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type) return new QRasterPixmapData(type); } -QWaylandWindow::QWaylandWindow(QWidget *window, QWaylandDisplay *display) - : QPlatformWindow(window) - , mSurface(0) - , mDisplay(display) - , mGLContext(0) - , mBuffer(0) -{ - static WId id = 1; - - mWindowId = id++; -} - -QWaylandWindow::~QWaylandWindow() -{ - if (mGLContext) - delete mGLContext; -} -WId QWaylandWindow::winId() const -{ - return mWindowId; -} - -void QWaylandWindow::setParent(const QPlatformWindow *parent) -{ - QWaylandWindow *wParent = (QWaylandWindow *)parent; - - mParentWindow = wParent; -} - -void QWaylandWindow::setVisible(bool visible) -{ - if (visible) { - mSurface = mDisplay->createSurface(); - wl_surface_set_user_data(mSurface, this); - attach(mBuffer); - } else { - wl_surface_destroy(mSurface); - mSurface = NULL; - } -} - -void QWaylandWindow::attach(QWaylandBuffer *buffer) -{ - QRect geometry = widget()->geometry(); - - mBuffer = buffer; - if (mSurface) { - wl_surface_attach(mSurface, mBuffer->mBuffer,geometry.x(),geometry.y()); - wl_surface_map_toplevel(mSurface); - } -} - -void QWaylandWindow::configure(uint32_t time, uint32_t edges, - int32_t x, int32_t y, - int32_t width, int32_t height) -{ - Q_UNUSED(time); - Q_UNUSED(edges); - QRect geometry = QRect(x, y, width, height); - - QWindowSystemInterface::handleGeometryChange(widget(), geometry); -} QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const { diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index 84afcb4..d707612 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -42,138 +42,12 @@ #ifndef QPLATFORMINTEGRATION_WAYLAND_H #define QPLATFORMINTEGRATION_WAYLAND_H -#include -#include #include -#include -#include -#include -#include "qgl.h" - -#include - -#include -#include "qwaylandinputdevice.h" - -#define MESA_EGL_NO_X11_HEADERS -#define EGL_EGLEXT_PROTOTYPES -#include -#include QT_BEGIN_NAMESPACE class QWaylandBuffer; - -class QWaylandDisplay : public QObject { - Q_OBJECT; - -public: - QWaylandDisplay(void); - ~QWaylandDisplay(void); - - QList 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_buffer *createDrmBuffer(int name, int width, int height, - uint32_t stride, - struct wl_visual *visual); - struct wl_visual *rgbVisual(); - struct wl_visual *argbVisual(); - struct wl_visual *argbPremultipliedVisual(); - EGLDisplay eglDisplay() { return mEglDisplay; } - - void setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y); - -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; - struct wl_shell *mShell; - char *mDeviceName; - int mFd; - QList mScreens; - QList mInputDevices; - QSocketNotifier *mReadNotifier; - QSocketNotifier *mWriteNotifier; - EGLDisplay mEglDisplay; - - 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 x, int32_t y, - int32_t width, int32_t height); - - static void shellHandleConfigure(void *data, struct wl_shell *shell, - uint32_t time, uint32_t edges, - struct wl_surface *surface, - 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; - static const struct wl_shell_listener shellListener; -}; - -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; } - - void setVisible(bool visible); - void configure(uint32_t time, uint32_t edges, - int32_t x, int32_t y, int32_t width, int32_t height); - WId winId() const; - void setParent(const QPlatformWindow *parent); - QPlatformGLContext *glContext() const; - void attach(QWaylandBuffer *buffer); - QWaylandBuffer *getBuffer(void) { return mBuffer; } - QWaylandWindow *getParentWindow(void) { return mParentWindow; } - -private: - struct wl_surface *mSurface; - QWaylandDisplay *mDisplay; - QPlatformGLContext *mGLContext; - WId mWindowId; - - QWaylandBuffer *mBuffer; - QWaylandWindow *mParentWindow; -}; +class QWaylandDisplay; class QWaylandIntegration : public QPlatformIntegration { @@ -194,23 +68,6 @@ private: bool mUseOpenGL; }; -class QWaylandGLContext : public QPlatformGLContext { -public: - QWaylandGLContext(QWaylandDisplay *wd, QWaylandWindow *window, const QPlatformWindowFormat &format); - ~QWaylandGLContext(); - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString&); - QPlatformWindowFormat platformWindowFormat() const { return mFormat; } - -private: - QPlatformWindowFormat mFormat; - QWaylandDisplay *mDisplay; - QWaylandWindow *mWindow; - GLuint parentFbo, parentRbo; -}; - QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp new file mode 100644 index 0000000..4a7e727 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "qwaylandscreen.h" + diff --git a/src/plugins/platforms/wayland/qwaylandscreen.h b/src/plugins/platforms/wayland/qwaylandscreen.h new file mode 100644 index 0000000..808266e --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandscreen.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 QWAYLANDSCREEN_H +#define QWAYLANDSCREEN_H + +#include + +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; +}; + +#endif // QWAYLANDSCREEN_H diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp index 004b93a..1c3a26c 100644 --- a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp @@ -42,8 +42,9 @@ #include #include -#include "qwaylandintegration.h" +#include "qwaylanddisplay.h" #include "qwaylandwindowsurface.h" +#include "qwaylandwindow.h" #include #include diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp new file mode 100644 index 0000000..4f696b0 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the config.tests 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 "qwaylandwindow.h" + +#include "qwaylanddisplay.h" +#include "qwaylandwindowsurface.h" +#include "qwaylandglcontext.h" + +#include +#include + +QWaylandWindow::QWaylandWindow(QWidget *window, QWaylandDisplay *display) + : QPlatformWindow(window) + , mSurface(0) + , mDisplay(display) + , mGLContext(0) + , mBuffer(0) +{ + static WId id = 1; + + mWindowId = id++; +} + +QWaylandWindow::~QWaylandWindow() +{ + if (mGLContext) + delete mGLContext; +} + +WId QWaylandWindow::winId() const +{ + return mWindowId; +} + +void QWaylandWindow::setParent(const QPlatformWindow *parent) +{ + QWaylandWindow *wParent = (QWaylandWindow *)parent; + + mParentWindow = wParent; +} + +void QWaylandWindow::setVisible(bool visible) +{ + if (visible) { + mSurface = mDisplay->createSurface(); + wl_surface_set_user_data(mSurface, this); + attach(mBuffer); + } else { + wl_surface_destroy(mSurface); + mSurface = NULL; + } +} + +void QWaylandWindow::attach(QWaylandBuffer *buffer) +{ + QRect geometry = widget()->geometry(); + + mBuffer = buffer; + if (mSurface) { + wl_surface_attach(mSurface, mBuffer->mBuffer,geometry.x(),geometry.y()); + wl_surface_map_toplevel(mSurface); + } +} + +void QWaylandWindow::configure(uint32_t time, uint32_t edges, + int32_t x, int32_t y, + int32_t width, int32_t height) +{ + Q_UNUSED(time); + Q_UNUSED(edges); + QRect geometry = QRect(x, y, width, height); + + QWindowSystemInterface::handleGeometryChange(widget(), geometry); +} diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h new file mode 100644 index 0000000..d5cc923 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the config.tests 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 QWAYLANDWINDOW_H +#define QWAYLANDWINDOW_H + +#include + +#include + +class QWaylandDisplay; +class QWaylandBuffer; + +class QWaylandWindow : public QPlatformWindow +{ +public: + QWaylandWindow(QWidget *window, QWaylandDisplay *display); + ~QWaylandWindow(); + struct wl_surface *surface() { return mSurface; } + + void setVisible(bool visible); + void configure(uint32_t time, uint32_t edges, + int32_t x, int32_t y, int32_t width, int32_t height); + WId winId() const; + void setParent(const QPlatformWindow *parent); + QPlatformGLContext *glContext() const; + void attach(QWaylandBuffer *buffer); + QWaylandBuffer *getBuffer(void) { return mBuffer; } + QWaylandWindow *getParentWindow(void) { return mParentWindow; } + +private: + struct wl_surface *mSurface; + QWaylandDisplay *mDisplay; + QPlatformGLContext *mGLContext; + WId mWindowId; + + QWaylandBuffer *mBuffer; + QWaylandWindow *mParentWindow; +}; + + +#endif // QWAYLANDWINDOW_H diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.h b/src/plugins/platforms/wayland/qwaylandwindowsurface.h index 21c48f9..db57619 100644 --- a/src/plugins/platforms/wayland/qwaylandwindowsurface.h +++ b/src/plugins/platforms/wayland/qwaylandwindowsurface.h @@ -52,8 +52,6 @@ #include #include -#include - QT_BEGIN_NAMESPACE class QWaylandDisplay; diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro index 4c01fa2..784a248 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -8,10 +8,19 @@ SOURCES = main.cpp \ qwaylandshmsurface.cpp \ qwaylanddrmsurface.cpp \ qwaylandinputdevice.cpp \ - qwaylandglcontext.cpp + qwaylandglcontext.cpp \ + qwaylandcursor.cpp \ + qwaylanddisplay.cpp \ + qwaylandwindow.cpp \ + qwaylandscreen.cpp HEADERS = qwaylandintegration.h \ - qwaylandwindowsurface.h + qwaylandwindowsurface.h \ + qwaylandcursor.h \ + qwaylanddisplay.h \ + qwaylandwindow.h \ + qwaylandscreen.h \ + qwaylandglcontext.h contains(QT_CONFIG, opengl) { QT += opengl -- 2.7.4