1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39
40 #ifndef QWINDOWSCURSOR_H
41 #define QWINDOWSCURSOR_H
42
43 #include <QtCore/qt_windows.h>
44
45 #include <qpa/qplatformcursor.h>
46 #include <QtCore/qsharedpointer.h>
47 #include <QtCore/qhash.h>
48
49 QT_BEGIN_NAMESPACE
50
51 struct QWindowsPixmapCursorCacheKey
52 {
53 explicit QWindowsPixmapCursorCacheKey(const QCursor &c);
54
55 qint64 bitmapCacheKey;
56 qint64 maskCacheKey;
57 };
58
59 inline bool operator==(const QWindowsPixmapCursorCacheKey &k1, const QWindowsPixmapCursorCacheKey &k2)
60 {
61 return k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey;
62 }
63
qHash(const QWindowsPixmapCursorCacheKey & k,uint seed)64 inline uint qHash(const QWindowsPixmapCursorCacheKey &k, uint seed) noexcept
65 {
66 return (uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed;
67 }
68
69 class CursorHandle
70 {
Q_DISABLE_COPY_MOVE(CursorHandle)71 Q_DISABLE_COPY_MOVE(CursorHandle)
72 public:
73 explicit CursorHandle(HCURSOR hcursor = nullptr) : m_hcursor(hcursor) {}
~CursorHandle()74 ~CursorHandle()
75 {
76 if (m_hcursor)
77 DestroyCursor(m_hcursor);
78 }
79
isNull()80 bool isNull() const { return !m_hcursor; }
handle()81 HCURSOR handle() const { return m_hcursor; }
82
83 private:
84 const HCURSOR m_hcursor;
85 };
86
87 using CursorHandlePtr = QSharedPointer<CursorHandle>;
88
89 class QWindowsCursor : public QPlatformCursor
90 {
91 public:
92 enum class State {
93 Showing,
94 Hidden,
95 Suppressed // Cursor suppressed by touch interaction (Windows 8).
96 };
97
98 struct PixmapCursor {
pixmapPixmapCursor99 explicit PixmapCursor(const QPixmap &pix = QPixmap(), const QPoint &h = QPoint()) : pixmap(pix), hotSpot(h) {}
100
101 QPixmap pixmap;
102 QPoint hotSpot;
103 };
104
105 explicit QWindowsCursor(const QPlatformScreen *screen);
106
107 void changeCursor(QCursor * widgetCursor, QWindow * widget) override;
108 void setOverrideCursor(const QCursor &cursor) override;
109 void clearOverrideCursor() override;
110 static void enforceOverrideCursor();
hasOverrideCursor()111 static bool hasOverrideCursor() { return m_overriddenCursor != nullptr; }
112
113 QPoint pos() const override;
114 void setPos(const QPoint &pos) override;
115
116 QSize size() const override;
117
118 static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1);
119 static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); }
120 static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = nullptr);
121
122 static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = nullptr);
123 static QPoint mousePosition();
124 static State cursorState();
125
126 CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
127 CursorHandlePtr pixmapWindowCursor(const QCursor &c);
128
129 QPixmap dragDefaultCursor(Qt::DropAction action) const;
130
131 HCURSOR hCursor(const QCursor &c) const;
132
133 private:
134 typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
135 typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
136
137 CursorHandlePtr cursorHandle(const QCursor &c);
138
139 const QPlatformScreen *const m_screen;
140 StandardCursorCache m_standardCursorCache;
141 PixmapCursorCache m_pixmapCursorCache;
142
143 mutable QPixmap m_copyDragCursor;
144 mutable QPixmap m_moveDragCursor;
145 mutable QPixmap m_linkDragCursor;
146 mutable QPixmap m_ignoreDragCursor;
147
148 static HCURSOR m_overriddenCursor;
149 static HCURSOR m_overrideCursor;
150 };
151
152 QT_END_NAMESPACE
153
154 #endif // QWINDOWSCURSOR_H
155