Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qcursor.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 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#include "qcursor.h"
5
6#include <qcoreapplication.h>
7#include <qbitmap.h>
8#include <qimage.h>
9#include <qdatastream.h>
10#include <qvariant.h>
11#include <private/qcursor_p.h>
12#include <qdebug.h>
13
14#include <qpa/qplatformcursor.h>
15#include <private/qguiapplication_p.h>
16#include <private/qhighdpiscaling_p.h>
17
19
158{
159 if (screen) {
160 if (const QPlatformCursor *cursor = screen->handle()->cursor()) {
161 const QPlatformScreen *ps = screen->handle();
162 QPoint nativePos = cursor->pos();
163 ps = ps->screenForPosition(nativePos);
164 return QHighDpi::fromNativePixels(nativePos, ps->screen());
165 }
166 }
168}
169
189{
191}
192
215{
216 if (screen) {
218 const QPoint pos(x, y);
220 // Need to check, since some X servers generate null mouse move
221 // events, causing looping in applications which call setPos() on
222 // every mouse move event.
223 if (devicePos != cursor->pos())
224 cursor->setPos(devicePos);
225 }
226 }
227}
228
240void QCursor::setPos(int x, int y)
241{
243}
244
245#ifndef QT_NO_CURSOR
246
265/*****************************************************************************
266 QCursor stream functions
267 *****************************************************************************/
268
269#ifndef QT_NO_DATASTREAM
270
271
282{
283 s << (qint16)c.shape(); // write shape id to stream
284 if (c.shape() == Qt::BitmapCursor) { // bitmap cursor
285 bool isPixmap = false;
286 if (s.version() >= 7) {
287 isPixmap = !c.pixmap().isNull();
288 s << isPixmap;
289 }
290 if (isPixmap)
291 s << c.pixmap();
292 else
293 s << c.bitmap() << c.mask();
294 s << c.hotSpot();
295 }
296 return s;
297}
298
309{
310 qint16 shape;
311 s >> shape; // read shape id from stream
312 if (shape == Qt::BitmapCursor) { // read bitmap cursor
313 bool isPixmap = false;
314 if (s.version() >= 7)
315 s >> isPixmap;
316 if (isPixmap) {
317 QPixmap pm;
318 QPoint hot;
319 s >> pm >> hot;
320 c = QCursor(pm, hot.x(), hot.y());
321 } else {
322 QBitmap bm, bmm;
323 QPoint hot;
324 s >> bm >> bmm >> hot;
325 c = QCursor(bm, bmm, hot.x(), hot.y());
326 }
327 } else {
328 c.setShape((Qt::CursorShape)shape); // create cursor with shape
329 }
330 return s;
331}
332#endif // QT_NO_DATASTREAM
333
334
353QCursor::QCursor(const QPixmap &pixmap, int hotX, int hotY)
354 : d(nullptr)
355{
358 QBitmap bmm = pixmap.mask();
359 if (!bmm.isNull()) {
360 QBitmap nullBm;
361 bm.setMask(nullBm);
362 }
363 else if (!pixmap.mask().isNull()) {
366 }
367 else {
368 bmm = QBitmap(bm.size());
369 bmm.fill(Qt::color1);
370 }
371
372 d = QCursorData::setBitmap(bm, bmm, hotX, hotY, pixmap.devicePixelRatio());
373 d->pixmap = pixmap;
374}
375
376
377
409QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
410 : d(nullptr)
411{
412 d = QCursorData::setBitmap(bitmap, mask, hotX, hotY, 1.0);
413}
414
419{
422 d = nullptr;
423 return;
424 }
426 }
428 c->ref.ref();
429 d = c;
430}
431
440 : d(nullptr)
441{
445}
446
463bool operator==(const QCursor &lhs, const QCursor &rhs) noexcept
464{
465 if (lhs.d == rhs.d)
466 return true; // Copy or same shape
467
468 // Check pixmaps or bitmaps cache keys. Notice that having BitmapCursor
469 // shape implies either non-null pixmap or non-null bitmap and mask
470 if (lhs.shape() == Qt::BitmapCursor && rhs.shape() == Qt::BitmapCursor
471 && lhs.hotSpot() == rhs.hotSpot()) {
472 if (!lhs.d->pixmap.isNull())
473 return lhs.d->pixmap.cacheKey() == rhs.d->pixmap.cacheKey();
474
475 if (!rhs.d->pixmap.isNull())
476 return false;
477
478 return lhs.d->bm->cacheKey() == rhs.d->bm->cacheKey()
479 && lhs.d->bmm->cacheKey() == rhs.d->bmm->cacheKey();
480 }
481
482 return false;
483}
484
500{
503 return d->cshape;
504}
505
514{
518 if (!c)
519 c = qt_cursorTable[0];
520 c->ref.ref();
521 if (!d) {
522 d = c;
523 } else {
524 if (!d->ref.deref())
525 delete d;
526 d = c;
527 }
528}
529
549{
552 if (d->bm)
553 return *(d->bm);
554 return QBitmap();
555}
556
576{
579 if (d->bmm)
580 return *(d->bmm);
581 return QBitmap();
582}
583
590{
593 return d->pixmap;
594}
595
602{
605 return QPoint(d->hx, d->hy);
606}
607
613{
616 d = c.d;
617 d->ref.ref();
618}
619
625{
626 if (d && !d->ref.deref())
627 delete d;
628}
629
630
637{
640 if (c.d)
641 c.d->ref.ref();
642 if (d && !d->ref.deref())
643 delete d;
644 d = c.d;
645 return *this;
646}
647
651QCursor::operator QVariant() const
652{
653 return QVariant::fromValue(*this);
654}
655
656#ifndef QT_NO_DEBUG_STREAM
658{
659 QDebugStateSaver saver(dbg);
660 dbg.nospace() << "QCursor(Qt::CursorShape(" << c.shape() << "))";
661 return dbg;
662}
663#endif
664
665/*****************************************************************************
666 Internal QCursorData class
667 *****************************************************************************/
668
670bool QCursorData::initialized = false;
671
673 : ref(1), cshape(s), bm(nullptr), bmm(nullptr), hx(0), hy(0)
674{
675}
676
678{
679 delete bm;
680 delete bmm;
681}
682
685{
687 return;
688
689 for (int shape = 0; shape <= Qt::LastCursor; ++shape) {
690 // In case someone has a static QCursor defined with this shape
691 if (!qt_cursorTable[shape]->ref.deref())
692 delete qt_cursorTable[shape];
693 qt_cursorTable[shape] = nullptr;
694 }
696}
697
700{
702 return;
703 for (int shape = 0; shape <= Qt::LastCursor; ++shape)
704 qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape);
706}
707
708QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY, qreal devicePixelRatio)
709{
712 if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
713 qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
715 c->ref.ref();
716 return c;
717 }
719 d->bm = new QBitmap(bitmap);
720 d->bmm = new QBitmap(mask);
721 d->cshape = Qt::BitmapCursor;
722 d->hx = hotX >= 0 ? hotX : bitmap.width() / 2 / devicePixelRatio;
723 d->hy = hotY >= 0 ? hotY : bitmap.height() / 2 / devicePixelRatio;
724
725 return d;
726}
727
729{
730}
731
733#endif // QT_NO_CURSOR
734
bool ref() noexcept
bool deref() noexcept
\inmodule QtGui
Definition qbitmap.h:16
static QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Returns a copy of the given image converted to a bitmap using the specified image conversion flags.
Definition qbitmap.cpp:170
static bool startingUp()
Returns true if an application object has not been created yet; otherwise returns false.
QBitmap * bm
Definition qcursor_p.h:38
static bool initialized
Definition qcursor_p.h:41
QBitmap * bmm
Definition qcursor_p.h:38
QPixmap pixmap
Definition qcursor_p.h:39
QCursorData(Qt::CursorShape s=Qt::ArrowCursor)
Definition qcursor.cpp:672
Qt::CursorShape cshape
Definition qcursor_p.h:37
static QCursorData * setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY, qreal devicePixelRatio)
Definition qcursor.cpp:708
void update()
Definition qcursor.cpp:728
static void initialize()
Definition qcursor.cpp:699
static void cleanup()
Definition qcursor.cpp:684
QAtomicInt ref
Definition qcursor_p.h:36
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition qcursor.h:45
QBitmap bitmap() const
Returns the cursor bitmap, or a null bitmap if it is one of the standard cursors.
Definition qcursor.cpp:548
QPixmap pixmap() const
Returns the cursor pixmap.
Definition qcursor.cpp:589
~QCursor()
Destroys the cursor.
Definition qcursor.cpp:624
static void setPos(int x, int y)
Moves the cursor (hot spot) of the primary screen to the global screen position (x,...
Definition qcursor.cpp:240
Qt::CursorShape shape() const
Returns the cursor shape identifier.
Definition qcursor.cpp:499
static QPoint pos()
Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.
Definition qcursor.cpp:188
QCursor & operator=(const QCursor &cursor)
Move-assigns other to this QCursor instance.
Definition qcursor.cpp:636
QCursor()
Constructs a cursor with the default arrow shape.
Definition qcursor.cpp:418
QPoint hotSpot() const
Returns the cursor hot spot, or (0, 0) if it is one of the standard cursors.
Definition qcursor.cpp:601
void setShape(Qt::CursorShape newShape)
Sets the cursor to the shape identified by shape.
Definition qcursor.cpp:513
QBitmap mask() const
Returns the cursor bitmap mask, or a null bitmap if it is one of the standard cursors.
Definition qcursor.cpp:575
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore
\inmodule QtCore
static struct QGuiApplicationPrivate::QLastCursorPosition lastCursorPosition
QScreen * primaryScreen
the primary (or default) screen of the application.
\inmodule QtGui
Definition qimage.h:37
@ Format_Indexed8
Definition qimage.h:45
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const &
Definition qimage.h:124
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
QImage toImage() const
Converts the pixmap to a QImage.
Definition qpixmap.cpp:412
QSize size() const
Returns the size of the pixmap.
Definition qpixmap.cpp:497
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition qpixmap.cpp:460
QBitmap mask() const
Returns true if this pixmap has an alpha channel, or has a mask, otherwise returns false.
void setMask(const QBitmap &)
Sets a mask bitmap.
Definition qpixmap.cpp:547
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
Definition qpixmap.cpp:854
qreal devicePixelRatio() const
Returns the device pixel ratio for the pixmap.
Definition qpixmap.cpp:580
The QPlatformCursor class provides information about pointer device events (movement,...
The QPlatformScreen class provides an abstraction for visual displays.
const QPlatformScreen * screenForPosition(const QPoint &point) const
Find the sibling screen corresponding to globalPos.
virtual QPlatformCursor * cursor() const
Reimplement this function in subclass to return the cursor of the screen.
QScreen * screen() const
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
QScreen * virtualSiblingAt(QPoint point)
Returns the screen at point within the set of \l QScreen::virtualSiblings(), or nullptr if outside of...
Definition qscreen.cpp:629
QPlatformScreen * handle() const
Get the platform screen handle.
Definition qscreen.cpp:83
\inmodule QtCore
Definition qvariant.h:64
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:531
QCursor cursor
T toNativePixels(const T &value, const C *context)
T fromNativePixels(const T &value, const C *context)
Combined button and popup list for selecting options.
@ AvoidDither
Definition qnamespace.h:497
@ ThresholdDither
Definition qnamespace.h:491
CursorShape
@ BitmapCursor
@ LastCursor
@ color1
Definition qnamespace.h:28
QCursorData * qt_cursorTable[Qt::LastCursor+1]
Definition qcursor.cpp:669
QDataStream & operator<<(QDataStream &s, const QCursor &c)
Definition qcursor.cpp:281
bool operator==(const QCursor &lhs, const QCursor &rhs) noexcept
Definition qcursor.cpp:463
QDataStream & operator>>(QDataStream &s, QCursor &c)
Definition qcursor.cpp:308
QCursorData * qt_cursorTable[Qt::LastCursor+1]
Definition qcursor.cpp:669
#define qWarning
Definition qlogging.h:162
GLint GLint GLint GLint GLint x
[0]
GLint ref
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint y
const GLubyte * c
GLint void * img
Definition qopenglext.h:233
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
GLdouble s
[6]
Definition qopenglext.h:235
QScreen * screen
[1]
Definition main.cpp:29
short qint16
Definition qtypes.h:42
unsigned int uint
Definition qtypes.h:29
double qreal
Definition qtypes.h:92
QObject::connect nullptr
widget render & pixmap
Q_GUI_EXPORT QPoint toPoint() const noexcept