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 QXCBCURSOR_H
41#define QXCBCURSOR_H
42
43#include <qpa/qplatformcursor.h>
44#include "qxcbscreen.h"
45
46#include <QtCore/QCache>
47
48QT_BEGIN_NAMESPACE
49
50#ifndef QT_NO_CURSOR
51
52struct QXcbCursorCacheKey
53{
54 explicit QXcbCursorCacheKey(const QCursor &c);
55 explicit QXcbCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {}
56 QXcbCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {}
57
58 Qt::CursorShape shape;
59 qint64 bitmapCacheKey;
60 qint64 maskCacheKey;
61};
62
63inline bool operator==(const QXcbCursorCacheKey &k1, const QXcbCursorCacheKey &k2)
64{
65 return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey;
66}
67
68inline uint qHash(const QXcbCursorCacheKey &k, uint seed) noexcept
69{
70 return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed;
71}
72
73#endif // !QT_NO_CURSOR
74
75class QXcbCursor : public QXcbObject, public QPlatformCursor
76{
77public:
78 QXcbCursor(QXcbConnection *conn, QXcbScreen *screen);
79 ~QXcbCursor();
80#ifndef QT_NO_CURSOR
81 void changeCursor(QCursor *cursor, QWindow *window) override;
82#endif
83 QPoint pos() const override;
84 void setPos(const QPoint &pos) override;
85
86 static void queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask = nullptr);
87
88#ifndef QT_NO_CURSOR
89 xcb_cursor_t xcbCursor(const QCursor &c) const
90 { return m_cursorHash.value(QXcbCursorCacheKey(c), xcb_cursor_t(0)); }
91#endif
92
93private:
94
95#ifndef QT_NO_CURSOR
96 typedef QHash<QXcbCursorCacheKey, xcb_cursor_t> CursorHash;
97
98 struct CachedCursor
99 {
100 explicit CachedCursor(xcb_connection_t *conn, xcb_cursor_t c)
101 : cursor(c), connection(conn) {}
102 ~CachedCursor() { xcb_free_cursor(connection, cursor); }
103 xcb_cursor_t cursor;
104 xcb_connection_t *connection;
105 };
106 typedef QCache<QXcbCursorCacheKey, CachedCursor> BitmapCursorCache;
107
108 xcb_cursor_t createFontCursor(int cshape);
109 xcb_cursor_t createBitmapCursor(QCursor *cursor);
110 xcb_cursor_t createNonStandardCursor(int cshape);
111#endif
112
113 QXcbScreen *m_screen;
114#ifndef QT_NO_CURSOR
115 CursorHash m_cursorHash;
116 BitmapCursorCache m_bitmapCache;
117#endif
118#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
119 static void cursorThemePropertyChanged(QXcbVirtualDesktop *screen,
120 const QByteArray &name,
121 const QVariant &property,
122 void *handle);
123#endif
124 bool m_gtkCursorThemeInitialized;
125};
126
127QT_END_NAMESPACE
128
129#endif
130