Move wayland into a client directory not under the plugins src folder

And make wayland common files into a library, exporting all classes. Now
there is no need to do bulild hacks to make your own version of the
wayland plugin.

Change-Id: Ib4872863dfb5ab3f2bc0f4a94ae16fc1e7b63b88
Reviewed-by: Andy Nichols <andy.nichols@digia.com>
This commit is contained in:
Jorgen Lind 2013-11-14 13:22:13 +01:00 committed by The Qt Project
parent b89c7f238f
commit 0984830c33
55 changed files with 8486 additions and 0 deletions

View File

@ -0,0 +1,103 @@
TARGET = QtWaylandClient
QT += core-private gui-private
QT_FOR_PRIVATE += platformsupport-private
MODULE=waylandclient
load(qt_module)
CONFIG += link_pkgconfig qpa/genericunixfontdatabase wayland-scanner
!equals(QT_WAYLAND_GL_CONFIG, nogl) {
DEFINES += QT_WAYLAND_GL_SUPPORT
}
config_xkbcommon {
!contains(QT_CONFIG, no-pkg-config) {
PKGCONFIG += xkbcommon
} else {
LIBS += -lxkbcommon
}
} else {
DEFINES += QT_NO_WAYLAND_XKB
}
!contains(QT_CONFIG, no-pkg-config) {
PKGCONFIG += wayland-client wayland-cursor
contains(QT_CONFIG, glib): PKGCONFIG_PRIVATE += glib-2.0
} else {
LIBS += -lwayland-client -lwayland-cursor $$QT_LIBS_GLIB
}
INCLUDEPATH += $$PWD/../shared
WAYLANDCLIENTSOURCES += \
../3rdparty/protocol/wayland.xml \
../extensions/surface-extension.xml \
../extensions/sub-surface-extension.xml \
../extensions/output-extension.xml \
../extensions/touch-extension.xml \
../extensions/qtkey-extension.xml \
../extensions/windowmanager.xml \
../3rdparty/protocol/text.xml \
SOURCES += qwaylandintegration.cpp \
qwaylandnativeinterface.cpp \
qwaylandshmbackingstore.cpp \
qwaylandinputdevice.cpp \
qwaylandcursor.cpp \
qwaylanddisplay.cpp \
qwaylandwindow.cpp \
qwaylandscreen.cpp \
qwaylandshmwindow.cpp \
qwaylandclipboard.cpp \
qwaylanddnd.cpp \
qwaylanddataoffer.cpp \
qwaylanddatadevicemanager.cpp \
qwaylanddatasource.cpp \
qwaylandshellsurface.cpp \
qwaylandextendedoutput.cpp \
qwaylandextendedsurface.cpp \
qwaylandsubsurface.cpp \
qwaylandtouch.cpp \
qwaylandqtkey.cpp \
../shared/qwaylandmimehelper.cpp \
qwaylanddecoration.cpp \
qwaylandeventthread.cpp\
qwaylandwindowmanagerintegration.cpp \
qwaylandinputcontext.cpp \
qwaylanddatadevice.cpp \
HEADERS += qwaylandintegration.h \
qwaylandnativeinterface.h \
qwaylandcursor.h \
qwaylanddisplay.h \
qwaylandwindow.h \
qwaylandscreen.h \
qwaylandshmbackingstore.h \
qwaylandinputdevice.h \
qwaylandbuffer.h \
qwaylandshmwindow.h \
qwaylandclipboard.h \
qwaylanddnd.h \
qwaylanddataoffer.h \
qwaylanddatadevicemanager.h \
qwaylanddatasource.h \
qwaylandshellsurface.h \
qwaylandextendedoutput.h \
qwaylandextendedsurface.h \
qwaylandsubsurface.h \
qwaylandtouch.h \
qwaylandqtkey.h \
../shared/qwaylandmimehelper.h \
qwaylanddecoration.h \
qwaylandeventthread.h \
qwaylandwindowmanagerintegration.h \
qwaylandinputcontext.h \
qwaylanddatadevice.h \
contains(DEFINES, QT_WAYLAND_GL_SUPPORT) {
SOURCES += qwaylandglintegration.cpp
HEADERS += qwaylandglintegration.h
}

View File

@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDBUFFER_H
#define QWAYLANDBUFFER_H
#include "qwaylandclientexport.h"
#include <QtCore/QSize>
#include <QtCore/QRect>
#include <wayland-client.h>
#include <wayland-client-protocol.h>
QT_BEGIN_NAMESPACE
class Q_WAYLAND_CLIENT_EXPORT QWaylandBuffer {
public:
QWaylandBuffer() { }
virtual ~QWaylandBuffer() { }
wl_buffer *buffer() {return mBuffer;}
virtual QSize size() const = 0;
protected:
struct wl_buffer *mBuffer;
};
QT_END_NAMESPACE
#endif // QWAYLANDBUFFER_H

View File

@ -0,0 +1,60 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDCLIENTEXPORT_H
#define QWAYLANDCLIENTEXPORT_H
#include <QtCore/qglobal.h>
QT_BEGIN_NAMESPACE
#if !defined(Q_WAYLAND_CLIENT_EXPORT)
# if defined(QT_SHARED)
# define Q_WAYLAND_CLIENT_EXPORT Q_DECL_EXPORT
# else
# define Q_WAYLAND_CLIENT_EXPORT
# endif
#endif
QT_END_NAMESPACE
#endif //QWAYLANDCLIENTEXPORT_H

View File

@ -0,0 +1,111 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandclipboard.h"
#include "qwaylanddisplay.h"
#include "qwaylandinputdevice.h"
#include "qwaylanddataoffer.h"
#include "qwaylanddatasource.h"
#include "qwaylanddatadevice.h"
QT_BEGIN_NAMESPACE
QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display)
: mDisplay(display)
{
}
QWaylandClipboard::~QWaylandClipboard()
{
}
QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
{
if (mode != QClipboard::Clipboard)
return 0;
QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice();
if (!inputDevice || !inputDevice->dataDevice())
return 0;
QWaylandDataSource *source = inputDevice->dataDevice()->selectionSource();
if (source) {
return source->mimeData();
}
if (inputDevice->dataDevice()->selectionOffer())
return inputDevice->dataDevice()->selectionOffer()->mimeData();
return 0;
}
void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
{
if (mode != QClipboard::Clipboard)
return;
QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice();
if (!inputDevice || !inputDevice->dataDevice())
return;
inputDevice->dataDevice()->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(), data) : 0);
emitChanged(mode);
}
bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const
{
return mode == QClipboard::Clipboard;
}
bool QWaylandClipboard::ownsMode(QClipboard::Mode mode) const
{
if (mode != QClipboard::Clipboard)
return false;
QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice();
if (!inputDevice || !inputDevice->dataDevice())
return false;
return inputDevice->dataDevice()->selectionSource() != 0;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,72 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDCLIPBOARD_H
#define QWAYLANDCLIPBOARD_H
#include <qpa/qplatformclipboard.h>
#include <QtCore/QVariant>
#include <QtWaylandClient/qwaylandclientexport.h>
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class Q_WAYLAND_CLIENT_EXPORT QWaylandClipboard : public QPlatformClipboard
{
public:
QWaylandClipboard(QWaylandDisplay *display);
~QWaylandClipboard();
QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
private:
QWaylandDisplay *mDisplay;
};
QT_END_NAMESPACE
#endif // QWAYLANDCLIPBOARD_H

View File

@ -0,0 +1,302 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandcursor.h"
#include "qwaylanddisplay.h"
#include "qwaylandinputdevice.h"
#include "qwaylandscreen.h"
#include "qwaylandshmbackingstore.h"
#include <QtGui/QImageReader>
#include <QDebug>
#include <wayland-cursor.h>
QT_BEGIN_NAMESPACE
QWaylandCursor::QWaylandCursor(QWaylandScreen *screen)
: mDisplay(screen->display())
{
//TODO: Make wl_cursor_theme_load arguments configurable here
QByteArray cursorTheme = qgetenv("XCURSOR_THEME");
if (cursorTheme.isEmpty())
cursorTheme = QByteArray("default");
QByteArray cursorSizeFromEnv = qgetenv("XCURSOR_SIZE");
bool hasCursorSize = false;
int cursorSize = cursorSizeFromEnv.toInt(&hasCursorSize);
if (!hasCursorSize || cursorSize <= 0)
cursorSize = 32;
mCursorTheme = wl_cursor_theme_load(cursorTheme, cursorSize, mDisplay->shm());
initCursorMap();
}
QWaylandCursor::~QWaylandCursor()
{
wl_cursor_theme_destroy(mCursorTheme);
}
struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape newShape)
{
struct wl_cursor *waylandCursor = 0;
/* Hide cursor */
if (newShape == Qt::BlankCursor)
{
mDisplay->setCursor(NULL, NULL);
return NULL;
}
if (newShape < Qt::BitmapCursor) {
waylandCursor = requestCursor((WaylandCursor)newShape);
} else if (newShape == Qt::BitmapCursor) {
//TODO: Bitmap cursor logic
} else {
//TODO: Custom cursor logic (for resize arrows)
}
if (!waylandCursor) {
qDebug("Could not find cursor for shape %d", newShape);
return NULL;
}
struct wl_cursor_image *image = waylandCursor->images[0];
struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
if (!buffer) {
qDebug("Could not find buffer for cursor");
return NULL;
}
return image;
}
void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window)
{
Q_UNUSED(window)
const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
struct wl_cursor_image *image = cursorImage(newShape);
if (!image) {
return;
}
struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
mDisplay->setCursor(buffer, image);
}
void QWaylandDisplay::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image)
{
/* 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->setCursor(buffer, image);
}
}
QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
{
return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
}
void QWaylandCursor::pointerEvent(const QMouseEvent &event)
{
mLastPos = event.globalPos();
}
QPoint QWaylandCursor::pos() const
{
return mLastPos;
}
void QWaylandCursor::setPos(const QPoint &pos)
{
Q_UNUSED(pos);
qWarning() << "QWaylandCursor::setPos: not implemented";
}
wl_cursor *QWaylandCursor::requestCursor(WaylandCursor shape)
{
struct wl_cursor *cursor = mCursors.value(shape, 0);
//If the cursor has not been loaded already, load it
if (!cursor) {
QList<QByteArray> cursorNames = mCursorNamesMap.values(shape);
foreach (QByteArray name, cursorNames) {
cursor = wl_cursor_theme_get_cursor(mCursorTheme, name.constData());
if (cursor) {
mCursors.insert(shape, cursor);
break;
}
}
}
//If there still no cursor for a shape, use the default cursor
if (!cursor && shape != ArrowCursor) {
cursor = requestCursor(ArrowCursor);
}
return cursor;
}
void QWaylandCursor::initCursorMap()
{
//Fill the cursor name map will the table of xcursor names
mCursorNamesMap.insert(ArrowCursor, "left_ptr");
mCursorNamesMap.insert(ArrowCursor, "default");
mCursorNamesMap.insert(ArrowCursor, "top_left_arrow");
mCursorNamesMap.insert(ArrowCursor, "left_arrow");
mCursorNamesMap.insert(UpArrowCursor, "up_arrow");
mCursorNamesMap.insert(CrossCursor, "cross");
mCursorNamesMap.insert(WaitCursor, "wait");
mCursorNamesMap.insert(WaitCursor, "watch");
mCursorNamesMap.insert(WaitCursor, "0426c94ea35c87780ff01dc239897213");
mCursorNamesMap.insert(IBeamCursor, "ibeam");
mCursorNamesMap.insert(IBeamCursor, "text");
mCursorNamesMap.insert(IBeamCursor, "xterm");
mCursorNamesMap.insert(SizeVerCursor, "size_ver");
mCursorNamesMap.insert(SizeVerCursor, "ns-resize");
mCursorNamesMap.insert(SizeVerCursor, "v_double_arrow");
mCursorNamesMap.insert(SizeVerCursor, "00008160000006810000408080010102");
mCursorNamesMap.insert(SizeHorCursor, "size_hor");
mCursorNamesMap.insert(SizeHorCursor, "ew-resize");
mCursorNamesMap.insert(SizeHorCursor, "h_double_arrow");
mCursorNamesMap.insert(SizeHorCursor, "028006030e0e7ebffc7f7070c0600140");
mCursorNamesMap.insert(SizeBDiagCursor, "size_bdiag");
mCursorNamesMap.insert(SizeBDiagCursor, "nesw-resize");
mCursorNamesMap.insert(SizeBDiagCursor, "50585d75b494802d0151028115016902");
mCursorNamesMap.insert(SizeBDiagCursor, "fcf1c3c7cd4491d801f1e1c78f100000");
mCursorNamesMap.insert(SizeFDiagCursor, "size_fdiag");
mCursorNamesMap.insert(SizeFDiagCursor, "nwse-resize");
mCursorNamesMap.insert(SizeFDiagCursor, "38c5dff7c7b8962045400281044508d2");
mCursorNamesMap.insert(SizeFDiagCursor, "c7088f0f3e6c8088236ef8e1e3e70000");
mCursorNamesMap.insert(SizeAllCursor, "size_all");
mCursorNamesMap.insert(SplitVCursor, "split_v");
mCursorNamesMap.insert(SplitVCursor, "row-resize");
mCursorNamesMap.insert(SplitVCursor, "sb_v_double_arrow");
mCursorNamesMap.insert(SplitVCursor, "2870a09082c103050810ffdffffe0204");
mCursorNamesMap.insert(SplitVCursor, "c07385c7190e701020ff7ffffd08103c");
mCursorNamesMap.insert(SplitHCursor, "split_h");
mCursorNamesMap.insert(SplitHCursor, "col-resize");
mCursorNamesMap.insert(SplitHCursor, "sb_h_double_arrow");
mCursorNamesMap.insert(SplitHCursor, "043a9f68147c53184671403ffa811cc5");
mCursorNamesMap.insert(SplitHCursor, "14fef782d02440884392942c11205230");
mCursorNamesMap.insert(PointingHandCursor, "pointing_hand");
mCursorNamesMap.insert(PointingHandCursor, "pointer");
mCursorNamesMap.insert(PointingHandCursor, "hand1");
mCursorNamesMap.insert(PointingHandCursor, "e29285e634086352946a0e7090d73106");
mCursorNamesMap.insert(ForbiddenCursor, "forbidden");
mCursorNamesMap.insert(ForbiddenCursor, "not-allowed");
mCursorNamesMap.insert(ForbiddenCursor, "crossed_circle");
mCursorNamesMap.insert(ForbiddenCursor, "circle");
mCursorNamesMap.insert(ForbiddenCursor, "03b6e0fcb3499374a867c041f52298f0");
mCursorNamesMap.insert(WhatsThisCursor, "whats_this");
mCursorNamesMap.insert(WhatsThisCursor, "help");
mCursorNamesMap.insert(WhatsThisCursor, "question_arrow");
mCursorNamesMap.insert(WhatsThisCursor, "5c6cd98b3f3ebcb1f9c7f1c204630408");
mCursorNamesMap.insert(WhatsThisCursor, "d9ce0ab605698f320427677b458ad60b");
mCursorNamesMap.insert(BusyCursor, "left_ptr_watch");
mCursorNamesMap.insert(BusyCursor, "half-busy");
mCursorNamesMap.insert(BusyCursor, "progress");
mCursorNamesMap.insert(BusyCursor, "00000000000000020006000e7e9ffc3f");
mCursorNamesMap.insert(BusyCursor, "08e8e1c95fe2fc01f976f1e063a24ccd");
mCursorNamesMap.insert(OpenHandCursor, "openhand");
mCursorNamesMap.insert(OpenHandCursor, "fleur");
mCursorNamesMap.insert(OpenHandCursor, "5aca4d189052212118709018842178c0");
mCursorNamesMap.insert(OpenHandCursor, "9d800788f1b08800ae810202380a0822");
mCursorNamesMap.insert(ClosedHandCursor, "closedhand");
mCursorNamesMap.insert(ClosedHandCursor, "grabbing");
mCursorNamesMap.insert(ClosedHandCursor, "208530c400c041818281048008011002");
mCursorNamesMap.insert(DragCopyCursor, "dnd-copy");
mCursorNamesMap.insert(DragCopyCursor, "copy");
mCursorNamesMap.insert(DragMoveCursor, "dnd-move");
mCursorNamesMap.insert(DragMoveCursor, "move");
mCursorNamesMap.insert(DragLinkCursor, "dnd-link");
mCursorNamesMap.insert(DragLinkCursor, "link");
mCursorNamesMap.insert(ResizeNorthCursor, "n-resize");
mCursorNamesMap.insert(ResizeNorthCursor, "top_side");
mCursorNamesMap.insert(ResizeSouthCursor, "s-resize");
mCursorNamesMap.insert(ResizeSouthCursor, "bottom_side");
mCursorNamesMap.insert(ResizeEastCursor, "e-resize");
mCursorNamesMap.insert(ResizeEastCursor, "right_side");
mCursorNamesMap.insert(ResizeWestCursor, "w-resize");
mCursorNamesMap.insert(ResizeWestCursor, "left_side");
mCursorNamesMap.insert(ResizeNorthWestCursor, "nw-resize");
mCursorNamesMap.insert(ResizeNorthWestCursor, "top_left_corner");
mCursorNamesMap.insert(ResizeSouthEastCursor, "se-resize");
mCursorNamesMap.insert(ResizeSouthEastCursor, "bottom_right_corner");
mCursorNamesMap.insert(ResizeNorthEastCursor, "ne-resize");
mCursorNamesMap.insert(ResizeNorthEastCursor, "top_right_corner");
mCursorNamesMap.insert(ResizeSouthWestCursor, "sw-resize");
mCursorNamesMap.insert(ResizeSouthWestCursor, "bottom_left_corner");
}
QT_END_NAMESPACE

View File

@ -0,0 +1,116 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDCURSOR_H
#define QWAYLANDCURSOR_H
#include <qpa/qplatformcursor.h>
#include <QtCore/QMap>
#include <QtWaylandClient/qwaylandclientexport.h>
struct wl_cursor;
struct wl_cursor_image;
struct wl_cursor_theme;
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class QWaylandScreen;
class Q_WAYLAND_CLIENT_EXPORT QWaylandCursor : public QPlatformCursor
{
public:
QWaylandCursor(QWaylandScreen *screen);
~QWaylandCursor();
void changeCursor(QCursor *cursor, QWindow *window);
void pointerEvent(const QMouseEvent &event);
QPoint pos() const;
void setPos(const QPoint &pos);
struct wl_cursor_image *cursorImage(Qt::CursorShape shape);
private:
enum WaylandCursor {
ArrowCursor = Qt::ArrowCursor,
UpArrowCursor,
CrossCursor,
WaitCursor,
IBeamCursor,
SizeVerCursor,
SizeHorCursor,
SizeBDiagCursor,
SizeFDiagCursor,
SizeAllCursor,
BlankCursor,
SplitVCursor,
SplitHCursor,
PointingHandCursor,
ForbiddenCursor,
WhatsThisCursor,
BusyCursor,
OpenHandCursor,
ClosedHandCursor,
DragCopyCursor,
DragMoveCursor,
DragLinkCursor,
ResizeNorthCursor = Qt::CustomCursor + 1,
ResizeSouthCursor,
ResizeEastCursor,
ResizeWestCursor,
ResizeNorthWestCursor,
ResizeSouthEastCursor,
ResizeNorthEastCursor,
ResizeSouthWestCursor
};
struct wl_cursor* requestCursor(WaylandCursor shape);
void initCursorMap();
QWaylandDisplay *mDisplay;
struct wl_cursor_theme *mCursorTheme;
QPoint mLastPos;
QMap<WaylandCursor, wl_cursor *> mCursors;
QMultiMap<WaylandCursor, QByteArray> mCursorNamesMap;
};
QT_END_NAMESPACE
#endif // QWAYLANDCURSOR_H

View File

@ -0,0 +1,242 @@
/****************************************************************************
**
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Compositor.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylanddatadevice.h"
#include "qwaylanddatadevicemanager.h"
#include "qwaylanddataoffer.h"
#include "qwaylanddatasource.h"
#include "qwaylanddnd.h"
#include "qwaylandinputdevice.h"
#include <QtCore/QMimeData>
#include <QtGui/QGuiApplication>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformclipboard.h>
#include <qpa/qplatformdrag.h>
#include <qpa/qwindowsysteminterface.h>
#include <QDebug>
QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWaylandInputDevice *inputDevice)
: QtWayland::wl_data_device(manager->get_data_device(inputDevice->wl_seat()))
, m_display(manager->display())
, m_enterSerial(0)
, m_dragWindow(0)
, m_dragPoint()
, m_dragOffer()
, m_selectionOffer()
{
}
QWaylandDataDevice::~QWaylandDataDevice()
{
}
QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const
{
return m_selectionOffer.data();
}
QWaylandDataSource *QWaylandDataDevice::selectionSource() const
{
return m_selectionSource.data();
}
void QWaylandDataDevice::setSelectionSource(QWaylandDataSource *source)
{
m_selectionSource.reset(source);
set_selection(source ? source->object() : 0, 0 /* TODO m_display->serial() */);
}
QWaylandDataOffer *QWaylandDataDevice::dragOffer() const
{
return m_dragOffer.data();
}
void QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon)
{
m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData));
QWaylandWindow *origin = m_display->currentInputDevice()->pointerFocus();
start_drag(m_dragSource->object(), origin->object(), icon->object(), m_display->currentInputDevice()->serial());
}
void QWaylandDataDevice::cancelDrag()
{
m_dragSource.reset();
}
void QWaylandDataDevice::data_device_data_offer(struct ::wl_data_offer *id)
{
QWaylandDataOffer *offer = new QWaylandDataOffer(m_display, id);
}
void QWaylandDataDevice::data_device_drop()
{
QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag();
qDebug() << Q_FUNC_INFO << drag << m_dragOffer.data();
QMimeData *dragData;
Qt::DropActions supportedActions;
if (drag) {
dragData = drag->mimeData();
supportedActions = drag->supportedActions();
} else if (m_dragOffer) {
dragData = m_dragOffer->mimeData();
supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
} else {
return;
}
QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_dragWindow, dragData, m_dragPoint, supportedActions);
if (drag) {
static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(response);
}
}
void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer *id)
{
m_enterSerial = serial;
m_dragWindow = QWaylandWindow::fromWlSurface(surface)->window();
m_dragPoint = QPoint(wl_fixed_to_int(x), wl_fixed_to_int(y));
QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag();
QMimeData *dragData;
Qt::DropActions supportedActions;
if (drag) {
dragData = drag->mimeData();
supportedActions = drag->supportedActions();
} else {
m_dragOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)));
if (m_dragOffer) {
dragData = m_dragOffer->mimeData();
supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
}
}
const QPlatformDragQtResponse &response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions);
if (drag) {
static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
} else {
if (response.isAccepted()) {
wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData());
} else {
wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, 0);
}
}
}
void QWaylandDataDevice::data_device_leave()
{
QWindowSystemInterface::handleDrag(m_dragWindow, 0, QPoint(), Qt::IgnoreAction);
QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag();
if (!drag) {
m_dragOffer.reset();
}
}
void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixed_t y)
{
Q_UNUSED(time);
QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag();
if (!drag && !m_dragOffer)
return;
m_dragPoint = QPoint(wl_fixed_to_int(x), wl_fixed_to_int(y));
QMimeData *dragData;
Qt::DropActions supportedActions;
if (drag) {
dragData = drag->mimeData();
supportedActions = drag->supportedActions();
} else {
dragData = m_dragOffer->mimeData();
supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
}
QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions);
if (drag) {
static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
} else {
if (response.isAccepted()) {
wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData());
} else {
wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, 0);
}
}
}
void QWaylandDataDevice::data_device_selection(wl_data_offer *id)
{
if (id)
m_selectionOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)));
else
m_selectionOffer.reset();
QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
}
void QWaylandDataDevice::selectionSourceCancelled()
{
m_selectionSource.reset();
QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
}
void QWaylandDataDevice::dragSourceCancelled()
{
m_dragSource.reset();
}
void QWaylandDataDevice::dragSourceTargetChanged(const QString &mimeType)
{
static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->updateTarget(mimeType);
}

View File

@ -0,0 +1,97 @@
/****************************************************************************
**
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Compositor.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDDATADEVICE_H
#define QWAYLANDDATADEVICE_H
#include "qwaylanddisplay.h"
QT_BEGIN_NAMESPACE
class QMimeData;
class QWaylandDataDeviceManager;
class QWaylandDataOffer;
class QWaylandDataSource;
class QWindow;
class QWaylandDataDevice : public QObject, public QtWayland::wl_data_device
{
Q_OBJECT
public:
QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWaylandInputDevice *inputDevice);
~QWaylandDataDevice();
QWaylandDataOffer *selectionOffer() const;
QWaylandDataSource *selectionSource() const;
void setSelectionSource(QWaylandDataSource *source);
QWaylandDataOffer *dragOffer() const;
void startDrag(QMimeData *mimeData, QWaylandWindow *icon);
void cancelDrag();
protected:
void data_device_data_offer(struct ::wl_data_offer *id) Q_DECL_OVERRIDE;
void data_device_drop() Q_DECL_OVERRIDE;
void data_device_enter(uint32_t serial, struct ::wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct ::wl_data_offer *id) Q_DECL_OVERRIDE;
void data_device_leave() Q_DECL_OVERRIDE;
void data_device_motion(uint32_t time, wl_fixed_t x, wl_fixed_t y) Q_DECL_OVERRIDE;
void data_device_selection(struct ::wl_data_offer *id) Q_DECL_OVERRIDE;
private Q_SLOTS:
void selectionSourceCancelled();
void dragSourceCancelled();
void dragSourceTargetChanged(const QString &mimeType);
private:
QWaylandDisplay *m_display;
uint32_t m_enterSerial;
QWindow *m_dragWindow;
QPoint m_dragPoint;
QScopedPointer<QWaylandDataOffer> m_dragOffer;
QScopedPointer<QWaylandDataOffer> m_selectionOffer;
QScopedPointer<QWaylandDataSource> m_selectionSource;
QScopedPointer<QWaylandDataSource> m_dragSource;
};
QT_END_NAMESPACE
#endif // QWAYLANDDATADEVICE_H

View File

@ -0,0 +1,80 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylanddatadevicemanager.h"
#include "qwaylandinputdevice.h"
#include "qwaylanddatadevice.h"
#include "qwaylanddataoffer.h"
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id)
: wl_data_device_manager(display->wl_registry(), id)
, m_display(display)
{
// Create transfer devices for all input devices.
// ### This only works if we get the global before all devices and is surely wrong when hotplugging.
QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices();
for (int i = 0; i < inputDevices.size();i++) {
inputDevices.at(i)->setDataDevice(getDataDevice(inputDevices.at(i)));
}
}
QWaylandDataDeviceManager::~QWaylandDataDeviceManager()
{
wl_data_device_manager_destroy(object());
}
QWaylandDataDevice *QWaylandDataDeviceManager::getDataDevice(QWaylandInputDevice *inputDevice)
{
return new QWaylandDataDevice(this, inputDevice);
}
QWaylandDisplay *QWaylandDataDeviceManager::display() const
{
return m_display;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,69 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDDATADEVICEMANAGER_H
#define QWAYLANDDATADEVICEMANAGER_H
#include "qwaylanddisplay.h"
QT_BEGIN_NAMESPACE
class QWaylandDataDevice;
class QWaylandDataSource;
class Q_WAYLAND_CLIENT_EXPORT QWaylandDataDeviceManager : public QtWayland::wl_data_device_manager
{
public:
QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id);
~QWaylandDataDeviceManager();
QWaylandDataDevice *getDataDevice(QWaylandInputDevice *inputDevice);
QWaylandDisplay *display() const;
private:
struct wl_data_device_manager *m_data_device_manager;
QWaylandDisplay *m_display;
};
QT_END_NAMESPACE
#endif // QWAYLANDDATADEVICEMANAGER_H

View File

@ -0,0 +1,139 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylanddataoffer.h"
#include "qwaylanddatadevicemanager.h"
#include <QtCore/private/qcore_unix_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformclipboard.h>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
QWaylandDataOffer::QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer)
: QtWayland::wl_data_offer(offer)
, m_mimeData(new QWaylandMimeData(this, display))
{
}
QWaylandDataOffer::~QWaylandDataOffer()
{
destroy();
}
QString QWaylandDataOffer::firstFormat() const
{
if (m_mimeData->formats().isEmpty())
return QString();
return m_mimeData->formats().first();
}
QMimeData *QWaylandDataOffer::mimeData()
{
return m_mimeData.data();
}
void QWaylandDataOffer::data_offer_offer(const QString &mime_type)
{
m_mimeData->appendFormat(mime_type);
}
QWaylandMimeData::QWaylandMimeData(QWaylandDataOffer *dataOffer, QWaylandDisplay *display)
: QInternalMimeData()
, m_dataOffer(dataOffer)
, m_display(display)
, m_offered_mime_types()
{
}
QWaylandMimeData::~QWaylandMimeData()
{
}
void QWaylandMimeData::appendFormat(const QString &mimeType)
{
m_offered_mime_types.append(mimeType);
}
bool QWaylandMimeData::hasFormat_sys(const QString &mimeType) const
{
return m_offered_mime_types.contains(mimeType);
}
QStringList QWaylandMimeData::formats_sys() const
{
return m_offered_mime_types;
}
QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const
{
Q_UNUSED(type);
if (m_offered_mime_types.isEmpty())
return QVariant();
int pipefd[2];
if (qt_safe_pipe(pipefd, O_CLOEXEC) == -1) {
qWarning("QWaylandMimeData: pipe() failed");
return QVariant();
}
m_dataOffer->receive(mimeType, pipefd[1]);
close(pipefd[1]);
// m_display->forceRoundTrip();
QByteArray content;
char buf[4096];
int n;
while ((n = QT_READ(pipefd[0], &buf, sizeof buf)) > 0) {
content.append(buf, n);
}
close(pipefd[0]);
return content;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,92 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDDATAOFFER_H
#define QWAYLANDDATAOFFER_H
#include "qwaylanddisplay.h"
#include <QtGui/private/qdnd_p.h>
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class QWaylandMimeData;
class Q_WAYLAND_CLIENT_EXPORT QWaylandDataOffer : public QtWayland::wl_data_offer
{
public:
explicit QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer);
~QWaylandDataOffer();
QString firstFormat() const;
QMimeData *mimeData();
protected:
void data_offer_offer(const QString &mime_type) Q_DECL_OVERRIDE;
private:
QScopedPointer<QWaylandMimeData> m_mimeData;
};
class QWaylandMimeData : public QInternalMimeData {
public:
explicit QWaylandMimeData(QWaylandDataOffer *dataOffer, QWaylandDisplay *display);
~QWaylandMimeData();
void appendFormat(const QString &mimeType);
protected:
bool hasFormat_sys(const QString &mimeType) const Q_DECL_OVERRIDE;
QStringList formats_sys() const Q_DECL_OVERRIDE;
QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const Q_DECL_OVERRIDE;
private:
mutable QWaylandDataOffer *m_dataOffer;
QWaylandDisplay *m_display;
QStringList m_offered_mime_types;
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylanddatasource.h"
#include "qwaylanddataoffer.h"
#include "qwaylanddatadevicemanager.h"
#include "qwaylandinputdevice.h"
#include "qwaylandmimehelper.h"
#include <QtCore/QFile>
#include <QtCore/QDebug>
#include <unistd.h>
QT_BEGIN_NAMESPACE
QWaylandDataSource::QWaylandDataSource(QWaylandDataDeviceManager *dataDeviceManager, QMimeData *mimeData)
: QtWayland::wl_data_source(dataDeviceManager->create_data_source())
, m_mime_data(mimeData)
{
if (!mimeData)
return;
Q_FOREACH (const QString &format, mimeData->formats()) {
offer(format);
}
}
QWaylandDataSource::~QWaylandDataSource()
{
destroy();
}
QMimeData * QWaylandDataSource::mimeData() const
{
return m_mime_data;
}
void QWaylandDataSource::data_source_cancelled()
{
Q_EMIT cancelled();
}
void QWaylandDataSource::data_source_send(const QString &mime_type, int32_t fd)
{
QByteArray content = QWaylandMimeHelper::getByteArray(m_mime_data, mime_type);
if (!content.isEmpty()) {
write(fd, content.constData(), content.size());
}
close(fd);
}
void QWaylandDataSource::data_source_target(const QString &mime_type)
{
Q_EMIT targetChanged(mime_type);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDDATASOURCE_H
#define QWAYLANDDATASOURCE_H
#include "qwaylanddisplay.h"
QT_BEGIN_NAMESPACE
class QMimeData;
class QWaylandDataDeviceManager;
class Q_WAYLAND_CLIENT_EXPORT QWaylandDataSource : public QObject, public QtWayland::wl_data_source
{
Q_OBJECT
public:
QWaylandDataSource(QWaylandDataDeviceManager *dataDeviceManager, QMimeData *mimeData);
~QWaylandDataSource();
QMimeData *mimeData() const;
Q_SIGNALS:
void targetChanged(const QString &mime_type);
void cancelled();
protected:
void data_source_cancelled() Q_DECL_OVERRIDE;
void data_source_send(const QString &mime_type, int32_t fd) Q_DECL_OVERRIDE;
void data_source_target(const QString &mime_type) Q_DECL_OVERRIDE;
private:
QWaylandDisplay *m_display;
QMimeData *m_mime_data;
};
QT_END_NAMESPACE
#endif // QWAYLANDDATASOURCE_H

View File

@ -0,0 +1,459 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylanddecoration.h"
#include "qwaylandwindow.h"
#include "qwaylandshellsurface.h"
#include "qwaylandinputdevice.h"
#include "qwaylandscreen.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QImage>
#include <QtGui/QCursor>
#include <QtGui/QPainter>
#include <QtGui/QPalette>
#include <QtGui/QLinearGradient>
QT_BEGIN_NAMESPACE
#define BUTTON_SPACING 5
#ifndef QT_NO_IMAGEFORMAT_XPM
# define BUTTON_WIDTH 10
static const char * const qt_close_xpm[] = {
"10 10 2 1",
"# c #000000",
". c None",
"..........",
".##....##.",
"..##..##..",
"...####...",
"....##....",
"...####...",
"..##..##..",
".##....##.",
"..........",
".........."};
static const char * const qt_maximize_xpm[]={
"10 10 2 1",
"# c #000000",
". c None",
"#########.",
"#########.",
"#.......#.",
"#.......#.",
"#.......#.",
"#.......#.",
"#.......#.",
"#.......#.",
"#########.",
".........."};
static const char * const qt_minimize_xpm[] = {
"10 10 2 1",
"# c #000000",
". c None",
"..........",
"..........",
"..........",
"..........",
"..........",
"..........",
"..........",
".#######..",
".#######..",
".........."};
static const char * const qt_normalizeup_xpm[] = {
"10 10 2 1",
"# c #000000",
". c None",
"...######.",
"...######.",
"...#....#.",
".######.#.",
".######.#.",
".#....###.",
".#....#...",
".#....#...",
".######...",
".........."};
#else
# define BUTTON_WIDTH 22
#endif
QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window)
: m_window(window->window())
, m_wayland_window(window)
, m_isDirty(true)
, m_decorationContentImage(0)
, m_margins(3,30,3,3)
, m_mouseButtons(Qt::NoButton)
{
m_wayland_window->setDecoration(this);
QPalette palette;
m_foregroundColor = palette.color(QPalette::Active, QPalette::HighlightedText);
m_backgroundColor = palette.color(QPalette::Active, QPalette::Highlight);
QTextOption option(Qt::AlignHCenter | Qt::AlignVCenter);
option.setWrapMode(QTextOption::NoWrap);
m_windowTitle.setTextOption(option);
}
QWaylandDecoration::~QWaylandDecoration()
{
m_wayland_window->setDecoration(0);
}
const QImage &QWaylandDecoration::contentImage()
{
if (m_isDirty) {
//Update the decoration backingstore
m_decorationContentImage = QImage(window()->frameGeometry().size(), QImage::Format_ARGB32_Premultiplied);
m_decorationContentImage.fill(Qt::transparent);
this->paint(&m_decorationContentImage);
m_isDirty = false;
}
return m_decorationContentImage;
}
void QWaylandDecoration::update()
{
m_isDirty = true;
}
void QWaylandDecoration::paint(QPaintDevice *device)
{
QRect surfaceRect(QPoint(), window()->frameGeometry().size());
QRect clips[] =
{
QRect(0, 0, surfaceRect.width(), margins().top()),
QRect(0, surfaceRect.height() - margins().bottom(), surfaceRect.width(), margins().bottom()),
QRect(0, margins().top(), margins().left(), surfaceRect.height() - margins().top() - margins().bottom()),
QRect(surfaceRect.width() - margins().right(), margins().top(), margins().left(), surfaceRect.height() - margins().top() - margins().bottom())
};
QRect top = clips[0];
QPainter p(device);
p.setRenderHint(QPainter::Antialiasing);
// Title bar
QPoint gradCenter(top.center()+ QPoint(30, 60));
QLinearGradient grad(top.topLeft(), top.bottomLeft());
QColor base(backgroundColor());
grad.setColorAt(0, base.lighter(100));
grad.setColorAt(1, base.darker(180));
QPainterPath roundedRect;
roundedRect.addRoundedRect(surfaceRect, 6, 6);
for (int i = 0; i < 4; ++i) {
p.save();
p.setClipRect(clips[i]);
p.fillPath(roundedRect, grad);
p.restore();
}
// Window icon
QIcon icon = m_wayland_window->windowIcon();
if (!icon.isNull()) {
QPixmap pixmap = icon.pixmap(QSize(128, 128));
QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
QRectF iconRect(0, 0, 22, 22);
p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
margins().left() + BUTTON_SPACING, 4),
scaled, iconRect);
}
// Window title
QString windowTitleText = window()->title();
if (!windowTitleText.isEmpty()) {
if (m_windowTitle.text() != windowTitleText) {
m_windowTitle.setText(windowTitleText);
m_windowTitle.prepare();
}
QRect titleBar = top;
titleBar.setLeft(m_margins.left() + BUTTON_SPACING +
(icon.isNull() ? 0 : 22 + BUTTON_SPACING));
titleBar.setRight(minimizeButtonRect().left() - BUTTON_SPACING);
p.save();
p.setClipRect(titleBar);
p.setPen(m_foregroundColor);
QSizeF size = m_windowTitle.size();
int dx = (top.width() - size.width()) /2;
int dy = (top.height()- size.height()) /2;
QFont font = p.font();
font.setBold(true);
p.setFont(font);
QPoint windowTitlePoint(top.topLeft().x() + dx,
top.topLeft().y() + dy);
p.drawStaticText(windowTitlePoint,m_windowTitle);
p.restore();
}
#ifndef QT_NO_IMAGEFORMAT_XPM
p.save();
// Close button
QPixmap closePixmap(qt_close_xpm);
p.drawPixmap(closeButtonRect(), closePixmap, closePixmap.rect());
// Maximize button
QPixmap maximizePixmap(m_wayland_window->isMaximized()
? qt_normalizeup_xpm : qt_maximize_xpm);
p.drawPixmap(maximizeButtonRect(), maximizePixmap, maximizePixmap.rect());
// Minimize button
QPixmap minimizePixmap(qt_minimize_xpm);
p.drawPixmap(minimizeButtonRect(), minimizePixmap, minimizePixmap.rect());
p.restore();
#else
// We don't need antialiasing from now on
p.setRenderHint(QPainter::Antialiasing, false);
QRectF rect;
// Default pen
QPen pen(m_foregroundColor);
p.setPen(pen);
// Close button
p.save();
rect = closeButtonRect();
p.drawRect(rect);
qreal crossSize = rect.height() / 2;
QPointF crossCenter(rect.center());
QRectF crossRect(crossCenter.x() - crossSize / 2, crossCenter.y() - crossSize / 2, crossSize, crossSize);
pen.setWidth(2);
p.setPen(pen);
p.drawLine(crossRect.topLeft(), crossRect.bottomRight());
p.drawLine(crossRect.bottomLeft(), crossRect.topRight());
p.restore();
// Maximize button
p.save();
p.drawRect(maximizeButtonRect());
rect = maximizeButtonRect().adjusted(5, 5, -5, -5);
if (m_wayland_window->isMaximized()) {
QRectF rect1 = rect.adjusted(rect.width() / 3, 0, 0, -rect.height() / 3);
QRectF rect2 = rect.adjusted(0, rect.height() / 4, -rect.width() / 4, 0);
p.drawRect(rect1);
p.drawRect(rect2);
} else {
p.setPen(m_foregroundColor);
p.drawRect(rect);
p.drawLine(rect.left(), rect.top() + 1, rect.right(), rect.top() + 1);
}
p.restore();
// Minimize button
p.save();
p.drawRect(minimizeButtonRect());
rect = minimizeButtonRect().adjusted(5, 5, -5, -5);
pen.setWidth(2);
p.setPen(pen);
p.drawLine(rect.bottomLeft(), rect.bottomRight());
p.restore();
#endif
}
bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(global);
// Figure out what area mouse is in
if (closeButtonRect().contains(local) && isLeftClicked(b)) {
QWindowSystemInterface::handleCloseEvent(m_window);
} else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) {
m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
} else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) {
m_window->setWindowState(Qt::WindowMinimized);
} else if (local.y() <= m_margins.top()) {
processMouseTop(inputDevice,local,b,mods);
} else if (local.y() > m_window->height() - m_margins.bottom() + m_margins.top()) {
processMouseBottom(inputDevice,local,b,mods);
} else if (local.x() <= m_margins.left()) {
processMouseLeft(inputDevice,local,b,mods);
} else if (local.x() > m_window->width() - m_margins.right() + m_margins.left()) {
processMouseRight(inputDevice,local,b,mods);
} else {
m_wayland_window->restoreMouseCursor(inputDevice);
m_mouseButtons = b;
return false;
}
m_mouseButtons = b;
return true;
}
bool QWaylandDecoration::inMouseButtonPressedState() const
{
return m_mouseButtons & Qt::NoButton;
}
void QWaylandDecoration::startResize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize resize, Qt::MouseButtons buttons)
{
if (isLeftClicked(buttons)) {
m_wayland_window->shellSurface()->resize(inputDevice, resize);
inputDevice->removeMouseButtonFromState(Qt::LeftButton);
}
}
void QWaylandDecoration::startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons)
{
if (isLeftClicked(buttons)) {
m_wayland_window->shellSurface()->move(inputDevice);
inputDevice->removeMouseButtonFromState(Qt::LeftButton);
}
}
void QWaylandDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(mods);
if (local.y() <= m_margins.bottom()) {
if (local.x() <= margins().left()) {
//top left bit
m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b);
} else if (local.x() > m_window->width() - margins().right()) {
//top right bit
m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b);
} else {
//top reszie bit
m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b);
}
} else {
m_wayland_window->restoreMouseCursor(inputDevice);
startMove(inputDevice,b);
}
}
void QWaylandDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(mods);
if (local.x() <= margins().left()) {
//bottom left bit
m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b);
} else if (local.x() > m_window->width() - margins().right()) {
//bottom right bit
m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b);
} else {
//bottom bit
m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b);
}
}
void QWaylandDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(local);
Q_UNUSED(mods);
m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b);
}
void QWaylandDecoration::processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(local);
Q_UNUSED(mods);
m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor);
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b);
}
bool QWaylandDecoration::isLeftClicked(Qt::MouseButtons newMouseButtonState)
{
if ((!m_mouseButtons & Qt::LeftButton) && (newMouseButtonState & Qt::LeftButton))
return true;
return false;
}
bool QWaylandDecoration::isLeftReleased(Qt::MouseButtons newMouseButtonState)
{
if ((m_mouseButtons & Qt::LeftButton) && !(newMouseButtonState & Qt::LeftButton))
return true;
return false;
}
QRectF QWaylandDecoration::closeButtonRect() const
{
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH - BUTTON_SPACING * 2,
(m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
}
QRectF QWaylandDecoration::maximizeButtonRect() const
{
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 2 - BUTTON_SPACING * 3,
(m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
}
QRectF QWaylandDecoration::minimizeButtonRect() const
{
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 3 - BUTTON_SPACING * 4,
(m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
}
void QWaylandDecoration::setForegroundColor(const QColor &c)
{
m_foregroundColor = c;
}
void QWaylandDecoration::setBackgroundColor(const QColor &c)
{
m_backgroundColor = c;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,155 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDDECORATION_H
#define QWAYLANDDECORATION_H
#include <QtCore/QMargins>
#include <QtCore/QPointF>
#include <QtGui/QGuiApplication>
#include <QtGui/QCursor>
#include <QtGui/QColor>
#include <QtGui/QStaticText>
#include <QtGui/QImage>
#include <QtWaylandClient/qwaylandclientexport.h>
#include <wayland-client.h>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
class QWindow;
class QPaintDevice;
class QPainter;
class QEvent;
class QWaylandScreen;
class QWaylandWindow;
class QWaylandInputDevice;
class Q_WAYLAND_CLIENT_EXPORT QWaylandDecoration
{
public:
QWaylandDecoration(QWaylandWindow *window);
virtual ~QWaylandDecoration();
void update();
bool isDirty() const;
bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods);
bool inMouseButtonPressedState() const;
void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons);
void startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons);
QMargins margins() const;
QWindow *window() const;
QWaylandWindow *waylandWindow() const;
const QImage &contentImage();
void setForegroundColor(const QColor &c);
inline QColor foregroundColor() const;
void setBackgroundColor(const QColor &c);
inline QColor backgroundColor() const;
protected:
void paint(QPaintDevice *device);
private:
void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
bool isLeftClicked(Qt::MouseButtons newMouseButtonState);
bool isLeftReleased(Qt::MouseButtons newMouseButtonState);
QRectF closeButtonRect() const;
QRectF maximizeButtonRect() const;
QRectF minimizeButtonRect() const;
QWindow *m_window;
QWaylandWindow *m_wayland_window;
bool m_isDirty;
QImage m_decorationContentImage;
QMargins m_margins;
Qt::MouseButtons m_mouseButtons;
QColor m_foregroundColor;
QColor m_backgroundColor;
QStaticText m_windowTitle;
};
inline bool QWaylandDecoration::isDirty() const
{
return m_isDirty;
}
inline QMargins QWaylandDecoration::margins() const
{
return m_margins;
}
inline QWindow *QWaylandDecoration::window() const
{
return m_window;
}
inline QWaylandWindow *QWaylandDecoration::waylandWindow() const
{
return m_wayland_window;
}
inline QColor QWaylandDecoration::foregroundColor() const
{
return m_foregroundColor;
}
inline QColor QWaylandDecoration::backgroundColor() const
{
return m_backgroundColor;
}
QT_END_NAMESPACE
#endif // QWAYLANDDECORATION_H

View File

@ -0,0 +1,272 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylanddisplay.h"
#include "qwaylandeventthread.h"
#include "qwaylandwindow.h"
#include "qwaylandscreen.h"
#include "qwaylandcursor.h"
#include "qwaylandinputdevice.h"
#include "qwaylandclipboard.h"
#include "qwaylanddatadevicemanager.h"
#ifdef QT_WAYLAND_GL_SUPPORT
#include "qwaylandglintegration.h"
#endif
#include "qwaylandwindowmanagerintegration.h"
#include "qwaylandextendedoutput.h"
#include "qwaylandextendedsurface.h"
#include "qwaylandsubsurface.h"
#include "qwaylandtouch.h"
#include "qwaylandqtkey.h"
#include <QtWaylandClient/private/qwayland-text.h>
#include <QtCore/QAbstractEventDispatcher>
#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/QDebug>
#include <errno.h>
QT_BEGIN_NAMESPACE
struct wl_surface *QWaylandDisplay::createSurface(void *handle)
{
struct wl_surface *surface = mCompositor.create_surface();
wl_surface_set_user_data(surface, handle);
return surface;
}
#ifdef QT_WAYLAND_GL_SUPPORT
QWaylandGLIntegration * QWaylandDisplay::eglIntegration()
{
return mEglIntegration;
}
#endif
QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration()
{
return mWindowManagerIntegration;
}
QWaylandInputDevice *QWaylandDisplay::lastKeyboardFocusInputDevice() const
{
return mLastKeyboardFocusInputDevice;
}
void QWaylandDisplay::setLastKeyboardFocusInputDevice(QWaylandInputDevice *device)
{
mLastKeyboardFocusInputDevice = device;
}
static QWaylandDisplay *display = 0;
QWaylandDisplay::QWaylandDisplay()
: mLastKeyboardFocusInputDevice(0)
, mDndSelectionHandler(0)
, mWindowExtension(0)
, mSubSurfaceExtension(0)
, mOutputExtension(0)
, mTouchExtension(0)
, mQtKeyExtension(0)
, mTextInputManager(0)
{
display = this;
qRegisterMetaType<uint32_t>("uint32_t");
mEventThreadObject = new QWaylandEventThread(0);
mEventThread = new QThread(this);
mEventThreadObject->moveToThread(mEventThread);
mEventThread->start();
mEventThreadObject->displayConnect();
mDisplay = mEventThreadObject->display(); //blocks until display is available
//Create a new even queue for the QtGui thread
mEventQueue = wl_display_create_queue(mDisplay);
struct ::wl_registry *registry = wl_display_get_registry(mDisplay);
wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue);
init(registry);
connect(mEventThreadObject, SIGNAL(newEventsRead()), this, SLOT(flushRequests()));
#ifdef QT_WAYLAND_GL_SUPPORT
//mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
#endif
mWindowManagerIntegration = new QWaylandWindowManagerIntegration(this);
blockingReadEvents();
#ifdef QT_WAYLAND_GL_SUPPORT
mEglIntegration->initialize();
flushRequests();
while (mEglIntegration->waitingForEvents())
blockingReadEvents();
#endif
waitForScreens();
}
QWaylandDisplay::~QWaylandDisplay(void)
{
#ifdef QT_WAYLAND_GL_SUPPORT
delete mEglIntegration;
#endif
mEventThread->quit();
mEventThread->wait();
delete mEventThreadObject;
}
void QWaylandDisplay::flushRequests()
{
if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) == -1 && errno == EPIPE) {
qWarning("The Wayland connection broke. Did the Wayland compositor die?");
::exit(1);
}
wl_display_flush(mDisplay);
}
void QWaylandDisplay::blockingReadEvents()
{
if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1 && errno == EPIPE) {
qWarning("The Wayland connection broke. Did the Wayland compositor die?");
::exit(1);
}
}
QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const
{
for (int i = 0; i < mScreens.size(); ++i) {
QWaylandScreen *screen = static_cast<QWaylandScreen *>(mScreens.at(i));
if (screen->output() == output)
return screen;
}
return 0;
}
void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
{
Listener l = { listener, data };
mRegistryListeners.append(l);
}
void QWaylandDisplay::waitForScreens()
{
flushRequests();
while (true) {
bool screensReady = !mScreens.isEmpty();
for (int ii = 0; screensReady && ii < mScreens.count(); ++ii) {
if (mScreens.at(ii)->geometry() == QRect(0, 0, 0, 0))
screensReady = false;
}
if (!screensReady)
blockingReadEvents();
else
return;
}
}
void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uint32_t version)
{
Q_UNUSED(version);
struct ::wl_registry *registry = object();
if (interface == "wl_output") {
mScreens.append(new QWaylandScreen(this, id));
} else if (interface == "wl_compositor") {
mCompositor.init(registry, id);
} else if (interface == "wl_shm") {
mShm = static_cast<struct wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface,1));
} else if (interface == "wl_shell"){
mShell = new QtWayland::wl_shell(registry, id);
} else if (interface == "wl_seat") {
QWaylandInputDevice *inputDevice = new QWaylandInputDevice(this, id);
mInputDevices.append(inputDevice);
} else if (interface == "wl_data_device_manager") {
mDndSelectionHandler = new QWaylandDataDeviceManager(this, id);
} else if (interface == "qt_output_extension") {
mOutputExtension = new QtWayland::qt_output_extension(registry, id);
foreach (QPlatformScreen *screen, screens())
static_cast<QWaylandScreen *>(screen)->createExtendedOutput();
} else if (interface == "qt_surface_extension") {
mWindowExtension = new QtWayland::qt_surface_extension(registry, id);
} else if (interface == "qt_sub_surface_extension") {
mSubSurfaceExtension = new QtWayland::qt_sub_surface_extension(registry, id);
} else if (interface == "qt_touch_extension") {
mTouchExtension = new QWaylandTouchExtension(this, id);
} else if (interface == "qt_key_extension") {
mQtKeyExtension = new QWaylandQtKeyExtension(this, id);
} else if (interface == "wl_text_input_manager") {
mTextInputManager = new QtWayland::wl_text_input_manager(registry, id);
}
foreach (Listener l, mRegistryListeners)
(*l.listener)(l.data, registry, id, interface, version);
}
uint32_t QWaylandDisplay::currentTimeMillisec()
{
//### we throw away the time information
struct timeval tv;
int ret = gettimeofday(&tv, 0);
if (ret == 0)
return tv.tv_sec*1000 + tv.tv_usec/1000;
return 0;
}
void QWaylandDisplay::forceRoundTrip()
{
wl_display_roundtrip(mDisplay);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,193 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDDISPLAY_H
#define QWAYLANDDISPLAY_H
#include <QtCore/QObject>
#include <QtCore/QRect>
#include <QtCore/QWaitCondition>
#include <wayland-client.h>
#include <QtWaylandClient/private/qwayland-wayland.h>
#include <QtWaylandClient/qwaylandclientexport.h>
struct wl_cursor_image;
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
class QWaylandInputDevice;
class QSocketNotifier;
class QWaylandBuffer;
class QPlatformScreen;
class QWaylandScreen;
class QWaylandGLIntegration;
class QWaylandWindowManagerIntegration;
class QWaylandDataDeviceManager;
class QWaylandTouchExtension;
class QWaylandQtKeyExtension;
class QWaylandWindow;
class QWaylandEventThread;
namespace QtWayland {
class qt_output_extension;
class qt_shell;
class qt_sub_surface_extension;
class qt_surface_extension;
class wl_text_input_manager;
}
typedef void (*RegistryListener)(void *data,
struct wl_registry *registry,
uint32_t id,
const QString &interface,
uint32_t version);
class Q_WAYLAND_CLIENT_EXPORT QWaylandDisplay : public QObject, public QtWayland::wl_registry {
Q_OBJECT
public:
QWaylandDisplay(void);
~QWaylandDisplay(void);
QList<QPlatformScreen *> screens() const { return mScreens; }
QWaylandScreen *screenForOutput(struct wl_output *output) const;
struct wl_surface *createSurface(void *handle);
#ifdef QT_WAYLAND_GL_SUPPORT
QWaylandGLIntegration *eglIntegration();
#endif
QWaylandWindowManagerIntegration *windowManagerIntegration();
void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image);
struct wl_display *wl_display() const { return mDisplay; }
struct wl_event_queue *wl_event_queue() const { return mEventQueue; }
struct ::wl_registry *wl_registry() { return object(); }
const struct wl_compositor *wl_compositor() const { return mCompositor.object(); }
QtWayland::wl_compositor *compositor() { return &mCompositor; }
QtWayland::wl_shell *shell() { return mShell; }
QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; }
QWaylandInputDevice *defaultInputDevice() const;
QWaylandInputDevice *currentInputDevice() const { return defaultInputDevice(); }
QWaylandInputDevice *lastKeyboardFocusInputDevice() const;
void setLastKeyboardFocusInputDevice(QWaylandInputDevice *device);
QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler; }
QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension; }
QtWayland::qt_sub_surface_extension *subSurfaceExtension() const { return mSubSurfaceExtension; }
QtWayland::qt_output_extension *outputExtension() const { return mOutputExtension; }
QWaylandTouchExtension *touchExtension() const { return mTouchExtension; }
QtWayland::wl_text_input_manager *textInputManager() const { return mTextInputManager; }
/* wl_registry_add_listener does not add but rather sets a listener, so this function is used
* to enable many listeners at once. */
void addRegistryListener(RegistryListener listener, void *data);
struct wl_shm *shm() const { return mShm; }
static uint32_t currentTimeMillisec();
void forceRoundTrip();
public slots:
void blockingReadEvents();
void flushRequests();
private:
void waitForScreens();
struct Listener {
RegistryListener listener;
void *data;
};
struct wl_display *mDisplay;
struct wl_event_queue *mEventQueue;
QtWayland::wl_compositor mCompositor;
struct wl_shm *mShm;
QThread *mEventThread;
QWaylandEventThread *mEventThreadObject;
QtWayland::wl_shell *mShell;
QList<QPlatformScreen *> mScreens;
QList<QWaylandInputDevice *> mInputDevices;
QList<Listener> mRegistryListeners;
QWaylandInputDevice *mLastKeyboardFocusInputDevice;
QWaylandDataDeviceManager *mDndSelectionHandler;
QtWayland::qt_surface_extension *mWindowExtension;
QtWayland::qt_sub_surface_extension *mSubSurfaceExtension;
QtWayland::qt_output_extension *mOutputExtension;
QWaylandTouchExtension *mTouchExtension;
QWaylandQtKeyExtension *mQtKeyExtension;
QWaylandWindowManagerIntegration *mWindowManagerIntegration;
QtWayland::wl_text_input_manager *mTextInputManager;
QSocketNotifier *mReadNotifier;
int mFd;
int mWritableNotificationFd;
bool mScreensInitialized;
void registry_global(uint32_t id, const QString &interface, uint32_t version) Q_DECL_OVERRIDE;
#ifdef QT_WAYLAND_GL_SUPPORT
QWaylandGLIntegration *mEglIntegration;
#endif
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);
};
QT_END_NAMESPACE
#endif // QWAYLANDDISPLAY_H

View File

@ -0,0 +1,136 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylanddnd.h"
#include "qwaylanddatadevice.h"
#include "qwaylanddatadevicemanager.h"
#include "qwaylanddataoffer.h"
#include "qwaylandinputdevice.h"
#include <QtGui/private/qshapedpixmapdndwindow_p.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
QWaylandDrag::QWaylandDrag(QWaylandDisplay *display)
: m_display(display)
{
}
QWaylandDrag::~QWaylandDrag()
{
}
QMimeData * QWaylandDrag::platformDropData()
{
if (drag())
return drag()->mimeData();
return 0;
}
void QWaylandDrag::startDrag()
{
if (!shapedPixmapWindow()) {
QBasicDrag::startDrag();
QBasicDrag::cancel();
}
QWaylandWindow *icon = static_cast<QWaylandWindow *>(shapedPixmapWindow()->handle());
m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), icon);
QBasicDrag::startDrag();
}
void QWaylandDrag::cancel()
{
QBasicDrag::cancel();
m_display->currentInputDevice()->dataDevice()->cancelDrag();
}
void QWaylandDrag::move(const QMouseEvent *me)
{
Q_UNUSED(me);
// Do nothing
}
void QWaylandDrag::drop(const QMouseEvent *me)
{
Q_UNUSED(me);
// Do nothing
}
void QWaylandDrag::endDrag()
{
// Do nothing
}
void QWaylandDrag::updateTarget(const QString &mimeType)
{
setCanDrop(!mimeType.isEmpty());
if (canDrop()) {
updateCursor(defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers()));
} else {
updateCursor(Qt::IgnoreAction);
}
}
void QWaylandDrag::setResponse(const QPlatformDragQtResponse &response)
{
setCanDrop(response.isAccepted());
if (canDrop()) {
updateCursor(defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers()));
} else {
updateCursor(Qt::IgnoreAction);
}
}
void QWaylandDrag::finishDrag(const QPlatformDropQtResponse &response)
{
setExecutedDropAction(response.acceptedAction());
QKeyEvent event(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier);
eventFilter(shapedPixmapWindow(), &event);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,80 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDDND_H
#define QWAYLANDDND_H
#include <qpa/qplatformdrag.h>
#include <QtGui/private/qsimpledrag_p.h>
#include <QtGui/QDrag>
#include <QtCore/QMimeData>
#include "qwaylanddisplay.h"
QT_BEGIN_NAMESPACE
class Q_WAYLAND_CLIENT_EXPORT QWaylandDrag : public QBasicDrag
{
public:
QWaylandDrag(QWaylandDisplay *display);
~QWaylandDrag();
QMimeData *platformDropData() Q_DECL_OVERRIDE;
void updateTarget(const QString &mimeType);
void setResponse(const QPlatformDragQtResponse &response);
void finishDrag(const QPlatformDropQtResponse &response);
protected:
void startDrag() Q_DECL_OVERRIDE;
void cancel() Q_DECL_OVERRIDE;
void move(const QMouseEvent *me) Q_DECL_OVERRIDE;
void drop(const QMouseEvent *me) Q_DECL_OVERRIDE;
void endDrag() Q_DECL_OVERRIDE;
private:
QWaylandDisplay *m_display;
};
QT_END_NAMESPACE
#endif // QWAYLANDDND_H

View File

@ -0,0 +1,63 @@
#include "qwaylandeventthread.h"
#include <QtCore/QSocketNotifier>
#include <QCoreApplication>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
QT_BEGIN_NAMESPACE
QWaylandEventThread::QWaylandEventThread(QObject *parent)
: QObject(parent)
, m_display(0)
, m_fileDescriptor(-1)
, m_readNotifier(0)
, m_displayLock(new QMutex)
{
}
QWaylandEventThread::~QWaylandEventThread()
{
delete m_displayLock;
wl_display_disconnect(m_display);
}
void QWaylandEventThread::displayConnect()
{
m_displayLock->lock();
QMetaObject::invokeMethod(this, "waylandDisplayConnect", Qt::QueuedConnection);
}
void QWaylandEventThread::readWaylandEvents()
{
if (wl_display_dispatch(m_display) == -1 && errno == EPIPE) {
qWarning("The Wayland connection broke. Did the Wayland compositor die?");
::exit(1);
}
emit newEventsRead();
}
void QWaylandEventThread::waylandDisplayConnect()
{
m_display = wl_display_connect(NULL);
if (m_display == NULL) {
qErrnoWarning(errno, "Failed to create display");
::exit(1);
}
m_displayLock->unlock();
m_fileDescriptor = wl_display_get_fd(m_display);
m_readNotifier = new QSocketNotifier(m_fileDescriptor, QSocketNotifier::Read, this);
connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(readWaylandEvents()));
}
wl_display *QWaylandEventThread::display() const
{
QMutexLocker displayLock(m_displayLock);
return m_display;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,46 @@
#ifndef QWAYLANDEVENTTHREAD_H
#define QWAYLANDEVENTTHREAD_H
#include <QObject>
#include <QMutex>
#include <wayland-client.h>
#include <QtWaylandClient/qwaylandclientexport.h>
QT_BEGIN_NAMESPACE
class QSocketNotifier;
class Q_WAYLAND_CLIENT_EXPORT QWaylandEventThread : public QObject
{
Q_OBJECT
public:
explicit QWaylandEventThread(QObject *parent = 0);
~QWaylandEventThread();
void displayConnect();
wl_display *display() const;
private slots:
void readWaylandEvents();
void waylandDisplayConnect();
signals:
void newEventsRead();
private:
struct wl_display *m_display;
int m_fileDescriptor;
QSocketNotifier *m_readNotifier;
QMutex *m_displayLock;
};
QT_END_NAMESPACE
#endif // QWAYLANDEVENTTHREAD_H

View File

@ -0,0 +1,100 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandextendedoutput.h"
#include "qwaylandscreen.h"
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
QWaylandExtendedOutput::QWaylandExtendedOutput(QWaylandScreen *screen, ::qt_extended_output *extended_output)
: QtWayland::qt_extended_output(extended_output)
, m_screen(screen)
, m_orientation(m_screen->orientation())
{
}
Qt::ScreenOrientation QWaylandExtendedOutput::currentOrientation() const
{
return m_orientation;
}
void QWaylandExtendedOutput::setOrientationUpdateMask(Qt::ScreenOrientations orientations)
{
int mask = 0;
if (orientations & Qt::PortraitOrientation)
mask |= QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION;
if (orientations & Qt::LandscapeOrientation)
mask |= QT_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION;
if (orientations & Qt::InvertedPortraitOrientation)
mask |= QT_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION;
if (orientations & Qt::InvertedLandscapeOrientation)
mask |= QT_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION;
set_orientation_update_mask(mask);
}
void QWaylandExtendedOutput::extended_output_set_screen_rotation(int32_t rotation)
{
switch (rotation) {
case QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION:
m_orientation = Qt::PortraitOrientation;
break;
case QT_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION:
m_orientation = Qt::LandscapeOrientation;
break;
case QT_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION:
m_orientation = Qt::InvertedPortraitOrientation;
break;
case QT_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION:
m_orientation = Qt::InvertedLandscapeOrientation;
break;
default:
m_orientation = Qt::PortraitOrientation;
break;
}
QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,69 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDEXTENDEDOUTPUT_H
#define QWAYLANDEXTENDEDOUTPUT_H
#include "qwaylanddisplay.h"
#include <QtWaylandClient/private/qwayland-output-extension.h>
QT_BEGIN_NAMESPACE
class QWaylandExtendedOutput;
class Q_WAYLAND_CLIENT_EXPORT QWaylandExtendedOutput : public QtWayland::qt_extended_output
{
public:
QWaylandExtendedOutput(QWaylandScreen *screen, struct ::qt_extended_output *extended_output);
Qt::ScreenOrientation currentOrientation() const;
void setOrientationUpdateMask(Qt::ScreenOrientations mask);
private:
void extended_output_set_screen_rotation(int32_t rotation) Q_DECL_OVERRIDE;
QWaylandScreen *m_screen;
Qt::ScreenOrientation m_orientation;
};
QT_END_NAMESPACE
#endif // QWAYLANDEXTENDEDOUTPUT_H

View File

@ -0,0 +1,152 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandextendedsurface.h"
#include "qwaylandwindow.h"
#include "wayland-client.h"
#include "qwaylanddisplay.h"
#include "qwaylandnativeinterface.h"
#include <QtGui/QGuiApplication>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qwindowsysteminterface.h>
QT_BEGIN_NAMESPACE
QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface)
: QtWayland::qt_extended_surface(extended_surface)
, m_window(window)
{
}
QWaylandExtendedSurface::~QWaylandExtendedSurface()
{
qt_extended_surface_destroy(object());
}
void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const QVariant &value)
{
QByteArray byteValue;
QDataStream ds(&byteValue, QIODevice::WriteOnly);
ds << value;
update_generic_property(name, byteValue);
m_properties.insert(name, value);
QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>(
QGuiApplication::platformNativeInterface());
nativeInterface->emitWindowPropertyChanged(m_window, name);
}
static int32_t waylandRotationFromScreenOrientation(Qt::ScreenOrientation orientation)
{
switch (orientation) {
case Qt::PortraitOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION;
case Qt::InvertedPortraitOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION;
case Qt::LandscapeOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION;
case Qt::InvertedLandscapeOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION;
default: return QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION;
}
}
void QWaylandExtendedSurface::setContentOrientation(Qt::ScreenOrientation orientation)
{
set_content_orientation(waylandRotationFromScreenOrientation(orientation));
}
QVariantMap QWaylandExtendedSurface::properties() const
{
return m_properties;
}
QVariant QWaylandExtendedSurface::property(const QString &name)
{
return m_properties.value(name);
}
QVariant QWaylandExtendedSurface::property(const QString &name, const QVariant &defaultValue)
{
return m_properties.value(name,defaultValue);
}
void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visibility)
{
m_window->window()->setVisibility(static_cast<QWindow::Visibility>(visibility));
}
void QWaylandExtendedSurface::extended_surface_set_generic_property(const QString &name, wl_array *value)
{
QByteArray data = QByteArray::fromRawData(static_cast<char *>(value->data), value->size);
QVariant variantValue;
QDataStream ds(data);
ds >> variantValue;
m_properties.insert(name, variantValue);
QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>(
QGuiApplication::platformNativeInterface());
nativeInterface->emitWindowPropertyChanged(m_window, name);
}
void QWaylandExtendedSurface::extended_surface_close()
{
QWindowSystemInterface::handleCloseEvent(m_window->window());
}
Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags)
{
uint wlFlags = 0;
if (flags & Qt::WindowStaysOnTopHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP;
if (flags & Qt::WindowOverridesSystemGestures) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES;
if (flags & Qt::BypassWindowManagerHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER;
set_window_flags(wlFlags);
return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures | Qt::BypassWindowManagerHint);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,85 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDEXTENDEDSURFACE_H
#define QWAYLANDEXTENDEDSURFACE_H
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <QtWaylandClient/qwaylandclientexport.h>
#include <wayland-client.h>
#include <QtWaylandClient/private/qwayland-surface-extension.h>
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class QWaylandWindow;
class Q_WAYLAND_CLIENT_EXPORT QWaylandExtendedSurface : public QtWayland::qt_extended_surface
{
public:
QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface);
~QWaylandExtendedSurface();
void setContentOrientation(Qt::ScreenOrientation orientation);
void updateGenericProperty(const QString &name, const QVariant &value);
QVariantMap properties() const;
QVariant property(const QString &name);
QVariant property(const QString &name, const QVariant &defaultValue);
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
private:
void extended_surface_onscreen_visibility(int32_t visibility) Q_DECL_OVERRIDE;
void extended_surface_set_generic_property(const QString &name, wl_array *value) Q_DECL_OVERRIDE;
void extended_surface_close() Q_DECL_OVERRIDE;
QWaylandWindow *m_window;
QVariantMap m_properties;
};
QT_END_NAMESPACE
#endif // QWAYLANDEXTENDEDSURFACE_H

View File

@ -0,0 +1,56 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandglintegration.h"
QT_BEGIN_NAMESPACE
QWaylandGLIntegration::QWaylandGLIntegration()
{
}
QWaylandGLIntegration::~QWaylandGLIntegration()
{
}
QT_END_NAMESPACE

View File

@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDGLINTEGRATION_H
#define QWAYLANDGLINTEGRATION_H
#include <QtCore/qglobal.h>
#include <QtWaylandClient/qwaylandclientexport.h>
QT_BEGIN_NAMESPACE
class QWaylandWindow;
class QWaylandDisplay;
class QWindow;
class QPlatformOpenGLContext;
class QSurfaceFormat;
class Q_WAYLAND_CLIENT_EXPORT QWaylandGLIntegration
{
public:
QWaylandGLIntegration();
virtual ~QWaylandGLIntegration();
virtual void initialize() = 0;
virtual bool waitingForEvents() { return false; }
virtual bool supportsThreadedOpenGL() const { return false; }
virtual QWaylandWindow *createEglWindow(QWindow *window) = 0;
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0;
static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay);
};
QT_END_NAMESPACE
#endif // QWAYLANDGLINTEGRATION_H

View File

@ -0,0 +1,260 @@
/****************************************************************************
**
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Compositor.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandinputcontext.h"
#include <QGuiApplication>
#include <QWindow>
#ifndef QT_NO_WAYLAND_XKB
#include <xkbcommon/xkbcommon.h>
#endif
#include "qwaylanddisplay.h"
#include "qwaylandinputdevice.h"
#include "qwaylandwindow.h"
QT_BEGIN_NAMESPACE
static Qt::Key toQtKey(uint32_t sym)
{
#ifndef QT_NO_WAYLAND_XKB
switch (static_cast<xkb_keysym_t>(sym)) {
case XKB_KEY_BackSpace:
return Qt::Key_Backspace;
case XKB_KEY_Return:
return Qt::Key_Return;
case XKB_KEY_Left:
return Qt::Key_Left;
case XKB_KEY_Up:
return Qt::Key_Up;
case XKB_KEY_Right:
return Qt::Key_Right;
case XKB_KEY_Down:
return Qt::Key_Down;
default:
return Qt::Key_unknown;
}
#else
return Qt::Key_unknown;
#endif
}
static QEvent::Type toQEventType(uint32_t state)
{
switch (static_cast<wl_keyboard_key_state>(state)) {
default:
case WL_KEYBOARD_KEY_STATE_PRESSED:
return QEvent::KeyPress;
case WL_KEYBOARD_KEY_STATE_RELEASED:
return QEvent::KeyRelease;
}
}
QWaylandTextInput::QWaylandTextInput(struct ::wl_text_input *text_input)
: QtWayland::wl_text_input(text_input)
, m_commit()
, m_serial(0)
, m_resetSerial(0)
{
}
QString QWaylandTextInput::commitString() const
{
return m_commit;
}
void QWaylandTextInput::reset()
{
wl_text_input::reset();
updateState();
m_resetSerial = m_serial;
}
void QWaylandTextInput::updateState()
{
if (!QGuiApplication::focusObject())
return;
QInputMethodQueryEvent event(Qt::ImQueryAll);
QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
const QString &text = event.value(Qt::ImSurroundingText).toString();
const int cursor = event.value(Qt::ImCursorPosition).toInt();
const int anchor = event.value(Qt::ImAnchorPosition).toInt();
set_surrounding_text(text, text.leftRef(cursor).toUtf8().size(), text.leftRef(anchor).toUtf8().size());
commit_state(++m_serial);
}
void QWaylandTextInput::text_input_commit_string(uint32_t serial, const QString &text)
{
if (!QGuiApplication::focusObject())
return;
QInputMethodEvent event;
event.setCommitString(text);
QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
}
void QWaylandTextInput::text_input_enter(wl_surface *)
{
updateState();
m_resetSerial = m_serial;
}
void QWaylandTextInput::text_input_leave()
{
}
void QWaylandTextInput::text_input_keysym(uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers)
{
if (!QGuiApplication::focusObject())
return;
// TODO: Convert modifiers to Qt::KeyboardModifiers.
QKeyEvent event(toQEventType(state), toQtKey(sym), Qt::NoModifier);
QCoreApplication::sendEvent(qGuiApp->focusWindow(), &event);
}
QWaylandInputContext::QWaylandInputContext(QWaylandDisplay *display)
: QPlatformInputContext()
, mDisplay(display)
, mTextInput()
{
}
bool QWaylandInputContext::isValid() const
{
return mDisplay->textInputManager() != 0;
}
void QWaylandInputContext::reset()
{
if (!ensureTextInput())
return;
mTextInput->reset();
}
void QWaylandInputContext::commit()
{
if (!ensureTextInput())
return;
if (!QGuiApplication::focusObject())
return;
QInputMethodEvent event;
event.setCommitString(mTextInput->commitString());
QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
mTextInput->reset();
}
void QWaylandInputContext::update(Qt::InputMethodQueries queries)
{
if (!ensureTextInput())
return;
mTextInput->updateState();
}
void QWaylandInputContext::invokeAction(QInputMethod::Action, int cursorPosition)
{
if (!ensureTextInput())
return;
mTextInput->invoke_action(0, cursorPosition); // FIXME button, to UTF8 cursor position
}
void QWaylandInputContext::showInputPanel()
{
if (!ensureTextInput())
return;
mTextInput->show_input_panel();
}
void QWaylandInputContext::hideInputPanel()
{
if (!ensureTextInput())
return;
mTextInput->hide_input_panel();
}
bool QWaylandInputContext::isInputPanelVisible() const
{
return false;
}
void QWaylandInputContext::setFocusObject(QObject *object)
{
if (!ensureTextInput())
return;
if (!object) {
mTextInput->deactivate(mDisplay->defaultInputDevice()->wl_seat());
return;
}
QWindow *window = QGuiApplication::focusWindow();
if (!window || !window->handle())
return;
struct ::wl_surface *surface = static_cast<QWaylandWindow *>(window->handle())->object();
mTextInput->activate(mDisplay->defaultInputDevice()->wl_seat(), surface);
}
bool QWaylandInputContext::ensureTextInput()
{
if (mTextInput)
return true;
if (!isValid())
return false;
mTextInput.reset(new QWaylandTextInput(mDisplay->textInputManager()->create_text_input()));
return true;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,103 @@
/****************************************************************************
**
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Compositor.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDINPUTCONTEXT_H
#define QWAYLANDINPUTCONTEXT_H
#include <qpa/qplatforminputcontext.h>
#include <QtWaylandClient/private/qwayland-text.h>
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class QWaylandTextInput : public QtWayland::wl_text_input
{
public:
QWaylandTextInput(struct ::wl_text_input *text_input);
QString commitString() const;
void reset();
void updateState();
protected:
void text_input_commit_string(uint32_t serial, const QString &text) Q_DECL_OVERRIDE;
void text_input_enter(wl_surface *surface) Q_DECL_OVERRIDE;
void text_input_leave() Q_DECL_OVERRIDE;
void text_input_keysym(uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers);
private:
QString m_commit;
uint32_t m_serial;
uint32_t m_resetSerial;
};
class QWaylandInputContext : public QPlatformInputContext
{
Q_OBJECT
public:
explicit QWaylandInputContext(QWaylandDisplay *display);
bool isValid() const Q_DECL_OVERRIDE;
void reset() Q_DECL_OVERRIDE;
void commit() Q_DECL_OVERRIDE;
void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE;
void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE;
void showInputPanel() Q_DECL_OVERRIDE;
void hideInputPanel() Q_DECL_OVERRIDE;
bool isInputPanelVisible() const Q_DECL_OVERRIDE;
void setFocusObject(QObject *object) Q_DECL_OVERRIDE;
private:
bool ensureTextInput();
QWaylandDisplay *mDisplay;
QScopedPointer<QWaylandTextInput> mTextInput;
};
QT_END_NAMESPACE
#endif // QWAYLANDINPUTCONTEXT_H

View File

@ -0,0 +1,798 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandinputdevice.h"
#include "qwaylandintegration.h"
#include "qwaylandwindow.h"
#include "qwaylandbuffer.h"
#include "qwaylanddatadevice.h"
#include "qwaylanddatadevicemanager.h"
#include "qwaylandtouch.h"
#include "qwaylandscreen.h"
#include "qwaylandcursor.h"
#include <QtGui/private/qpixmap_raster_p.h>
#include <qpa/qplatformwindow.h>
#include <QDebug>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <wayland-cursor.h>
#include <QtGui/QGuiApplication>
#ifndef QT_NO_WAYLAND_XKB
#include <xkbcommon/xkbcommon.h>
#include <X11/keysym.h>
#endif
QT_BEGIN_NAMESPACE
QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id)
: QObject()
, QtWayland::wl_seat(display->wl_registry(), id)
, mQDisplay(display)
, mDisplay(display->wl_display())
, mFocusCallback(0)
, mCaps(0)
, mDataDevice(0)
, mPointerFocus(0)
, mKeyboardFocus(0)
, mTouchFocus(0)
, mButtons(0)
, mTime(0)
, mSerial(0)
, mEnterSerial(0)
, mCursorSerial(0)
, mTouchDevice(0)
#ifndef QT_NO_WAYLAND_XKB
, mXkbContext(0)
, mXkbMap(0)
, mXkbState(0)
#endif
{
#ifndef QT_NO_WAYLAND_XKB
xkb_rule_names names;
names.rules = strdup("evdev");
names.model = strdup("pc105");
names.layout = strdup("us");
names.variant = strdup("");
names.options = strdup("");
mXkbContext = xkb_context_new(xkb_context_flags(0));
if (mXkbContext) {
mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0));
if (mXkbMap) {
mXkbState = xkb_state_new(mXkbMap);
}
}
if (!mXkbContext || !mXkbMap || !mXkbState)
qWarning() << "xkb_map_new_from_names failed, no key input";
#endif
if (mQDisplay->dndSelectionHandler()) {
mDataDevice = mQDisplay->dndSelectionHandler()->getDataDevice(this);
}
connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey()));
}
QWaylandInputDevice::~QWaylandInputDevice()
{
#ifndef QT_NO_WAYLAND_XKB
if (mXkbState)
xkb_state_unref(mXkbState);
if (mXkbMap)
xkb_map_unref(mXkbMap);
if (mXkbContext)
xkb_context_unref(mXkbContext);
#endif
}
void QWaylandInputDevice::seat_capabilities(uint32_t caps)
{
mCaps = caps;
if (caps & WL_SEAT_CAPABILITY_KEYBOARD)
QtWayland::wl_keyboard::init(get_keyboard());
if (caps & WL_SEAT_CAPABILITY_POINTER) {
QtWayland::wl_pointer::init(get_pointer());
pointerSurface = mQDisplay->createSurface(this);
}
if (caps & WL_SEAT_CAPABILITY_TOUCH) {
QtWayland::wl_touch::init(get_touch());
if (!mTouchDevice) {
mTouchDevice = new QTouchDevice;
mTouchDevice->setType(QTouchDevice::TouchScreen);
mTouchDevice->setCapabilities(QTouchDevice::Position);
QWindowSystemInterface::registerTouchDevice(mTouchDevice);
}
}
}
void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
{
if (window == mPointerFocus)
mPointerFocus = 0;
if (window == mKeyboardFocus) {
mKeyboardFocus = 0;
mRepeatTimer.stop();
}
}
void QWaylandInputDevice::setDataDevice(QWaylandDataDevice *device)
{
mDataDevice = device;
}
QWaylandDataDevice *QWaylandInputDevice::dataDevice() const
{
Q_ASSERT(mDataDevice);
return mDataDevice;
}
void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button)
{
mButtons = mButtons & !button;
}
QWaylandWindow *QWaylandInputDevice::pointerFocus() const
{
return mPointerFocus;
}
Qt::KeyboardModifiers QWaylandInputDevice::modifiers() const
{
Qt::KeyboardModifiers ret = Qt::NoModifier;
#ifndef QT_NO_WAYLAND_XKB
xkb_state_component cstate = static_cast<xkb_state_component>(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED);
if (xkb_state_mod_name_is_active(mXkbState, "Shift", cstate))
ret |= Qt::ShiftModifier;
if (xkb_state_mod_name_is_active(mXkbState, "Control", cstate))
ret |= Qt::ControlModifier;
if (xkb_state_mod_name_is_active(mXkbState, "Alt", cstate))
ret |= Qt::AltModifier;
if (xkb_state_mod_name_is_active(mXkbState, "Mod1", cstate))
ret |= Qt::AltModifier;
if (xkb_state_mod_name_is_active(mXkbState, "Mod4", cstate))
ret |= Qt::MetaModifier;
#endif
return ret;
}
void QWaylandInputDevice::setCursor(Qt::CursorShape newShape, QWaylandScreen *screen)
{
struct wl_cursor_image *image = screen->waylandCursor()->cursorImage(newShape);
if (!image) {
return;
}
struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
setCursor(buffer, image);
}
void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image)
{
if (mCaps & WL_SEAT_CAPABILITY_POINTER) {
mCursorSerial = mEnterSerial;
/* Hide cursor */
if (!buffer)
{
set_cursor(mEnterSerial, NULL, 0, 0);
return;
}
set_cursor(mEnterSerial, pointerSurface,
image->hotspot_x, image->hotspot_y);
wl_surface_attach(pointerSurface, buffer, 0, 0);
wl_surface_damage(pointerSurface, 0, 0, image->width, image->height);
wl_surface_commit(pointerSurface);
}
}
void QWaylandInputDevice::pointer_enter(uint32_t serial, struct wl_surface *surface,
wl_fixed_t sx, wl_fixed_t sy)
{
Q_UNUSED(sx);
Q_UNUSED(sy);
if (!surface)
return;
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
window->window()->setCursor(window->window()->cursor());
mPointerFocus = window;
mTime = QWaylandDisplay::currentTimeMillisec();
mSerial = serial;
mEnterSerial = serial;
QWaylandWindow *grab = QWaylandWindow::mouseGrab();
if (!grab) {
window->handleMouseEnter(this);
window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
}
}
void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surface)
{
// The event may arrive after destroying the window, indicated by
// a null surface.
if (!surface)
return;
if (!QWaylandWindow::mouseGrab()) {
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
window->handleMouseLeave(this);
}
mPointerFocus = 0;
mButtons = Qt::NoButton;
mTime = time;
}
void QWaylandInputDevice::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
{
Q_UNUSED(surface_x);
Q_UNUSED(surface_y);
QWaylandWindow *window = mPointerFocus;
if (window == NULL) {
// We destroyed the pointer focus surface, but the server
// didn't get the message yet.
return;
}
QPointF pos(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y));
QPointF delta = pos - pos.toPoint();
QPointF global = window->window()->mapToGlobal(pos.toPoint());
global += delta;
mSurfacePos = pos;
mGlobalPos = global;
mTime = time;
QWaylandWindow *grab = QWaylandWindow::mouseGrab();
if (grab && grab != window) {
// We can't know the true position since we're getting events for another surface,
// so we just set it outside of the window boundaries.
pos = QPointF(-1, -1);
global = grab->window()->mapToGlobal(pos.toPoint());
grab->handleMouse(this, time, pos, global, mButtons, Qt::NoModifier);
} else
window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
}
void QWaylandInputDevice::pointer_button(uint32_t serial, uint32_t time,
uint32_t button, uint32_t state)
{
Q_UNUSED(serial);
QWaylandWindow *window = mPointerFocus;
Qt::MouseButton qt_button;
// translate from kernel (input.h) 'button' to corresponding Qt:MouseButton.
// The range of mouse values is 0x110 <= mouse_button < 0x120, the first Joystick button.
switch (button) {
case 0x110: qt_button = Qt::LeftButton; break; // kernel BTN_LEFT
case 0x111: qt_button = Qt::RightButton; break;
case 0x112: qt_button = Qt::MiddleButton; break;
case 0x113: qt_button = Qt::ExtraButton1; break; // AKA Qt::BackButton
case 0x114: qt_button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton
case 0x115: qt_button = Qt::ExtraButton3; break; // AKA Qt::TaskButton
case 0x116: qt_button = Qt::ExtraButton4; break;
case 0x117: qt_button = Qt::ExtraButton5; break;
case 0x118: qt_button = Qt::ExtraButton6; break;
case 0x119: qt_button = Qt::ExtraButton7; break;
case 0x11a: qt_button = Qt::ExtraButton8; break;
case 0x11b: qt_button = Qt::ExtraButton9; break;
case 0x11c: qt_button = Qt::ExtraButton10; break;
case 0x11d: qt_button = Qt::ExtraButton11; break;
case 0x11e: qt_button = Qt::ExtraButton12; break;
case 0x11f: qt_button = Qt::ExtraButton13; break;
default: return; // invalid button number (as far as Qt is concerned)
}
if (state)
mButtons |= qt_button;
else
mButtons &= ~qt_button;
mTime = time;
mSerial = serial;
QWaylandWindow *grab = QWaylandWindow::mouseGrab();
if (grab && grab != mPointerFocus) {
QPointF pos = QPointF(-1, -1);
QPointF global = grab->window()->mapToGlobal(pos.toPoint());
grab->handleMouse(this, time, pos, global, mButtons, Qt::NoModifier);
} else if (window)
window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
}
void QWaylandInputDevice::pointer_axis(uint32_t time, uint32_t axis, int32_t value)
{
QWaylandWindow *window = mPointerFocus;
QPoint pixelDelta;
QPoint angleDelta;
//normalize value and inverse axis
int valueDelta = wl_fixed_to_int(value) * -12;
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
pixelDelta = QPoint();
angleDelta.setX(valueDelta);
} else {
pixelDelta = QPoint();
angleDelta.setY(valueDelta);
}
QWindowSystemInterface::handleWheelEvent(window->window(),
time, mSurfacePos,
mGlobalPos, pixelDelta,
angleDelta);
}
#ifndef QT_NO_WAYLAND_XKB
static const uint32_t KeyTbl[] = {
XK_Escape, Qt::Key_Escape,
XK_Tab, Qt::Key_Tab,
XK_ISO_Left_Tab, Qt::Key_Backtab,
XK_BackSpace, Qt::Key_Backspace,
XK_Return, Qt::Key_Return,
XK_Insert, Qt::Key_Insert,
XK_Delete, Qt::Key_Delete,
XK_Clear, Qt::Key_Delete,
XK_Pause, Qt::Key_Pause,
XK_Print, Qt::Key_Print,
XK_Home, Qt::Key_Home,
XK_End, Qt::Key_End,
XK_Left, Qt::Key_Left,
XK_Up, Qt::Key_Up,
XK_Right, Qt::Key_Right,
XK_Down, Qt::Key_Down,
XK_Prior, Qt::Key_PageUp,
XK_Next, Qt::Key_PageDown,
XK_Shift_L, Qt::Key_Shift,
XK_Shift_R, Qt::Key_Shift,
XK_Shift_Lock, Qt::Key_Shift,
XK_Control_L, Qt::Key_Control,
XK_Control_R, Qt::Key_Control,
XK_Meta_L, Qt::Key_Meta,
XK_Meta_R, Qt::Key_Meta,
XK_Alt_L, Qt::Key_Alt,
XK_Alt_R, Qt::Key_Alt,
XK_Caps_Lock, Qt::Key_CapsLock,
XK_Num_Lock, Qt::Key_NumLock,
XK_Scroll_Lock, Qt::Key_ScrollLock,
XK_Super_L, Qt::Key_Super_L,
XK_Super_R, Qt::Key_Super_R,
XK_Menu, Qt::Key_Menu,
XK_Hyper_L, Qt::Key_Hyper_L,
XK_Hyper_R, Qt::Key_Hyper_R,
XK_Help, Qt::Key_Help,
XK_KP_Space, Qt::Key_Space,
XK_KP_Tab, Qt::Key_Tab,
XK_KP_Enter, Qt::Key_Enter,
XK_KP_Home, Qt::Key_Home,
XK_KP_Left, Qt::Key_Left,
XK_KP_Up, Qt::Key_Up,
XK_KP_Right, Qt::Key_Right,
XK_KP_Down, Qt::Key_Down,
XK_KP_Prior, Qt::Key_PageUp,
XK_KP_Next, Qt::Key_PageDown,
XK_KP_End, Qt::Key_End,
XK_KP_Begin, Qt::Key_Clear,
XK_KP_Insert, Qt::Key_Insert,
XK_KP_Delete, Qt::Key_Delete,
XK_KP_Equal, Qt::Key_Equal,
XK_KP_Multiply, Qt::Key_Asterisk,
XK_KP_Add, Qt::Key_Plus,
XK_KP_Separator, Qt::Key_Comma,
XK_KP_Subtract, Qt::Key_Minus,
XK_KP_Decimal, Qt::Key_Period,
XK_KP_Divide, Qt::Key_Slash,
XK_ISO_Level3_Shift, Qt::Key_AltGr,
XK_Multi_key, Qt::Key_Multi_key,
XK_Codeinput, Qt::Key_Codeinput,
XK_SingleCandidate, Qt::Key_SingleCandidate,
XK_MultipleCandidate, Qt::Key_MultipleCandidate,
XK_PreviousCandidate, Qt::Key_PreviousCandidate,
XK_Mode_switch, Qt::Key_Mode_switch,
XK_script_switch, Qt::Key_Mode_switch,
0, 0
};
static int keysymToQtKey(xkb_keysym_t key)
{
int code = 0;
int i = 0;
while (KeyTbl[i]) {
if (key == KeyTbl[i]) {
code = (int)KeyTbl[i+1];
break;
}
i += 2;
}
return code;
}
static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text)
{
int code = 0;
if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
code = Qt::Key_F1 + (int(keysym) - XKB_KEY_F1);
} else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) {
if (keysym >= XKB_KEY_KP_0) {
// numeric keypad keys
code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0);
} else {
code = keysymToQtKey(keysym);
}
modifiers |= Qt::KeypadModifier;
} else if (text.length() == 1 && text.unicode()->unicode() > 0x1f
&& text.unicode()->unicode() != 0x7f
&& !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_currency)) {
code = text.unicode()->toUpper().unicode();
} else {
// any other keys
code = keysymToQtKey(keysym);
}
return code;
}
#endif // QT_NO_WAYLAND_XKB
void QWaylandInputDevice::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size)
{
#ifndef QT_NO_WAYLAND_XKB
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
close(fd);
return;
}
char *map_str = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (map_str == MAP_FAILED) {
close(fd);
return;
}
mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0);
munmap(map_str, size);
close(fd);
mXkbState = xkb_state_new(mXkbMap);
#else
Q_UNUSED(format);
Q_UNUSED(fd);
Q_UNUSED(size);
#endif
}
void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surface, struct wl_array *keys)
{
Q_UNUSED(time);
Q_UNUSED(keys);
if (!surface)
return;
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
mKeyboardFocus = window;
if (!mFocusCallback) {
mFocusCallback = wl_display_sync(mDisplay);
wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this);
}
}
void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surface)
{
Q_UNUSED(time);
Q_UNUSED(surface);
mKeyboardFocus = NULL;
// Use a callback to set the focus because we may get a leave/enter pair, and
// the latter one would be lost in the QWindowSystemInterface queue, if
// we issue the handleWindowActivated() calls immediately.
if (!mFocusCallback) {
mFocusCallback = wl_display_sync(mDisplay);
wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this);
}
mRepeatTimer.stop();
}
const wl_callback_listener QWaylandInputDevice::callback = {
QWaylandInputDevice::focusCallback
};
void QWaylandInputDevice::focusCallback(void *data, struct wl_callback *callback, uint32_t time)
{
Q_UNUSED(time);
Q_UNUSED(callback);
QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data);
if (self->mFocusCallback) {
wl_callback_destroy(self->mFocusCallback);
self->mFocusCallback = 0;
}
self->mQDisplay->setLastKeyboardFocusInputDevice(self->mKeyboardFocus ? self : 0);
QWindowSystemInterface::handleWindowActivated(self->mKeyboardFocus ? self->mKeyboardFocus->window() : 0);
}
void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
{
Q_UNUSED(serial);
QWaylandWindow *window = mKeyboardFocus;
#ifndef QT_NO_WAYLAND_XKB
if (!mXkbMap)
return;
uint32_t code = key + 8;
bool isDown = state != 0;
const xkb_keysym_t *syms;
uint32_t numSyms = xkb_key_get_syms(mXkbState, code, &syms);
xkb_state_update_key(mXkbState, code,
isDown ? XKB_KEY_DOWN : XKB_KEY_UP);
QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease;
if (!window) {
// We destroyed the keyboard focus surface, but the server
// didn't get the message yet.
return;
}
int qtkey = key + 8; // qt-compositor substracts 8 for some reason
QString text;
if (numSyms == 1) {
xkb_keysym_t sym = syms[0];
Qt::KeyboardModifiers modifiers = this->modifiers();
uint utf32 = xkb_keysym_to_utf32(sym);
text = QString::fromUcs4(&utf32, 1);
qtkey = keysymToQtKey(sym, modifiers, text);
QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
time, type, qtkey,
modifiers,
code, 0, 0, text);
}
#else
// Generic fallback for single hard keys: Assume 'key' is a Qt key code.
if (window) {
QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
time, type,
qtkey,
Qt::NoModifier,
code, 0, 0);
}
#endif
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
mRepeatKey = qtkey;
mRepeatCode = code;
mRepeatTime = time;
mRepeatText = text;
mRepeatTimer.setInterval(400);
mRepeatTimer.start();
} else {
mRepeatTimer.stop();
}
}
void QWaylandInputDevice::repeatKey()
{
mRepeatTimer.setInterval(25);
QWindowSystemInterface::handleExtendedKeyEvent(mKeyboardFocus->window(),
mRepeatTime, QEvent::KeyPress, mRepeatKey,
Qt::NoModifier,
mRepeatCode, 0, 0, mRepeatText);
}
void QWaylandInputDevice::keyboard_modifiers(uint32_t serial,
uint32_t mods_depressed,
uint32_t mods_latched,
uint32_t mods_locked,
uint32_t group)
{
Q_UNUSED(serial);
#ifndef QT_NO_WAYLAND_XKB
if (mXkbState)
xkb_state_update_mask(mXkbState,
mods_depressed, mods_latched, mods_locked,
0, 0, group);
#else
Q_UNUSED(serial);
Q_UNUSED(mods_depressed);
Q_UNUSED(mods_latched);
Q_UNUSED(mods_locked);
Q_UNUSED(group);
#endif
}
void QWaylandInputDevice::touch_down(uint32_t serial,
uint32_t time,
struct wl_surface *surface,
int32_t id,
wl_fixed_t x,
wl_fixed_t y)
{
Q_UNUSED(serial);
Q_UNUSED(time);
mTouchFocus = QWaylandWindow::fromWlSurface(surface);
handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed);
}
void QWaylandInputDevice::touch_up(uint32_t serial, uint32_t time, int32_t id)
{
Q_UNUSED(serial);
Q_UNUSED(time);
mTouchFocus = 0;
handleTouchPoint(id, 0, 0, Qt::TouchPointReleased);
}
void QWaylandInputDevice::touch_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y)
{
Q_UNUSED(time);
handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved);
}
void QWaylandInputDevice::touch_cancel()
{
mPrevTouchPoints.clear();
mTouchPoints.clear();
QWaylandTouchExtension *touchExt = mQDisplay->touchExtension();
if (touchExt)
touchExt->touchCanceled();
QWindowSystemInterface::handleTouchCancelEvent(0, mTouchDevice);
}
void QWaylandInputDevice::handleTouchPoint(int id, double x, double 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 = mTouchFocus;
//is it possible that mTouchFocus is null;
if (!win)
win = mPointerFocus;
if (!win)
win = mKeyboardFocus;
if (!win || !win->window())
return;
tp.area = QRectF(0, 0, 8, 8);
QMargins margins = win->frameMargins();
tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x+margins.left(), y+margins.top())));
}
tp.state = state;
tp.id = id;
tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1;
mTouchPoints.append(tp);
}
void QWaylandInputDevice::touch_frame()
{
// 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;
}
QWindow *window = mTouchFocus ? mTouchFocus->window() : 0;
QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, 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) {
QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints);
mPrevTouchPoints.clear();
}
}
QT_END_NAMESPACE

View File

@ -0,0 +1,204 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDINPUTDEVICE_H
#define QWAYLANDINPUTDEVICE_H
#include "qwaylandwindow.h"
#include <QSocketNotifier>
#include <QObject>
#include <QTimer>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
#include <wayland-client.h>
#include <QtWaylandClient/private/qwayland-wayland.h>
#ifndef QT_NO_WAYLAND_XKB
struct xkb_context;
struct xkb_keymap;
struct xkb_state;
#endif
QT_BEGIN_NAMESPACE
class QWaylandWindow;
class QWaylandDisplay;
class QWaylandDataDevice;
class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice
: public QObject
, public QtWayland::wl_pointer
, public QtWayland::wl_keyboard
, public QtWayland::wl_touch
, public QtWayland::wl_seat
{
Q_OBJECT
public:
QWaylandInputDevice(QWaylandDisplay *display, uint32_t id);
~QWaylandInputDevice();
uint32_t capabilities() const { return mCaps; }
struct ::wl_seat *wl_seat() { return QtWayland::wl_seat::object(); }
void setCursor(Qt::CursorShape cursor, QWaylandScreen *screen);
void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image);
void handleWindowDestroyed(QWaylandWindow *window);
void setDataDevice(QWaylandDataDevice *device);
QWaylandDataDevice *dataDevice() const;
void removeMouseButtonFromState(Qt::MouseButton button);
QWaylandWindow *pointerFocus() const;
Qt::KeyboardModifiers modifiers() const;
uint32_t serial() const;
uint32_t cursorSerial() const { return mCursorSerial; }
private slots:
void repeatKey();
private:
QWaylandDisplay *mQDisplay;
struct wl_display *mDisplay;
struct wl_callback *mFocusCallback;
uint32_t mCaps;
struct wl_surface *pointerSurface;
QWaylandDataDevice *mDataDevice;
QWaylandWindow *mPointerFocus;
QWaylandWindow *mKeyboardFocus;
QWaylandWindow *mTouchFocus;
Qt::MouseButtons mButtons;
QPointF mSurfacePos;
QPointF mGlobalPos;
uint32_t mTime;
uint32_t mSerial;
uint32_t mEnterSerial;
uint32_t mCursorSerial;
void seat_capabilities(uint32_t caps) Q_DECL_OVERRIDE;
void pointer_enter(uint32_t serial, struct wl_surface *surface,
wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE;
void pointer_leave(uint32_t time, struct wl_surface *surface);
void pointer_motion(uint32_t time,
wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE;
void pointer_button(uint32_t serial, uint32_t time,
uint32_t button, uint32_t state) Q_DECL_OVERRIDE;
void pointer_axis(uint32_t time,
uint32_t axis,
wl_fixed_t value) Q_DECL_OVERRIDE;
void keyboard_keymap(uint32_t format,
int32_t fd,
uint32_t size) Q_DECL_OVERRIDE;
void keyboard_enter(uint32_t time,
struct wl_surface *surface,
struct wl_array *keys) Q_DECL_OVERRIDE;
void keyboard_leave(uint32_t time,
struct wl_surface *surface) Q_DECL_OVERRIDE;
void keyboard_key(uint32_t serial, uint32_t time,
uint32_t key, uint32_t state) Q_DECL_OVERRIDE;
void keyboard_modifiers(uint32_t serial,
uint32_t mods_depressed,
uint32_t mods_latched,
uint32_t mods_locked,
uint32_t group) Q_DECL_OVERRIDE;
void touch_down(uint32_t serial,
uint32_t time,
struct wl_surface *surface,
int32_t id,
wl_fixed_t x,
wl_fixed_t y) Q_DECL_OVERRIDE;
void touch_up(uint32_t serial,
uint32_t time,
int32_t id) Q_DECL_OVERRIDE;
void touch_motion(uint32_t time,
int32_t id,
wl_fixed_t x,
wl_fixed_t y) Q_DECL_OVERRIDE;
void touch_frame() Q_DECL_OVERRIDE;
void touch_cancel() Q_DECL_OVERRIDE;
void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state);
static const wl_callback_listener callback;
static void focusCallback(void *data, struct wl_callback *callback, uint32_t time);
QList<QWindowSystemInterface::TouchPoint> mTouchPoints;
QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints;
QTouchDevice *mTouchDevice;
#ifndef QT_NO_WAYLAND_XKB
xkb_context *mXkbContext;
xkb_keymap *mXkbMap;
xkb_state *mXkbState;
#endif
int mRepeatKey;
uint32_t mRepeatCode;
uint32_t mRepeatTime;
QString mRepeatText;
QTimer mRepeatTimer;
friend class QWaylandTouchExtension;
friend class QWaylandQtKeyExtension;
};
inline uint32_t QWaylandInputDevice::serial() const
{
return mSerial;
}
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,252 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandintegration.h"
#include "qwaylanddisplay.h"
#include "qwaylandinputcontext.h"
#include "qwaylandshmbackingstore.h"
#include "qwaylandshmwindow.h"
#include "qwaylandnativeinterface.h"
#include "qwaylandclipboard.h"
#include "qwaylanddnd.h"
#include "qwaylandwindowmanagerintegration.h"
#include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h"
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qgenericunixthemes_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformcursor.h>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QOpenGLContext>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatformaccessibility.h>
#include <qpa/qplatforminputcontext.h>
#ifdef QT_WAYLAND_GL_SUPPORT
#include "qwaylandglintegration.h"
#endif
QT_BEGIN_NAMESPACE
class GenericWaylandTheme: public QGenericUnixTheme
{
public:
static QStringList themeNames()
{
QStringList result;
if (QGuiApplication::desktopSettingsAware()) {
const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment();
// Ignore X11 desktop environments
if (!desktopEnvironment.isEmpty() &&
desktopEnvironment != QByteArrayLiteral("UNKNOWN") &&
desktopEnvironment != QByteArrayLiteral("KDE") &&
desktopEnvironment != QByteArrayLiteral("GNOME") &&
desktopEnvironment != QByteArrayLiteral("UNITY") &&
desktopEnvironment != QByteArrayLiteral("MATE") &&
desktopEnvironment != QByteArrayLiteral("XFCE") &&
desktopEnvironment != QByteArrayLiteral("LXDE"))
result.push_back(desktopEnvironment.toLower());
}
if (result.isEmpty())
result.push_back(QLatin1String(QGenericUnixTheme::name));
return result;
}
};
QWaylandIntegration::QWaylandIntegration()
: mFontDb(new QGenericUnixFontDatabase())
, mNativeInterface(new QWaylandNativeInterface(this))
#ifndef QT_NO_ACCESSIBILITY
, mAccessibility(new QPlatformAccessibility())
#else
, mAccessibility(0)
#endif
{
mDisplay = new QWaylandDisplay();
mClipboard = new QWaylandClipboard(mDisplay);
mDrag = new QWaylandDrag(mDisplay);
foreach (QPlatformScreen *screen, mDisplay->screens())
screenAdded(screen);
mInputContext.reset(new QWaylandInputContext(mDisplay));
}
QWaylandIntegration::~QWaylandIntegration()
{
delete mDrag;
delete mClipboard;
#ifndef QT_NO_ACCESSIBILITY
delete mAccessibility;
#endif
delete mNativeInterface;
delete mDisplay;
}
QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
{
return mNativeInterface;
}
bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
case OpenGL:
#ifdef QT_WAYLAND_GL_SUPPORT
return true;
#else
return false;
#endif
case ThreadedOpenGL:
#ifdef QT_WAYLAND_GL_SUPPORT
return mDisplay->eglIntegration()->supportsThreadedOpenGL();
#else
return false;
#endif
case BufferQueueingOpenGL:
return true;
case MultipleWindows:
case NonFullScreenWindows:
return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const
{
#ifdef QT_WAYLAND_GL_SUPPORT
if (window->surfaceType() == QWindow::OpenGLSurface)
return mDisplay->eglIntegration()->createEglWindow(window);
#endif
return new QWaylandShmWindow(window);
}
QPlatformOpenGLContext *QWaylandIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
#ifdef QT_WAYLAND_GL_SUPPORT
return mDisplay->eglIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle());
#else
Q_UNUSED(context);
return 0;
#endif
}
QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const
{
return new QWaylandShmBackingStore(window);
}
QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
{
return createUnixEventDispatcher();
}
void QWaylandIntegration::initialize()
{
QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay, SLOT(flushRequests()));
}
QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
{
return mFontDb;
}
QPlatformClipboard *QWaylandIntegration::clipboard() const
{
return mClipboard;
}
QPlatformDrag *QWaylandIntegration::drag() const
{
return mDrag;
}
QPlatformInputContext *QWaylandIntegration::inputContext() const
{
return mInputContext.data();
}
QVariant QWaylandIntegration::styleHint(StyleHint hint) const
{
if (hint == ShowIsFullScreen && mDisplay->windowManagerIntegration())
return mDisplay->windowManagerIntegration()->showIsFullScreen();
return QPlatformIntegration::styleHint(hint);
}
QPlatformAccessibility *QWaylandIntegration::accessibility() const
{
return mAccessibility;
}
QPlatformServices *QWaylandIntegration::services() const
{
return mDisplay->windowManagerIntegration();
}
QWaylandDisplay *QWaylandIntegration::display() const
{
return mDisplay;
}
QStringList QWaylandIntegration::themeNames() const
{
return GenericWaylandTheme::themeNames();
}
QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) const
{
return GenericWaylandTheme::createUnixTheme(name);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,101 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPLATFORMINTEGRATION_WAYLAND_H
#define QPLATFORMINTEGRATION_WAYLAND_H
#include <qpa/qplatformintegration.h>
#include <QtWaylandClient/qwaylandclientexport.h>
QT_BEGIN_NAMESPACE
class QWaylandBuffer;
class QWaylandDisplay;
class Q_WAYLAND_CLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration
{
public:
QWaylandIntegration();
~QWaylandIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
QAbstractEventDispatcher *createEventDispatcher() const;
void initialize();
QPlatformFontDatabase *fontDatabase() const;
QPlatformNativeInterface *nativeInterface() const;
QPlatformClipboard *clipboard() const;
QPlatformDrag *drag() const;
QPlatformInputContext *inputContext() const;
QVariant styleHint(StyleHint hint) const;
QPlatformAccessibility *accessibility() const;
QPlatformServices *services() const;
QWaylandDisplay *display() const;
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
private:
QPlatformFontDatabase *mFontDb;
QPlatformClipboard *mClipboard;
QPlatformDrag *mDrag;
QWaylandDisplay *mDisplay;
QPlatformNativeInterface *mNativeInterface;
QScopedPointer<QPlatformInputContext> mInputContext;
QPlatformAccessibility *mAccessibility;
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,134 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandnativeinterface.h"
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
#include "qwaylandextendedsurface.h"
#include "qwaylandintegration.h"
#include "qwaylanddisplay.h"
#include "qwaylandwindowmanagerintegration.h"
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QScreen>
QT_BEGIN_NAMESPACE
QWaylandNativeInterface::QWaylandNativeInterface(QWaylandIntegration *integration)
: m_integration(integration)
{
}
void *QWaylandNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
{
QByteArray lowerCaseResource = resourceString.toLower();
if (lowerCaseResource == "display")
return m_integration->display()->wl_display();
if (lowerCaseResource == "compositor")
return const_cast<wl_compositor *>(m_integration->display()->wl_compositor());
return 0;
}
void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
QByteArray lowerCaseResource = resourceString.toLower();
if (lowerCaseResource == "display")
return m_integration->display()->wl_display();
if (lowerCaseResource == "compositor")
return const_cast<wl_compositor *>(m_integration->display()->wl_compositor());
if (lowerCaseResource == "surface") {
return ((QWaylandWindow *) window->handle())->object();
}
return NULL;
}
void *QWaylandNativeInterface::nativeResourceForScreen(const QByteArray &resourceString, QScreen *screen)
{
QByteArray lowerCaseResource = resourceString.toLower();
if (lowerCaseResource == "output")
return ((QWaylandScreen *) screen->handle())->output();
return NULL;
}
QVariantMap QWaylandNativeInterface::windowProperties(QPlatformWindow *window) const
{
QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
if (QWaylandExtendedSurface *extendedWindow = waylandWindow->extendedWindow())
return extendedWindow->properties();
return QVariantMap();
}
QVariant QWaylandNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
{
QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
if (QWaylandExtendedSurface *extendedWindow = waylandWindow->extendedWindow())
return extendedWindow->property(name);
return QVariant();
}
QVariant QWaylandNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const
{
QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
if (QWaylandExtendedSurface *extendedWindow = waylandWindow->extendedWindow()) {
return extendedWindow->property(name,defaultValue);
}
return defaultValue;
}
void QWaylandNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
{
QWaylandWindow *wlWindow = static_cast<QWaylandWindow*>(window);
if (QWaylandExtendedSurface *extendedWindow = wlWindow->extendedWindow())
extendedWindow->updateGenericProperty(name,value);
}
void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window, const QString &name)
{
emit windowPropertyChanged(window,name);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,79 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDNATIVEINTERFACE_H
#define QWAYLANDNATIVEINTERFACE_H
#include "qwaylandscreen.h"
#include <QVariantMap>
#include <qpa/qplatformnativeinterface.h>
QT_BEGIN_NAMESPACE
class QWaylandIntegration;
class Q_WAYLAND_CLIENT_EXPORT QWaylandNativeInterface : public QPlatformNativeInterface
{
public:
QWaylandNativeInterface(QWaylandIntegration *integration);
void *nativeResourceForIntegration(const QByteArray &resource);
void *nativeResourceForWindow(const QByteArray &resourceString,
QWindow *window);
void *nativeResourceForScreen(const QByteArray &resourceString,
QScreen *screen);
QVariantMap windowProperties(QPlatformWindow *window) const;
QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
void emitWindowPropertyChanged(QPlatformWindow *window, const QString &name);
private:
static QWaylandScreen *qPlatformScreenForWindow(QWindow *window);
private:
QWaylandIntegration *m_integration;
QHash<QPlatformWindow*, QVariantMap> m_windowProperties;
};
QT_END_NAMESPACE
#endif // QWAYLANDNATIVEINTERFACE_H

View File

@ -0,0 +1,85 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandqtkey.h"
#include "qwaylandinputdevice.h"
QT_BEGIN_NAMESPACE
QWaylandQtKeyExtension::QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id)
: QtWayland::qt_key_extension(display->wl_registry(), id)
, m_display(display)
{
}
void QWaylandQtKeyExtension::key_extension_qtkey(struct wl_surface *surface,
uint32_t time,
uint32_t type,
uint32_t key,
uint32_t modifiers,
uint32_t nativeScanCode,
uint32_t nativeVirtualKey,
uint32_t nativeModifiers,
const QString &text,
uint32_t autorep,
uint32_t count)
{
QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices();
if (!surface && inputDevices.isEmpty()) {
qWarning("qt_key_extension: handle_qtkey: No input device");
return;
}
QWaylandInputDevice *dev = inputDevices.first();
QWaylandWindow *win = surface ? QWaylandWindow::fromWlSurface(surface) : dev->mKeyboardFocus;
if (!win || !win->window()) {
qWarning("qt_key_extension: handle_qtkey: No keyboard focus");
return;
}
QWindow *window = win->window();
QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::Type(type), key, Qt::KeyboardModifiers(modifiers),
nativeScanCode, nativeVirtualKey, nativeModifiers, text,
autorep, count);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDQTKEY_H
#define QWAYLANDQTKEY_H
#include "qwaylanddisplay.h"
#include <qpa/qwindowsysteminterface.h>
#include <QtWaylandClient/private/qwayland-qtkey-extension.h>
QT_BEGIN_NAMESPACE
class Q_WAYLAND_CLIENT_EXPORT QWaylandQtKeyExtension : public QtWayland::qt_key_extension
{
public:
QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id);
private:
QWaylandDisplay *m_display;
void key_extension_qtkey(struct wl_surface *surface,
uint32_t time,
uint32_t type,
uint32_t key,
uint32_t modifiers,
uint32_t nativeScanCode,
uint32_t nativeVirtualKey,
uint32_t nativeModifiers,
const QString &text,
uint32_t autorep,
uint32_t count) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
#endif // QWAYLANDQTKEY_H

View File

@ -0,0 +1,184 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandscreen.h"
#include "qwaylanddisplay.h"
#include "qwaylandcursor.h"
#include "qwaylandextendedoutput.h"
#include <qpa/qwindowsysteminterface.h>
QT_BEGIN_NAMESPACE
QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id)
: QtWayland::wl_output(waylandDisplay->wl_registry(), id)
, mWaylandDisplay(waylandDisplay)
, mExtendedOutput(0)
, mDepth(32)
, mRefreshRate(60000)
, mFormat(QImage::Format_ARGB32_Premultiplied)
, mOutputName(QStringLiteral("Screen%1").arg(id))
, mWaylandCursor(new QWaylandCursor(this))
{
// handle case of output extension global being sent after outputs
createExtendedOutput();
}
QWaylandScreen::~QWaylandScreen()
{
delete mWaylandCursor;
}
QWaylandDisplay * QWaylandScreen::display() const
{
return mWaylandDisplay;
}
QRect QWaylandScreen::geometry() const
{
return mGeometry;
}
int QWaylandScreen::depth() const
{
return mDepth;
}
QImage::Format QWaylandScreen::format() const
{
return mFormat;
}
QDpi QWaylandScreen::logicalDpi() const
{
static int force_dpi = !qgetenv("QT_WAYLAND_FORCE_DPI").isEmpty() ? qgetenv("QT_WAYLAND_FORCE_DPI").toInt() : -1;
if (force_dpi > 0)
return QDpi(force_dpi, force_dpi);
return QPlatformScreen::logicalDpi();
}
void QWaylandScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
{
if (mExtendedOutput)
mExtendedOutput->setOrientationUpdateMask(mask);
}
Qt::ScreenOrientation QWaylandScreen::orientation() const
{
if (mExtendedOutput)
return mExtendedOutput->currentOrientation();
return QPlatformScreen::orientation();
}
qreal QWaylandScreen::refreshRate() const
{
return mRefreshRate / 1000.f;
}
QPlatformCursor *QWaylandScreen::cursor() const
{
return mWaylandCursor;
}
QWaylandExtendedOutput *QWaylandScreen::extendedOutput() const
{
return mExtendedOutput;
}
void QWaylandScreen::createExtendedOutput()
{
QtWayland::qt_output_extension *extension = mWaylandDisplay->outputExtension();
if (!mExtendedOutput && extension)
mExtendedOutput = new QWaylandExtendedOutput(this, extension->get_extended_output(output()));
}
QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window)
{
QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window);
return static_cast<QWaylandScreen *>(platformScreen);
}
void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh)
{
if (!(flags & WL_OUTPUT_MODE_CURRENT))
return;
QSize size(width, height);
if (size != mGeometry.size()) {
mGeometry.setSize(size);
QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry);
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry);
}
if (refresh != mRefreshRate) {
mRefreshRate = refresh;
QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate());
}
}
void QWaylandScreen::output_geometry(int32_t x, int32_t y,
int32_t width, int32_t height,
int subpixel,
const QString &make,
const QString &model,
int32_t transform)
{
Q_UNUSED(subpixel);
Q_UNUSED(make);
Q_UNUSED(transform);
if (!model.isEmpty())
mOutputName = model;
QRect geom(x, y, width, height);
if (mGeometry == geom)
return;
mGeometry = geom;
QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry);
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,110 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDSCREEN_H
#define QWAYLANDSCREEN_H
#include <qpa/qplatformscreen.h>
#include <QtWaylandClient/qwaylandclientexport.h>
#include <QtWaylandClient/private/qwayland-wayland.h>
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class QWaylandCursor;
class QWaylandExtendedOutput;
class Q_WAYLAND_CLIENT_EXPORT QWaylandScreen : public QPlatformScreen, QtWayland::wl_output
{
public:
QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id);
~QWaylandScreen();
QWaylandDisplay *display() const;
QRect geometry() const;
int depth() const;
QImage::Format format() const;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
void setOrientationUpdateMask(Qt::ScreenOrientations mask);
Qt::ScreenOrientation orientation() const;
qreal refreshRate() const;
QString name() const { return mOutputName; }
QPlatformCursor *cursor() const;
QWaylandCursor *waylandCursor() const { return mWaylandCursor; };
::wl_output *output() { return object(); }
QWaylandExtendedOutput *extendedOutput() const;
void createExtendedOutput();
static QWaylandScreen *waylandScreenFromWindow(QWindow *window);
private:
void output_mode(uint32_t flags, int width, int height, int refresh) Q_DECL_OVERRIDE;
void output_geometry(int32_t x, int32_t y,
int32_t width, int32_t height,
int subpixel,
const QString &make,
const QString &model,
int32_t transform) Q_DECL_OVERRIDE;
QWaylandDisplay *mWaylandDisplay;
QWaylandExtendedOutput *mExtendedOutput;
QRect mGeometry;
int mDepth;
int mRefreshRate;
QImage::Format mFormat;
QSize mPhysicalSize;
QString mOutputName;
QWaylandCursor *mWaylandCursor;
};
QT_END_NAMESPACE
#endif // QWAYLANDSCREEN_H

View File

@ -0,0 +1,176 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandshellsurface.h"
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
#include "qwaylandinputdevice.h"
#include "qwaylanddecoration.h"
#include "qwaylandscreen.h"
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
QWaylandShellSurface::QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window)
: QtWayland::wl_shell_surface(shell_surface)
, m_window(window)
, m_maximized(false)
, m_fullscreen(false)
{
}
QWaylandShellSurface::~QWaylandShellSurface()
{
wl_shell_surface_destroy(object());
}
void QWaylandShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges)
{
resize(inputDevice->wl_seat(),
inputDevice->serial(),
edges);
}
void QWaylandShellSurface::move(QWaylandInputDevice *inputDevice)
{
move(inputDevice->wl_seat(),
inputDevice->serial());
}
void QWaylandShellSurface::setMaximized()
{
m_maximized = true;
m_size = m_window->window()->geometry().size();
set_maximized(0);
}
void QWaylandShellSurface::setFullscreen()
{
m_fullscreen = true;
m_size = m_window->window()->geometry().size();
set_fullscreen(WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, 0);
}
void QWaylandShellSurface::setNormal()
{
if (m_fullscreen || m_maximized) {
m_fullscreen = m_maximized = false;
setTopLevel();
QMargins m = m_window->frameMargins();
m_window->configure(0, m_size.width() + m.left() + m.right(), m_size.height() + m.top() + m.bottom());
}
}
void QWaylandShellSurface::setMinimized()
{
// TODO: There's no wl_shell_surface API for this
}
void QWaylandShellSurface::setTopLevel()
{
set_toplevel();
}
void QWaylandShellSurface::updateTransientParent(QWindow *parent)
{
QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle());
if (!parent_wayland_window)
return;
// set_transient expects a position relative to the parent
QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
QWindow *parentWin = m_window->window()->transientParent();
transientPos -= parentWin->geometry().topLeft();
if (parent_wayland_window->decoration()) {
transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
}
uint32_t flags = 0;
Qt::WindowFlags wf = m_window->window()->flags();
if (wf.testFlag(Qt::ToolTip)
|| wf.testFlag(Qt::WindowTransparentForInput))
flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
set_transient(parent_wayland_window->object(),
transientPos.x(),
transientPos.y(),
flags);
}
void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial)
{
QWaylandWindow *parent_wayland_window = parent;
if (!parent_wayland_window)
return;
// set_popup expects a position relative to the parent
QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
transientPos -= parent_wayland_window->geometry().topLeft();
if (parent_wayland_window->decoration()) {
transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
}
set_popup(device->wl_seat(), serial, parent_wayland_window->object(),
transientPos.x(), transientPos.y(), 0);
}
void QWaylandShellSurface::shell_surface_ping(uint32_t serial)
{
pong(serial);
}
void QWaylandShellSurface::shell_surface_configure(uint32_t edges,
int32_t width,
int32_t height)
{
m_window->configure(edges, width, height);
}
void QWaylandShellSurface::shell_surface_popup_done()
{
QCoreApplication::postEvent(m_window->window(), new QCloseEvent());
}
QT_END_NAMESPACE

View File

@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDSHELLSURFACE_H
#define QWAYLANDSHELLSURFACE_H
#include <QtCore/QSize>
#include <wayland-client.h>
#include <QtWaylandClient/private/qwayland-wayland.h>
#include <QtWaylandClient/qwaylandclientexport.h>
QT_BEGIN_NAMESPACE
class QWaylandWindow;
class QWaylandInputDevice;
class QWindow;
class Q_WAYLAND_CLIENT_EXPORT QWaylandShellSurface : public QtWayland::wl_shell_surface
{
public:
QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window);
~QWaylandShellSurface();
using QtWayland::wl_shell_surface::resize;
void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges);
using QtWayland::wl_shell_surface::move;
void move(QWaylandInputDevice *inputDevice);
private:
void setMaximized();
void setFullscreen();
void setNormal();
void setMinimized();
void setTopLevel();
void updateTransientParent(QWindow *parent);
void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial);
QWaylandWindow *m_window;
bool m_maximized;
bool m_fullscreen;
QSize m_size;
void shell_surface_ping(uint32_t serial) Q_DECL_OVERRIDE;
void shell_surface_configure(uint32_t edges,
int32_t width,
int32_t height) Q_DECL_OVERRIDE;
void shell_surface_popup_done() Q_DECL_OVERRIDE;
friend class QWaylandWindow;
};
QT_END_NAMESPACE
#endif // QWAYLANDSHELLSURFACE_H

View File

@ -0,0 +1,322 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandshmbackingstore.h"
#include <QtCore/qdebug.h>
#include "qwaylanddisplay.h"
#include "qwaylandshmwindow.h"
#include "qwaylandscreen.h"
#include "qwaylanddecoration.h"
#include <QtGui/QPainter>
#include <wayland-client.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
QT_BEGIN_NAMESPACE
QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
const QSize &size, QImage::Format format)
: mMarginsImage(0)
{
int stride = size.width() * 4;
int alloc = stride * size.height();
char filename[] = "/tmp/wayland-shm-XXXXXX";
int fd = mkstemp(filename);
if (fd < 0) {
qWarning("mkstemp %s failed: %s", filename, strerror(errno));
return;
}
int flags = fcntl(fd, F_GETFD);
if (flags != -1)
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
if (ftruncate(fd, alloc) < 0) {
qWarning("ftruncate failed: %s", strerror(errno));
close(fd);
return;
}
uchar *data = (uchar *)
mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
unlink(filename);
if (data == (uchar *) MAP_FAILED) {
qWarning("mmap /dev/zero failed: %s", strerror(errno));
close(fd);
return;
}
mImage = QImage(data, size.width(), size.height(), stride, format);
mShmPool = wl_shm_create_pool(display->shm(), fd, alloc);
mBuffer = wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(),
stride, WL_SHM_FORMAT_ARGB8888);
close(fd);
}
QWaylandShmBuffer::~QWaylandShmBuffer(void)
{
delete mMarginsImage;
munmap((void *) mImage.constBits(), mImage.byteCount());
wl_buffer_destroy(mBuffer);
wl_shm_pool_destroy(mShmPool);
}
QImage *QWaylandShmBuffer::imageInsideMargins(const QMargins &margins)
{
if (!margins.isNull() && margins != mMargins) {
if (mMarginsImage) {
delete mMarginsImage;
}
uchar *bits = const_cast<uchar *>(mImage.constBits());
uchar *b_s_data = bits + margins.top() * mImage.bytesPerLine() + margins.left() * 4;
int b_s_width = mImage.size().width() - margins.left() - margins.right();
int b_s_height = mImage.size().height() - margins.top() - margins.bottom();
mMarginsImage = new QImage(b_s_data, b_s_width,b_s_height,mImage.bytesPerLine(),mImage.format());
}
if (margins.isNull()) {
delete mMarginsImage;
mMarginsImage = 0;
}
mMargins = margins;
if (!mMarginsImage)
return &mImage;
return mMarginsImage;
}
QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window)
: QPlatformBackingStore(window)
, mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display())
, mFrontBuffer(0)
, mBackBuffer(0)
, mFrontBufferIsDirty(false)
, mPainting(false)
, mFrameCallback(0)
{
}
QWaylandShmBackingStore::~QWaylandShmBackingStore()
{
if (mFrameCallback)
wl_callback_destroy(mFrameCallback);
// if (mFrontBuffer == waylandWindow()->attached())
// waylandWindow()->attach(0);
if (mFrontBuffer != mBackBuffer)
delete mFrontBuffer;
delete mBackBuffer;
}
QPaintDevice *QWaylandShmBackingStore::paintDevice()
{
if (!windowDecoration())
return mBackBuffer->image();
return mBackBuffer->imageInsideMargins(windowDecorationMargins());
}
void QWaylandShmBackingStore::beginPaint(const QRegion &)
{
mPainting = true;
ensureSize();
if (waylandWindow()->attached() && mBackBuffer == waylandWindow()->attached() && mFrameCallback) {
QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle());
Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
waylandWindow->waitForFrameSync();
}
waylandWindow()->setCanResize(false);
}
void QWaylandShmBackingStore::endPaint()
{
mPainting = false;
waylandWindow()->setCanResize(true);
}
void QWaylandShmBackingStore::ensureSize()
{
waylandWindow()->setBackingStore(this);
waylandWindow()->createDecoration();
resize(mRequestedSize);
}
void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(window);
Q_UNUSED(offset);
Q_ASSERT(waylandWindow()->windowType() == QWaylandWindow::Shm);
if (windowDecoration() && windowDecoration()->isDirty())
updateDecorations();
mFrontBuffer = mBackBuffer;
if (mFrameCallback) {
mFrontBufferIsDirty = true;
return;
}
mFrameCallback = waylandWindow()->frame();
wl_callback_add_listener(mFrameCallback,&frameCallbackListener,this);
QMargins margins = windowDecorationMargins();
bool damageAll = false;
if (waylandWindow()->attached() != mFrontBuffer) {
delete waylandWindow()->attached();
damageAll = true;
}
waylandWindow()->attachOffset(mFrontBuffer);
if (damageAll) {
//need to damage it all, otherwise the attach offset may screw up
waylandWindow()->damage(QRect(QPoint(0,0),mFrontBuffer->size()));
} else {
QVector<QRect> rects = region.rects();
for (int i = 0; i < rects.size(); i++) {
QRect rect = rects.at(i);
rect.translate(margins.left(),margins.top());
waylandWindow()->damage(rect);
}
}
waylandWindow()->commit();
mFrontBufferIsDirty = false;
}
void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &)
{
mRequestedSize = size;
}
void QWaylandShmBackingStore::resize(const QSize &size)
{
QMargins margins = windowDecorationMargins();
QSize sizeWithMargins = size + QSize(margins.left()+margins.right(),margins.top()+margins.bottom());
QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format();
if (mBackBuffer != NULL && mBackBuffer->size() == sizeWithMargins)
return;
if (mBackBuffer != mFrontBuffer) {
delete mBackBuffer; //we delete the attached buffer when we flush
}
mBackBuffer = new QWaylandShmBuffer(mDisplay, sizeWithMargins, format);
if (windowDecoration() && window()->isVisible())
windowDecoration()->update();
}
QImage *QWaylandShmBackingStore::entireSurface() const
{
return mBackBuffer->image();
}
void QWaylandShmBackingStore::updateDecorations()
{
QPainter decorationPainter(entireSurface());
decorationPainter.setCompositionMode(QPainter::CompositionMode_Source);
QImage sourceImage = windowDecoration()->contentImage();
QRect target;
//Top
target.setX(0);
target.setY(0);
target.setWidth(sourceImage.width());
target.setHeight(windowDecorationMargins().top());
decorationPainter.drawImage(target, sourceImage, target);
//Left
target.setWidth(windowDecorationMargins().left());
target.setHeight(sourceImage.height());
decorationPainter.drawImage(target, sourceImage, target);
//Right
target.setX(sourceImage.width() - windowDecorationMargins().right());
decorationPainter.drawImage(target, sourceImage, target);
//Bottom
target.setX(0);
target.setY(sourceImage.height() - windowDecorationMargins().bottom());
target.setWidth(sourceImage.width());
target.setHeight(windowDecorationMargins().bottom());
decorationPainter.drawImage(target, sourceImage, target);
}
void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t time)
{
Q_UNUSED(time);
QWaylandShmBackingStore *self =
static_cast<QWaylandShmBackingStore *>(data);
if (callback != self->mFrameCallback) // others, like QWaylandWindow, may trigger callbacks too
return;
QWaylandShmWindow *window = self->waylandWindow();
wl_callback_destroy(self->mFrameCallback);
self->mFrameCallback = 0;
if (self->mFrontBufferIsDirty && !self->mPainting) {
self->mFrontBufferIsDirty = false;
self->mFrameCallback = wl_surface_frame(window->object());
wl_callback_add_listener(self->mFrameCallback,&self->frameCallbackListener,self);
if (self->mFrontBuffer != window->attached()) {
delete window->attached();
}
window->attachOffset(self->mFrontBuffer);
window->damage(QRect(QPoint(0,0),self->mFrontBuffer->size()));
window->commit();
}
}
const struct wl_callback_listener QWaylandShmBackingStore::frameCallbackListener = {
QWaylandShmBackingStore::done
};
QT_END_NAMESPACE

View File

@ -0,0 +1,134 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDSHMBACKINGSTORE_H
#define QWAYLANDSHMBACKINGSTORE_H
#include "qwaylandbuffer.h"
#include "qwaylanddecoration.h"
#include "qwaylandshmwindow.h"
#include <qpa/qplatformbackingstore.h>
#include <QtGui/QImage>
#include <qpa/qplatformwindow.h>
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBuffer : public QWaylandBuffer {
public:
QWaylandShmBuffer(QWaylandDisplay *display,
const QSize &size, QImage::Format format);
~QWaylandShmBuffer();
QSize size() const { return mImage.size(); }
QImage *image() { return &mImage; }
QImage *imageInsideMargins(const QMargins &margins);
private:
QImage mImage;
struct wl_shm_pool *mShmPool;
QMargins mMargins;
QImage *mMarginsImage;
};
class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBackingStore : public QPlatformBackingStore
{
public:
QWaylandShmBackingStore(QWindow *window);
~QWaylandShmBackingStore();
QPaintDevice *paintDevice();
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
void resize(const QSize &size, const QRegion &staticContents);
void resize(const QSize &size);
void beginPaint(const QRegion &);
void endPaint();
QWaylandDecoration *windowDecoration() const;
QMargins windowDecorationMargins() const;
QImage *entireSurface() const;
void ensureSize();
QWaylandShmWindow *waylandWindow() const;
void iterateBuffer();
private:
void updateDecorations();
QWaylandDisplay *mDisplay;
QWaylandShmBuffer *mFrontBuffer;
QWaylandShmBuffer *mBackBuffer;
bool mFrontBufferIsDirty;
bool mPainting;
QSize mRequestedSize;
Qt::WindowFlags mCurrentWindowFlags;
static const struct wl_callback_listener frameCallbackListener;
static void done(void *data,
struct wl_callback *callback,
uint32_t time);
struct wl_callback *mFrameCallback;
};
inline QWaylandDecoration *QWaylandShmBackingStore::windowDecoration() const
{
return waylandWindow()->decoration();
}
inline QMargins QWaylandShmBackingStore::windowDecorationMargins() const
{
if (windowDecoration())
return windowDecoration()->margins();
return QMargins();
}
inline QWaylandShmWindow *QWaylandShmBackingStore::waylandWindow() const
{
return static_cast<QWaylandShmWindow *>(window()->handle());
}
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,73 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandshmwindow.h"
#include "qwaylandbuffer.h"
#include <QtCore/QVector>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
QWaylandShmWindow::QWaylandShmWindow(QWindow *window)
: QWaylandWindow(window)
, mBackingStore(0)
{
}
QWaylandShmWindow::~QWaylandShmWindow()
{
}
QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
{
return QWaylandWindow::Shm;
}
void QWaylandShmWindow::setBackingStore(QWaylandShmBackingStore *backingStore)
{
mBackingStore = backingStore;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,75 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDSHMWINDOW_H
#define QWAYLANDSHMWINDOW_H
#include "qwaylandwindow.h"
#include <QtGui/QRegion>
QT_BEGIN_NAMESPACE
class QWaylandShmBackingStore;
class Q_WAYLAND_CLIENT_EXPORT QWaylandShmWindow : public QWaylandWindow
{
public:
QWaylandShmWindow(QWindow *window);
~QWaylandShmWindow();
WindowType windowType() const;
QSurfaceFormat format() const { return QSurfaceFormat(); }
void setBackingStore(QWaylandShmBackingStore *backingStore);
QWaylandShmBackingStore *backingStore() const;
private:
QWaylandShmBackingStore *mBackingStore;
};
inline QWaylandShmBackingStore *QWaylandShmWindow::backingStore() const
{
return mBackingStore;
}
QT_END_NAMESPACE
#endif // QWAYLANDSHMWINDOW_H

View File

@ -0,0 +1,91 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandsubsurface.h"
#include "qwaylandwindow.h"
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface)
: QtWayland::qt_sub_surface(sub_surface)
, m_window(window)
{
}
void QWaylandSubSurface::setParent(const QWaylandWindow *parent)
{
QWaylandSubSurface *parentSurface = parent ? parent->subSurfaceWindow() : 0;
if (parentSurface) {
int x = m_window->geometry().x() + parent->frameMargins().left();
int y = m_window->geometry().y() + parent->frameMargins().top();
parentSurface->attach_sub_surface(object(), x, y);
}
}
static void setPositionToParent(QWaylandWindow *parentWaylandWindow)
{
QObjectList children = parentWaylandWindow->window()->children();
for (int i = 0; i < children.size(); i++) {
QWindow *childWindow = qobject_cast<QWindow *>(children.at(i));
if (!childWindow)
continue;
if (childWindow->handle()) {
QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(childWindow->handle());
waylandWindow->subSurfaceWindow()->setParent(parentWaylandWindow);
setPositionToParent(waylandWindow);
}
}
}
void QWaylandSubSurface::adjustPositionOfChildren()
{
QWindow *window = m_window->window();
if (window->parent()) {
qDebug() << "QWaylandSubSurface::adjustPositionOfChildren not called for toplevel window";
}
setPositionToParent(m_window);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,73 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDSUBSURFACE_H
#define QWAYLANDSUBSURFACE_H
#include <wayland-client.h>
#include <QtCore/qglobal.h>
#include <QtWaylandClient/qwaylandclientexport.h>
#include <QtWaylandClient/private/qwayland-sub-surface-extension.h>
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class QWaylandWindow;
class QWaylandSubSurface;
class Q_WAYLAND_CLIENT_EXPORT QWaylandSubSurface : public QtWayland::qt_sub_surface
{
public:
QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface);
void setParent(const QWaylandWindow *parent);
void adjustPositionOfChildren();
private:
QWaylandWindow *m_window;
};
QT_END_NAMESPACE
#endif // QWAYLANDSUBSURFACE_H

View File

@ -0,0 +1,209 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandtouch.h"
#include "qwaylandinputdevice.h"
QT_BEGIN_NAMESPACE
QWaylandTouchExtension::QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id)
: QtWayland::qt_touch_extension(display->wl_registry(), id),
mDisplay(display),
mTouchDevice(0),
mPointsLeft(0),
mFlags(0),
mMouseSourceId(-1),
mInputDevice(0)
{
}
void QWaylandTouchExtension::registerDevice(int caps)
{
mTouchDevice = new QTouchDevice;
mTouchDevice->setType(QTouchDevice::TouchScreen);
mTouchDevice->setCapabilities(QTouchDevice::Capabilities(caps));
QWindowSystemInterface::registerTouchDevice(mTouchDevice);
}
static inline qreal fromFixed(int f)
{
return f / qreal(10000);
}
void QWaylandTouchExtension::touch_extension_touch(uint32_t time,
uint32_t id, uint32_t state, int32_t x, int32_t y,
int32_t normalized_x, int32_t normalized_y,
int32_t width, int32_t height, uint32_t pressure,
int32_t velocity_x, int32_t velocity_y,
uint32_t flags, wl_array *rawdata)
{
if (!mInputDevice) {
QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices();
if (inputDevices.isEmpty()) {
qWarning("qt_touch_extension: handle_touch: No input devices");
return;
}
mInputDevice = inputDevices.first();
}
QWaylandWindow *win = mInputDevice->mTouchFocus;
if (!win)
win = mInputDevice->mPointerFocus;
if (!win)
win = mInputDevice->mKeyboardFocus;
if (!win || !win->window()) {
qWarning("qt_touch_extension: handle_touch: No pointer focus");
return;
}
mTargetWindow = win->window();
QWindowSystemInterface::TouchPoint tp;
tp.id = id;
tp.state = Qt::TouchPointState(int(state & 0xFFFF));
int sentPointCount = state >> 16;
if (!mPointsLeft) {
Q_ASSERT(sentPointCount > 0);
mPointsLeft = sentPointCount;
}
tp.flags = QTouchEvent::TouchPoint::InfoFlags(int(flags & 0xFFFF));
if (!mTouchDevice)
registerDevice(flags >> 16);
tp.area = QRectF(0, 0, fromFixed(width), fromFixed(height));
// Got surface-relative coords but need a (virtual) screen position.
QPointF relPos = QPointF(fromFixed(x), fromFixed(y));
QPointF delta = relPos - relPos.toPoint();
tp.area.moveCenter(mTargetWindow->mapToGlobal(relPos.toPoint()) + delta);
tp.normalPosition.setX(fromFixed(normalized_x));
tp.normalPosition.setY(fromFixed(normalized_y));
tp.pressure = pressure / 255.0;
tp.velocity.setX(fromFixed(velocity_x));
tp.velocity.setY(fromFixed(velocity_y));
if (rawdata) {
const int rawPosCount = rawdata->size / sizeof(float) / 2;
float *p = static_cast<float *>(rawdata->data);
for (int i = 0; i < rawPosCount; ++i) {
float x = *p++;
float y = *p++;
tp.rawPositions.append(QPointF(x, y));
}
}
mTouchPoints.append(tp);
mTimestamp = time;
if (!--mPointsLeft)
sendTouchEvent();
}
void QWaylandTouchExtension::sendTouchEvent()
{
// 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;
}
QWindowSystemInterface::handleTouchEvent(mTargetWindow, mTimestamp, mTouchDevice, mTouchPoints);
Qt::TouchPointStates states = 0;
for (int i = 0; i < mTouchPoints.count(); ++i)
states |= mTouchPoints.at(i).state;
if (mFlags & QT_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH) {
if (states == Qt::TouchPointPressed)
mMouseSourceId = mTouchPoints.first().id;
for (int i = 0; i < mTouchPoints.count(); ++i) {
const QWindowSystemInterface::TouchPoint &tp(mTouchPoints.at(i));
if (tp.id == mMouseSourceId) {
Qt::MouseButtons buttons = tp.state == Qt::TouchPointReleased ? Qt::NoButton : Qt::LeftButton;
mLastMouseGlobal = tp.area.center();
QPoint globalPoint = mLastMouseGlobal.toPoint();
QPointF delta = mLastMouseGlobal - globalPoint;
mLastMouseLocal = mTargetWindow->mapFromGlobal(globalPoint) + delta;
QWindowSystemInterface::handleMouseEvent(mTargetWindow, mTimestamp, mLastMouseLocal, mLastMouseGlobal, buttons);
if (buttons == Qt::NoButton)
mMouseSourceId = -1;
break;
}
}
}
mPrevTouchPoints = mTouchPoints;
mTouchPoints.clear();
if (states == Qt::TouchPointReleased)
mPrevTouchPoints.clear();
}
void QWaylandTouchExtension::touchCanceled()
{
mTouchPoints.clear();
mPrevTouchPoints.clear();
if (mMouseSourceId != -1)
QWindowSystemInterface::handleMouseEvent(mTargetWindow, mTimestamp, mLastMouseLocal, mLastMouseGlobal, Qt::NoButton);
}
void QWaylandTouchExtension::touch_extension_configure(uint32_t flags)
{
mFlags = flags;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,97 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDTOUCh_H
#define QWAYLANDTOUCH_H
#include "qwaylanddisplay.h"
#include <qpa/qwindowsysteminterface.h>
#include <QtWaylandClient/private/qwayland-touch-extension.h>
QT_BEGIN_NAMESPACE
class Q_WAYLAND_CLIENT_EXPORT QWaylandTouchExtension : public QtWayland::qt_touch_extension
{
public:
QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id);
void touchCanceled();
private:
void registerDevice(int caps);
QWaylandDisplay *mDisplay;
void touch_extension_touch(uint32_t time,
uint32_t id,
uint32_t state,
int32_t x,
int32_t y,
int32_t normalized_x,
int32_t normalized_y,
int32_t width,
int32_t height,
uint32_t pressure,
int32_t velocity_x,
int32_t velocity_y,
uint32_t flags,
struct wl_array *rawdata) Q_DECL_OVERRIDE;
void touch_extension_configure(uint32_t flags) Q_DECL_OVERRIDE;
void sendTouchEvent();
QList<QWindowSystemInterface::TouchPoint> mTouchPoints;
QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints;
QTouchDevice *mTouchDevice;
uint32_t mTimestamp;
int mPointsLeft;
uint32_t mFlags;
int mMouseSourceId;
QPointF mLastMouseLocal;
QPointF mLastMouseGlobal;
QWindow *mTargetWindow;
QWaylandInputDevice *mInputDevice;
};
QT_END_NAMESPACE
#endif // QWAYLANDTOUCH_H

View File

@ -0,0 +1,608 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandwindow.h"
#include "qwaylandbuffer.h"
#include "qwaylanddisplay.h"
#include "qwaylandinputdevice.h"
#include "qwaylandscreen.h"
#include "qwaylandshellsurface.h"
#include "qwaylandextendedsurface.h"
#include "qwaylandsubsurface.h"
#include "qwaylanddecoration.h"
#include "qwaylandwindowmanagerintegration.h"
#include <QtCore/QFileInfo>
#include <QtGui/QWindow>
#include <QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
QWaylandWindow *QWaylandWindow::mMouseGrab = 0;
QWaylandWindow::QWaylandWindow(QWindow *window)
: QObject()
, QPlatformWindow(window)
, mScreen(QWaylandScreen::waylandScreenFromWindow(window))
, mDisplay(mScreen->display())
, mShellSurface(0)
, mExtendedWindow(0)
, mSubSurfaceWindow(0)
, mWindowDecoration(0)
, mMouseEventsInContentArea(false)
, mMousePressedInContentArea(Qt::NoButton)
, m_cursorShape(Qt::ArrowCursor)
, mBuffer(0)
, mWaitingForFrameSync(false)
, mFrameCallback(0)
, mRequestResizeSent(false)
, mCanResize(true)
, mSentInitialResize(false)
, mMouseDevice(0)
, mMouseSerial(0)
, mState(Qt::WindowNoState)
{
init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
static WId id = 1;
mWindowId = id++;
if (mDisplay->shell() && window->type() & Qt::Window && !(window->flags() & Qt::BypassWindowManagerHint))
mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(object()), this);
if (mDisplay->windowExtension())
mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(object()));
if (mDisplay->subSurfaceExtension())
mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(object()));
if (mShellSurface) {
// Set initial surface title
mShellSurface->set_title(window->title());
// Set surface class to the .desktop file name (obtained from executable name)
QFileInfo exeFileInfo(qApp->applicationFilePath());
QString className = exeFileInfo.baseName() + QLatin1String(".desktop");
mShellSurface->set_class(className);
}
if (QPlatformWindow::parent() && mSubSurfaceWindow) {
mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(QPlatformWindow::parent()));
} else if (window->transientParent() && mShellSurface) {
if (window->type() != Qt::Popup) {
mShellSurface->updateTransientParent(window->transientParent());
}
} else if (mShellSurface) {
mShellSurface->setTopLevel();
}
setWindowFlags(window->flags());
setGeometry(window->geometry());
setWindowState(window->windowState());
}
QWaylandWindow::~QWaylandWindow()
{
if (isInitialized()) {
delete mShellSurface;
delete mExtendedWindow;
destroy();
}
if (mFrameCallback)
wl_callback_destroy(mFrameCallback);
QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices();
for (int i = 0; i < inputDevices.size(); ++i)
inputDevices.at(i)->handleWindowDestroyed(this);
const QWindow *parent = window();
foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
if (w->transientParent() == parent)
QWindowSystemInterface::handleCloseEvent(w);
}
if (mMouseGrab == this) {
mMouseGrab = 0;
}
}
QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
{
return static_cast<QWaylandWindow *>(static_cast<QtWayland::wl_surface *>(wl_surface_get_user_data(surface)));
}
WId QWaylandWindow::winId() const
{
return mWindowId;
}
void QWaylandWindow::setParent(const QPlatformWindow *parent)
{
const QWaylandWindow *parentWaylandWindow = static_cast<const QWaylandWindow *>(parent);
if (subSurfaceWindow()) {
subSurfaceWindow()->setParent(parentWaylandWindow);
}
}
void QWaylandWindow::setWindowTitle(const QString &title)
{
if (mShellSurface) {
mShellSurface->set_title(title);
}
if (mWindowDecoration && window()->isVisible())
mWindowDecoration->update();
}
void QWaylandWindow::setWindowIcon(const QIcon &icon)
{
mWindowIcon = icon;
if (mWindowDecoration && window()->isVisible())
mWindowDecoration->update();
}
void QWaylandWindow::setGeometry(const QRect &rect)
{
QPlatformWindow::setGeometry(QRect(rect.x(), rect.y(),
qBound(window()->minimumWidth(), rect.width(), window()->maximumWidth()),
qBound(window()->minimumHeight(), rect.height(), window()->maximumHeight())));
if (shellSurface() && window()->transientParent() && window()->type() != Qt::Popup)
shellSurface()->updateTransientParent(window()->transientParent());
if (mWindowDecoration && window()->isVisible())
mWindowDecoration->update();
if (mConfigure.isEmpty()) {
QWindowSystemInterface::handleGeometryChange(window(), geometry());
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
}
void QWaylandWindow::setVisible(bool visible)
{
if (visible) {
if (mBuffer)
attach(mBuffer->buffer(), 0, 0);
if (window()->type() == Qt::Popup && transientParent()) {
QWaylandWindow *parent = transientParent();
mMouseDevice = parent->mMouseDevice;
mMouseSerial = parent->mMouseSerial;
if (mMouseDevice)
mShellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial);
}
if (!mSentInitialResize) {
QWindowSystemInterface::handleGeometryChange(window(), geometry());
mSentInitialResize = true;
}
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
// Don't flush the events here, or else the newly visible window may start drawing, but since
// there was no frame before it will be stuck at the waitForFrameSync() in
// QWaylandShmBackingStore::beginPaint().
} else {
QWindowSystemInterface::handleExposeEvent(window(), QRegion());
attach(static_cast<QWaylandBuffer *>(0), 0, 0);
}
damage(QRect(QPoint(0,0),geometry().size()));
commit();
}
void QWaylandWindow::raise()
{
if (mExtendedWindow)
mExtendedWindow->raise();
}
void QWaylandWindow::lower()
{
if (mExtendedWindow)
mExtendedWindow->lower();
}
void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height)
{
QMutexLocker resizeLocker(&mResizeLock);
mConfigure.edges |= edges;
mConfigure.width = width;
mConfigure.height = height;
if (!mRequestResizeSent && !mConfigure.isEmpty()) {
mRequestResizeSent= true;
QMetaObject::invokeMethod(this, "requestResize", Qt::QueuedConnection);
}
}
void QWaylandWindow::doResize()
{
if (mConfigure.isEmpty()) {
return;
}
int widthWithoutMargins = qMax(mConfigure.width-(frameMargins().left() +frameMargins().right()),1);
int heightWithoutMargins = qMax(mConfigure.height-(frameMargins().top()+frameMargins().bottom()),1);
widthWithoutMargins = qMax(widthWithoutMargins, window()->minimumSize().width());
heightWithoutMargins = qMax(heightWithoutMargins, window()->minimumSize().height());
QRect geometry = QRect(0,0, widthWithoutMargins, heightWithoutMargins);
int x = 0;
int y = 0;
QSize size = this->geometry().size();
if (mConfigure.edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
x = size.width() - geometry.width();
}
if (mConfigure.edges & WL_SHELL_SURFACE_RESIZE_TOP) {
y = size.height() - geometry.height();
}
mOffset += QPoint(x, y);
setGeometry(geometry);
mConfigure.clear();
QWindowSystemInterface::handleGeometryChange(window(), geometry);
}
void QWaylandWindow::setCanResize(bool canResize)
{
QMutexLocker lock(&mResizeLock);
mCanResize = canResize;
if (canResize && !mConfigure.isEmpty()) {
doResize();
QWindowSystemInterface::handleExposeEvent(window(), geometry());
}
}
void QWaylandWindow::requestResize()
{
QMutexLocker lock(&mResizeLock);
if (mCanResize) {
doResize();
}
mRequestResizeSent = false;
lock.unlock();
QWindowSystemInterface::handleExposeEvent(window(), geometry());
QWindowSystemInterface::flushWindowSystemEvents();
}
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
{
mBuffer = buffer;
if (mBuffer)
attach(mBuffer->buffer(), x, y);
else
QtWayland::wl_surface::attach(0, 0, 0);
}
void QWaylandWindow::attachOffset(QWaylandBuffer *buffer)
{
attach(buffer, mOffset.x(), mOffset.y());
mOffset = QPoint();
}
QWaylandBuffer *QWaylandWindow::attached() const
{
return mBuffer;
}
void QWaylandWindow::damage(const QRect &rect)
{
//We have to do sync stuff before calling damage, or we might
//get a frame callback before we get the timestamp
if (!mWaitingForFrameSync) {
mFrameCallback = frame();
wl_callback_add_listener(mFrameCallback,&QWaylandWindow::callbackListener,this);
mWaitingForFrameSync = true;
}
if (mBuffer) {
damage(rect.x(), rect.y(), rect.width(), rect.height());
}
}
const wl_callback_listener QWaylandWindow::callbackListener = {
QWaylandWindow::frameCallback
};
void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uint32_t time)
{
Q_UNUSED(time);
QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
if (callback != self->mFrameCallback) // might be a callback caused by the shm backingstore
return;
self->mWaitingForFrameSync = false;
if (self->mFrameCallback) {
wl_callback_destroy(self->mFrameCallback);
self->mFrameCallback = 0;
}
}
QMutex QWaylandWindow::mFrameSyncMutex;
void QWaylandWindow::waitForFrameSync()
{
QMutexLocker locker(&mFrameSyncMutex);
if (!mWaitingForFrameSync)
return;
mDisplay->flushRequests();
while (mWaitingForFrameSync)
mDisplay->blockingReadEvents();
}
QMargins QWaylandWindow::frameMargins() const
{
if (mWindowDecoration)
return mWindowDecoration->margins();
return QPlatformWindow::frameMargins();
}
QWaylandShellSurface *QWaylandWindow::shellSurface() const
{
return mShellSurface;
}
QWaylandExtendedSurface *QWaylandWindow::extendedWindow() const
{
return mExtendedWindow;
}
QWaylandSubSurface *QWaylandWindow::subSurfaceWindow() const
{
return mSubSurfaceWindow;
}
void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
{
if (mExtendedWindow)
mExtendedWindow->setContentOrientation(orientation);
}
void QWaylandWindow::setWindowState(Qt::WindowState state)
{
if (mState == state) {
return;
}
// As of february 2013 QWindow::setWindowState sets the new state value after
// QPlatformWindow::setWindowState returns, so we cannot rely on QWindow::windowState
// here. We use then this mState variable.
mState = state;
createDecoration();
switch (state) {
case Qt::WindowFullScreen:
mShellSurface->setFullscreen();
break;
case Qt::WindowMaximized:
mShellSurface->setMaximized();
break;
case Qt::WindowMinimized:
mShellSurface->setMinimized();
break;
default:
mShellSurface->setNormal();
}
QWindowSystemInterface::handleWindowStateChanged(window(), mState);
QWindowSystemInterface::flushWindowSystemEvents(); // Required for oldState to work on WindowStateChanged
}
void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags)
{
if (mExtendedWindow)
mExtendedWindow->setWindowFlags(flags);
}
bool QWaylandWindow::createDecoration()
{
static bool disableWaylandDecorations = !qgetenv("QT_WAYLAND_DISABLE_WINDOWDECORATION").isEmpty();
if (disableWaylandDecorations)
return false;
bool decoration = false;
switch (window()->type()) {
case Qt::Window:
case Qt::Widget:
case Qt::Dialog:
case Qt::Tool:
case Qt::Drawer:
decoration = true;
break;
default:
break;
}
if (window()->flags() & Qt::FramelessWindowHint || isFullscreen())
decoration = false;
if (window()->flags() & Qt::BypassWindowManagerHint)
decoration = false;
if (decoration) {
if (!mWindowDecoration)
mWindowDecoration = new QWaylandDecoration(this);
} else {
delete mWindowDecoration;
mWindowDecoration = 0;
}
return mWindowDecoration;
}
QWaylandDecoration *QWaylandWindow::decoration() const
{
return mWindowDecoration;
}
void QWaylandWindow::setDecoration(QWaylandDecoration *decoration)
{
mWindowDecoration = decoration;
if (subSurfaceWindow()) {
subSurfaceWindow()->adjustPositionOfChildren();
}
}
static QWindow *topLevelWindow(QWindow *window)
{
while (QWindow *parent = window->parent())
window = parent;
return window;
}
QWaylandWindow *QWaylandWindow::transientParent() const
{
if (window()->transientParent()) {
// Take the top level window here, since the transient parent may be a QWidgetWindow
// or some other window without a shell surface, which is then not able to get mouse
// events, nor set mMouseSerial and mMouseDevice.
return static_cast<QWaylandWindow *>(topLevelWindow(window()->transientParent())->handle());
}
return 0;
}
void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
if (b != Qt::NoButton) {
mMouseSerial = inputDevice->serial();
mMouseDevice = inputDevice;
}
if (mWindowDecoration) {
handleMouseEventWithDecoration(inputDevice, timestamp,local,global,b,mods);
return;
}
QWindowSystemInterface::handleMouseEvent(window(),timestamp,local,global,b,mods);
}
void QWaylandWindow::handleMouseEnter(QWaylandInputDevice *inputDevice)
{
if (!mWindowDecoration) {
QWindowSystemInterface::handleEnterEvent(window());
}
restoreMouseCursor(inputDevice);
}
void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice)
{
if (mWindowDecoration) {
if (mMouseEventsInContentArea) {
QWindowSystemInterface::handleLeaveEvent(window());
}
} else {
QWindowSystemInterface::handleLeaveEvent(window());
}
restoreMouseCursor(inputDevice);
}
void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
if (mWindowDecoration->handleMouse(inputDevice,local,global,b,mods))
return;
QMargins marg = frameMargins();
QRect windowRect(0 + marg.left(),
0 + marg.top(),
geometry().size().width() - marg.right(),
geometry().size().height() - marg.bottom());
if (windowRect.contains(local.toPoint()) || mMousePressedInContentArea != Qt::NoButton) {
QPointF localTranslated = local;
QPointF globalTranslated = global;
localTranslated.setX(localTranslated.x() - marg.left());
localTranslated.setY(localTranslated.y() - marg.top());
globalTranslated.setX(globalTranslated.x() - marg.left());
globalTranslated.setY(globalTranslated.y() - marg.top());
if (!mMouseEventsInContentArea) {
restoreMouseCursor(inputDevice);
QWindowSystemInterface::handleEnterEvent(window());
}
QWindowSystemInterface::handleMouseEvent(window(), timestamp, localTranslated, globalTranslated, b, mods);
mMouseEventsInContentArea = true;
mMousePressedInContentArea = b;
} else {
if (mMouseEventsInContentArea) {
QWindowSystemInterface::handleLeaveEvent(window());
mMouseEventsInContentArea = false;
}
mWindowDecoration->handleMouse(inputDevice,local,global,b,mods);
}
}
void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape)
{
if (m_cursorShape != shape || device->serial() > device->cursorSerial()) {
device->setCursor(shape, mScreen);
m_cursorShape = shape;
}
}
void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device)
{
setMouseCursor(device, window()->cursor().shape());
}
void QWaylandWindow::requestActivateWindow()
{
// no-op. Wayland does not have activation protocol,
// we rely on compositor setting keyboard focus based on window stacking.
}
bool QWaylandWindow::setMouseGrabEnabled(bool grab)
{
if (window()->type() != Qt::Popup) {
qWarning("This plugin supports grabbing the mouse only for popup windows");
return false;
}
mMouseGrab = grab ? this : 0;
return true;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,233 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDWINDOW_H
#define QWAYLANDWINDOW_H
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
#include <QtGui/QIcon>
#include <qpa/qplatformwindow.h>
#include "qwaylanddisplay.h"
#include <QtWaylandClient/private/qwayland-wayland.h>
struct wl_egl_window;
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class QWaylandBuffer;
class QWaylandShellSurface;
class QWaylandExtendedSurface;
class QWaylandSubSurface;
class QWaylandDecoration;
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowConfigure
{
public:
QWaylandWindowConfigure()
: width(0)
, height(0)
, edges(0)
{ }
void clear()
{ width = height = edges = 0; }
bool isEmpty() const
{ return !height || !width; }
int width;
int height;
uint32_t edges;
};
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow, public QtWayland::wl_surface
{
Q_OBJECT
public:
enum WindowType {
Shm,
Egl
};
QWaylandWindow(QWindow *window);
~QWaylandWindow();
virtual WindowType windowType() const = 0;
WId winId() const;
void setVisible(bool visible);
void setParent(const QPlatformWindow *parent);
void setWindowTitle(const QString &title);
inline QIcon windowIcon() const;
void setWindowIcon(const QIcon &icon);
void setGeometry(const QRect &rect);
void configure(uint32_t edges, int32_t width, int32_t height);
using QtWayland::wl_surface::attach;
void attach(QWaylandBuffer *buffer, int x, int y);
void attachOffset(QWaylandBuffer *buffer);
QWaylandBuffer *attached() const;
QPoint attachOffset() const;
using QtWayland::wl_surface::damage;
void damage(const QRect &rect);
void waitForFrameSync();
QMargins frameMargins() const;
static QWaylandWindow *fromWlSurface(::wl_surface *surface);
QWaylandShellSurface *shellSurface() const;
QWaylandExtendedSurface *extendedWindow() const;
QWaylandSubSurface *subSurfaceWindow() const;
void handleContentOrientationChange(Qt::ScreenOrientation orientation);
void setWindowState(Qt::WindowState state);
void setWindowFlags(Qt::WindowFlags flags);
void raise() Q_DECL_OVERRIDE;
void lower() Q_DECL_OVERRIDE;
void requestActivateWindow() Q_DECL_OVERRIDE;
QWaylandDecoration *decoration() const;
void setDecoration(QWaylandDecoration *decoration);
void handleMouse(QWaylandInputDevice *inputDevice,
ulong timestamp,
const QPointF & local,
const QPointF & global,
Qt::MouseButtons b,
Qt::KeyboardModifiers mods);
void handleMouseEnter(QWaylandInputDevice *inputDevice);
void handleMouseLeave(QWaylandInputDevice *inputDevice);
bool createDecoration();
inline bool isMaximized() const { return mState == Qt::WindowMaximized; }
inline bool isFullscreen() const { return mState == Qt::WindowFullScreen; }
void setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape);
void restoreMouseCursor(QWaylandInputDevice *device);
QWaylandWindow *transientParent() const;
QMutex *resizeMutex() { return &mResizeLock; }
void doResize();
void setCanResize(bool canResize);
bool setMouseGrabEnabled(bool grab);
static QWaylandWindow *mouseGrab() { return mMouseGrab; }
public slots:
void requestResize();
protected:
QWaylandScreen *mScreen;
QWaylandDisplay *mDisplay;
QWaylandShellSurface *mShellSurface;
QWaylandExtendedSurface *mExtendedWindow;
QWaylandSubSurface *mSubSurfaceWindow;
QWaylandDecoration *mWindowDecoration;
bool mMouseEventsInContentArea;
Qt::MouseButtons mMousePressedInContentArea;
Qt::CursorShape m_cursorShape;
QWaylandBuffer *mBuffer;
WId mWindowId;
bool mWaitingForFrameSync;
struct wl_callback *mFrameCallback;
QWaitCondition mFrameSyncWait;
QMutex mResizeLock;
QWaylandWindowConfigure mConfigure;
bool mRequestResizeSent;
bool mCanResize;
bool mSentInitialResize;
QPoint mOffset;
QIcon mWindowIcon;
QWaylandInputDevice *mMouseDevice;
int mMouseSerial;
Qt::WindowState mState;
private:
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice,
ulong timestamp,
const QPointF & local,
const QPointF & global,
Qt::MouseButtons b,
Qt::KeyboardModifiers mods);
static const wl_callback_listener callbackListener;
static void frameCallback(void *data, struct wl_callback *wl_callback, uint32_t time);
static QMutex mFrameSyncMutex;
static QWaylandWindow *mMouseGrab;
};
inline QIcon QWaylandWindow::windowIcon() const
{
return mWindowIcon;
}
inline QPoint QWaylandWindow::attachOffset() const
{
return mOffset;
}
QT_END_NAMESPACE
#endif // QWAYLANDWINDOW_H

View File

@ -0,0 +1,159 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandwindowmanagerintegration.h"
#include "qwaylandscreen.h"
#include "qwaylandwindow.h"
#include <stdint.h>
#include <QtCore/QEvent>
#include <QtCore/QHash>
#include <QtCore/QUrl>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformwindow.h>
#include <QtGui/QtEvents>
#include <QtGui/QGuiApplication>
#include <QDebug>
QT_BEGIN_NAMESPACE
class QWaylandWindowManagerIntegrationPrivate {
public:
QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay);
bool m_blockPropertyUpdates;
QWaylandDisplay *m_waylandDisplay;
QHash<QWindow*, QVariantMap> m_queuedProperties;
bool m_showIsFullScreen;
};
QWaylandWindowManagerIntegrationPrivate::QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay)
: m_blockPropertyUpdates(false)
, m_waylandDisplay(waylandDisplay)
, m_showIsFullScreen(false)
{
}
QWaylandWindowManagerIntegration::QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay)
: d_ptr(new QWaylandWindowManagerIntegrationPrivate(waylandDisplay))
{
waylandDisplay->addRegistryListener(&wlHandleListenerGlobal, this);
}
QWaylandWindowManagerIntegration::~QWaylandWindowManagerIntegration()
{
}
bool QWaylandWindowManagerIntegration::showIsFullScreen() const
{
Q_D(const QWaylandWindowManagerIntegration);
return d->m_showIsFullScreen;
}
void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version)
{
Q_UNUSED(version);
if (interface == "qt_windowmanager")
static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id);
}
void QWaylandWindowManagerIntegration::windowmanager_hints(int32_t showIsFullScreen)
{
Q_D(QWaylandWindowManagerIntegration);
d->m_showIsFullScreen = showIsFullScreen;
}
void QWaylandWindowManagerIntegration::windowmanager_quit()
{
QGuiApplication::quit();
}
QByteArray QWaylandWindowManagerIntegration::desktopEnvironment() const
{
const QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
if (!xdgCurrentDesktop.isEmpty())
return xdgCurrentDesktop.toUpper(); // KDE, GNOME, UNITY, LXDE, MATE, XFCE...
// Classic fallbacks
if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION"))
return QByteArrayLiteral("KDE");
if (!qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID"))
return QByteArrayLiteral("GNOME");
// Fallback to checking $DESKTOP_SESSION (unreliable)
const QByteArray desktopSession = qgetenv("DESKTOP_SESSION");
if (desktopSession == "gnome")
return QByteArrayLiteral("GNOME");
if (desktopSession == "xfce")
return QByteArrayLiteral("XFCE");
return QByteArrayLiteral("UNKNOWN");
}
void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url)
{
if (isInitialized()) {
QByteArray data = url.toString().toUtf8();
static const int chunkSize = 128;
while (!data.isEmpty()) {
QByteArray chunk = data.left(chunkSize);
data = data.mid(chunkSize);
open_url(!data.isEmpty(), QString::fromUtf8(chunk));
}
}
}
bool QWaylandWindowManagerIntegration::openUrl(const QUrl &url)
{
openUrl_helper(url);
return true;
}
bool QWaylandWindowManagerIntegration::openDocument(const QUrl &url)
{
openUrl_helper(url);
return true;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,88 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDWINDOWMANAGERINTEGRATION_H
#define QWAYLANDWINDOWMANAGERINTEGRATION_H
#include <QtCore/QObject>
#include <QtCore/QScopedPointer>
#include "wayland-client.h"
#include "qwaylanddisplay.h"
#include <qpa/qplatformservices.h>
#include "QtWaylandClient/private/qwayland-windowmanager.h"
QT_BEGIN_NAMESPACE
class QWaylandWindow;
class QWaylandWindowManagerIntegrationPrivate;
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowManagerIntegration : public QObject, public QPlatformServices, public QtWayland::qt_windowmanager
{
Q_OBJECT
Q_DECLARE_PRIVATE(QWaylandWindowManagerIntegration)
public:
explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay);
virtual ~QWaylandWindowManagerIntegration();
QByteArray desktopEnvironment() const;
bool openUrl(const QUrl &url);
bool openDocument(const QUrl &url);
bool showIsFullScreen() const;
private:
static void wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id,
const QString &interface, uint32_t version);
QScopedPointer<QWaylandWindowManagerIntegrationPrivate> d_ptr;
void windowmanager_hints(int32_t showIsFullScreen) Q_DECL_OVERRIDE;
void windowmanager_quit() Q_DECL_OVERRIDE;
void openUrl_helper(const QUrl &url);
};
QT_END_NAMESPACE
#endif // QWAYLANDWINDOWMANAGERINTEGRATION_H