~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/kernel/qcursor.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the gui module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qcursor.h"
 
30
 
 
31
#ifndef QT_NO_CURSOR
 
32
 
 
33
#include <qapplication.h>
 
34
#include <qbitmap.h>
 
35
#include <qimage.h>
 
36
#include <qdatastream.h>
 
37
#include <qvariant.h>
 
38
#include <private/qcursor_p.h>
 
39
 
 
40
/*!
 
41
    \class QCursor
 
42
 
 
43
    \brief The QCursor class provides a mouse cursor with an arbitrary
 
44
    shape.
 
45
 
 
46
    \ingroup appearance
 
47
    \ingroup shared
 
48
    \mainclass
 
49
 
 
50
    This class is mainly used to create mouse cursors that are
 
51
    associated with particular widgets and to get and set the position
 
52
    of the mouse cursor.
 
53
 
 
54
    Qt has a number of standard cursor shapes, but you can also make
 
55
    custom cursor shapes based on a QBitmap, a mask and a hotspot.
 
56
 
 
57
    To associate a cursor with a widget, use QWidget::setCursor(). To
 
58
    associate a cursor with all widgets (normally for a short period
 
59
    of time), use QApplication::setOverrideCursor().
 
60
 
 
61
    To set a cursor shape use QCursor::setShape() or use the QCursor
 
62
    constructor which takes the shape as argument, or you can use one
 
63
    of the predefined cursors defined in the \l Qt::CursorShape enum.
 
64
 
 
65
    If you want to create a cursor with your own bitmap, either use
 
66
    the QCursor constructor which takes a bitmap and a mask or the
 
67
    constructor which takes a pixmap as arguments.
 
68
 
 
69
    To set or get the position of the mouse cursor use the static
 
70
    methods QCursor::pos() and QCursor::setPos().
 
71
 
 
72
    \img cursors.png Cursor Shapes
 
73
 
 
74
    \section1 A Note for X11 Users
 
75
 
 
76
    On X11, Qt supports the \link
 
77
    http://www.xfree86.org/4.3.0/Xcursor.3.html Xcursor\endlink
 
78
    library, which allows for full color icon themes. The table below
 
79
    shows the cursor name used for each Qt::CursorShape value. If a
 
80
    cursor cannot be found using the name shown below, a standard X11
 
81
    cursor will be used instead. Note: X11 does not provide
 
82
    appropriate cursors for all possible Qt::CursorShape values. It
 
83
    is possible that some cursors will be taken from the Xcursor
 
84
    theme, while others will use an internal bitmap cursor.
 
85
 
 
86
    \table
 
87
    \header \o Qt::CursorShape Values   \o Cursor Names
 
88
    \row \o Qt::ArrowCursor             \o \c left_ptr
 
89
    \row \o Qt::UpArrowCursor           \o \c up_arrow
 
90
    \row \o Qt::CrossCursor             \o \c cross
 
91
    \row \o Qt::WaitCursor              \o \c wait
 
92
    \row \o Qt::BusyCursor              \o \c left_ptr_watch
 
93
    \row \o Qt::IBeamCursor             \o \c ibeam
 
94
    \row \o Qt::SizeVerCursor           \o \c size_ver
 
95
    \row \o Qt::SizeHorCursor           \o \c size_hor
 
96
    \row \o Qt::SizeBDiagCursor         \o \c size_bdiag
 
97
    \row \o Qt::SizeFDiagCursor         \o \c size_fdiag
 
98
    \row \o Qt::SizeAllCursor           \o \c size_all
 
99
    \row \o Qt::SplitVCursor            \o \c split_v
 
100
    \row \o Qt::SplitHCursor            \o \c split_h
 
101
    \row \o Qt::PointingHandCursor      \o \c pointing_hand
 
102
    \row \o Qt::ForbiddenCursor         \o \c forbidden
 
103
    \row \o Qt::WhatsThisCursor         \o \c whats_this
 
104
    \endtable
 
105
 
 
106
    \sa QWidget, {fowler}{GUI Design Handbook: Cursors}
 
107
*/
 
108
 
 
109
/*!
 
110
    \fn HCURSOR_or_HANDLE QCursor::handle() const
 
111
 
 
112
    Returns a handle to the cursor.
 
113
 
 
114
    \warning Using the value returned by this function is not
 
115
    portable.
 
116
 
 
117
    \sa Qt::HANDLE
 
118
*/
 
119
 
 
120
/*!
 
121
    \fn QCursor::QCursor(HCURSOR cursor)
 
122
 
 
123
    Constructs a Qt cursor from the given Windows \a cursor.
 
124
 
 
125
    \warning This function is only available on Windows.
 
126
 
 
127
    \sa handle()
 
128
*/
 
129
 
 
130
/*!
 
131
    \fn QCursor::QCursor(Qt::HANDLE handle)
 
132
 
 
133
    Constructs a Qt cursor from the given \a handle.
 
134
 
 
135
    \warning This function is only available on X11.
 
136
 
 
137
    \sa handle()
 
138
*/
 
139
 
 
140
/*****************************************************************************
 
141
  QCursor stream functions
 
142
 *****************************************************************************/
 
143
 
 
144
#ifndef QT_NO_DATASTREAM
 
145
 
 
146
 
 
147
/*!
 
148
    \fn QDataStream &operator<<(QDataStream &stream, const QCursor &cursor)
 
149
    \relates QCursor
 
150
 
 
151
    Writes the \a cursor to the \a stream.
 
152
 
 
153
    \sa {Format of the QDataStream operators}
 
154
*/
 
155
 
 
156
QDataStream &operator<<(QDataStream &s, const QCursor &c)
 
157
{
 
158
    s << (qint16)c.shape();                        // write shape id to stream
 
159
    if (c.shape() == Qt::BitmapCursor) {                // bitmap cursor
 
160
#if !defined(QT_NO_IMAGEIO)
 
161
        bool isPixmap = false;
 
162
        if (s.version() >= 7) {
 
163
            isPixmap = !c.pixmap().isNull();
 
164
            s << isPixmap;
 
165
        }
 
166
        if (isPixmap)
 
167
            s << c.pixmap();
 
168
        else
 
169
            s << *c.bitmap() << *c.mask();
 
170
        s << c.hotSpot();
 
171
#else
 
172
        qWarning("No Image Cursor I/O");
 
173
#endif
 
174
    }
 
175
    return s;
 
176
}
 
177
 
 
178
/*!
 
179
    \fn QDataStream &operator>>(QDataStream &stream, QCursor &cursor)
 
180
    \relates QCursor
 
181
 
 
182
    Reads the \a cursor from the \a stream.
 
183
 
 
184
    \sa {Format of the QDataStream operators}
 
185
*/
 
186
 
 
187
QDataStream &operator>>(QDataStream &s, QCursor &c)
 
188
{
 
189
    qint16 shape;
 
190
    s >> shape;                                        // read shape id from stream
 
191
    if (shape == Qt::BitmapCursor) {                // read bitmap cursor
 
192
#if !defined(QT_NO_IMAGEIO)
 
193
        bool isPixmap = false;
 
194
        if (s.version() >= 7)
 
195
            s >> isPixmap;
 
196
        if (isPixmap) {
 
197
            QPixmap pm;
 
198
            QPoint hot;
 
199
            s >> pm >> hot;
 
200
            c = QCursor(pm, hot.x(), hot.y());
 
201
        } else {
 
202
            QBitmap bm, bmm;
 
203
            QPoint hot;
 
204
            s >> bm >> bmm >> hot;
 
205
            c = QCursor(bm, bmm, hot.x(), hot.y());
 
206
        }
 
207
#else
 
208
        qWarning("No Image Cursor I/O");
 
209
#endif
 
210
    } else {
 
211
        c.setShape((Qt::CursorShape)shape);                // create cursor with shape
 
212
    }
 
213
    return s;
 
214
}
 
215
#endif // QT_NO_DATASTREAM
 
216
 
 
217
 
 
218
/*!
 
219
    Constructs a custom pixmap cursor.
 
220
 
 
221
    \a pixmap is the image. It is usual to give it a mask (set using
 
222
    QPixmap::setMask()). \a hotX and \a hotY define the cursor's hot
 
223
    spot.
 
224
 
 
225
    If \a hotX is negative, it is set to the \c{pixmap().width()/2}.
 
226
    If \a hotY is negative, it is set to the \c{pixmap().height()/2}.
 
227
 
 
228
    Valid cursor sizes depend on the display hardware (or the
 
229
    underlying window system). We recommend using 32 x 32 cursors,
 
230
    because this size is supported on all platforms. Some platforms
 
231
    also support 16 x 16, 48 x 48, and 64 x 64 cursors.
 
232
 
 
233
    \sa QPixmap::QPixmap(), QPixmap::setMask()
 
234
*/
 
235
 
 
236
QCursor::QCursor(const QPixmap &pixmap, int hotX, int hotY)
 
237
    : d(0)
 
238
{
 
239
    QImage img = pixmap.toImage().convertToFormat(QImage::Format_Indexed8, Qt::ThresholdDither|Qt::AvoidDither);
 
240
    QBitmap bm = QBitmap::fromImage(img, Qt::ThresholdDither|Qt::AvoidDither);
 
241
    QBitmap bmm = bm.mask();
 
242
    if (!bmm.isNull()) {
 
243
        QBitmap nullBm;
 
244
        bm.setMask(nullBm);
 
245
    }
 
246
    else if (!pixmap.mask().isNull()) {
 
247
        QImage mimg = pixmap.mask().toImage().convertToFormat(QImage::Format_Indexed8, Qt::ThresholdDither|Qt::AvoidDither);
 
248
        bmm = QBitmap::fromImage(mimg, Qt::ThresholdDither|Qt::AvoidDither);
 
249
    }
 
250
    else {
 
251
        bmm = QBitmap(bm.size());
 
252
        bmm.fill(Qt::color1);
 
253
    }
 
254
 
 
255
    d = QCursorData::setBitmap(bm, bmm, hotX, hotY);
 
256
    d->pixmap = pixmap;
 
257
}
 
258
 
 
259
 
 
260
 
 
261
/*!
 
262
    Constructs a custom bitmap cursor.
 
263
 
 
264
    \a bitmap and
 
265
    \a mask make up the bitmap.
 
266
    \a hotX and
 
267
    \a hotY define the cursor's hot spot.
 
268
 
 
269
    If \a hotX is negative, it is set to the \c{bitmap().width()/2}.
 
270
    If \a hotY is negative, it is set to the \c{bitmap().height()/2}.
 
271
 
 
272
    The cursor \a bitmap (B) and \a mask (M) bits are combined like this:
 
273
    \list
 
274
    \o B=1 and M=1 gives black.
 
275
    \o B=0 and M=1 gives white.
 
276
    \o B=0 and M=0 gives transparent.
 
277
    \o B=1 and M=0 gives an undefined result.
 
278
    \endlist
 
279
 
 
280
    Use the global Qt color \c Qt::color0 to draw 0-pixels and \c Qt::color1 to
 
281
    draw 1-pixels in the bitmaps.
 
282
 
 
283
    Valid cursor sizes depend on the display hardware (or the
 
284
    underlying window system). We recommend using 32 x 32 cursors,
 
285
    because this size is supported on all platforms. Some platforms
 
286
    also support 16 x 16, 48 x 48, and 64 x 64 cursors.
 
287
 
 
288
    \sa QBitmap::QBitmap(), QBitmap::setMask()
 
289
*/
 
290
 
 
291
QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
 
292
    : d(0)
 
293
{
 
294
    d = QCursorData::setBitmap(bitmap, mask, hotX, hotY);
 
295
}
 
296
 
 
297
QCursorData *qt_cursorTable[Qt::LastCursor + 1];
 
298
bool QCursorData::initialized = false;
 
299
 
 
300
/*! \internal */
 
301
void QCursorData::cleanup()
 
302
{
 
303
    if(!QCursorData::initialized)
 
304
        return;
 
305
 
 
306
    for (int shape = 0; shape <= Qt::LastCursor; ++shape) {
 
307
        delete qt_cursorTable[shape];
 
308
        qt_cursorTable[shape] = 0;
 
309
    }
 
310
    QCursorData::initialized = false;
 
311
}
 
312
 
 
313
/*! \internal */
 
314
void QCursorData::initialize()
 
315
{
 
316
    if (QCursorData::initialized)
 
317
        return;
 
318
#ifdef Q_WS_MAC
 
319
    InitCursor();
 
320
#endif
 
321
    for (int shape = 0; shape <= Qt::LastCursor; ++shape)
 
322
        qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape);
 
323
    QCursorData::initialized = true;
 
324
}
 
325
 
 
326
/*!
 
327
    Constructs a cursor with the default arrow shape.
 
328
*/
 
329
QCursor::QCursor()
 
330
{
 
331
    if (!QCursorData::initialized) {
 
332
        if (qApp->startingUp()) {
 
333
            d = 0;
 
334
            return;
 
335
        }
 
336
        QCursorData::initialize();
 
337
    }
 
338
    QCursorData *c = qt_cursorTable[0];
 
339
    c->ref.ref();
 
340
    d = c;
 
341
}
 
342
 
 
343
/*!
 
344
    Constructs a cursor with the specified \a shape.
 
345
 
 
346
    See \l Qt::CursorShape for a list of shapes.
 
347
 
 
348
    \sa setShape()
 
349
*/
 
350
QCursor::QCursor(Qt::CursorShape shape)
 
351
    : d(0)
 
352
{
 
353
    if (!QCursorData::initialized)
 
354
        QCursorData::initialize();
 
355
    setShape(shape);
 
356
}
 
357
 
 
358
 
 
359
/*!
 
360
    Returns the cursor shape identifier. The return value is one of
 
361
    the \l Qt::CursorShape enum values (cast to an int).
 
362
 
 
363
    \sa setShape()
 
364
*/
 
365
Qt::CursorShape QCursor::shape() const
 
366
{
 
367
    if (!QCursorData::initialized)
 
368
        QCursorData::initialize();
 
369
    return d->cshape;
 
370
}
 
371
 
 
372
/*!
 
373
    Sets the cursor to the shape identified by \a shape.
 
374
 
 
375
    See \l Qt::CursorShape for the list of cursor shapes.
 
376
 
 
377
    \sa shape()
 
378
*/
 
379
void QCursor::setShape(Qt::CursorShape shape)
 
380
{
 
381
    if (!QCursorData::initialized)
 
382
        QCursorData::initialize();
 
383
    QCursorData *c = uint(shape) <= Qt::LastCursor ? qt_cursorTable[shape] : 0;
 
384
    if (!c)
 
385
        c = qt_cursorTable[0];
 
386
    c->ref.ref();
 
387
    if (!d) {
 
388
        d = c;
 
389
    } else {
 
390
        c = qAtomicSetPtr(&d, c);
 
391
        if (!c->ref.deref())
 
392
            delete c;
 
393
    }
 
394
}
 
395
 
 
396
/*!
 
397
    Returns the cursor bitmap, or 0 if it is one of the standard
 
398
    cursors.
 
399
*/
 
400
const QBitmap *QCursor::bitmap() const
 
401
{
 
402
    if (!QCursorData::initialized)
 
403
        QCursorData::initialize();
 
404
    return d->bm;
 
405
}
 
406
 
 
407
/*!
 
408
    Returns the cursor bitmap mask, or 0 if it is one of the standard
 
409
    cursors.
 
410
*/
 
411
 
 
412
const QBitmap *QCursor::mask() const
 
413
{
 
414
    if (!QCursorData::initialized)
 
415
        QCursorData::initialize();
 
416
    return d->bmm;
 
417
}
 
418
 
 
419
/*!
 
420
    Returns the cursor pixmap. This is only valid if the cursor is a
 
421
    pixmap cursor.
 
422
*/
 
423
 
 
424
QPixmap QCursor::pixmap() const
 
425
{
 
426
    if (!QCursorData::initialized)
 
427
        QCursorData::initialize();
 
428
    return d->pixmap;
 
429
}
 
430
 
 
431
/*!
 
432
    Returns the cursor hot spot, or (0, 0) if it is one of the
 
433
    standard cursors.
 
434
*/
 
435
 
 
436
QPoint QCursor::hotSpot() const
 
437
{
 
438
    if (!QCursorData::initialized)
 
439
        QCursorData::initialize();
 
440
    return QPoint(d->hx, d->hy);
 
441
}
 
442
 
 
443
/*!
 
444
    Constructs a copy of the cursor \a c.
 
445
*/
 
446
 
 
447
QCursor::QCursor(const QCursor &c)
 
448
{
 
449
    if (!QCursorData::initialized)
 
450
        QCursorData::initialize();
 
451
    d = c.d;
 
452
    d->ref.ref();
 
453
}
 
454
 
 
455
/*!
 
456
    Destroys the cursor.
 
457
*/
 
458
 
 
459
QCursor::~QCursor()
 
460
{
 
461
    if (d && !d->ref.deref())
 
462
        delete d;
 
463
}
 
464
 
 
465
 
 
466
/*!
 
467
    Assigns \a c to this cursor and returns a reference to this
 
468
    cursor.
 
469
*/
 
470
 
 
471
QCursor &QCursor::operator=(const QCursor &c)
 
472
{
 
473
    if (!QCursorData::initialized)
 
474
        QCursorData::initialize();
 
475
    qAtomicAssign(d, c.d);
 
476
    return *this;
 
477
}
 
478
 
 
479
/*!
 
480
   Returns the cursor as a QVariant.
 
481
*/
 
482
QCursor::operator QVariant() const
 
483
{
 
484
    return QVariant(QVariant::Cursor, this);
 
485
}
 
486
 
 
487
#endif // QT_NO_CURSOR