summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbcursor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbcursor.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp550
1 files changed, 550 insertions, 0 deletions
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
new file mode 100644
index 0000000000..cf1e5279a0
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -0,0 +1,550 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbcursor.h"
+#include "qxcbconnection.h"
+#include "qxcbwindow.h"
+#include "qxcbimage.h"
+#include <QtCore/QLibrary>
+#include <QtGui/QWindow>
+#include <QtGui/QBitmap>
+#include <QtGui/private/qguiapplication_p.h>
+#include <X11/cursorfont.h>
+#include <xcb/xfixes.h>
+#include <xcb/xcb_image.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef int (*PtrXcursorLibraryLoadCursor)(void *, const char *);
+static PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor = 0;
+static xcb_font_t cursorFont = 0;
+static int cursorCount = 0;
+
+static uint8_t cur_blank_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+static const uint8_t cur_ver_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
+ 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
+static const uint8_t mcur_ver_bits[] = {
+ 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
+ 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
+ 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
+static const uint8_t cur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
+ 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
+ 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
+ 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
+static const uint8_t cur_bdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
+ 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
+ 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_bdiag_bits[] = {
+ 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
+ 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
+ 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t cur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
+ 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
+ 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
+ 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
+ 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
+static const uint8_t *cursor_bits16[] = {
+ cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
+ cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
+ 0, 0, cur_blank_bits, cur_blank_bits };
+
+static const uint8_t vsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t vsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t hsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
+ 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t hsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
+ 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
+ 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
+ 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t whatsthis_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
+ 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
+ 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
+ 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
+ 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
+ 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+static const uint8_t whatsthism_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
+ 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
+ 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
+ 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
+ 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
+ 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+static const uint8_t busy_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+ 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
+ 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
+ 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
+ 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
+ 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t busym_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
+ 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
+ 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
+ 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
+ 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
+ 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const uint8_t * const cursor_bits32[] = {
+ vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
+ 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
+};
+
+static const uint8_t forbidden_bits[] = {
+ 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
+ 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
+ 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
+ 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
+
+static const uint8_t forbiddenm_bits[] = {
+ 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
+ 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
+ 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
+ 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
+
+static const uint8_t openhand_bits[] = {
+ 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
+ 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
+ 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
+static const uint8_t openhandm_bits[] = {
+ 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
+ 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
+ 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
+static const uint8_t closedhand_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
+ 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
+ 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
+static const uint8_t closedhandm_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
+ 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
+ 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
+
+static const uint8_t * const cursor_bits20[] = {
+ forbidden_bits, forbiddenm_bits
+};
+
+static const char * const cursorNames[] = {
+ "left_ptr",
+ "up_arrow",
+ "cross",
+ "wait",
+ "ibeam",
+ "size_ver",
+ "size_hor",
+ "size_bdiag",
+ "size_fdiag",
+ "size_all",
+ "blank",
+ "split_v",
+ "split_h",
+ "pointing_hand",
+ "forbidden",
+ "whats_this",
+ "left_ptr_watch",
+ "openhand",
+ "closedhand",
+ "copy",
+ "move",
+ "link"
+};
+
+QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen)
+ : QXcbObject(conn), QPlatformCursor(screen), m_screen(screen)
+{
+ if (cursorCount++)
+ return;
+
+ cursorFont = xcb_generate_id(xcb_connection());
+ const char *cursorStr = "cursor";
+ xcb_open_font(xcb_connection(), cursorFont, strlen(cursorStr), cursorStr);
+
+#ifdef XCB_USE_XLIB
+ QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
+ bool xcursorFound = xcursorLib.load();
+ if (!xcursorFound) { // try without the version number
+ xcursorLib.setFileName(QLatin1String("Xcursor"));
+ xcursorFound = xcursorLib.load();
+ }
+ if (xcursorFound)
+ ptrXcursorLibraryLoadCursor =
+ (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
+#endif
+}
+
+QXcbCursor::~QXcbCursor()
+{
+ if (!--cursorCount)
+ xcb_close_font(xcb_connection(), cursorFont);
+}
+
+void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget)
+{
+ QXcbWindow *w = 0;
+ if (widget && widget->handle())
+ w = static_cast<QXcbWindow *>(widget->handle());
+ else
+ // No X11 cursor control when there is no widget under the cursor
+ return;
+
+ xcb_cursor_t c;
+ if (cursor->shape() == Qt::BitmapCursor) {
+ qint64 id = cursor->pixmap().cacheKey();
+ if (!m_bitmapCursorMap.contains(id))
+ m_bitmapCursorMap.insert(id, createBitmapCursor(cursor));
+ c = m_bitmapCursorMap.value(id);
+ } else {
+ int id = cursor->handle();
+ if (!m_shapeCursorMap.contains(id))
+ m_shapeCursorMap.insert(id, createFontCursor(cursor->shape()));
+ c = m_shapeCursorMap.value(id);
+ }
+
+ w->setCursor(c);
+}
+
+static int cursorIdForShape(int cshape)
+{
+ int cursorId = 0;
+ switch (cshape) {
+ case Qt::ArrowCursor:
+ cursorId = XC_left_ptr;
+ break;
+ case Qt::UpArrowCursor:
+ cursorId = XC_center_ptr;
+ break;
+ case Qt::CrossCursor:
+ cursorId = XC_crosshair;
+ break;
+ case Qt::WaitCursor:
+ cursorId = XC_watch;
+ break;
+ case Qt::IBeamCursor:
+ cursorId = XC_xterm;
+ break;
+ case Qt::SizeAllCursor:
+ cursorId = XC_fleur;
+ break;
+ case Qt::PointingHandCursor:
+ cursorId = XC_hand2;
+ break;
+ case Qt::SizeBDiagCursor:
+ cursorId = XC_top_right_corner;
+ break;
+ case Qt::SizeFDiagCursor:
+ cursorId = XC_bottom_right_corner;
+ break;
+ case Qt::SizeVerCursor:
+ case Qt::SplitVCursor:
+ cursorId = XC_sb_v_double_arrow;
+ break;
+ case Qt::SizeHorCursor:
+ case Qt::SplitHCursor:
+ cursorId = XC_sb_h_double_arrow;
+ break;
+ case Qt::WhatsThisCursor:
+ cursorId = XC_question_arrow;
+ break;
+ case Qt::ForbiddenCursor:
+ cursorId = XC_circle;
+ break;
+ case Qt::BusyCursor:
+ cursorId = XC_watch;
+ break;
+ default:
+ break;
+ }
+ return cursorId;
+}
+
+xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
+{
+ xcb_cursor_t cursor = 0;
+ xcb_connection_t *conn = xcb_connection();
+
+ if (cshape == Qt::BlankCursor) {
+ xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16,
+ 1, 0, 0, 0);
+ xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16,
+ 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if (cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor) {
+ int i = (cshape - Qt::SizeVerCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits16[i]),
+ 16, 16, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits16[i + 1]),
+ 16, 16, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
+ || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
+ int i = (cshape - Qt::SplitVCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits32[i]),
+ 32, 32, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits32[i + 1]),
+ 32, 32, 1, 0, 0, 0);
+ int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
+ || cshape == Qt::BusyCursor) ? 0 : 16;
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, hs, hs);
+ } else if (cshape == Qt::ForbiddenCursor) {
+ int i = (cshape - Qt::ForbiddenCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits20[i]),
+ 20, 20, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits20[i + 1]),
+ 20, 20, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 10, 10);
+ } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
+ bool open = cshape == Qt::OpenHandCursor;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(open ? openhand_bits : closedhand_bits),
+ 16, 16, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(open ? openhandm_bits : closedhandm_bits),
+ 16, 16, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
+ || cshape == Qt::DragLinkCursor) {
+ QImage image = QGuiApplicationPrivate::instance()->getPixmapCursor(static_cast<Qt::CursorShape>(cshape)).toImage();
+ xcb_pixmap_t pm = qt_xcb_XPixmapFromBitmap(m_screen, image);
+ xcb_pixmap_t pmm = qt_xcb_XPixmapFromBitmap(m_screen, image.createAlphaMask());
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ }
+
+ return cursor;
+}
+
+xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
+{
+ xcb_connection_t *conn = xcb_connection();
+ int cursorId = cursorIdForShape(cshape);
+ xcb_cursor_t cursor = XCB_NONE;
+
+ // Try Xcursor first
+#ifdef XCB_USE_XLIB
+ if (ptrXcursorLibraryLoadCursor && cshape >= 0 && cshape < Qt::LastCursor) {
+ void *dpy = connection()->xlib_display();
+ // special case for non-standard dnd-* cursors
+ switch (cshape) {
+ case Qt::DragCopyCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-copy");
+ break;
+ case Qt::DragMoveCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-move");
+ break;
+ case Qt::DragLinkCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-link");
+ break;
+ default:
+ break;
+ }
+ if (!cursor)
+ cursor = ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
+ }
+ if (cursor)
+ return cursor;
+#endif
+
+ // Non-standard X11 cursors are created from bitmaps
+ cursor = createNonStandardCursor(cshape);
+
+ // Create a glpyh cursor if everything else failed
+ if (!cursor && cursorId) {
+ cursor = xcb_generate_id(conn);
+ xcb_create_glyph_cursor(conn, cursor, cursorFont, cursorFont,
+ cursorId, cursorId + 1,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0);
+ }
+
+ if (cursor && cshape >= 0 && cshape < Qt::LastCursor) {
+ const char *name = cursorNames[cshape];
+ xcb_xfixes_set_cursor_name(conn, cursor, strlen(name), name);
+ }
+
+ return cursor;
+}
+
+xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor)
+{
+ xcb_connection_t *conn = xcb_connection();
+ QPoint spot = cursor->hotSpot();
+ xcb_pixmap_t cp;
+ xcb_pixmap_t mp;
+ if (cursor->pixmap().depth() > 1) {
+ // ### this will result in monochrome cursors
+ cp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->bitmap()->toImage());
+ mp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->mask()->toImage());
+ } else {
+ cp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->bitmap()->toImage());
+ mp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->mask()->toImage());
+ }
+ xcb_cursor_t c = xcb_generate_id(conn);
+ xcb_create_cursor(conn, c, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF,
+ spot.x(), spot.y());
+ xcb_free_pixmap(conn, cp);
+ if (mp)
+ xcb_free_pixmap(conn, mp);
+ return c;
+}
+
+static void getPosAndRoot(xcb_connection_t *conn, xcb_window_t *rootWin, QPoint *pos)
+{
+ if (pos)
+ *pos = QPoint();
+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(conn));
+ while (it.rem) {
+ xcb_window_t root = it.data->root;
+ xcb_query_pointer_cookie_t cookie = xcb_query_pointer(conn, root);
+ xcb_generic_error_t *err = 0;
+ xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(conn, cookie, &err);
+ if (!err && reply) {
+ if (pos)
+ *pos = QPoint(reply->root_x, reply->root_y);
+ if (rootWin)
+ *rootWin = root;
+ free(reply);
+ return;
+ }
+ free(err);
+ free(reply);
+ xcb_screen_next(&it);
+ }
+}
+
+QPoint QXcbCursor::pos() const
+{
+ QPoint p;
+ getPosAndRoot(xcb_connection(), 0, &p);
+ return p;
+}
+
+void QXcbCursor::setPos(const QPoint &pos)
+{
+ xcb_connection_t *conn = xcb_connection();
+ xcb_window_t root;
+ getPosAndRoot(conn, &root, 0);
+ xcb_warp_pointer(conn, XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y());
+}
+
+QT_END_NAMESPACE