Cursor support in xcb plug-in.
Custom cursor pixmaps with depth greater than 1 are not yet supported and will be converted to monochrome always. Reviewed-by: Samuel Rødalbb10
parent
88f3b059a9
commit
4469de4ce7
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <qcursor.h>
|
||||
#include <private/qcursor_p.h>
|
||||
#include <qplatformcursor_qpa.h>
|
||||
#include <qbitmap.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -107,21 +108,39 @@ void QCursorData::update()
|
|||
|
||||
#endif //QT_NO_CURSOR
|
||||
|
||||
extern int qt_last_x,qt_last_y;
|
||||
extern int qt_last_x;
|
||||
extern int qt_last_y;
|
||||
|
||||
QPoint QCursor::pos()
|
||||
{
|
||||
QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
|
||||
int cursorCount = cursors.count();
|
||||
for (int i = 0; i < cursorCount; ++i) {
|
||||
const QWeakPointer<QPlatformCursor> &cursor(cursors.at(i));
|
||||
if (cursor)
|
||||
return cursor.data()->pos();
|
||||
}
|
||||
return QPoint(qt_last_x, qt_last_y);
|
||||
}
|
||||
|
||||
void QCursor::setPos(int x, int y)
|
||||
{
|
||||
QPoint target(x, y);
|
||||
|
||||
// Need to check, since some X servers generate null mouse move
|
||||
// events, causing looping in applications which call setPos() on
|
||||
// every mouse move event.
|
||||
//
|
||||
if (pos() == QPoint(x, y))
|
||||
if (pos() == target)
|
||||
return;
|
||||
|
||||
QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
|
||||
int cursorCount = cursors.count();
|
||||
for (int i = 0; i < cursorCount; ++i) {
|
||||
const QWeakPointer<QPlatformCursor> &cursor(cursors.at(i));
|
||||
if (cursor)
|
||||
cursor.data()->setPos(target);
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ static void init_platform(const QString &name, const QString &platformPluginPath
|
|||
QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
|
||||
QString fatalMessage =
|
||||
QString::fromLatin1("Failed to load platform plugin \"%1\". Available platforms are: \n").arg(name);
|
||||
foreach(QString key, keys) {
|
||||
foreach(const QString &key, keys) {
|
||||
fatalMessage.append(key + QString::fromLatin1("\n"));
|
||||
}
|
||||
qFatal("%s", fatalMessage.toLocal8Bit().constData());
|
||||
|
|
@ -221,7 +221,7 @@ static void init_platform(const QString &name, const QString &platformPluginPath
|
|||
|
||||
}
|
||||
|
||||
static void init_plugins(const QList<QByteArray> pluginList)
|
||||
static void init_plugins(const QList<QByteArray> &pluginList)
|
||||
{
|
||||
for (int i = 0; i < pluginList.count(); ++i) {
|
||||
QByteArray pluginSpec = pluginList.at(i);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,21 @@ QPlatformCursor::QPlatformCursor(QPlatformScreen *scr )
|
|||
QPlatformCursorPrivate::instances.append(this);
|
||||
}
|
||||
|
||||
extern int qt_last_x;
|
||||
extern int qt_last_y;
|
||||
|
||||
QPoint QPlatformCursor::pos() const
|
||||
{
|
||||
// As a fallback return the last mouse position seen by QGuiApplication.
|
||||
return QPoint(qt_last_x, qt_last_y);
|
||||
}
|
||||
|
||||
void QPlatformCursor::setPos(const QPoint &pos)
|
||||
{
|
||||
Q_UNUSED(pos);
|
||||
qWarning("This plugin does not support QCursor::setPos()");
|
||||
}
|
||||
|
||||
// End of display and pointer event handling code
|
||||
// Beginning of built-in cursor graphics
|
||||
// from src/gui/embedded/QGraphicsSystemCursorImage_qws.cpp
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ public:
|
|||
// input methods
|
||||
virtual void pointerEvent(const QMouseEvent & event) { Q_UNUSED(event); }
|
||||
virtual void changeCursor(QCursor * widgetCursor, QWindow * widget) = 0;
|
||||
virtual QPoint pos() const;
|
||||
virtual void setPos(const QPoint &pos);
|
||||
|
||||
protected:
|
||||
QPlatformScreen* screen; // Where to request an update
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <xcb/xfixes.h>
|
||||
|
||||
#ifdef XCB_USE_XLIB
|
||||
#include <X11/Xlib.h>
|
||||
|
|
@ -68,7 +69,6 @@
|
|||
|
||||
#ifdef XCB_USE_DRI2
|
||||
#include <xcb/dri2.h>
|
||||
#include <xcb/xfixes.h>
|
||||
extern "C" {
|
||||
#include <xf86drm.h>
|
||||
}
|
||||
|
|
@ -125,6 +125,8 @@ QXcbConnection::QXcbConnection(const char *displayName)
|
|||
m_clipboard = new QXcbClipboard(this);
|
||||
m_drag = new QXcbDrag(this);
|
||||
|
||||
initializeXFixes();
|
||||
|
||||
#ifdef XCB_USE_DRI2
|
||||
initializeDri2();
|
||||
#endif
|
||||
|
|
@ -830,6 +832,22 @@ void QXcbConnection::sync()
|
|||
free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
|
||||
}
|
||||
|
||||
void QXcbConnection::initializeXFixes()
|
||||
{
|
||||
xcb_generic_error_t *error = 0;
|
||||
xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
|
||||
xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection,
|
||||
XCB_XFIXES_MAJOR_VERSION,
|
||||
XCB_XFIXES_MINOR_VERSION);
|
||||
xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
|
||||
xfixes_query_cookie, &error);
|
||||
if (!xfixes_query || error || xfixes_query->major_version < 2) {
|
||||
qWarning("Failed to initialize XFixes");
|
||||
free(error);
|
||||
}
|
||||
free(xfixes_query);
|
||||
}
|
||||
|
||||
#if defined(XCB_USE_EGL)
|
||||
bool QXcbConnection::hasEgl() const
|
||||
{
|
||||
|
|
@ -900,26 +918,12 @@ bool QXcbConnection::hasSupportForDri2() const
|
|||
if (!m_dri2_support_probed) {
|
||||
xcb_generic_error_t *error = 0;
|
||||
|
||||
xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
|
||||
xcb_prefetch_extension_data (m_connection, &xcb_dri2_id);
|
||||
|
||||
xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection,
|
||||
XCB_XFIXES_MAJOR_VERSION,
|
||||
XCB_XFIXES_MINOR_VERSION);
|
||||
|
||||
xcb_dri2_query_version_cookie_t dri2_query_cookie = xcb_dri2_query_version (m_connection,
|
||||
XCB_DRI2_MAJOR_VERSION,
|
||||
XCB_DRI2_MINOR_VERSION);
|
||||
|
||||
xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
|
||||
xfixes_query_cookie, &error);
|
||||
if (!xfixes_query || error || xfixes_query->major_version < 2) {
|
||||
delete error;
|
||||
delete xfixes_query;
|
||||
return false;
|
||||
}
|
||||
delete xfixes_query;
|
||||
|
||||
xcb_dri2_query_version_reply_t *dri2_query = xcb_dri2_query_version_reply (m_connection,
|
||||
dri2_query_cookie, &error);
|
||||
if (!dri2_query || error) {
|
||||
|
|
|
|||
|
|
@ -292,6 +292,7 @@ private slots:
|
|||
private:
|
||||
void initializeAllAtoms();
|
||||
void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
|
||||
void initializeXFixes();
|
||||
#ifdef XCB_USE_DRI2
|
||||
void initializeDri2();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXCBCURSOR_H
|
||||
#define QXCBCURSOR_H
|
||||
|
||||
#include <QtGui/QPlatformCursor>
|
||||
#include "qxcbscreen.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QXcbCursor : public QXcbObject, public QPlatformCursor
|
||||
{
|
||||
public:
|
||||
QXcbCursor(QXcbConnection *conn, QXcbScreen *screen);
|
||||
~QXcbCursor();
|
||||
void changeCursor(QCursor *cursor, QWindow *widget);
|
||||
QPoint pos() const;
|
||||
void setPos(const QPoint &pos);
|
||||
|
||||
private:
|
||||
xcb_cursor_t createFontCursor(int cshape);
|
||||
xcb_cursor_t createBitmapCursor(QCursor *cursor);
|
||||
xcb_cursor_t createNonStandardCursor(int cshape);
|
||||
|
||||
QXcbScreen *m_screen;
|
||||
QMap<int, xcb_cursor_t> m_shapeCursorMap;
|
||||
QMap<qint64, xcb_cursor_t> m_bitmapCursorMap;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qxcbimage.h"
|
||||
#include <QtGui/QColor>
|
||||
#include <QtGui/private/qimage_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth,
|
||||
const xcb_visualtype_t *visual)
|
||||
{
|
||||
const xcb_format_t *format = connection->formatForDepth(depth);
|
||||
|
||||
if (!visual || !format)
|
||||
return QImage::Format_Invalid;
|
||||
|
||||
if (depth == 32 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000
|
||||
&& visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
|
||||
return QImage::Format_ARGB32_Premultiplied;
|
||||
|
||||
if (depth == 24 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000
|
||||
&& visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
|
||||
return QImage::Format_RGB32;
|
||||
|
||||
if (depth == 16 && format->bits_per_pixel == 16 && visual->red_mask == 0xf800
|
||||
&& visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f)
|
||||
return QImage::Format_RGB16;
|
||||
|
||||
return QImage::Format_Invalid;
|
||||
}
|
||||
|
||||
QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap,
|
||||
int width, int height, int depth,
|
||||
const xcb_visualtype_t *visual)
|
||||
{
|
||||
xcb_connection_t *conn = connection->xcb_connection();
|
||||
xcb_generic_error_t *error = 0;
|
||||
|
||||
xcb_get_image_cookie_t get_image_cookie =
|
||||
xcb_get_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap,
|
||||
0, 0, width, height, 0xffffffff);
|
||||
|
||||
xcb_get_image_reply_t *image_reply =
|
||||
xcb_get_image_reply(conn, get_image_cookie, &error);
|
||||
|
||||
if (!image_reply) {
|
||||
if (error) {
|
||||
connection->handleXcbError(error);
|
||||
free(error);
|
||||
}
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
uint8_t *data = xcb_get_image_data(image_reply);
|
||||
uint32_t length = xcb_get_image_data_length(image_reply);
|
||||
|
||||
QPixmap result;
|
||||
|
||||
QImage::Format format = qt_xcb_imageFormatForVisual(connection, depth, visual);
|
||||
if (format != QImage::Format_Invalid) {
|
||||
uint32_t bytes_per_line = length / height;
|
||||
QImage image(const_cast<uint8_t *>(data), width, height, bytes_per_line, format);
|
||||
uint8_t image_byte_order = connection->setup()->image_byte_order;
|
||||
|
||||
// we may have to swap the byte order
|
||||
if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
|
||||
|| (QSysInfo::ByteOrder == QSysInfo::BigEndian && image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST))
|
||||
{
|
||||
for (int i=0; i < image.height(); i++) {
|
||||
switch (format) {
|
||||
case QImage::Format_RGB16: {
|
||||
ushort *p = (ushort*)image.scanLine(i);
|
||||
ushort *end = p + image.width();
|
||||
while (p < end) {
|
||||
*p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
|
||||
p++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QImage::Format_RGB32: // fall-through
|
||||
case QImage::Format_ARGB32_Premultiplied: {
|
||||
uint *p = (uint*)image.scanLine(i);
|
||||
uint *end = p + image.width();
|
||||
while (p < end) {
|
||||
*p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
|
||||
| ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
|
||||
p++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fix-up alpha channel
|
||||
if (format == QImage::Format_RGB32) {
|
||||
QRgb *p = (QRgb *)image.bits();
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x)
|
||||
p[x] |= 0xff000000;
|
||||
p += bytes_per_line / 4;
|
||||
}
|
||||
}
|
||||
|
||||
result = QPixmap::fromImage(image.copy());
|
||||
}
|
||||
|
||||
free(image_reply);
|
||||
return result;
|
||||
}
|
||||
|
||||
xcb_pixmap_t qt_xcb_XPixmapFromBitmap(QXcbScreen *screen, const QImage &image)
|
||||
{
|
||||
xcb_connection_t *conn = screen->xcb_connection();
|
||||
QImage bitmap = image.convertToFormat(QImage::Format_MonoLSB);
|
||||
const QRgb c0 = QColor(Qt::black).rgb();
|
||||
const QRgb c1 = QColor(Qt::white).rgb();
|
||||
if (bitmap.color(0) == c0 && bitmap.color(1) == c1) {
|
||||
bitmap.invertPixels();
|
||||
bitmap.setColor(0, c1);
|
||||
bitmap.setColor(1, c0);
|
||||
}
|
||||
const int width = bitmap.width();
|
||||
const int height = bitmap.height();
|
||||
const int bytesPerLine = bitmap.bytesPerLine();
|
||||
int destLineSize = width / 8;
|
||||
if (width % 8)
|
||||
++destLineSize;
|
||||
const uchar *map = bitmap.bits();
|
||||
uint8_t *buf = new uint8_t[height * destLineSize];
|
||||
for (int i = 0; i < height; i++)
|
||||
memcpy(buf + (destLineSize * i), map + (bytesPerLine * i), destLineSize);
|
||||
xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, screen->root(), buf,
|
||||
width, height, 1, 0, 0, 0);
|
||||
delete[] buf;
|
||||
return pm;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXCBIMAGE_H
|
||||
#define QXCBIMAGE_H
|
||||
|
||||
#include "qxcbscreen.h"
|
||||
#include <QtCore/QPair>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <xcb/xcb_image.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection,
|
||||
uint8_t depth, const xcb_visualtype_t *visual);
|
||||
QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap,
|
||||
int width, int height, int depth,
|
||||
const xcb_visualtype_t *visual);
|
||||
xcb_pixmap_t qt_xcb_XPixmapFromBitmap(QXcbScreen *screen, const QImage &image);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -47,6 +47,7 @@
|
|||
#include "qxcbnativeinterface.h"
|
||||
#include "qxcbclipboard.h"
|
||||
#include "qxcbdrag.h"
|
||||
#include "qxcbimage.h"
|
||||
|
||||
#include <qgenericunixprintersupport.h>
|
||||
|
||||
|
|
@ -123,28 +124,6 @@ QPlatformFontDatabase *QXcbIntegration::fontDatabase() const
|
|||
return m_fontDatabase;
|
||||
}
|
||||
|
||||
static QImage::Format imageFormatForVisual(QXcbConnection *connection, uint8_t depth, const xcb_visualtype_t *visual)
|
||||
{
|
||||
const xcb_format_t *format = connection->formatForDepth(depth);
|
||||
|
||||
if (!visual || !format)
|
||||
return QImage::Format_Invalid;
|
||||
|
||||
if (depth == 32 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000
|
||||
&& visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
|
||||
return QImage::Format_ARGB32_Premultiplied;
|
||||
|
||||
if (depth == 24 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000
|
||||
&& visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
|
||||
return QImage::Format_RGB32;
|
||||
|
||||
if (depth == 16 && format->bits_per_pixel == 16 && visual->red_mask == 0xf800
|
||||
&& visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f)
|
||||
return QImage::Format_RGB16;
|
||||
|
||||
return QImage::Format_Invalid;
|
||||
}
|
||||
|
||||
QPixmap QXcbIntegration::grabWindow(WId window, int x, int y, int width, int height) const
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
|
|
@ -256,84 +235,11 @@ QPixmap QXcbIntegration::grabWindow(WId window, int x, int y, int width, int hei
|
|||
free(error);
|
||||
}
|
||||
|
||||
xcb_get_image_cookie_t get_image_cookie =
|
||||
xcb_get_image(connection, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap, 0, 0, width, height, 0xffffffff);
|
||||
|
||||
xcb_get_image_reply_t *image_reply =
|
||||
xcb_get_image_reply(connection, get_image_cookie, &error);
|
||||
|
||||
xcb_free_gc(connection, gc);
|
||||
xcb_free_pixmap(connection, pixmap);
|
||||
|
||||
uint8_t depth = reply->depth;
|
||||
QPixmap result = qt_xcb_pixmapFromXPixmap(m_connection, pixmap, width, height, reply->depth, visual);
|
||||
|
||||
free(reply);
|
||||
|
||||
if (!image_reply) {
|
||||
if (error) {
|
||||
m_connection->handleXcbError(error);
|
||||
free(error);
|
||||
}
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
uint8_t *data = xcb_get_image_data(image_reply);
|
||||
uint32_t length = xcb_get_image_data_length(image_reply);
|
||||
|
||||
QPixmap result;
|
||||
|
||||
QImage::Format format = imageFormatForVisual(m_connection, depth, visual);
|
||||
if (format != QImage::Format_Invalid) {
|
||||
uint32_t bytes_per_line = length / height;
|
||||
QImage image(const_cast<uint8_t *>(data), width, height, bytes_per_line, format);
|
||||
uint8_t image_byte_order = m_connection->setup()->image_byte_order;
|
||||
|
||||
// we may have to swap the byte order
|
||||
if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
|
||||
|| (QSysInfo::ByteOrder == QSysInfo::BigEndian && image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST))
|
||||
{
|
||||
for (int i=0; i < image.height(); i++) {
|
||||
switch (format) {
|
||||
case QImage::Format_RGB16: {
|
||||
ushort *p = (ushort*)image.scanLine(i);
|
||||
ushort *end = p + image.width();
|
||||
while (p < end) {
|
||||
*p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
|
||||
p++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QImage::Format_RGB32: // fall-through
|
||||
case QImage::Format_ARGB32_Premultiplied: {
|
||||
uint *p = (uint*)image.scanLine(i);
|
||||
uint *end = p + image.width();
|
||||
while (p < end) {
|
||||
*p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
|
||||
| ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
|
||||
p++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fix-up alpha channel
|
||||
if (format == QImage::Format_RGB32) {
|
||||
QRgb *p = (QRgb *)image.bits();
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x)
|
||||
p[x] |= 0xff000000;
|
||||
p += bytes_per_line / 4;
|
||||
}
|
||||
}
|
||||
|
||||
result = QPixmap::fromImage(image.copy());
|
||||
}
|
||||
|
||||
free(image_reply);
|
||||
xcb_free_gc(connection, gc);
|
||||
xcb_free_pixmap(connection, pixmap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "qxcbscreen.h"
|
||||
#include "qxcbwindow.h"
|
||||
#include "qxcbcursor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
@ -140,10 +141,13 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
|
|||
|
||||
xcb_depth_next(&depth_iterator);
|
||||
}
|
||||
|
||||
m_cursor = new QXcbCursor(connection, this);
|
||||
}
|
||||
|
||||
QXcbScreen::~QXcbScreen()
|
||||
{
|
||||
delete m_cursor;
|
||||
}
|
||||
|
||||
QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "qxcbobject.h"
|
||||
|
||||
class QXcbConnection;
|
||||
class QXcbCursor;
|
||||
|
||||
class QXcbScreen : public QXcbObject, public QPlatformScreen
|
||||
{
|
||||
|
|
@ -83,6 +84,7 @@ private:
|
|||
bool m_syncRequestSupported;
|
||||
xcb_window_t m_clientLeader;
|
||||
QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals;
|
||||
QXcbCursor *m_cursor;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1234,3 +1234,9 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
|
|||
free(err);
|
||||
return result;
|
||||
}
|
||||
|
||||
void QXcbWindow::setCursor(xcb_cursor_t cursor)
|
||||
{
|
||||
xcb_change_window_attributes(xcb_connection(), m_window, XCB_CW_CURSOR, &cursor);
|
||||
xcb_flush(xcb_connection());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ public:
|
|||
bool setKeyboardGrabEnabled(bool grab);
|
||||
bool setMouseGrabEnabled(bool grab);
|
||||
|
||||
void setCursor(xcb_cursor_t cursor);
|
||||
|
||||
xcb_window_t xcb_window() const { return m_window; }
|
||||
uint depth() const { return m_depth; }
|
||||
QImage::Format format() const { return m_format; }
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ SOURCES = \
|
|||
qxcbwindowsurface.cpp \
|
||||
qxcbwmsupport.cpp \
|
||||
main.cpp \
|
||||
qxcbnativeinterface.cpp
|
||||
qxcbnativeinterface.cpp \
|
||||
qxcbcursor.cpp \
|
||||
qxcbimage.cpp
|
||||
|
||||
HEADERS = \
|
||||
qxcbclipboard.h \
|
||||
|
|
@ -31,16 +33,21 @@ HEADERS = \
|
|||
qxcbwindow.h \
|
||||
qxcbwindowsurface.h \
|
||||
qxcbwmsupport.h \
|
||||
qxcbnativeinterface.h
|
||||
qxcbnativeinterface.h \
|
||||
qxcbcursor.h \
|
||||
qxcbimage.h
|
||||
|
||||
QT += gui-private core-private
|
||||
|
||||
# needed by GLX, Xcursor, ...
|
||||
DEFINES += XCB_USE_XLIB
|
||||
|
||||
contains(QT_CONFIG, opengl) {
|
||||
QT += opengl
|
||||
|
||||
# DEFINES += XCB_USE_DRI2
|
||||
contains(DEFINES, XCB_USE_DRI2) {
|
||||
LIBS += -lxcb-dri2 -lxcb-xfixes -lEGL
|
||||
LIBS += -lxcb-dri2 -lEGL
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += libdrm
|
||||
|
|
@ -49,9 +56,6 @@ contains(QT_CONFIG, opengl) {
|
|||
SOURCES += qdri2context.cpp
|
||||
|
||||
} else {
|
||||
DEFINES += XCB_USE_XLIB
|
||||
LIBS += -lX11 -lX11-xcb
|
||||
|
||||
contains(QT_CONFIG, opengles2) {
|
||||
DEFINES += XCB_USE_EGL
|
||||
load(qpa/egl/convenience)
|
||||
|
|
@ -68,7 +72,8 @@ contains(QT_CONFIG, opengl) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync
|
||||
LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes
|
||||
contains(DEFINES, XCB_USE_XLIB): LIBS += -lX11 -lX11-xcb
|
||||
|
||||
DEFINES += $$QMAKE_DEFINES_XCB
|
||||
LIBS += $$QMAKE_LIBS_XCB
|
||||
|
|
|
|||
|
|
@ -3348,6 +3348,12 @@ void QWidgetPrivate::setEnabled_helper(bool enable)
|
|||
// disabled widgets
|
||||
qt_x11_enforce_cursor(q);
|
||||
}
|
||||
#elif defined(Q_WS_QPA)
|
||||
if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
|
||||
// enforce the windows behavior of clearing the cursor on
|
||||
// disabled widgets
|
||||
qt_qpa_set_cursor(q, false);
|
||||
}
|
||||
#endif
|
||||
#if defined(Q_WS_MAC)
|
||||
setEnabled_helper_sys(enable);
|
||||
|
|
|
|||
|
|
@ -903,9 +903,6 @@ public:
|
|||
void setFullScreenSize_helper();
|
||||
bool stealKeyboardGrab(bool grab);
|
||||
bool stealMouseGrab(bool grab);
|
||||
#ifndef QT_NO_CURSOR
|
||||
void updateCursor() const;
|
||||
#endif
|
||||
#elif defined(Q_OS_SYMBIAN) // <--------------------------------------------------------- SYMBIAN
|
||||
static QWidget *mouseGrabber;
|
||||
static QWidget *keyboardGrabber;
|
||||
|
|
|
|||
|
|
@ -299,20 +299,13 @@ void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
|
|||
{
|
||||
Q_UNUSED(cursor);
|
||||
Q_Q(QWidget);
|
||||
if (q->isVisible())
|
||||
qt_qpa_set_cursor(q, false);
|
||||
qt_qpa_set_cursor(q, false);
|
||||
}
|
||||
|
||||
void QWidgetPrivate::unsetCursor_sys()
|
||||
{
|
||||
Q_Q(QWidget);
|
||||
if (q->isVisible())
|
||||
qt_qpa_set_cursor(q, false);
|
||||
}
|
||||
|
||||
void QWidgetPrivate::updateCursor() const
|
||||
{
|
||||
// XXX
|
||||
qt_qpa_set_cursor(q, false);
|
||||
}
|
||||
|
||||
#endif //QT_NO_CURSOR
|
||||
|
|
@ -858,56 +851,55 @@ void QWidgetPrivate::setModal_sys()
|
|||
}
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
void qt_qpa_set_cursor(QWidget * w, bool force)
|
||||
static void applyCursor(QWidget *w, const QCursor &c)
|
||||
{
|
||||
static QCursor arrowCursor(Qt::ArrowCursor);
|
||||
static QPointer<QWidget> lastUnderMouse = 0;
|
||||
QCursor cc = c;
|
||||
QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
|
||||
int cursorCount = cursors.count();
|
||||
for (int i = 0; i < cursorCount; ++i) {
|
||||
const QWeakPointer<QPlatformCursor> &cursor(cursors.at(i));
|
||||
if (cursor)
|
||||
cursor.data()->changeCursor(&cc, w->window()->windowHandle());
|
||||
}
|
||||
}
|
||||
|
||||
QCursor * override = QApplication::overrideCursor();
|
||||
|
||||
if (override && w != 0)
|
||||
void qt_qpa_set_cursor(QWidget *w, bool force)
|
||||
{
|
||||
if (!w->testAttribute(Qt::WA_WState_Created))
|
||||
return;
|
||||
|
||||
QWidget *cursorWidget;
|
||||
QCursor cursorCursor;
|
||||
static QPointer<QWidget> lastUnderMouse = 0;
|
||||
if (force) {
|
||||
lastUnderMouse = w;
|
||||
} else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
|
||||
w = lastUnderMouse;
|
||||
} else if (!w->internalWinId()) {
|
||||
return; // The mouse is not under this widget, and it's not native, so don't change it.
|
||||
}
|
||||
|
||||
do {
|
||||
if (w == 0) {
|
||||
if (override) {
|
||||
cursorCursor = *override;
|
||||
cursorWidget = QApplication::topLevelAt(QCursor::pos());
|
||||
break;
|
||||
}
|
||||
w = QApplication::widgetAt(QCursor::pos());
|
||||
if (w == 0) // clear the override cursor while over empty space
|
||||
w = QApplication::desktop();
|
||||
} else if (force) {
|
||||
lastUnderMouse = w;
|
||||
} else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse
|
||||
&& lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
|
||||
w = lastUnderMouse;
|
||||
}
|
||||
if (w == QApplication::desktop() && !override) {
|
||||
cursorCursor = arrowCursor;
|
||||
cursorWidget = w;
|
||||
break;
|
||||
}
|
||||
while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
|
||||
&& !w->testAttribute(Qt::WA_SetCursor))
|
||||
w = w->parentWidget();
|
||||
|
||||
QWidget * curWin = QApplication::activeWindow();
|
||||
if (!curWin && w && w->internalWinId())
|
||||
return;
|
||||
QWidget* cW = w && !w->internalWinId() ? w : curWin;
|
||||
QWidget *nativeParent = w;
|
||||
if (!w->internalWinId())
|
||||
nativeParent = w->nativeParentWidget();
|
||||
if (!nativeParent || !nativeParent->internalWinId())
|
||||
return;
|
||||
|
||||
if (!cW || cW->window() != w->window() ||
|
||||
!cW->isVisible() || !cW->underMouse() || override)
|
||||
return;
|
||||
|
||||
cursorCursor = w->cursor();
|
||||
cursorWidget = w;
|
||||
} while (0);
|
||||
foreach (QWeakPointer<QPlatformCursor> cursor, QPlatformCursorPrivate::getInstances())
|
||||
if (cursor)
|
||||
cursor.data()->changeCursor(&cursorCursor, cursorWidget->windowHandle());
|
||||
if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
|
||||
QCursor *oc = QApplication::overrideCursor();
|
||||
if (oc)
|
||||
applyCursor(nativeParent, *oc);
|
||||
else if (w->isEnabled())
|
||||
applyCursor(nativeParent, w->cursor());
|
||||
else
|
||||
// Enforce the windows behavior of clearing the cursor on
|
||||
// disabled widgets.
|
||||
applyCursor(nativeParent, Qt::ArrowCursor);
|
||||
} else {
|
||||
applyCursor(nativeParent, Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
#endif //QT_NO_CURSOR
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue