Qt 4.8
qcursor_mac.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 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 <private/qcursor_p.h>
43 #include <private/qpixmap_mac_p.h>
44 #include <qapplication.h>
45 #include <qbitmap.h>
46 #include <qcursor.h>
47 #include <qevent.h>
48 #include <string.h>
49 #include <unistd.h>
50 #include <AppKit/NSCursor.h>
51 #include <qpainter.h>
52 #include <private/qt_cocoa_helpers_mac_p.h>
53 #include <private/qapplication_p.h>
54 
56 
57 /*****************************************************************************
58  Externals
59  *****************************************************************************/
61 extern OSWindowRef qt_mac_window_for(const QWidget *); //qwidget_mac.cpp
62 extern GrafPtr qt_mac_qd_context(const QPaintDevice *); //qpaintdevice_mac.cpp
63 extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_mac.cpp
64 extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
65 
66 /*****************************************************************************
67  Internal QCursorData class
68  *****************************************************************************/
69 
70 class QMacAnimateCursor : public QObject
71 {
72  int timerId, step;
73  ThemeCursor curs;
74 public:
75  QMacAnimateCursor() : QObject(), timerId(-1) { }
76  void start(ThemeCursor c) {
77  step = 1;
78  if(timerId != -1)
79  killTimer(timerId);
80  timerId = startTimer(300);
81  curs = c;
82  }
83  void stop() {
84  if(timerId != -1) {
85  killTimer(timerId);
86  timerId = -1;
87  }
88  }
89 protected:
91  if(e->timerId() == timerId) {
92  /*
93  if(SetAnimatedThemeCursor(curs, step++) == themeBadCursorIndexErr)
94  stop();
95  */
96  }
97  }
98 };
99 
100 inline void *qt_mac_nsCursorForQCursor(const QCursor &c)
101 {
102  c.d->update();
103  return [[static_cast<NSCursor *>(c.d->curs.cp.nscursor) retain] autorelease];
104 }
105 
106 static QCursorData *currentCursor = 0; //current cursor
107 
109 {
110 #ifdef QT_MAC_USE_COCOA
112  [static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(*c)) set];
113 #else
114  if (!c) {
115  currentCursor = 0;
116  return;
117  }
118  c->handle(); //force the cursor to get loaded, if it's not
119 
120  if(currentCursor && currentCursor->type == QCursorData::TYPE_ThemeCursor
121  && currentCursor->curs.tc.anim)
122  currentCursor->curs.tc.anim->stop();
123  if(c->d->type == QCursorData::TYPE_ImageCursor) {
124  [static_cast<NSCursor *>(c->d->curs.cp.nscursor) set];
125  } else if(c->d->type == QCursorData::TYPE_ThemeCursor) {
126  if(SetAnimatedThemeCursor(c->d->curs.tc.curs, 0) == themeBadCursorIndexErr) {
127  SetThemeCursor(c->d->curs.tc.curs);
128  } else {
129  if(!c->d->curs.tc.anim)
130  c->d->curs.tc.anim = new QMacAnimateCursor;
131  c->d->curs.tc.anim->start(c->d->curs.tc.curs);
132  }
133  }
134 
135  currentCursor = c->d;
136 #endif
137 }
138 
141 static bool qt_button_down_on_prev_call = false;
142 static QCursor *grabCursor = 0;
143 
145 {
146  QCursor cursor(Qt::ArrowCursor);
147  if (qt_button_down) {
148  // The widget that is currently pressed
149  // grabs the mouse cursor:
150  widgetUnderMouse = qt_button_down;
152  } else if (qt_button_down_on_prev_call) {
153  // Grab has been released, so do
154  // a full check:
156  lastWidgetUnderMouse = 0;
157  lastMouseCursorWidget = 0;
158  }
159 
161  cursor = *QApplication::overrideCursor();
162  } else if (grabCursor) {
163  cursor = *grabCursor;
164  } else if (widgetUnderMouse) {
165  if (widgetUnderMouse == lastWidgetUnderMouse) {
166  // Optimization that should hit when the widget under
167  // the mouse does not change as the mouse moves:
168  if (lastMouseCursorWidget)
169  cursor = lastMouseCursorWidget->cursor();
170  } else {
171  QWidget *w = widgetUnderMouse;
172  for (; w; w = w->parentWidget()) {
174  cursor = w->cursor();
175  break;
176  }
177  if (w->isWindow())
178  break;
179  }
180  // One final check in case we ran out of parents in the loop:
181  if (w && !w->testAttribute(Qt::WA_SetCursor))
182  w = 0;
183 
184  lastWidgetUnderMouse = widgetUnderMouse;
185  lastMouseCursorWidget = w;
186  }
187  }
188 
189 #ifdef QT_MAC_USE_COCOA
190  cursor.d->update();
191  NSCursor *nsCursor = static_cast<NSCursor *>(cursor.d->curs.cp.nscursor);
192  if ([NSCursor currentCursor] != nsCursor) {
194  [nsCursor set];
195  }
196 #else
197  qt_mac_set_cursor(&cursor);
198 #endif
199 }
200 
202 {
203  // This function is similar to qt_mac_updateCursorWithWidgetUnderMouse
204  // except that is clears the optimization cache, and finds the widget
205  // under mouse itself. Clearing the cache is useful in cases where the
206  // application has been deactivated/activated etc.
207  // NB: since we dont have any true native widget, the call to
208  // qt_mac_getTargetForMouseEvent will fail when the mouse is over QMacNativeWidgets.
209 #ifdef QT_MAC_USE_COCOA
210  lastWidgetUnderMouse = 0;
211  lastMouseCursorWidget = 0;
212  QWidget *widgetUnderMouse = 0;
213 
214  if (qt_button_down) {
215  widgetUnderMouse = qt_button_down;
216  } else {
217  QPoint localPoint;
218  QPoint globalPoint;
219  qt_mac_getTargetForMouseEvent(0, QEvent::None, localPoint, globalPoint, 0, &widgetUnderMouse);
220  }
221  qt_mac_updateCursorWithWidgetUnderMouse(widgetUnderMouse);
222 #else
224 #endif
225 }
226 
227 void qt_mac_setMouseGrabCursor(bool set, QCursor *const cursor = 0)
228 {
229  if (grabCursor) {
230  delete grabCursor;
231  grabCursor = 0;
232  }
233  if (set) {
234  if (cursor)
235  grabCursor = new QCursor(*cursor);
236  else if (lastMouseCursorWidget)
237  grabCursor = new QCursor(lastMouseCursorWidget->cursor());
238  else
239  grabCursor = new QCursor(Qt::ArrowCursor);
240  }
242 }
243 
244 #ifndef QT_MAC_USE_COCOA
246 {
248 }
249 #endif
250 
252 
254  : cshape(s), bm(0), bmm(0), hx(-1), hy(-1), mId(s), type(TYPE_None)
255 {
256  ref = 1;
257  memset(&curs, '\0', sizeof(curs));
258 }
259 
261 {
262  if (type == TYPE_ImageCursor) {
263  if (curs.cp.my_cursor) {
265  [static_cast<NSCursor *>(curs.cp.nscursor) release];
266  }
267  } else if(type == TYPE_ThemeCursor) {
268  delete curs.tc.anim;
269  }
270  type = TYPE_None;
271 
272  delete bm;
273  delete bmm;
274  if(currentCursor == this)
275  currentCursor = 0;
276 }
277 
278 QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
279 {
282  if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
283  qWarning("Qt: QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
285  c->ref.ref();
286  return c;
287  }
288  // This is silly, but this is apparently called outside the constructor, so we have
289  // to be ready for that case.
290  QCursorData *x = new QCursorData;
291  x->ref = 1;
292  x->mId = ++nextCursorId;
293  x->bm = new QBitmap(bitmap);
294  x->bmm = new QBitmap(mask);
296  x->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
297  x->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
298  return x;
299 }
300 
302 {
305  if(d->type == QCursorData::TYPE_None)
306  d->update();
307  return (Qt::HANDLE)d->mId;
308 }
309 
311 {
312  return flipPoint([NSEvent mouseLocation]).toPoint();
313 }
314 
315 void QCursor::setPos(int x, int y)
316 {
317 #ifdef QT_MAC_USE_COCOA
318  CGPoint pos;
319  pos.x = x;
320  pos.y = y;
321 
322  CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0);
323  CGEventPost(kCGHIDEventTap, e);
324  CFRelease(e);
325 #else
326  CGWarpMouseCursorPosition(CGPointMake(x, y));
327 
328  /* I'm not too keen on doing this, but this makes it a lot easier, so I just
329  send the event back through the event system and let it get propagated correctly
330  ideally this would not really need to be faked --Sam
331  */
332  QWidget *widget = 0;
333  if(QWidget *grb = QWidget::mouseGrabber())
334  widget = grb;
335  else
336  widget = QApplication::widgetAt(QPoint(x, y));
337  if(widget) {
340  qt_sendSpontaneousEvent(widget, &me);
341  }
342 #endif
343 }
344 
345 void QCursorData::initCursorFromBitmap()
346 {
347  NSImage *nsimage;
348  QImage finalCursor(bm->size(), QImage::Format_ARGB32);
351  for (int row = 0; row < finalCursor.height(); ++row) {
352  QRgb *bmData = reinterpret_cast<QRgb *>(bmi.scanLine(row));
353  QRgb *bmmData = reinterpret_cast<QRgb *>(bmmi.scanLine(row));
354  QRgb *finalData = reinterpret_cast<QRgb *>(finalCursor.scanLine(row));
355  for (int col = 0; col < finalCursor.width(); ++col) {
356  if (bmmData[col] == 0xff000000 && bmData[col] == 0xffffffff) {
357  finalData[col] = 0xffffffff;
358  } else if (bmmData[col] == 0xff000000 && bmData[col] == 0xffffffff) {
359  finalData[col] = 0x7f000000;
360  } else if (bmmData[col] == 0xffffffff && bmData[col] == 0xffffffff) {
361  finalData[col] = 0x00000000;
362  } else {
363  finalData[col] = 0xff000000;
364  }
365  }
366  }
367  type = QCursorData::TYPE_ImageCursor;
368  curs.cp.my_cursor = true;
369  QPixmap bmCopy = QPixmap::fromImage(finalCursor);
370  NSPoint hotSpot = { hx, hy };
371  nsimage = static_cast<NSImage*>(qt_mac_create_nsimage(bmCopy));
372  curs.cp.nscursor = [[NSCursor alloc] initWithImage:nsimage hotSpot: hotSpot];
373  [nsimage release];
374 }
375 
376 void QCursorData::initCursorFromPixmap()
377 {
378  type = QCursorData::TYPE_ImageCursor;
379  curs.cp.my_cursor = true;
380  NSPoint hotSpot = { hx, hy };
381  NSImage *nsimage;
382  nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
383  curs.cp.nscursor = [[NSCursor alloc] initWithImage:nsimage hotSpot: hotSpot];
384  [nsimage release];
385 }
386 
388 {
391  if(type != QCursorData::TYPE_None)
392  return;
393 
394  /* Note to self... ***
395  * mask x data
396  * 0xFF x 0x00 == fully opaque white
397  * 0x00 x 0xFF == xor'd black
398  * 0xFF x 0xFF == fully opaque black
399  * 0x00 x 0x00 == fully transparent
400  */
401 
402  if (hx < 0)
403  hx = 0;
404  if (hy < 0)
405  hy = 0;
406 
407 #define QT_USE_APPROXIMATE_CURSORS
408 #ifdef QT_USE_APPROXIMATE_CURSORS
409  static const uchar cur_ver_bits[] = {
410  0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0,
411  0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x0f, 0xf0,
412  0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00, 0x00 };
413  static const uchar mcur_ver_bits[] = {
414  0x00, 0x00, 0x03, 0x80, 0x07, 0xc0, 0x0f, 0xe0, 0x1f, 0xf0, 0x3f, 0xf8,
415  0x7f, 0xfc, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x7f, 0xfc, 0x3f, 0xf8,
416  0x1f, 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80 };
417 
418  static const uchar cur_hor_bits[] = {
419  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x18, 0x30,
420  0x38, 0x38, 0x7f, 0xfc, 0x7f, 0xfc, 0x38, 0x38, 0x18, 0x30, 0x08, 0x20,
421  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
422  static const uchar mcur_hor_bits[] = {
423  0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x0c, 0x60, 0x1c, 0x70, 0x3c, 0x78,
424  0x7f, 0xfc, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0x7f, 0xfc, 0x3c, 0x78,
425  0x1c, 0x70, 0x0c, 0x60, 0x04, 0x40, 0x00, 0x00 };
426 
427  static const uchar cur_fdiag_bits[] = {
428  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0x78,
429  0x00, 0xf8, 0x01, 0xd8, 0x23, 0x88, 0x37, 0x00, 0x3e, 0x00, 0x3c, 0x00,
430  0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00 };
431  static const uchar mcur_fdiag_bits[] = {
432  0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0xfc,
433  0x41, 0xfc, 0x63, 0xfc, 0x77, 0xdc, 0x7f, 0x8c, 0x7f, 0x04, 0x7e, 0x00,
434  0x7f, 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x00, 0x00 };
435 
436  static const uchar cur_bdiag_bits[] = {
437  0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e, 0x00,
438  0x37, 0x00, 0x23, 0x88, 0x01, 0xd8, 0x00, 0xf8, 0x00, 0x78, 0x00, 0xf8,
439  0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
440  static const uchar mcur_bdiag_bits[] = {
441  0x00, 0x00, 0x7f, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7e, 0x00, 0x7f, 0x04,
442  0x7f, 0x8c, 0x77, 0xdc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01, 0xfc,
443  0x03, 0xfc, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00 };
444 
445  static const unsigned char cur_up_arrow_bits[] = {
446  0x00, 0x80, 0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0x02, 0x20, 0x04, 0x10,
447  0x04, 0x10, 0x08, 0x08, 0x0f, 0x78, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40,
448  0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0xc0 };
449  static const unsigned char mcur_up_arrow_bits[] = {
450  0x00, 0x80, 0x01, 0xc0, 0x01, 0xc0, 0x03, 0xe0, 0x03, 0xe0, 0x07, 0xf0,
451  0x07, 0xf0, 0x0f, 0xf8, 0x0f, 0xf8, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0,
452  0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0 };
453 #endif
454  const uchar *cursorData = 0;
455  const uchar *cursorMaskData = 0;
456 #ifdef QT_MAC_USE_COCOA
457  switch (cshape) { // map Q cursor to MAC cursor
458  case Qt::BitmapCursor: {
459  if (pixmap.isNull())
460  initCursorFromBitmap();
461  else
462  initCursorFromPixmap();
463  break; }
464  case Qt::BlankCursor: {
465  pixmap = QPixmap(16, 16);
467  initCursorFromPixmap();
468  break; }
469  case Qt::ArrowCursor: {
470  type = QCursorData::TYPE_ThemeCursor;
471  curs.cp.nscursor = [NSCursor arrowCursor];
472  break; }
473  case Qt::CrossCursor: {
474  type = QCursorData::TYPE_ThemeCursor;
475  curs.cp.nscursor = [NSCursor crosshairCursor];
476  break; }
477  case Qt::WaitCursor: {
478  pixmap = QPixmap(QLatin1String(":/trolltech/mac/cursors/images/spincursor.png"));
479  initCursorFromPixmap();
480  break; }
481  case Qt::IBeamCursor: {
482  type = QCursorData::TYPE_ThemeCursor;
483  curs.cp.nscursor = [NSCursor IBeamCursor];
484  break; }
485  case Qt::SizeAllCursor: {
486  pixmap = QPixmap(QLatin1String(":/trolltech/mac/cursors/images/pluscursor.png"));
487  initCursorFromPixmap();
488  break; }
489  case Qt::WhatsThisCursor: { //for now just use the pointing hand
491  type = QCursorData::TYPE_ThemeCursor;
492  curs.cp.nscursor = [NSCursor pointingHandCursor];
493  break; }
494  case Qt::BusyCursor: {
495  pixmap = QPixmap(QLatin1String(":/trolltech/mac/cursors/images/waitcursor.png"));
496  initCursorFromPixmap();
497  break; }
498  case Qt::SplitVCursor: {
499  type = QCursorData::TYPE_ThemeCursor;
500  curs.cp.nscursor = [NSCursor resizeUpDownCursor];
501  break; }
502  case Qt::SplitHCursor: {
503  type = QCursorData::TYPE_ThemeCursor;
504  curs.cp.nscursor = [NSCursor resizeLeftRightCursor];
505  break; }
506  case Qt::ForbiddenCursor: {
507  pixmap = QPixmap(QLatin1String(":/trolltech/mac/cursors/images/forbiddencursor.png"));
508  initCursorFromPixmap();
509  break; }
510  case Qt::OpenHandCursor:
511  type = QCursorData::TYPE_ThemeCursor;
512  curs.cp.nscursor = [NSCursor openHandCursor];
513  break;
515  type = QCursorData::TYPE_ThemeCursor;
516  curs.cp.nscursor = [NSCursor closedHandCursor];
517  break;
518  case Qt::DragCopyCursor:
519  type = QCursorData::TYPE_ThemeCursor;
520  if ([NSCursor respondsToSelector:@selector(dragCopyCursor)])
521  curs.cp.nscursor = [NSCursor performSelector:@selector(dragCopyCursor)];
522  break;
523  case Qt::DragMoveCursor:
524  type = QCursorData::TYPE_ThemeCursor;
525  curs.cp.nscursor = [NSCursor arrowCursor];
526  break;
527  case Qt::DragLinkCursor:
528  type = QCursorData::TYPE_ThemeCursor;
529  if ([NSCursor respondsToSelector:@selector(dragLinkCursor)])
530  curs.cp.nscursor = [NSCursor performSelector:@selector(dragLinkCursor)];
531  break;
532 #define QT_USE_APPROXIMATE_CURSORS
533 #ifdef QT_USE_APPROXIMATE_CURSORS
534  case Qt::SizeVerCursor:
535  cursorData = cur_ver_bits;
536  cursorMaskData = mcur_ver_bits;
537  hx = hy = 8;
538  break;
539  case Qt::SizeHorCursor:
540  cursorData = cur_hor_bits;
541  cursorMaskData = mcur_hor_bits;
542  hx = hy = 8;
543  break;
544  case Qt::SizeBDiagCursor:
545  cursorData = cur_fdiag_bits;
546  cursorMaskData = mcur_fdiag_bits;
547  hx = hy = 8;
548  break;
549  case Qt::SizeFDiagCursor:
550  cursorData = cur_bdiag_bits;
551  cursorMaskData = mcur_bdiag_bits;
552  hx = hy = 8;
553  break;
554  case Qt::UpArrowCursor:
555  cursorData = cur_up_arrow_bits;
556  cursorMaskData = mcur_up_arrow_bits;
557  hx = 8;
558  break;
559 #endif
560  default:
561  qWarning("Qt: QCursor::update: Invalid cursor shape %d", cshape);
562  return;
563  }
564 #else
565  // Carbon
566  switch (cshape) { // map Q cursor to MAC cursor
567  case Qt::BitmapCursor: {
568  if (pixmap.isNull())
569  initCursorFromBitmap();
570  else
571  initCursorFromPixmap();
572  break; }
573  case Qt::BlankCursor: {
574  pixmap = QPixmap(16, 16);
576  initCursorFromPixmap();
577  break; }
578  case Qt::ArrowCursor: {
579  type = QCursorData::TYPE_ThemeCursor;
580  curs.tc.curs = kThemeArrowCursor;
581  break; }
582  case Qt::CrossCursor: {
583  type = QCursorData::TYPE_ThemeCursor;
584  curs.tc.curs = kThemeCrossCursor;
585  break; }
586  case Qt::WaitCursor: {
587  type = QCursorData::TYPE_ThemeCursor;
588  curs.tc.curs = kThemeWatchCursor;
589  break; }
590  case Qt::IBeamCursor: {
591  type = QCursorData::TYPE_ThemeCursor;
592  curs.tc.curs = kThemeIBeamCursor;
593  break; }
594  case Qt::SizeAllCursor: {
595  type = QCursorData::TYPE_ThemeCursor;
596  curs.tc.curs = kThemePlusCursor;
597  break; }
598  case Qt::WhatsThisCursor: { //for now just use the pointing hand
600  type = QCursorData::TYPE_ThemeCursor;
601  curs.tc.curs = kThemePointingHandCursor;
602  break; }
603  case Qt::BusyCursor: {
604  type = QCursorData::TYPE_ThemeCursor;
605  curs.tc.curs = kThemeSpinningCursor;
606  break; }
607  case Qt::SplitVCursor: {
608  type = QCursorData::TYPE_ThemeCursor;
609  curs.tc.curs = kThemeResizeUpDownCursor;
610  break; }
611  case Qt::SplitHCursor: {
612  type = QCursorData::TYPE_ThemeCursor;
613  curs.tc.curs = kThemeResizeLeftRightCursor;
614  break; }
615  case Qt::ForbiddenCursor: {
616  type = QCursorData::TYPE_ThemeCursor;
617  curs.tc.curs = kThemeNotAllowedCursor;
618  break; }
619  case Qt::OpenHandCursor:
620  type = QCursorData::TYPE_ThemeCursor;
621  curs.tc.curs = kThemeOpenHandCursor;
622  break;
624  type = QCursorData::TYPE_ThemeCursor;
625  curs.tc.curs = kThemeClosedHandCursor;
626  break;
627  case Qt::DragMoveCursor:
628  type = QCursorData::TYPE_ThemeCursor;
629  curs.tc.curs = kThemeArrowCursor;
630  break;
631  case Qt::DragCopyCursor:
632  type = QCursorData::TYPE_ThemeCursor;
633  curs.tc.curs = kThemeCopyArrowCursor;
634  break;
635  case Qt::DragLinkCursor:
636  type = QCursorData::TYPE_ThemeCursor;
637  curs.tc.curs = kThemeAliasArrowCursor;
638  break;
639 #define QT_USE_APPROXIMATE_CURSORS
640 #ifdef QT_USE_APPROXIMATE_CURSORS
641  case Qt::SizeVerCursor:
642  cursorData = cur_ver_bits;
643  cursorMaskData = mcur_ver_bits;
644  hx = hy = 8;
645  break;
646  case Qt::SizeHorCursor:
647  cursorData = cur_hor_bits;
648  cursorMaskData = mcur_hor_bits;
649  hx = hy = 8;
650  break;
651  case Qt::SizeBDiagCursor:
652  cursorData = cur_fdiag_bits;
653  cursorMaskData = mcur_fdiag_bits;
654  hx = hy = 8;
655  break;
656  case Qt::SizeFDiagCursor:
657  cursorData = cur_bdiag_bits;
658  cursorMaskData = mcur_bdiag_bits;
659  hx = hy = 8;
660  break;
661  case Qt::UpArrowCursor:
662  cursorData = cur_up_arrow_bits;
663  cursorMaskData = mcur_up_arrow_bits;
664  hx = 8;
665  break;
666 #endif
667  default:
668  qWarning("Qt: QCursor::update: Invalid cursor shape %d", cshape);
669  return;
670  }
671 #endif
672 
673  if (cursorData) {
674  bm = new QBitmap(QBitmap::fromData(QSize(16, 16), cursorData,
676  bmm = new QBitmap(QBitmap::fromData(QSize(16, 16), cursorMaskData,
678  initCursorFromBitmap();
679  }
680 
681 #if 0
682  if(type == QCursorData::TYPE_CursPtr && curs.cp.hcurs && curs.cp.my_cursor) {
683  curs.cp.hcurs->hotSpot.h = hx >= 0 ? hx : 8;
684  curs.cp.hcurs->hotSpot.v = hy >= 0 ? hy : 8;
685  }
686 #endif
687 }
688 
void qt_mac_updateCursorWithWidgetUnderMouse(QWidget *widgetUnderMouse)
Definition: qcursor_mac.mm:144
int startTimer(int interval)
Starts a timer and returns a timer identifier, or returns zero if it could not start a timer...
Definition: qobject.cpp:1623
void qt_mac_set_cursor(const QCursor *c)
Definition: qcursor_mac.mm:108
HCURSOR_or_HANDLE handle() const
Returns a platform-specific cursor handle.
Definition: qcursor_mac.mm:301
double d
Definition: qnumeric_p.h:62
QImage toImage() const
Converts the pixmap to a QImage.
Definition: qpixmap.cpp:542
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
Definition: qpixmap.cpp:2197
unsigned int QRgb
Definition: qrgb.h:53
int type
Definition: qmetatype.cpp:239
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition: qcursor.h:89
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static QPointer< QWidget > lastWidgetUnderMouse
Definition: qcursor_mac.mm:139
static QPointer< QWidget > lastMouseCursorWidget
Definition: qcursor_mac.mm:140
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
QPointer< QWidget > widget
QSize size() const
Returns the size of the pixmap.
Definition: qpixmap.cpp:661
short hy
Definition: qcursor_p.h:91
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
void start(ThemeCursor c)
Definition: qcursor_mac.mm:76
void * qt_mac_nsCursorForQCursor(const QCursor &c)
Definition: qcursor_mac.mm:100
void qt_mac_update_cursor()
Definition: qcursor_mac.mm:201
QPixmap pixmap
Definition: qcursor_p.h:90
static const uchar cur_bdiag_bits[]
static QBitmap fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat=QImage::Format_MonoLSB)
Constructs a bitmap with the given size, and sets the contents to the bits supplied.
Definition: qbitmap.cpp:318
static const uchar cur_hor_bits[]
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
void * qt_mac_create_nsimage(const QPixmap &pm)
bool ref()
Atomically increments the value of this QAtomicInt.
static const uchar mcur_ver_bits[]
static bool initialized
Definition: qcursor_p.h:125
int depth() const
Returns the depth of the pixmap.
Definition: qpixmap.cpp:695
QPointF flipPoint(const NSPoint &p)
static void setPos(int x, int y)
Moves the cursor (hot spot) to the global screen position (x, y).
Definition: qcursor_mac.mm:315
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
GrafPtr qt_mac_qd_context(const QPaintDevice *)
Returns the QuickDraw CGrafPtr of the paint device.
static const uchar mcur_hor_bits[]
static QWidget * widgetAt(const QPoint &p)
Returns the widget at global screen position point, or 0 if there is no Qt widget there...
static QCursorData * setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
Definition: qcursor_mac.mm:278
unsigned char uchar
Definition: qglobal.h:994
The QBitmap class provides monochrome (1-bit depth) pixmaps.
Definition: qbitmap.h:55
void timerEvent(QTimerEvent *e)
This event handler can be reimplemented in a subclass to receive timer events for the object...
Definition: qcursor_mac.mm:90
static QCursor * overrideCursor()
Strips out vertical alignment flags and transforms an alignment align of Qt::AlignLeft into Qt::Align...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QCursorData(Qt::CursorShape s=Qt::ArrowCursor)
Definition: qcursor_mac.mm:253
WindowRef OSWindowRef
static QWidget * mouseGrabber()
Returns the widget that is currently grabbing the mouse input.
static QCursorData * currentCursor
Definition: qcursor_mac.mm:106
void qt_mac_setMouseGrabCursor(bool set, QCursor *const cursor=0)
Definition: qcursor_mac.mm:227
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
Q_CORE_EXPORT void qWarning(const char *,...)
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
Definition: qcoreevent.h:346
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
static const unsigned char cur_up_arrow_bits[]
QCursor cursor
the cursor shape for this widget
Definition: qwidget.h:183
void * HANDLE
Definition: qnamespace.h:1671
void update()
Creates the cursor.
Definition: qcursor_mac.mm:387
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:85
static bool qt_button_down_on_prev_call
Definition: qcursor_mac.mm:141
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
Definition: qpixmap.cpp:1080
Qt::CursorShape cshape
Definition: qcursor_p.h:88
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
static Qt::KeyboardModifiers keyboardModifiers()
Returns the current state of the modifier keys on the keyboard.
static int nextCursorId
Definition: qcursor_mac.mm:251
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:341
QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition: qpoint.h:376
CursorShape
Definition: qnamespace.h:1262
struct CGPoint NSPoint
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QCursorData * d
Definition: qcursor.h:141
short hx
Definition: qcursor_p.h:91
void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos)
Definition: qcursor_mac.mm:245
QPoint mapFromGlobal(const QPoint &) const
Translates the global screen coordinate pos to widget coordinates.
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
static QCursor * grabCursor
Definition: qcursor_mac.mm:142
QBitmap * bmm
Definition: qcursor_p.h:89
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
static void initialize()
Definition: qcursor.cpp:417
static const unsigned char mcur_up_arrow_bits[]
QAtomicInt ref
Definition: qcursor_p.h:87
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
static const uchar mcur_bdiag_bits[]
static Qt::MouseButtons mouseButtons()
Returns the current state of the buttons on the mouse.
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition: qpixmap.cpp:615
QBitmap * bm
Definition: qcursor_p.h:89
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
static const uchar cur_ver_bits[]
QPointer< QWidget > qt_button_down
ThemeCursor curs
Definition: qcursor_mac.mm:73
static const uchar mcur_fdiag_bits[]
QCursorData * qt_cursorTable[Qt::LastCursor+1]
Definition: qcursor.cpp:398
OSWindowRef qt_mac_window_for(const QWidget *)
Definition: qwidget_mac.mm:484
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
bool qt_sendSpontaneousEvent(QObject *, QEvent *)
static QPoint pos()
Returns the position of the cursor (hot spot) in global screen coordinates.
Definition: qcursor_mac.mm:310
qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, 0, &widgetToGetTouch)
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition: qobject.cpp:1650
static const uchar cur_fdiag_bits[]