1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QXCBCURSOR_H
5#define QXCBCURSOR_H
6
7#include <qpa/qplatformcursor.h>
8#include "qxcbscreen.h"
9#include <xcb/xcb_cursor.h>
10
11#include <QtCore/QCache>
12
13QT_BEGIN_NAMESPACE
14
15#ifndef QT_NO_CURSOR
16
17struct QXcbCursorCacheKey
18{
19 explicit QXcbCursorCacheKey(const QCursor &c);
20 explicit QXcbCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {}
21 QXcbCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {}
22
23 Qt::CursorShape shape;
24 qint64 bitmapCacheKey;
25 qint64 maskCacheKey;
26};
27
28inline bool operator==(const QXcbCursorCacheKey &k1, const QXcbCursorCacheKey &k2)
29{
30 return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey;
31}
32
33inline size_t qHash(const QXcbCursorCacheKey &k, size_t seed) noexcept
34{
35 return (size_t(k.shape) + size_t(k.bitmapCacheKey) + size_t(k.maskCacheKey)) ^ seed;
36}
37
38#endif // !QT_NO_CURSOR
39
40class QXcbCursor : public QXcbObject, public QPlatformCursor
41{
42public:
43 QXcbCursor(QXcbConnection *conn, QXcbScreen *screen);
44 ~QXcbCursor();
45#ifndef QT_NO_CURSOR
46 void changeCursor(QCursor *cursor, QWindow *window) override;
47#endif
48 QPoint pos() const override;
49 void setPos(const QPoint &pos) override;
50
51 void updateContext();
52
53 static void queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask = nullptr);
54
55#ifndef QT_NO_CURSOR
56 xcb_cursor_t xcbCursor(const QCursor &c) const
57 { return m_cursorHash.value(key: QXcbCursorCacheKey(c), defaultValue: xcb_cursor_t(0)); }
58#endif
59
60private:
61
62#ifndef QT_NO_CURSOR
63 typedef QHash<QXcbCursorCacheKey, xcb_cursor_t> CursorHash;
64
65 struct CachedCursor
66 {
67 explicit CachedCursor(xcb_connection_t *conn, xcb_cursor_t c)
68 : cursor(c), connection(conn) {}
69 ~CachedCursor() { xcb_free_cursor(c: connection, cursor); }
70 xcb_cursor_t cursor;
71 xcb_connection_t *connection;
72 };
73 typedef QCache<QXcbCursorCacheKey, CachedCursor> BitmapCursorCache;
74
75 xcb_cursor_t createFontCursor(int cshape);
76 xcb_cursor_t createBitmapCursor(QCursor *cursor);
77 xcb_cursor_t createNonStandardCursor(int cshape);
78#endif
79
80 QXcbScreen *m_screen;
81 xcb_cursor_context_t *m_cursorContext;
82#ifndef QT_NO_CURSOR
83 CursorHash m_cursorHash;
84 BitmapCursorCache m_bitmapCache;
85#endif
86 static void cursorThemePropertyChanged(QXcbVirtualDesktop *screen,
87 const QByteArray &name,
88 const QVariant &property,
89 void *handle);
90 bool m_callbackForPropertyRegistered;
91};
92
93QT_END_NAMESPACE
94
95#endif
96

source code of qtbase/src/plugins/platforms/xcb/qxcbcursor.h