Merge remote-tracking branch 'gerrit/master' into newdocs
[profile/ivi/qtbase.git] / src / gui / kernel / qcursor.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qcursor.h"
43
44 #ifndef QT_NO_CURSOR
45
46 #include <qcoreapplication.h>
47 #include <qbitmap.h>
48 #include <qimage.h>
49 #include <qdatastream.h>
50 #include <qvariant.h>
51 #include <private/qcursor_p.h>
52 #include <qdebug.h>
53
54 QT_BEGIN_NAMESPACE
55
56 /*!
57     \class QCursor
58
59     \brief The QCursor class provides a mouse cursor with an arbitrary
60     shape.
61
62     \inmodule QtGui
63     \ingroup appearance
64     \ingroup shared
65
66
67     This class is mainly used to create mouse cursors that are
68     associated with particular widgets and to get and set the position
69     of the mouse cursor.
70
71     Qt has a number of standard cursor shapes, but you can also make
72     custom cursor shapes based on a QBitmap, a mask and a hotspot.
73
74     To associate a cursor with a widget, use QWidget::setCursor(). To
75     associate a cursor with all widgets (normally for a short period
76     of time), use QGuiApplication::setOverrideCursor().
77
78     To set a cursor shape use QCursor::setShape() or use the QCursor
79     constructor which takes the shape as argument, or you can use one
80     of the predefined cursors defined in the \l Qt::CursorShape enum.
81
82     If you want to create a cursor with your own bitmap, either use
83     the QCursor constructor which takes a bitmap and a mask or the
84     constructor which takes a pixmap as arguments.
85
86     To set or get the position of the mouse cursor use the static
87     methods QCursor::pos() and QCursor::setPos().
88
89     \b{Note:} It is possible to create a QCursor before
90     QGuiApplication, but it is not useful except as a place-holder for a
91     real QCursor created after QGuiApplication. Attempting to use a
92     QCursor that was created before QGuiApplication will result in a
93     crash.
94
95     \section1 A Note for X11 Users
96
97     On X11, Qt supports the \l{Xcursor}{Xcursor}
98     library, which allows for full color icon themes. The table below
99     shows the cursor name used for each Qt::CursorShape value. If a
100     cursor cannot be found using the name shown below, a standard X11
101     cursor will be used instead. Note: X11 does not provide
102     appropriate cursors for all possible Qt::CursorShape values. It
103     is possible that some cursors will be taken from the Xcursor
104     theme, while others will use an internal bitmap cursor.
105
106     \table
107     \header \li Shape \li Qt::CursorShape Value \li Cursor Name
108             \li Shape \li Qt::CursorShape Value \li Cursor Name
109     \row \li \inlineimage cursor-arrow.png
110          \li Qt::ArrowCursor   \li \c left_ptr
111          \li \inlineimage      cursor-sizev.png
112          \li Qt::SizeVerCursor \li \c size_ver
113     \row \li \inlineimage      cursor-uparrow.png
114          \li Qt::UpArrowCursor \li \c up_arrow
115          \li \inlineimage      cursor-sizeh.png
116          \li Qt::SizeHorCursor \li \c size_hor
117     \row \li \inlineimage      cursor-cross.png
118          \li Qt::CrossCursor   \li \c cross
119          \li \inlineimage      cursor-sizeb.png
120          \li Qt::SizeBDiagCursor \li \c size_bdiag
121     \row \li \inlineimage      cursor-ibeam.png
122          \li Qt::IBeamCursor   \li \c ibeam
123          \li \inlineimage      cursor-sizef.png
124          \li Qt::SizeFDiagCursor \li \c size_fdiag
125     \row \li \inlineimage      cursor-wait.png
126          \li Qt::WaitCursor    \li \c wait
127          \li \inlineimage      cursor-sizeall.png
128          \li Qt::SizeAllCursor \li \c size_all
129     \row \li \inlineimage      cursor-busy.png
130          \li Qt::BusyCursor    \li \c left_ptr_watch
131          \li \inlineimage      cursor-vsplit.png
132          \li Qt::SplitVCursor  \li \c split_v
133     \row \li \inlineimage      cursor-forbidden.png
134          \li Qt::ForbiddenCursor \li \c forbidden
135          \li \inlineimage      cursor-hsplit.png
136          \li Qt::SplitHCursor  \li \c split_h
137     \row \li \inlineimage      cursor-hand.png
138          \li Qt::PointingHandCursor \li \c pointing_hand
139          \li \inlineimage      cursor-openhand.png
140          \li Qt::OpenHandCursor  \li \c openhand
141     \row \li \inlineimage      cursor-whatsthis.png
142          \li Qt::WhatsThisCursor \li \c whats_this
143          \li \inlineimage      cursor-closedhand.png
144          \li Qt::ClosedHandCursor \li \c closedhand
145     \row \li
146          \li Qt::DragMoveCursor      \li \c dnd-move or \c move
147          \li
148          \li Qt::DragCopyCursor      \li \c dnd-copy or \c copy
149     \row \li
150          \li Qt::DragLinkCursor      \li \c dnd-link or \c link
151     \endtable
152
153     \sa QWidget, {fowler}{GUI Design Handbook: Cursors}
154 */
155
156 /*!
157     \fn QPoint QCursor::pos(const QScreen *screen)
158
159     Returns the position of the cursor (hot spot) of the \a screen
160     in global screen coordinates.
161
162     You can call QWidget::mapFromGlobal() to translate it to widget
163     coordinates.
164
165     \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal()
166 */
167
168 /*!
169     \fn QPoint QCursor::pos()
170
171     Returns the position of the cursor (hot spot) of
172     the primary screen in global screen coordinates.
173
174     You can call QWidget::mapFromGlobal() to translate it to widget
175     coordinates.
176
177     \note The position is queried from the windowing system. If mouse events are generated
178     via other means (e.g., via QWindowSystemInterface in a unit test), those fake mouse
179     moves will not be reflected in the returned value.
180
181     \note On platforms where there is no windowing system or cursors are not available, the returned
182     position is based on the mouse move events generated via QWindowSystemInterface.
183
184     \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen()
185 */
186
187
188 /*!
189     \fn void QCursor::setPos(QScreen *screen, int x, int y)
190
191     Moves the cursor (hot spot) of the \a screen to the global
192     screen position (\a x, \a y).
193
194     You can call QWidget::mapToGlobal() to translate widget
195     coordinates to global screen coordinates.
196
197     \note Calling this function results in changing the cursor position through the windowing
198     system. The windowing system will typically respond by sending mouse events to the application's
199     window. This means that the usage of this function should be avoided in unit tests and
200     everywhere where fake mouse events are being injected via QWindowSystemInterface because the
201     windowing system's mouse state (with regards to buttons for example) may not match the state in
202     the application-generated events.
203
204     \note On platforms where there is no windowing system or cursors are not available, this
205     function may do nothing.
206
207     \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal()
208 */
209
210 /*!
211     \fn void QCursor::setPos(int x, int y)
212
213     Moves the cursor (hot spot) of the primary screen
214     to the global screen position (\a x, \a y).
215
216     You can call QWidget::mapToGlobal() to translate widget
217     coordinates to global screen coordinates.
218
219     \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen()
220 */
221
222 /*!
223     \fn void QCursor::setPos (const QPoint &p)
224
225     \overload
226
227     Moves the cursor (hot spot) to the global screen position at point
228     \a p.
229 */
230
231 /*!
232     \fn void QCursor::setPos (QScreen *screen,const QPoint &p)
233
234     \overload
235
236     Moves the cursor (hot spot) to the global screen position of the
237     \a screen at point \a p.
238 */
239
240 /*****************************************************************************
241   QCursor stream functions
242  *****************************************************************************/
243
244 #ifndef QT_NO_DATASTREAM
245
246
247 /*!
248     \fn QDataStream &operator<<(QDataStream &stream, const QCursor &cursor)
249     \relates QCursor
250
251     Writes the \a cursor to the \a stream.
252
253     \sa {Serializing Qt Data Types}
254 */
255
256 QDataStream &operator<<(QDataStream &s, const QCursor &c)
257 {
258     s << (qint16)c.shape();                        // write shape id to stream
259     if (c.shape() == Qt::BitmapCursor) {                // bitmap cursor
260         bool isPixmap = false;
261         if (s.version() >= 7) {
262             isPixmap = !c.pixmap().isNull();
263             s << isPixmap;
264         }
265         if (isPixmap)
266             s << c.pixmap();
267         else
268             s << *c.bitmap() << *c.mask();
269         s << c.hotSpot();
270     }
271     return s;
272 }
273
274 /*!
275     \fn QDataStream &operator>>(QDataStream &stream, QCursor &cursor)
276     \relates QCursor
277
278     Reads the \a cursor from the \a stream.
279
280     \sa {Serializing Qt Data Types}
281 */
282
283 QDataStream &operator>>(QDataStream &s, QCursor &c)
284 {
285     qint16 shape;
286     s >> shape;                                        // read shape id from stream
287     if (shape == Qt::BitmapCursor) {                // read bitmap cursor
288         bool isPixmap = false;
289         if (s.version() >= 7)
290             s >> isPixmap;
291         if (isPixmap) {
292             QPixmap pm;
293             QPoint hot;
294             s >> pm >> hot;
295             c = QCursor(pm, hot.x(), hot.y());
296         } else {
297             QBitmap bm, bmm;
298             QPoint hot;
299             s >> bm >> bmm >> hot;
300             c = QCursor(bm, bmm, hot.x(), hot.y());
301         }
302     } else {
303         c.setShape((Qt::CursorShape)shape);                // create cursor with shape
304     }
305     return s;
306 }
307 #endif // QT_NO_DATASTREAM
308
309
310 /*!
311     Constructs a custom pixmap cursor.
312
313     \a pixmap is the image. It is usual to give it a mask (set using
314     QPixmap::setMask()). \a hotX and \a hotY define the cursor's hot
315     spot.
316
317     If \a hotX is negative, it is set to the \c{pixmap().width()/2}.
318     If \a hotY is negative, it is set to the \c{pixmap().height()/2}.
319
320     Valid cursor sizes depend on the display hardware (or the
321     underlying window system). We recommend using 32 x 32 cursors,
322     because this size is supported on all platforms. Some platforms
323     also support 16 x 16, 48 x 48, and 64 x 64 cursors.
324
325     \note On Windows CE, the cursor size is fixed. If the pixmap
326     is bigger than the system size, it will be scaled.
327
328     \sa QPixmap::QPixmap(), QPixmap::setMask()
329 */
330
331 QCursor::QCursor(const QPixmap &pixmap, int hotX, int hotY)
332     : d(0)
333 {
334     QImage img = pixmap.toImage().convertToFormat(QImage::Format_Indexed8, Qt::ThresholdDither|Qt::AvoidDither);
335     QBitmap bm = QBitmap::fromImage(img, Qt::ThresholdDither|Qt::AvoidDither);
336     QBitmap bmm = pixmap.mask();
337     if (!bmm.isNull()) {
338         QBitmap nullBm;
339         bm.setMask(nullBm);
340     }
341     else if (!pixmap.mask().isNull()) {
342         QImage mimg = pixmap.mask().toImage().convertToFormat(QImage::Format_Indexed8, Qt::ThresholdDither|Qt::AvoidDither);
343         bmm = QBitmap::fromImage(mimg, Qt::ThresholdDither|Qt::AvoidDither);
344     }
345     else {
346         bmm = QBitmap(bm.size());
347         bmm.fill(Qt::color1);
348     }
349
350     d = QCursorData::setBitmap(bm, bmm, hotX, hotY);
351     d->pixmap = pixmap;
352 }
353
354
355
356 /*!
357     Constructs a custom bitmap cursor.
358
359     \a bitmap and
360     \a mask make up the bitmap.
361     \a hotX and
362     \a hotY define the cursor's hot spot.
363
364     If \a hotX is negative, it is set to the \c{bitmap().width()/2}.
365     If \a hotY is negative, it is set to the \c{bitmap().height()/2}.
366
367     The cursor \a bitmap (B) and \a mask (M) bits are combined like this:
368     \list
369     \li B=1 and M=1 gives black.
370     \li B=0 and M=1 gives white.
371     \li B=0 and M=0 gives transparent.
372     \li B=1 and M=0 gives an XOR'd result under Windows, undefined
373     results on all other platforms.
374     \endlist
375
376     Use the global Qt color Qt::color0 to draw 0-pixels and Qt::color1 to
377     draw 1-pixels in the bitmaps.
378
379     Valid cursor sizes depend on the display hardware (or the
380     underlying window system). We recommend using 32 x 32 cursors,
381     because this size is supported on all platforms. Some platforms
382     also support 16 x 16, 48 x 48, and 64 x 64 cursors.
383
384     \note On Windows CE, the cursor size is fixed. If the pixmap
385     is bigger than the system size, it will be scaled.
386
387     \sa QBitmap::QBitmap(), QBitmap::setMask()
388 */
389
390 QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
391     : d(0)
392 {
393     d = QCursorData::setBitmap(bitmap, mask, hotX, hotY);
394 }
395
396 QCursorData *qt_cursorTable[Qt::LastCursor + 1];
397 bool QCursorData::initialized = false;
398
399 /*! \internal */
400 void QCursorData::cleanup()
401 {
402     if(!QCursorData::initialized)
403         return;
404
405     for (int shape = 0; shape <= Qt::LastCursor; ++shape) {
406         // In case someone has a static QCursor defined with this shape
407         if (!qt_cursorTable[shape]->ref.deref())
408             delete qt_cursorTable[shape];
409         qt_cursorTable[shape] = 0;
410     }
411     QCursorData::initialized = false;
412 }
413
414 /*! \internal */
415 void QCursorData::initialize()
416 {
417     if (QCursorData::initialized)
418         return;
419     for (int shape = 0; shape <= Qt::LastCursor; ++shape)
420         qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape);
421     QCursorData::initialized = true;
422 }
423
424 /*!
425     Constructs a cursor with the default arrow shape.
426 */
427 QCursor::QCursor()
428 {
429     if (!QCursorData::initialized) {
430         if (QCoreApplication::startingUp()) {
431             d = 0;
432             return;
433         }
434         QCursorData::initialize();
435     }
436     QCursorData *c = qt_cursorTable[0];
437     c->ref.ref();
438     d = c;
439 }
440
441 /*!
442     Constructs a cursor with the specified \a shape.
443
444     See \l Qt::CursorShape for a list of shapes.
445
446     \sa setShape()
447 */
448 QCursor::QCursor(Qt::CursorShape shape)
449     : d(0)
450 {
451     if (!QCursorData::initialized)
452         QCursorData::initialize();
453     setShape(shape);
454 }
455
456
457 /*!
458     Returns the cursor shape identifier. The return value is one of
459     the \l Qt::CursorShape enum values (cast to an int).
460
461     \sa setShape()
462 */
463 Qt::CursorShape QCursor::shape() const
464 {
465     if (!QCursorData::initialized)
466         QCursorData::initialize();
467     return d->cshape;
468 }
469
470 /*!
471     Sets the cursor to the shape identified by \a shape.
472
473     See \l Qt::CursorShape for the list of cursor shapes.
474
475     \sa shape()
476 */
477 void QCursor::setShape(Qt::CursorShape shape)
478 {
479     if (!QCursorData::initialized)
480         QCursorData::initialize();
481     QCursorData *c = uint(shape) <= Qt::LastCursor ? qt_cursorTable[shape] : 0;
482     if (!c)
483         c = qt_cursorTable[0];
484     c->ref.ref();
485     if (!d) {
486         d = c;
487     } else {
488         if (!d->ref.deref())
489             delete d;
490         d = c;
491     }
492 }
493
494 /*!
495     Returns the cursor bitmap, or 0 if it is one of the standard
496     cursors.
497 */
498 const QBitmap *QCursor::bitmap() const
499 {
500     if (!QCursorData::initialized)
501         QCursorData::initialize();
502     return d->bm;
503 }
504
505 /*!
506     Returns the cursor bitmap mask, or 0 if it is one of the standard
507     cursors.
508 */
509
510 const QBitmap *QCursor::mask() const
511 {
512     if (!QCursorData::initialized)
513         QCursorData::initialize();
514     return d->bmm;
515 }
516
517 /*!
518     Returns the cursor pixmap. This is only valid if the cursor is a
519     pixmap cursor.
520 */
521
522 QPixmap QCursor::pixmap() const
523 {
524     if (!QCursorData::initialized)
525         QCursorData::initialize();
526     return d->pixmap;
527 }
528
529 /*!
530     Returns the cursor hot spot, or (0, 0) if it is one of the
531     standard cursors.
532 */
533
534 QPoint QCursor::hotSpot() const
535 {
536     if (!QCursorData::initialized)
537         QCursorData::initialize();
538     return QPoint(d->hx, d->hy);
539 }
540
541 /*!
542     Constructs a copy of the cursor \a c.
543 */
544
545 QCursor::QCursor(const QCursor &c)
546 {
547     if (!QCursorData::initialized)
548         QCursorData::initialize();
549     d = c.d;
550     d->ref.ref();
551 }
552
553 /*!
554     Destroys the cursor.
555 */
556
557 QCursor::~QCursor()
558 {
559     if (d && !d->ref.deref())
560         delete d;
561 }
562
563
564 /*!
565     Assigns \a c to this cursor and returns a reference to this
566     cursor.
567 */
568
569 QCursor &QCursor::operator=(const QCursor &c)
570 {
571     if (!QCursorData::initialized)
572         QCursorData::initialize();
573     if (c.d)
574         c.d->ref.ref();
575     if (d && !d->ref.deref())
576         delete d;
577     d = c.d;
578     return *this;
579 }
580
581 /*!
582    Returns the cursor as a QVariant.
583 */
584 QCursor::operator QVariant() const
585 {
586     return QVariant(QVariant::Cursor, this);
587 }
588
589 #ifndef QT_NO_DEBUG_STREAM
590 QDebug operator<<(QDebug dbg, const QCursor &c)
591 {
592     dbg.nospace() << "QCursor(Qt::CursorShape(" << c.shape() << "))";
593     return dbg.space();
594 }
595 #endif
596
597 QT_END_NAMESPACE
598 #endif // QT_NO_CURSOR
599