summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-03-29 10:26:12 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2016-03-29 10:26:12 +0000
commitf3913dddee41b4a2c52518e720ac1945fde3bbab (patch)
tree9254a98a96329ce10d253e049910e054e263e993
parent6942edb5a7cd58cf16bd244bfb9f1efc3b8f91c0 (diff)
parent573fbed837e2b7281c7a828cdcda141fbbcac030 (diff)
Merge "Merge remote-tracking branch 'origin/5.6' into 5.7" into refs/staging/5.7
-rw-r--r--src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h2
-rw-r--r--src/client/qwaylandcursor.cpp29
-rw-r--r--src/client/qwaylandcursor_p.h2
-rw-r--r--src/client/qwaylanddisplay_p.h1
-rw-r--r--src/client/qwaylandinputdevice.cpp28
-rw-r--r--src/client/qwaylandinputdevice_p.h5
-rw-r--r--src/client/qwaylandwindow.cpp12
-rw-r--r--src/client/qwaylandwindow_p.h4
-rw-r--r--src/client/qwaylandxdgsurface.cpp10
9 files changed, 76 insertions, 17 deletions
diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h b/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h
index c2cc0f212..21d0c8bd8 100644
--- a/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h
+++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h
@@ -54,6 +54,8 @@
#include <QtCore/qglobal.h>
#include <QtWaylandClient/private/qwaylandclientexport_p.h>
+#include <stdint.h>
+
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp
index f96b5c1e1..e3e3469be 100644
--- a/src/client/qwaylandcursor.cpp
+++ b/src/client/qwaylandcursor.cpp
@@ -91,7 +91,8 @@ struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape newShape)
if (newShape < Qt::BitmapCursor) {
waylandCursor = requestCursor((WaylandCursor)newShape);
} else if (newShape == Qt::BitmapCursor) {
- //TODO: Bitmap cursor logic
+ // cannot create a wl_cursor_image for a CursorShape
+ return Q_NULLPTR;
} else {
//TODO: Custom cursor logic (for resize arrows)
}
@@ -111,12 +112,28 @@ struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape newShape)
return image;
}
+QSharedPointer<QWaylandBuffer> QWaylandCursor::cursorBitmapImage(const QCursor *cursor)
+{
+ if (cursor->shape() != Qt::BitmapCursor)
+ return QSharedPointer<QWaylandShmBuffer>();
+
+ const QImage &img = cursor->pixmap().toImage();
+ QSharedPointer<QWaylandShmBuffer> buffer(new QWaylandShmBuffer(mDisplay, img.size(), img.format()));
+ memcpy(buffer->image()->bits(), img.bits(), img.byteCount());
+ return buffer;
+}
+
void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window)
{
Q_UNUSED(window)
const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
+ if (newShape == Qt::BitmapCursor) {
+ mDisplay->setCursor(cursorBitmapImage(cursor), cursor->hotSpot());
+ return;
+ }
+
struct wl_cursor_image *image = cursorImage(newShape);
if (!image) {
return;
@@ -136,6 +153,16 @@ void QWaylandDisplay::setCursor(struct wl_buffer *buffer, struct wl_cursor_image
}
}
+void QWaylandDisplay::setCursor(const QSharedPointer<QWaylandBuffer> &buffer, const QPoint &hotSpot)
+{
+ /* 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, hotSpot);
+ }
+}
+
QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
{
return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
diff --git a/src/client/qwaylandcursor_p.h b/src/client/qwaylandcursor_p.h
index 52924f11e..a54841a28 100644
--- a/src/client/qwaylandcursor_p.h
+++ b/src/client/qwaylandcursor_p.h
@@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
+class QWaylandBuffer;
class QWaylandDisplay;
class QWaylandScreen;
@@ -78,6 +79,7 @@ public:
void setPos(const QPoint &pos);
struct wl_cursor_image *cursorImage(Qt::CursorShape shape);
+ QSharedPointer<QWaylandBuffer> cursorBitmapImage(const QCursor *cursor);
private:
enum WaylandCursor {
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index a1e71acc3..82d87cb92 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -124,6 +124,7 @@ public:
QWaylandWindowManagerIntegration *windowManagerIntegration() const;
void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image);
+ void setCursor(const QSharedPointer<QWaylandBuffer> &buffer, const QPoint &hotSpot);
struct wl_display *wl_display() const { return mDisplay; }
struct ::wl_registry *wl_registry() { return object(); }
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
index 99c54238a..46c473e70 100644
--- a/src/client/qwaylandinputdevice.cpp
+++ b/src/client/qwaylandinputdevice.cpp
@@ -48,6 +48,7 @@
#include "qwaylandscreen_p.h"
#include "qwaylandcursor_p.h"
#include "qwaylanddisplay_p.h"
+#include "qwaylandshmbackingstore_p.h"
#include "../shared/qwaylandxkb.h"
#include <QtGui/private/qpixmap_raster_p.h>
@@ -337,9 +338,26 @@ void QWaylandInputDevice::setCursor(Qt::CursorShape newShape, QWaylandScreen *sc
setCursor(buffer, image);
}
+void QWaylandInputDevice::setCursor(const QCursor &cursor, QWaylandScreen *screen)
+{
+ if (cursor.shape() == Qt::BitmapCursor) {
+ setCursor(screen->waylandCursor()->cursorBitmapImage(&cursor), cursor.hotSpot());
+ return;
+ }
+ setCursor(cursor.shape(), screen);
+}
+
void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image)
{
+ setCursor(buffer,
+ image ? QPoint(image->hotspot_x, image->hotspot_y) : QPoint(),
+ image ? QSize(image->width, image->height) : QSize());
+}
+
+void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, const QPoint &hotSpot, const QSize &size)
+{
if (mCaps & WL_SEAT_CAPABILITY_POINTER) {
+ mPixmapCursor.clear();
mPointer->mCursorSerial = mPointer->mEnterSerial;
/* Hide cursor */
if (!buffer)
@@ -349,13 +367,19 @@ void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_i
}
mPointer->set_cursor(mPointer->mEnterSerial, pointerSurface,
- image->hotspot_x, image->hotspot_y);
+ hotSpot.x(), hotSpot.y());
wl_surface_attach(pointerSurface, buffer, 0, 0);
- wl_surface_damage(pointerSurface, 0, 0, image->width, image->height);
+ wl_surface_damage(pointerSurface, 0, 0, size.width(), size.height());
wl_surface_commit(pointerSurface);
}
}
+void QWaylandInputDevice::setCursor(const QSharedPointer<QWaylandBuffer> &buffer, const QPoint &hotSpot)
+{
+ setCursor(buffer->buffer(), hotSpot, buffer->size());
+ mPixmapCursor = buffer;
+}
+
class EnterEvent : public QWaylandPointerEvent
{
public:
diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h
index f3db0df78..0da45c384 100644
--- a/src/client/qwaylandinputdevice_p.h
+++ b/src/client/qwaylandinputdevice_p.h
@@ -99,7 +99,10 @@ public:
struct ::wl_seat *wl_seat() { return QtWayland::wl_seat::object(); }
void setCursor(Qt::CursorShape cursor, QWaylandScreen *screen);
+ void setCursor(const QCursor &cursor, QWaylandScreen *screen);
void setCursor(struct wl_buffer *buffer, struct ::wl_cursor_image *image);
+ void setCursor(struct wl_buffer *buffer, const QPoint &hotSpot, const QSize &size);
+ void setCursor(const QSharedPointer<QWaylandBuffer> &buffer, const QPoint &hotSpot);
void handleWindowDestroyed(QWaylandWindow *window);
void setDataDevice(QWaylandDataDevice *device);
@@ -143,6 +146,8 @@ private:
QTouchDevice *mTouchDevice;
+ QSharedPointer<QWaylandBuffer> mPixmapCursor;
+
friend class QWaylandTouchExtension;
friend class QWaylandQtKeyExtension;
};
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index eebc9bda0..80783060a 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -80,7 +80,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
, mWindowDecoration(0)
, mMouseEventsInContentArea(false)
, mMousePressedInContentArea(Qt::NoButton)
- , m_cursorShape(Qt::ArrowCursor)
+ , m_cursor(Qt::ArrowCursor)
, mWaitingForFrameSync(false)
, mFrameCallback(0)
, mRequestResizeSent(false)
@@ -752,17 +752,17 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe
}
}
-void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape)
+void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor)
{
- if (m_cursorShape != shape || device->serial() > device->cursorSerial()) {
- device->setCursor(shape, mScreen);
- m_cursorShape = shape;
+ if (device->serial() >= device->cursorSerial()) {
+ device->setCursor(cursor, mScreen);
+ m_cursor = cursor;
}
}
void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device)
{
- setMouseCursor(device, window()->cursor().shape());
+ setMouseCursor(device, window()->cursor());
}
void QWaylandWindow::requestActivateWindow()
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index c1346e666..02671a933 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -174,7 +174,7 @@ public:
inline bool isMaximized() const { return mState == Qt::WindowMaximized; }
inline bool isFullscreen() const { return mState == Qt::WindowFullScreen; }
- void setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape);
+ void setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor);
void restoreMouseCursor(QWaylandInputDevice *device);
QWaylandWindow *transientParent() const;
@@ -212,7 +212,7 @@ protected:
QWaylandAbstractDecoration *mWindowDecoration;
bool mMouseEventsInContentArea;
Qt::MouseButtons mMousePressedInContentArea;
- Qt::CursorShape m_cursorShape;
+ QCursor m_cursor;
WId mWindowId;
bool mWaitingForFrameSync;
diff --git a/src/client/qwaylandxdgsurface.cpp b/src/client/qwaylandxdgsurface.cpp
index 51630af96..b9f07f0cc 100644
--- a/src/client/qwaylandxdgsurface.cpp
+++ b/src/client/qwaylandxdgsurface.cpp
@@ -179,15 +179,13 @@ void QWaylandXdgSurface::sendProperty(const QString &name, const QVariant &value
void QWaylandXdgSurface::xdg_surface_configure(int32_t width, int32_t height, struct wl_array *states,uint32_t serial)
{
- uint32_t *state = 0;
+ uint32_t *state = reinterpret_cast<uint32_t*>(states->data);
+ size_t numStates = states->size / sizeof(uint32_t);
bool aboutToMaximize = false;
bool aboutToFullScreen = false;
- state = (uint32_t*) states->data;
-
- for (uint32_t i = 0; i < states->size / sizeof(state) ; i++)
- {
- switch (*(state+i)) {
+ for (size_t i = 0; i < numStates; i++) {
+ switch (state[i]) {
case XDG_SURFACE_STATE_MAXIMIZED:
aboutToMaximize = ((width > 0) && (height > 0));
break;