source: trunk/src/gui/kernel/qcursor_x11.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 25.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <qdebug.h>
43#include <qdatastream.h>
44#include <private/qcursor_p.h>
45#include <private/qt_x11_p.h>
46#include <private/qapplication_p.h>
47#include <qbitmap.h>
48#include <qcursor.h>
49#include <X11/cursorfont.h>
50
51#include <qlibrary.h>
52
53#ifndef QT_NO_XCURSOR
54# include <X11/Xcursor/Xcursor.h>
55#endif // QT_NO_XCURSOR
56
57#ifndef QT_NO_XFIXES
58# include <X11/extensions/Xfixes.h>
59#endif // QT_NO_XFIXES
60
61#include "qx11info_x11.h"
62#include <private/qpixmap_x11_p.h>
63
64QT_BEGIN_NAMESPACE
65
66// Define QT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
67// use the ugly X11 cursors.
68
69/*****************************************************************************
70 Internal QCursorData class
71 *****************************************************************************/
72
73QCursorData::QCursorData(Qt::CursorShape s)
74 : cshape(s), bm(0), bmm(0), hx(0), hy(0), hcurs(0), pm(0), pmm(0)
75{
76 ref = 1;
77}
78
79QCursorData::~QCursorData()
80{
81 Display *dpy = X11 ? X11->display : (Display*)0;
82
83 // Add in checking for the display too as on HP-UX
84 // we seem to get a core dump as the cursor data is
85 // deleted again from main() on exit...
86 if (hcurs && dpy)
87 XFreeCursor(dpy, hcurs);
88 if (pm && dpy)
89 XFreePixmap(dpy, pm);
90 if (pmm && dpy)
91 XFreePixmap(dpy, pmm);
92 delete bm;
93 delete bmm;
94}
95
96#ifndef QT_NO_CURSOR
97QCursor::QCursor(Qt::HANDLE cursor)
98{
99 if (!QCursorData::initialized)
100 QCursorData::initialize();
101 d = new QCursorData(Qt::CustomCursor);
102 d->hcurs = cursor;
103}
104
105#endif
106
107QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
108{
109 if (!QCursorData::initialized)
110 QCursorData::initialize();
111 if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
112 qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
113 QCursorData *c = qt_cursorTable[0];
114 c->ref.ref();
115 return c;
116 }
117 QCursorData *d = new QCursorData;
118 d->ref = 1;
119
120 extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
121 d->bm = new QBitmap(qt_toX11Pixmap(bitmap));
122 d->bmm = new QBitmap(qt_toX11Pixmap(mask));
123
124 d->hcurs = 0;
125 d->cshape = Qt::BitmapCursor;
126 d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
127 d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
128 d->fg.red = 0x0000;
129 d->fg.green = 0x0000;
130 d->fg.blue = 0x0000;
131 d->bg.red = 0xffff;
132 d->bg.green = 0xffff;
133 d->bg.blue = 0xffff;
134 return d;
135}
136
137
138
139#ifndef QT_NO_CURSOR
140Qt::HANDLE QCursor::handle() const
141{
142 if (!QCursorData::initialized)
143 QCursorData::initialize();
144 if (!d->hcurs)
145 d->update();
146 return d->hcurs;
147}
148#endif
149
150QPoint QCursor::pos()
151{
152 Window root;
153 Window child;
154 int root_x, root_y, win_x, win_y;
155 uint buttons;
156 Display* dpy = X11->display;
157 for (int i = 0; i < ScreenCount(dpy); ++i) {
158 if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
159 &win_x, &win_y, &buttons))
160
161 return QPoint(root_x, root_y);
162 }
163 return QPoint();
164}
165
166/*! \internal
167*/
168#ifndef QT_NO_CURSOR
169int QCursor::x11Screen()
170{
171 Window root;
172 Window child;
173 int root_x, root_y, win_x, win_y;
174 uint buttons;
175 Display* dpy = X11->display;
176 for (int i = 0; i < ScreenCount(dpy); ++i) {
177 if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
178 &win_x, &win_y, &buttons))
179 return i;
180 }
181 return -1;
182}
183#endif
184
185void QCursor::setPos(int x, int y)
186{
187 QPoint current, target(x, y);
188
189 // this is copied from pos(), since we need the screen number for the correct
190 // root window in the XWarpPointer call
191 Window root;
192 Window child;
193 int root_x, root_y, win_x, win_y;
194 uint buttons;
195 Display* dpy = X11->display;
196 int screen;
197 for (screen = 0; screen < ScreenCount(dpy); ++screen) {
198 if (XQueryPointer(dpy, QX11Info::appRootWindow(screen), &root, &child, &root_x, &root_y,
199 &win_x, &win_y, &buttons)) {
200 current = QPoint(root_x, root_y);
201 break;
202 }
203 }
204
205 if (screen >= ScreenCount(dpy))
206 return;
207
208 // Need to check, since some X servers generate null mouse move
209 // events, causing looping in applications which call setPos() on
210 // every mouse move event.
211 //
212 if (current == target)
213 return;
214
215 XWarpPointer(X11->display, XNone, QX11Info::appRootWindow(screen), 0, 0, 0, 0, x, y);
216}
217
218
219/*!
220 \internal
221
222 Creates the cursor.
223*/
224
225void QCursorData::update()
226{
227 if (!QCursorData::initialized)
228 QCursorData::initialize();
229 if (hcurs)
230 return;
231
232 Display *dpy = X11->display;
233 Window rootwin = QX11Info::appRootWindow();
234
235 if (cshape == Qt::BitmapCursor) {
236 extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
237#ifndef QT_NO_XRENDER
238 if (!pixmap.isNull() && X11->use_xrender) {
239 pixmap = qt_toX11Pixmap(pixmap);
240 hcurs = XRenderCreateCursor (X11->display, pixmap.x11PictureHandle(), hx, hy);
241 } else
242#endif
243 {
244 hcurs = XCreatePixmapCursor(dpy, bm->handle(), bmm->handle(), &fg, &bg, hx, hy);
245 }
246 return;
247 }
248
249 static const char *cursorNames[] = {
250 "left_ptr",
251 "up_arrow",
252 "cross",
253 "wait",
254 "ibeam",
255 "size_ver",
256 "size_hor",
257 "size_bdiag",
258 "size_fdiag",
259 "size_all",
260 "blank",
261 "split_v",
262 "split_h",
263 "pointing_hand",
264 "forbidden",
265 "whats_this",
266 "left_ptr_watch",
267 "openhand",
268 "closedhand",
269 "copy",
270 "move",
271 "link"
272 };
273
274#ifndef QT_NO_XCURSOR
275 if (X11->ptrXcursorLibraryLoadCursor) {
276 // special case for non-standard dnd-* cursors
277 switch (cshape) {
278 case Qt::DragCopyCursor:
279 hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-copy");
280 break;
281 case Qt::DragMoveCursor:
282 hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-move");
283 break;
284 case Qt::DragLinkCursor:
285 hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-link");
286 break;
287 default:
288 break;
289 }
290 if (!hcurs)
291 hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
292 }
293 if (hcurs)
294 return;
295#endif // QT_NO_XCURSOR
296
297 static const uchar cur_blank_bits[] = {
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
301
302 // Non-standard X11 cursors are created from bitmaps
303
304#ifndef QT_USE_APPROXIMATE_CURSORS
305 static const uchar cur_ver_bits[] = {
306 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
307 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
308 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
309 static const uchar mcur_ver_bits[] = {
310 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
311 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
312 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
313 static const uchar cur_hor_bits[] = {
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
315 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
317 static const uchar mcur_hor_bits[] = {
318 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
319 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
320 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
321 static const uchar cur_bdiag_bits[] = {
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
323 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
324 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
325 static const uchar mcur_bdiag_bits[] = {
326 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
327 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
328 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
329 static const uchar cur_fdiag_bits[] = {
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
331 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
332 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
333 static const uchar mcur_fdiag_bits[] = {
334 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
335 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
336 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
337 static const uchar *cursor_bits16[] = {
338 cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
339 cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
340 0, 0, cur_blank_bits, cur_blank_bits };
341
342 static const uchar vsplit_bits[] = {
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
346 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
347 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
349 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
350 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
351 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
354 static const uchar vsplitm_bits[] = {
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
357 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
358 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
359 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
360 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
361 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
362 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
363 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
366 static const uchar hsplit_bits[] = {
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
370 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
371 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
372 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
373 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
374 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
378 static const uchar hsplitm_bits[] = {
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
382 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
383 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
384 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
385 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
386 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
390 static const uchar whatsthis_bits[] = {
391 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
392 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
393 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
394 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
395 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
396 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
397 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
402 static const uchar whatsthism_bits[] = {
403 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
404 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
405 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
406 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
407 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
408 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
409 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
414 static const uchar busy_bits[] = {
415 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
416 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
417 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
418 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
419 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
420 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
421 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
422 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
426 static const uchar busym_bits[] = {
427 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
428 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
429 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
430 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
431 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
432 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
433 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
434 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
438
439 static const uchar * const cursor_bits32[] = {
440 vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
441 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
442 };
443
444 static const uchar forbidden_bits[] = {
445 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
446 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
447 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
448 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
449
450 static const uchar forbiddenm_bits[] = {
451 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
452 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
453 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
454 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
455
456 static const uchar openhand_bits[] = {
457 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
458 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
459 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
460 static const uchar openhandm_bits[] = {
461 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
462 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
463 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
464 static const uchar closedhand_bits[] = {
465 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
466 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
467 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
468 static const uchar closedhandm_bits[] = {
469 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
470 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
471 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
472
473 static const uchar * const cursor_bits20[] = {
474 forbidden_bits, forbiddenm_bits
475 };
476
477 if ((cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor)
478 || cshape == Qt::BlankCursor) {
479 XColor bg, fg;
480 bg.red = 255 << 8;
481 bg.green = 255 << 8;
482 bg.blue = 255 << 8;
483 fg.red = 0;
484 fg.green = 0;
485 fg.blue = 0;
486 int i = (cshape - Qt::SizeVerCursor) * 2;
487 pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i]), 16, 16);
488 pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i + 1]), 16, 16);
489 hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
490 } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
491 || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
492 XColor bg, fg;
493 bg.red = 255 << 8;
494 bg.green = 255 << 8;
495 bg.blue = 255 << 8;
496 fg.red = 0;
497 fg.green = 0;
498 fg.blue = 0;
499 int i = (cshape - Qt::SplitVCursor) * 2;
500 pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i]), 32, 32);
501 pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i + 1]), 32, 32);
502 int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
503 || cshape == Qt::BusyCursor) ? 0 : 16;
504 hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, hs, hs);
505 } else if (cshape == Qt::ForbiddenCursor) {
506 XColor bg, fg;
507 bg.red = 255 << 8;
508 bg.green = 255 << 8;
509 bg.blue = 255 << 8;
510 fg.red = 0;
511 fg.green = 0;
512 fg.blue = 0;
513 int i = (cshape - Qt::ForbiddenCursor) * 2;
514 pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i]), 20, 20);
515 pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i + 1]), 20, 20);
516 hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 10, 10);
517 } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
518 XColor bg, fg;
519 bg.red = 255 << 8;
520 bg.green = 255 << 8;
521 bg.blue = 255 << 8;
522 fg.red = 0;
523 fg.green = 0;
524 fg.blue = 0;
525 bool open = cshape == Qt::OpenHandCursor;
526 pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhand_bits : closedhand_bits), 16, 16);
527 pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhandm_bits : closedhandm_bits), 16, 16);
528 hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
529 } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
530 || cshape == Qt::DragLinkCursor) {
531 XColor bg, fg;
532 bg.red = 255 << 8;
533 bg.green = 255 << 8;
534 bg.blue = 255 << 8;
535 fg.red = 0;
536 fg.green = 0;
537 fg.blue = 0;
538 QImage image = QApplicationPrivate::instance()->getPixmapCursor(cshape).toImage();
539 pm = QX11PixmapData::createBitmapFromImage(image);
540 pmm = QX11PixmapData::createBitmapFromImage(image.createAlphaMask().convertToFormat(QImage::Format_MonoLSB));
541 hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
542 }
543
544 if (hcurs)
545 {
546#ifndef QT_NO_XFIXES
547 if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
548 X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
549#endif /* ! QT_NO_XFIXES */
550 return;
551 }
552
553#endif /* ! QT_USE_APPROXIMATE_CURSORS */
554
555 uint sh;
556 switch (cshape) { // map Q cursor to X cursor
557 case Qt::ArrowCursor:
558 sh = XC_left_ptr;
559 break;
560 case Qt::UpArrowCursor:
561 sh = XC_center_ptr;
562 break;
563 case Qt::CrossCursor:
564 sh = XC_crosshair;
565 break;
566 case Qt::WaitCursor:
567 sh = XC_watch;
568 break;
569 case Qt::IBeamCursor:
570 sh = XC_xterm;
571 break;
572 case Qt::SizeAllCursor:
573 sh = XC_fleur;
574 break;
575 case Qt::PointingHandCursor:
576 sh = XC_hand2;
577 break;
578#ifdef QT_USE_APPROXIMATE_CURSORS
579 case Qt::SizeBDiagCursor:
580 sh = XC_top_right_corner;
581 break;
582 case Qt::SizeFDiagCursor:
583 sh = XC_bottom_right_corner;
584 break;
585 case Qt::BlankCursor:
586 XColor bg, fg;
587 bg.red = 255 << 8;
588 bg.green = 255 << 8;
589 bg.blue = 255 << 8;
590 fg.red = 0;
591 fg.green = 0;
592 fg.blue = 0;
593 pm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
594 pmm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
595 hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
596 return;
597 break;
598 case Qt::SizeVerCursor:
599 case Qt::SplitVCursor:
600 sh = XC_sb_v_double_arrow;
601 break;
602 case Qt::SizeHorCursor:
603 case Qt::SplitHCursor:
604 sh = XC_sb_h_double_arrow;
605 break;
606 case Qt::WhatsThisCursor:
607 sh = XC_question_arrow;
608 break;
609 case Qt::ForbiddenCursor:
610 sh = XC_circle;
611 break;
612 case Qt::BusyCursor:
613 sh = XC_watch;
614 break;
615 case Qt::DragCopyCursor:
616 sh = XC_tcross;
617 break;
618 case Qt::DragLinkCursor:
619 sh = XC_center_ptr;
620 break;
621 case Qt::DragMoveCursor:
622 sh = XC_top_left_arrow;
623 break;
624#endif /* QT_USE_APPROXIMATE_CURSORS */
625 default:
626 qWarning("QCursor::update: Invalid cursor shape %d", cshape);
627 return;
628 }
629 hcurs = XCreateFontCursor(dpy, sh);
630
631#ifndef QT_NO_XFIXES
632 if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
633 X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
634#endif /* ! QT_NO_XFIXES */
635}
636
637QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.