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:
parent
b89c7f238f
commit
0984830c33
103
src/plugins/platforms/wayland/client.pro
Normal file
103
src/plugins/platforms/wayland/client.pro
Normal 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
|
||||
}
|
||||
|
68
src/plugins/platforms/wayland/qwaylandbuffer.h
Normal file
68
src/plugins/platforms/wayland/qwaylandbuffer.h
Normal 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
|
60
src/plugins/platforms/wayland/qwaylandclientexport.h
Normal file
60
src/plugins/platforms/wayland/qwaylandclientexport.h
Normal 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
|
||||
|
111
src/plugins/platforms/wayland/qwaylandclipboard.cpp
Normal file
111
src/plugins/platforms/wayland/qwaylandclipboard.cpp
Normal 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
|
72
src/plugins/platforms/wayland/qwaylandclipboard.h
Normal file
72
src/plugins/platforms/wayland/qwaylandclipboard.h
Normal 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
|
302
src/plugins/platforms/wayland/qwaylandcursor.cpp
Normal file
302
src/plugins/platforms/wayland/qwaylandcursor.cpp
Normal 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
|
116
src/plugins/platforms/wayland/qwaylandcursor.h
Normal file
116
src/plugins/platforms/wayland/qwaylandcursor.h
Normal 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
|
242
src/plugins/platforms/wayland/qwaylanddatadevice.cpp
Normal file
242
src/plugins/platforms/wayland/qwaylanddatadevice.cpp
Normal 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);
|
||||
}
|
97
src/plugins/platforms/wayland/qwaylanddatadevice.h
Normal file
97
src/plugins/platforms/wayland/qwaylanddatadevice.h
Normal 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
|
80
src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp
Normal file
80
src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp
Normal 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
|
69
src/plugins/platforms/wayland/qwaylanddatadevicemanager.h
Normal file
69
src/plugins/platforms/wayland/qwaylanddatadevicemanager.h
Normal 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
|
139
src/plugins/platforms/wayland/qwaylanddataoffer.cpp
Normal file
139
src/plugins/platforms/wayland/qwaylanddataoffer.cpp
Normal 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
|
92
src/plugins/platforms/wayland/qwaylanddataoffer.h
Normal file
92
src/plugins/platforms/wayland/qwaylanddataoffer.h
Normal 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
|
96
src/plugins/platforms/wayland/qwaylanddatasource.cpp
Normal file
96
src/plugins/platforms/wayland/qwaylanddatasource.cpp
Normal 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
|
77
src/plugins/platforms/wayland/qwaylanddatasource.h
Normal file
77
src/plugins/platforms/wayland/qwaylanddatasource.h
Normal 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
|
459
src/plugins/platforms/wayland/qwaylanddecoration.cpp
Normal file
459
src/plugins/platforms/wayland/qwaylanddecoration.cpp
Normal 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
|
155
src/plugins/platforms/wayland/qwaylanddecoration.h
Normal file
155
src/plugins/platforms/wayland/qwaylanddecoration.h
Normal 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
|
272
src/plugins/platforms/wayland/qwaylanddisplay.cpp
Normal file
272
src/plugins/platforms/wayland/qwaylanddisplay.cpp
Normal 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
|
193
src/plugins/platforms/wayland/qwaylanddisplay.h
Normal file
193
src/plugins/platforms/wayland/qwaylanddisplay.h
Normal 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
|
136
src/plugins/platforms/wayland/qwaylanddnd.cpp
Normal file
136
src/plugins/platforms/wayland/qwaylanddnd.cpp
Normal 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
|
80
src/plugins/platforms/wayland/qwaylanddnd.h
Normal file
80
src/plugins/platforms/wayland/qwaylanddnd.h
Normal 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
|
63
src/plugins/platforms/wayland/qwaylandeventthread.cpp
Normal file
63
src/plugins/platforms/wayland/qwaylandeventthread.cpp
Normal 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
|
46
src/plugins/platforms/wayland/qwaylandeventthread.h
Normal file
46
src/plugins/platforms/wayland/qwaylandeventthread.h
Normal 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
|
100
src/plugins/platforms/wayland/qwaylandextendedoutput.cpp
Normal file
100
src/plugins/platforms/wayland/qwaylandextendedoutput.cpp
Normal 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
|
69
src/plugins/platforms/wayland/qwaylandextendedoutput.h
Normal file
69
src/plugins/platforms/wayland/qwaylandextendedoutput.h
Normal 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
|
152
src/plugins/platforms/wayland/qwaylandextendedsurface.cpp
Normal file
152
src/plugins/platforms/wayland/qwaylandextendedsurface.cpp
Normal 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
|
85
src/plugins/platforms/wayland/qwaylandextendedsurface.h
Normal file
85
src/plugins/platforms/wayland/qwaylandextendedsurface.h
Normal 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
|
56
src/plugins/platforms/wayland/qwaylandglintegration.cpp
Normal file
56
src/plugins/platforms/wayland/qwaylandglintegration.cpp
Normal 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
|
76
src/plugins/platforms/wayland/qwaylandglintegration.h
Normal file
76
src/plugins/platforms/wayland/qwaylandglintegration.h
Normal 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
|
260
src/plugins/platforms/wayland/qwaylandinputcontext.cpp
Normal file
260
src/plugins/platforms/wayland/qwaylandinputcontext.cpp
Normal 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
|
||||
|
103
src/plugins/platforms/wayland/qwaylandinputcontext.h
Normal file
103
src/plugins/platforms/wayland/qwaylandinputcontext.h
Normal 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
|
798
src/plugins/platforms/wayland/qwaylandinputdevice.cpp
Normal file
798
src/plugins/platforms/wayland/qwaylandinputdevice.cpp
Normal 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
|
204
src/plugins/platforms/wayland/qwaylandinputdevice.h
Normal file
204
src/plugins/platforms/wayland/qwaylandinputdevice.h
Normal 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
|
252
src/plugins/platforms/wayland/qwaylandintegration.cpp
Normal file
252
src/plugins/platforms/wayland/qwaylandintegration.cpp
Normal 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
|
101
src/plugins/platforms/wayland/qwaylandintegration.h
Normal file
101
src/plugins/platforms/wayland/qwaylandintegration.h
Normal 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
|
134
src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
Normal file
134
src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
Normal 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
|
79
src/plugins/platforms/wayland/qwaylandnativeinterface.h
Normal file
79
src/plugins/platforms/wayland/qwaylandnativeinterface.h
Normal 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
|
85
src/plugins/platforms/wayland/qwaylandqtkey.cpp
Normal file
85
src/plugins/platforms/wayland/qwaylandqtkey.cpp
Normal 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
|
76
src/plugins/platforms/wayland/qwaylandqtkey.h
Normal file
76
src/plugins/platforms/wayland/qwaylandqtkey.h
Normal 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
|
184
src/plugins/platforms/wayland/qwaylandscreen.cpp
Normal file
184
src/plugins/platforms/wayland/qwaylandscreen.cpp
Normal 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
|
110
src/plugins/platforms/wayland/qwaylandscreen.h
Normal file
110
src/plugins/platforms/wayland/qwaylandscreen.h
Normal 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
|
176
src/plugins/platforms/wayland/qwaylandshellsurface.cpp
Normal file
176
src/plugins/platforms/wayland/qwaylandshellsurface.cpp
Normal 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
|
96
src/plugins/platforms/wayland/qwaylandshellsurface.h
Normal file
96
src/plugins/platforms/wayland/qwaylandshellsurface.h
Normal 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
|
322
src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
Normal file
322
src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
Normal 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 ®ion, 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
|
134
src/plugins/platforms/wayland/qwaylandshmbackingstore.h
Normal file
134
src/plugins/platforms/wayland/qwaylandshmbackingstore.h
Normal 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 ®ion, 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
|
73
src/plugins/platforms/wayland/qwaylandshmwindow.cpp
Normal file
73
src/plugins/platforms/wayland/qwaylandshmwindow.cpp
Normal 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
|
75
src/plugins/platforms/wayland/qwaylandshmwindow.h
Normal file
75
src/plugins/platforms/wayland/qwaylandshmwindow.h
Normal 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
|
91
src/plugins/platforms/wayland/qwaylandsubsurface.cpp
Normal file
91
src/plugins/platforms/wayland/qwaylandsubsurface.cpp
Normal 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
|
73
src/plugins/platforms/wayland/qwaylandsubsurface.h
Normal file
73
src/plugins/platforms/wayland/qwaylandsubsurface.h
Normal 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
|
209
src/plugins/platforms/wayland/qwaylandtouch.cpp
Normal file
209
src/plugins/platforms/wayland/qwaylandtouch.cpp
Normal 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
|
97
src/plugins/platforms/wayland/qwaylandtouch.h
Normal file
97
src/plugins/platforms/wayland/qwaylandtouch.h
Normal 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
|
608
src/plugins/platforms/wayland/qwaylandwindow.cpp
Normal file
608
src/plugins/platforms/wayland/qwaylandwindow.cpp
Normal 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
|
233
src/plugins/platforms/wayland/qwaylandwindow.h
Normal file
233
src/plugins/platforms/wayland/qwaylandwindow.h
Normal 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
|
@ -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
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user