QortalOS Brooklyn for Raspberry Pi 4
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

90 lines
2.2 KiB

/*
SPDX-FileCopyrightText: 2007 Fredrik Höglund <[email protected]>
SPDX-License-Identifier: LGPL-2.0-only
*/
#include "cursornotificationhandler.h"
#include <QX11Info>
#include <X11/extensions/Xfixes.h>
/*
* This class is a QWidget because we need an X window to
* be able to receive XFixes events. We don't actually map
* the widget.
*/
CursorNotificationHandler::CursorNotificationHandler()
: QWidget()
, currentName(0)
{
Display *dpy = QX11Info::display();
int errorBase;
haveXfixes = false;
// Request cursor change notification events
if (XFixesQueryExtension(dpy, &fixesEventBase, &errorBase)) {
int major, minor;
XFixesQueryVersion(dpy, &major, &minor);
if (major >= 2) {
XFixesSelectCursorInput(dpy, winId(), XFixesDisplayCursorNotifyMask);
haveXfixes = true;
}
}
}
CursorNotificationHandler::~CursorNotificationHandler()
{
}
QString CursorNotificationHandler::cursorName()
{
if (!haveXfixes)
return QString();
if (!currentName) {
// Xfixes doesn't have a request for getting the current cursor name,
// but it's included in the XFixesCursorImage struct.
XFixesCursorImage *image = XFixesGetCursorImage(QX11Info::display());
currentName = image->atom;
XFree(image);
}
return cursorName(currentName);
}
QString CursorNotificationHandler::cursorName(Atom cursor)
{
QString name;
// XGetAtomName() is a synchronous call, so we cache the name
// in an atom<->string map the first time we see a name
// to keep the X server round trips down.
if (names.contains(cursor))
name = names[cursor];
else {
char *data = XGetAtomName(QX11Info::display(), cursor);
name = QString::fromUtf8(data);
XFree(data);
names.insert(cursor, name);
}
return name;
}
bool CursorNotificationHandler::x11Event(XEvent *event)
{
if (event->type != fixesEventBase + XFixesCursorNotify)
return false;
XFixesCursorNotifyEvent *xfe = reinterpret_cast<XFixesCursorNotifyEvent *>(event);
currentName = xfe->cursor_name;
Q_EMIT cursorNameChanged(cursorName(currentName));
return false;
}