source: trunk/src/gui/kernel/qt_cocoa_helpers_mac.mm@ 345

Last change on this file since 345 was 2, checked in by Dmitry A. Kuminov, 17 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 41.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/****************************************************************************
43**
44** Copyright (c) 2007-2008, Apple, Inc.
45**
46** All rights reserved.
47**
48** Redistribution and use in source and binary forms, with or without
49** modification, are permitted provided that the following conditions are met:
50**
51** * Redistributions of source code must retain the above copyright notice,
52** this list of conditions and the following disclaimer.
53**
54** * Redistributions in binary form must reproduce the above copyright notice,
55** this list of conditions and the following disclaimer in the documentation
56** and/or other materials provided with the distribution.
57**
58** * Neither the name of Apple, Inc. nor the names of its contributors
59** may be used to endorse or promote products derived from this software
60** without specific prior written permission.
61**
62** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
63** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
64** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
65** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
66** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
67** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
68** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
69** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
70** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
71** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73**
74****************************************************************************/
75
76#include <private/qcore_mac_p.h>
77#include <qwidget.h>
78#include <qdesktopwidget.h>
79#include <qevent.h>
80#include <private/qevent_p.h>
81#include <private/qt_cocoa_helpers_mac_p.h>
82#include <private/qt_mac_p.h>
83#include <private/qapplication_p.h>
84#include <private/qcocoawindow_mac_p.h>
85#include <private/qcocoaview_mac_p.h>
86#include <private/qkeymapper_p.h>
87#include <private/qwidget_p.h>
88
89QT_BEGIN_NAMESPACE
90
91extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp;
92extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
93extern QWidget * mac_mouse_grabber;
94
95void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
96{
97 OSWindowRef wnd = static_cast<OSWindowRef>(window);
98 if( wnd ) {
99#if QT_MAC_USE_COCOA
100 QMacCocoaAutoReleasePool pool;
101 [NSAnimationContext beginGrouping];
102 [[wnd animator] setAlphaValue:0.0];
103 if (durationSeconds > 0) {
104 [[NSAnimationContext currentContext] setDuration:NSTimeInterval(durationSeconds)];
105 } else {
106 durationSeconds = [[NSAnimationContext currentContext] duration];
107 }
108 [NSAnimationContext endGrouping];
109 QTimer::singleShot(qRound(durationSeconds * 1000), [wnd QT_MANGLE_NAMESPACE(qt_qwidget)], SLOT(hide()));
110#else
111 if (durationSeconds <= 0)
112 durationSeconds = 0.15;
113 TransitionWindowOptions options = {0, durationSeconds, 0, 0};
114 TransitionWindowWithOptions(wnd, kWindowFadeTransitionEffect, kWindowHideTransitionAction, 0, 1, &options);
115#endif
116 }
117}
118
119
120
121bool macWindowIsTextured( void * /*OSWindowRef*/ window )
122{
123 OSWindowRef wnd = static_cast<OSWindowRef>(window);
124#if QT_MAC_USE_COCOA
125 return ( [wnd styleMask] & NSTexturedBackgroundWindowMask ) ? true : false;
126#else
127 WindowAttributes currentAttributes;
128 GetWindowAttributes(wnd, &currentAttributes);
129 return (currentAttributes & kWindowMetalAttribute) ? true : false;
130#endif
131}
132
133void macWindowToolbarShow(const QWidget *widget, bool show )
134{
135 OSWindowRef wnd = qt_mac_window_for(widget);
136#if QT_MAC_USE_COCOA
137 NSToolbar *toolbar = [wnd toolbar];
138 if (toolbar) {
139 QMacCocoaAutoReleasePool pool;
140 if (show != [toolbar isVisible]) {
141 [wnd toggleToolbarShown:wnd];
142 } else {
143 // The toolbar may be in sync, but we are not, update our framestrut.
144 qt_widget_private(const_cast<QWidget *>(widget))->updateFrameStrut();
145 }
146 }
147#else
148 ShowHideWindowToolbar(wnd, show, false);
149#endif
150}
151
152
153void macWindowToolbarSet( void * /*OSWindowRef*/ window, void *toolbarRef )
154{
155 OSWindowRef wnd = static_cast<OSWindowRef>(window);
156#if QT_MAC_USE_COCOA
157 [wnd setToolbar:static_cast<NSToolbar *>(toolbarRef)];
158#else
159 SetWindowToolbar(wnd, static_cast<HIToolbarRef>(toolbarRef));
160#endif
161}
162
163bool macWindowToolbarVisible( void * /*OSWindowRef*/ window )
164{
165 OSWindowRef wnd = static_cast<OSWindowRef>(window);
166#if QT_MAC_USE_COCOA
167 NSToolbar *toolbar = [wnd toolbar];
168 if (toolbar)
169 return [toolbar isVisible];
170 return false;
171#else
172 return IsWindowToolbarVisible(wnd);
173#endif
174}
175
176void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow )
177{
178 OSWindowRef wnd = static_cast<OSWindowRef>(window);
179#if QT_MAC_USE_COCOA
180 [wnd setHasShadow:BOOL(hasShadow)];
181#else
182 if (hasShadow)
183 ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute);
184 else
185 ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0);
186#endif
187}
188
189void macWindowFlush(void * /*OSWindowRef*/ window)
190{
191 OSWindowRef wnd = static_cast<OSWindowRef>(window);
192#if QT_MAC_USE_COCOA
193 [wnd flushWindowIfNeeded];
194#else
195 HIWindowFlush(wnd);
196#endif
197}
198
199void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm)
200{
201 QMacCocoaAutoReleasePool pool;
202 if(QCFType<CGImageRef> image = pm.toMacCGImageRef()) {
203 NSImage *newImage = 0;
204 NSRect imageRect = NSMakeRect(0.0, 0.0, CGImageGetWidth(image), CGImageGetHeight(image));
205 newImage = [[NSImage alloc] initWithSize:imageRect.size];
206 [newImage lockFocus];
207 {
208 CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
209 CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
210 }
211 [newImage unlockFocus];
212 return newImage;
213 }
214 return 0;
215}
216
217void qt_mac_update_mouseTracking(QWidget *widget)
218{
219#ifdef QT_MAC_USE_COCOA
220 [qt_mac_nativeview_for(widget) updateTrackingAreas];
221#else
222 Q_UNUSED(widget);
223#endif
224}
225
226OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage)
227{
228 // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
229 OSStatus err = noErr;
230
231 require_action(inContext != NULL, InvalidContext, err = paramErr);
232 require_action(inBounds != NULL, InvalidBounds, err = paramErr);
233 require_action(inImage != NULL, InvalidImage, err = paramErr);
234
235 CGContextSaveGState( inContext );
236 CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
237 CGContextScaleCTM(inContext, 1, -1);
238
239 CGContextDrawImage(inContext, *inBounds, inImage);
240
241 CGContextRestoreGState(inContext);
242InvalidImage:
243InvalidBounds:
244InvalidContext:
245 return err;
246}
247
248bool qt_mac_checkForNativeSizeGrip(const QWidget *widget)
249{
250#ifndef QT_MAC_USE_COCOA
251 OSViewRef nativeSizeGrip = 0;
252 HIViewFindByID(HIViewGetRoot(HIViewGetWindow(HIViewRef(widget->winId()))), kHIViewWindowGrowBoxID, &nativeSizeGrip);
253 return (nativeSizeGrip != 0);
254#else
255 return [[reinterpret_cast<NSView *>(widget->winId()) window] showsResizeIndicator];
256#endif
257}
258struct qt_mac_enum_mapper
259{
260 int mac_code;
261 int qt_code;
262#if defined(DEBUG_MOUSE_MAPS)
263# define QT_MAC_MAP_ENUM(x) x, #x
264 const char *desc;
265#else
266# define QT_MAC_MAP_ENUM(x) x
267#endif
268};
269
270//mouse buttons
271static qt_mac_enum_mapper qt_mac_mouse_symbols[] = {
272{ kEventMouseButtonPrimary, QT_MAC_MAP_ENUM(Qt::LeftButton) },
273{ kEventMouseButtonSecondary, QT_MAC_MAP_ENUM(Qt::RightButton) },
274{ kEventMouseButtonTertiary, QT_MAC_MAP_ENUM(Qt::MidButton) },
275{ 4, QT_MAC_MAP_ENUM(Qt::XButton1) },
276{ 5, QT_MAC_MAP_ENUM(Qt::XButton2) },
277{ 0, QT_MAC_MAP_ENUM(0) }
278};
279Qt::MouseButtons qt_mac_get_buttons(int buttons)
280{
281#ifdef DEBUG_MOUSE_MAPS
282 qDebug("Qt: internal: **Mapping buttons: %d (0x%04x)", buttons, buttons);
283#endif
284 Qt::MouseButtons ret = Qt::NoButton;
285 for(int i = 0; qt_mac_mouse_symbols[i].qt_code; i++) {
286 if (buttons & (0x01<<(qt_mac_mouse_symbols[i].mac_code-1))) {
287#ifdef DEBUG_MOUSE_MAPS
288 qDebug("Qt: internal: got button: %s", qt_mac_mouse_symbols[i].desc);
289#endif
290 ret |= Qt::MouseButtons(qt_mac_mouse_symbols[i].qt_code);
291 }
292 }
293 return ret;
294}
295Qt::MouseButton qt_mac_get_button(EventMouseButton button)
296{
297#ifdef DEBUG_MOUSE_MAPS
298 qDebug("Qt: internal: **Mapping button: %d (0x%04x)", button, button);
299#endif
300 Qt::MouseButtons ret = 0;
301 for(int i = 0; qt_mac_mouse_symbols[i].qt_code; i++) {
302 if (button == qt_mac_mouse_symbols[i].mac_code) {
303#ifdef DEBUG_MOUSE_MAPS
304 qDebug("Qt: internal: got button: %s", qt_mac_mouse_symbols[i].desc);
305#endif
306 return Qt::MouseButton(qt_mac_mouse_symbols[i].qt_code);
307 }
308 }
309 return Qt::NoButton;
310}
311
312Q_GLOBAL_STATIC(QMacTabletHash, tablet_hash)
313QMacTabletHash *qt_mac_tablet_hash()
314{
315 return tablet_hash();
316}
317
318#ifdef QT_MAC_USE_COCOA
319void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent)
320{
321 NSEvent *proximityEvent = static_cast<NSEvent *>(tabletEvent);
322 // simply construct a Carbon proximity record and handle it all in one spot.
323 TabletProximityRec carbonProximityRec = { [proximityEvent vendorID],
324 [proximityEvent tabletID],
325 [proximityEvent pointingDeviceID],
326 [proximityEvent deviceID],
327 [proximityEvent systemTabletID],
328 [proximityEvent vendorPointingDeviceType],
329 [proximityEvent pointingDeviceSerialNumber],
330 [proximityEvent uniqueID],
331 [proximityEvent capabilityMask],
332 [proximityEvent pointingDeviceType],
333 [proximityEvent isEnteringProximity] };
334 qt_dispatchTabletProximityEvent(carbonProximityRec);
335}
336#endif // QT_MAC_USE_COCOA
337
338void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec)
339{
340 QTabletDeviceData proximityDevice;
341 proximityDevice.tabletUniqueID = proxRec.uniqueID;
342 proximityDevice.capabilityMask = proxRec.capabilityMask;
343
344 switch (proxRec.pointerType) {
345 case NSUnknownPointingDevice:
346 default:
347 proximityDevice.tabletPointerType = QTabletEvent::UnknownPointer;
348 break;
349 case NSPenPointingDevice:
350 proximityDevice.tabletPointerType = QTabletEvent::Pen;
351 break;
352 case NSCursorPointingDevice:
353 proximityDevice.tabletPointerType = QTabletEvent::Cursor;
354 break;
355 case NSEraserPointingDevice:
356 proximityDevice.tabletPointerType = QTabletEvent::Eraser;
357 break;
358 }
359 uint bits = proxRec.vendorPointerType;
360 if (bits == 0 && proximityDevice.tabletUniqueID != 0) {
361 // Fallback. It seems that the driver doesn't always include all the information.
362 // High-End Wacom devices store their "type" in the uper bits of the Unique ID.
363 // I'm not sure how to handle it for consumer devices, but I'll test that in a bit.
364 bits = proximityDevice.tabletUniqueID >> 32;
365 }
366 // Defined in the "EN0056-NxtGenImpGuideX"
367 // on Wacom's Developer Website (www.wacomeng.com)
368 if (((bits & 0x0006) == 0x0002) && ((bits & 0x0F06) != 0x0902)) {
369 proximityDevice.tabletDeviceType = QTabletEvent::Stylus;
370 } else {
371 switch (bits & 0x0F06) {
372 case 0x0802:
373 proximityDevice.tabletDeviceType = QTabletEvent::Stylus;
374 break;
375 case 0x0902:
376 proximityDevice.tabletDeviceType = QTabletEvent::Airbrush;
377 break;
378 case 0x0004:
379 proximityDevice.tabletDeviceType = QTabletEvent::FourDMouse;
380 break;
381 case 0x0006:
382 proximityDevice.tabletDeviceType = QTabletEvent::Puck;
383 break;
384 case 0x0804:
385 proximityDevice.tabletDeviceType = QTabletEvent::RotationStylus;
386 break;
387 default:
388 proximityDevice.tabletDeviceType = QTabletEvent::NoDevice;
389 }
390 }
391 // The deviceID is "unique" while in the proximity, it's a key that we can use for
392 // linking up TabletDeviceData to an event (especially if there are two devices in action).
393 bool entering = proxRec.enterProximity;
394 if (entering) {
395 qt_mac_tablet_hash()->insert(proxRec.deviceID, proximityDevice);
396 } else {
397 qt_mac_tablet_hash()->remove(proxRec.deviceID);
398 }
399
400 QTabletEvent qtabletProximity(entering ? QEvent::TabletEnterProximity
401 : QEvent::TabletLeaveProximity,
402 QPoint(), QPoint(), QPointF(), proximityDevice.tabletDeviceType,
403 proximityDevice.tabletPointerType, 0., 0, 0, 0., 0., 0, 0,
404 proximityDevice.tabletUniqueID);
405
406 qt_sendSpontaneousEvent(qApp, &qtabletProximity);
407}
408
409#ifdef QT_MAC_USE_COCOA
410// Use this method to keep all the information in the TextSegment. As long as it is ordered
411// we are in OK shape, and we can influence that ourselves.
412struct KeyPair
413{
414 QChar cocoaKey;
415 Qt::Key qtKey;
416};
417
418bool operator==(const KeyPair &entry, QChar qchar)
419{
420 return entry.cocoaKey == qchar;
421}
422
423bool operator<(const KeyPair &entry, QChar qchar)
424{
425 return entry.cocoaKey < qchar;
426}
427
428bool operator<(QChar qchar, const KeyPair &entry)
429{
430 return qchar < entry.cocoaKey;
431}
432
433static Qt::Key cocoaKey2QtKey(QChar keyCode)
434{
435 static const int NumEntries = 57;
436 static const KeyPair entries[NumEntries] = {
437 { NSEnterCharacter, Qt::Key_Enter },
438 { NSTabCharacter, Qt::Key_Tab },
439 { NSCarriageReturnCharacter, Qt::Key_Return },
440 { NSBackTabCharacter, Qt::Key_Backtab },
441 { kEscapeCharCode, Qt::Key_Escape },
442 { NSDeleteCharacter, Qt::Key_Backspace },
443 { NSUpArrowFunctionKey, Qt::Key_Up },
444 { NSDownArrowFunctionKey, Qt::Key_Down },
445 { NSLeftArrowFunctionKey, Qt::Key_Left },
446 { NSRightArrowFunctionKey, Qt::Key_Right },
447 { NSF1FunctionKey, Qt::Key_F1 },
448 { NSF2FunctionKey, Qt::Key_F2 },
449 { NSF3FunctionKey, Qt::Key_F3 },
450 { NSF4FunctionKey, Qt::Key_F4 },
451 { NSF5FunctionKey, Qt::Key_F5 },
452 { NSF6FunctionKey, Qt::Key_F6 },
453 { NSF7FunctionKey, Qt::Key_F7 },
454 { NSF8FunctionKey, Qt::Key_F8 },
455 { NSF9FunctionKey, Qt::Key_F8 },
456 { NSF10FunctionKey, Qt::Key_F10 },
457 { NSF11FunctionKey, Qt::Key_F11 },
458 { NSF12FunctionKey, Qt::Key_F12 },
459 { NSF13FunctionKey, Qt::Key_F13 },
460 { NSF14FunctionKey, Qt::Key_F14 },
461 { NSF15FunctionKey, Qt::Key_F15 },
462 { NSF16FunctionKey, Qt::Key_F16 },
463 { NSF17FunctionKey, Qt::Key_F17 },
464 { NSF18FunctionKey, Qt::Key_F18 },
465 { NSF19FunctionKey, Qt::Key_F19 },
466 { NSF20FunctionKey, Qt::Key_F20 },
467 { NSF21FunctionKey, Qt::Key_F21 },
468 { NSF22FunctionKey, Qt::Key_F22 },
469 { NSF23FunctionKey, Qt::Key_F23 },
470 { NSF24FunctionKey, Qt::Key_F24 },
471 { NSF25FunctionKey, Qt::Key_F25 },
472 { NSF26FunctionKey, Qt::Key_F26 },
473 { NSF27FunctionKey, Qt::Key_F27 },
474 { NSF28FunctionKey, Qt::Key_F28 },
475 { NSF29FunctionKey, Qt::Key_F29 },
476 { NSF30FunctionKey, Qt::Key_F30 },
477 { NSF31FunctionKey, Qt::Key_F31 },
478 { NSF32FunctionKey, Qt::Key_F32 },
479 { NSF33FunctionKey, Qt::Key_F33 },
480 { NSF34FunctionKey, Qt::Key_F34 },
481 { NSF35FunctionKey, Qt::Key_F35 },
482 { NSInsertFunctionKey, Qt::Key_Insert },
483 { NSDeleteFunctionKey, Qt::Key_Delete },
484 { NSHomeFunctionKey, Qt::Key_Home },
485 { NSEndFunctionKey, Qt::Key_End },
486 { NSPageUpFunctionKey, Qt::Key_PageUp },
487 { NSPageDownFunctionKey, Qt::Key_PageDown },
488 { NSPrintScreenFunctionKey, Qt::Key_Print },
489 { NSScrollLockFunctionKey, Qt::Key_ScrollLock },
490 { NSPauseFunctionKey, Qt::Key_Pause },
491 { NSSysReqFunctionKey, Qt::Key_SysReq },
492 { NSMenuFunctionKey, Qt::Key_Menu },
493 { NSHelpFunctionKey, Qt::Key_Help },
494 };
495 static const KeyPair * const end = entries + NumEntries;
496 const KeyPair *i = qBinaryFind(entries, end, keyCode);
497 if (i == end)
498 return Qt::Key(keyCode.unicode());
499 return i->qtKey;
500}
501
502Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags)
503{
504 Qt::KeyboardModifiers qtMods =Qt::NoModifier;
505 if (modifierFlags & NSShiftKeyMask)
506 qtMods |= Qt::ShiftModifier;
507 if (modifierFlags & NSControlKeyMask)
508 qtMods |= Qt::MetaModifier;
509 if (modifierFlags & NSAlternateKeyMask)
510 qtMods |= Qt::AltModifier;
511 if (modifierFlags & NSCommandKeyMask)
512 qtMods |= Qt::ControlModifier;
513 if (modifierFlags & NSNumericPadKeyMask)
514 qtMods |= Qt::KeypadModifier;
515 return qtMods;
516}
517
518static inline QEvent::Type cocoaEvent2QtEvent(NSUInteger eventType)
519{
520 // Handle the trivial cases that can be determined from the type.
521 switch (eventType) {
522 case NSKeyDown:
523 return QEvent::KeyPress;
524 case NSKeyUp:
525 return QEvent::KeyRelease;
526 case NSLeftMouseDown:
527 case NSRightMouseDown:
528 case NSOtherMouseDown:
529 return QEvent::MouseButtonPress;
530 case NSLeftMouseUp:
531 case NSRightMouseUp:
532 case NSOtherMouseUp:
533 return QEvent::MouseButtonRelease;
534 case NSMouseMoved:
535 case NSLeftMouseDragged:
536 case NSRightMouseDragged:
537 case NSOtherMouseDragged:
538 return QEvent::MouseMove;
539 case NSScrollWheel:
540 return QEvent::Wheel;
541 }
542 return QEvent::None;
543}
544
545static bool mustUseCocoaKeyEvent()
546{
547 QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource();
548 return TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData) == 0;
549}
550
551bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent)
552{
553 NSEvent *event = static_cast<NSEvent *>(keyEvent);
554 NSString *keyChars = [event charactersIgnoringModifiers];
555 int keyLength = [keyChars length];
556 if (keyLength == 0)
557 return false; // Dead Key, nothing to do!
558 bool ignoreText = false;
559 Qt::Key qtKey = Qt::Key_unknown;
560 if (keyLength == 1) {
561 QChar ch([keyChars characterAtIndex:0]);
562 if (ch.isLower())
563 ch = ch.toUpper();
564 qtKey = cocoaKey2QtKey(ch);
565 // Do not set the text for Function-Key Unicodes characters (0xF700–0xF8FF).
566 ignoreText = (ch.unicode() >= 0xF700 && ch.unicode() <= 0xF8FF);
567 }
568 Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]);
569 QString text;
570
571 // To quote from the Carbon port: This is actually wrong--but it is the best that
572 // can be done for now because of the Control/Meta mapping issues
573 // (we always get text on the Mac)
574 if (!ignoreText && !(keyMods & (Qt::ControlModifier | Qt::MetaModifier)))
575 text = QCFString::toQString(reinterpret_cast<CFStringRef>(keyChars));
576
577 UInt32 macScanCode = 1;
578 QKeyEventEx ke(cocoaEvent2QtEvent([event type]), qtKey, keyMods, text, [event isARepeat], qMax(1, keyLength),
579 macScanCode, [event keyCode], [event modifierFlags]);
580 qt_sendSpontaneousEvent(widgetToGetEvent, &ke);
581 return ke.isAccepted();
582}
583#endif
584
585// Helper to share code between QCocoaWindow and QCocoaView
586bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent)
587{
588#ifndef QT_MAC_USE_COCOA
589 Q_UNUSED(keyEvent);
590 Q_UNUSED(widgetToGetEvent);
591 return false;
592#else
593 NSEvent *event = static_cast<NSEvent *>(keyEvent);
594 EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef]));
595 Q_ASSERT(key_event);
596 if ([event type] == NSKeyDown) {
597 qt_keymapper_private()->updateKeyMap(0, key_event, 0);
598 }
599 if (widgetToGetEvent == 0)
600 return false;
601
602 if (qt_mac_sendMacEventToWidget(widgetToGetEvent, key_event))
603 return true;
604
605 if (mustUseCocoaKeyEvent())
606 return qt_dispatchKeyEventWithCocoa(keyEvent, widgetToGetEvent);
607 bool isAccepted;
608 qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &isAccepted, true);
609 return isAccepted;
610#endif
611}
612
613void qt_dispatchModifiersChanged(void * /*NSEvent * */flagsChangedEvent, QWidget *widgetToGetEvent)
614{
615#ifndef QT_MAC_USE_COCOA
616 Q_UNUSED(flagsChangedEvent);
617 Q_UNUSED(widgetToGetEvent);
618#else
619 UInt32 modifiers = 0;
620 // Sync modifiers with Qt
621 NSEvent *event = static_cast<NSEvent *>(flagsChangedEvent);
622 EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef]));
623 Q_ASSERT(key_event);
624 GetEventParameter(key_event, kEventParamKeyModifiers, typeUInt32, 0,
625 sizeof(modifiers), 0, &modifiers);
626 extern void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object);
627 qt_mac_send_modifiers_changed(modifiers, widgetToGetEvent);
628#endif
629}
630
631
632QPointF flipPoint(const NSPoint &p)
633{
634 return QPointF(p.x, flipYCoordinate(p.y));
635}
636
637NSPoint flipPoint(const QPoint &p)
638{
639 return NSMakePoint(p.x(), flipYCoordinate(p.y()));
640}
641
642NSPoint flipPoint(const QPointF &p)
643{
644 return NSMakePoint(p.x(), flipYCoordinate(p.y()));
645}
646
647void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /* NSEvent* */mouseEvent,
648 QWidget *widgetToGetEvent, bool &leftButtonIsRightButton)
649{
650#ifndef QT_MAC_USE_COCOA
651 Q_UNUSED(eventWindow);
652 Q_UNUSED(mouseEvent);
653 Q_UNUSED(widgetToGetEvent);
654 Q_UNUSED(leftButtonIsRightButton);
655#else
656 if (widgetToGetEvent == 0)
657 return;
658 NSWindow *window = static_cast<NSWindow *>(eventWindow);
659 NSEvent *event = static_cast<NSEvent *>(mouseEvent);
660 NSEventType evtType = [event type];
661
662 QPoint qlocalPoint;
663 QPoint qglobalPoint;
664 bool processThisEvent = false;
665 bool fakeNCEvents = false;
666 bool fakeMouseEvents = false;
667
668 // Check if this is a mouse event.
669 if (evtType == NSLeftMouseDown || evtType == NSLeftMouseUp
670 || evtType == NSRightMouseDown || evtType == NSRightMouseUp
671 || evtType == NSOtherMouseDown || evtType == NSOtherMouseUp
672 || evtType == NSMouseMoved || evtType == NSLeftMouseDragged
673 || evtType == NSRightMouseDragged || evtType == NSOtherMouseDragged) {
674 // Check if we want to pass this message to another window
675 if (mac_mouse_grabber && mac_mouse_grabber != widgetToGetEvent) {
676 NSWindow *grabWindow = static_cast<NSWindow *>(qt_mac_window_for(mac_mouse_grabber));
677 if (window != grabWindow) {
678 window = grabWindow;
679 widgetToGetEvent = mac_mouse_grabber;
680 fakeNCEvents = true;
681 }
682 }
683 // Dont generate normal NC mouse events for Left Button dragged
684 if(evtType != NSLeftMouseDragged || fakeNCEvents) {
685 NSPoint windowPoint = [event locationInWindow];
686 NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint];
687 NSRect frameRect = [window frame];
688 if (fakeNCEvents || NSMouseInRect(globalPoint, frameRect, NO)) {
689 NSRect contentRect = [window contentRectForFrameRect:frameRect];
690 if (fakeNCEvents || !NSMouseInRect(globalPoint, contentRect, NO)) {
691 qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
692 qlocalPoint = widgetToGetEvent->mapFromGlobal(qglobalPoint);
693 processThisEvent = true;
694 }
695 }
696 }
697 }
698 // This is not an NC area mouse message.
699 if (!processThisEvent)
700 return;
701 // If the window is frame less, generate fake mouse events instead. (floating QToolBar)
702 if (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint))
703 fakeMouseEvents = true;
704
705 Qt::MouseButton button;
706 QEvent::Type eventType;
707 // Convert to Qt::Event type
708 switch (evtType) {
709 case NSLeftMouseDown:
710 button = Qt::LeftButton;
711 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
712 : QEvent::MouseButtonPress;
713 break;
714 case NSLeftMouseUp:
715 button = Qt::LeftButton;
716 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
717 : QEvent::MouseButtonRelease;
718 break;
719 case NSRightMouseDown:
720 button = Qt::RightButton;
721 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
722 : QEvent::MouseButtonPress;
723 break;
724 case NSRightMouseUp:
725 button = Qt::RightButton;
726 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
727 : QEvent::MouseButtonRelease;
728 break;
729 case NSOtherMouseDown:
730 button = cocoaButton2QtButton([event buttonNumber]);
731 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
732 : QEvent::MouseButtonPress;
733 break;
734 case NSOtherMouseUp:
735 button = cocoaButton2QtButton([event buttonNumber]);
736 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
737 : QEvent::MouseButtonRelease;
738 break;
739 case NSMouseMoved:
740 button = Qt::NoButton;
741 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
742 : QEvent::MouseMove;
743 break;
744 case NSLeftMouseDragged:
745 button = Qt::LeftButton;
746 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
747 : QEvent::MouseMove;
748 break;
749 case NSRightMouseDragged:
750 button = Qt::RightButton;
751 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
752 : QEvent::MouseMove;
753 break;
754 case NSOtherMouseDragged:
755 button = cocoaButton2QtButton([event buttonNumber]);
756 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
757 : QEvent::MouseMove;
758 break;
759 default:
760 qWarning("not handled! Non client area mouse message");
761 return;
762 }
763
764 Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]);
765 if (eventType == QEvent::NonClientAreaMouseButtonPress || eventType == QEvent::MouseButtonPress) {
766 NSInteger clickCount = [event clickCount];
767 if (clickCount % 2 == 0)
768 eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonDblClick
769 : QEvent::MouseButtonDblClick;
770 if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) {
771 button = Qt::RightButton;
772 leftButtonIsRightButton = true;
773 }
774 } else if (eventType == QEvent::NonClientAreaMouseButtonRelease || eventType == QEvent::MouseButtonRelease) {
775 if (button == Qt::LeftButton && leftButtonIsRightButton) {
776 button = Qt::RightButton;
777 leftButtonIsRightButton = false;
778 }
779 }
780 QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, button, keyMods);
781 qt_sendSpontaneousEvent(widgetToGetEvent, &qme);
782#endif
783}
784
785bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */event, QEvent::Type eventType, Qt::MouseButton button)
786{
787#ifndef QT_MAC_USE_COCOA
788 Q_UNUSED(view);
789 Q_UNUSED(event);
790 Q_UNUSED(eventType);
791 Q_UNUSED(button);
792 return false;
793#else
794 QT_MANGLE_NAMESPACE(QCocoaView) *theView = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view);
795 NSEvent *theEvent = static_cast<NSEvent *>(event);
796
797 // Give the Input Manager a chance to process the mouse events.
798 NSInputManager *currentIManager = [NSInputManager currentInputManager];
799 if (currentIManager && [currentIManager wantsToHandleMouseEvents]) {
800 [currentIManager handleMouseEvent:theEvent];
801 }
802
803 // Handle tablet events (if any) first.
804 if (qt_mac_handleTabletEvent(theView, theEvent)) {
805 // Tablet event was handled. In Qt we aren't supposed to send the mouse event.
806 return true;
807 }
808
809 NSPoint windowPoint = [theEvent locationInWindow];
810 NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
811
812 // Find the widget that *should* get the event (e.g., maybe it was a pop-up,
813 // they always get the mouse event).
814 QWidget *qwidget = [theView qt_qwidget];
815 QWidget *widgetToGetMouse = qwidget;
816 QWidget *popup = qAppInstance()->activePopupWidget();
817 if (popup && popup != qwidget->window())
818 widgetToGetMouse = popup;
819 NSView *tmpView = theView;
820 if (widgetToGetMouse != qwidget) {
821 tmpView = qt_mac_nativeview_for(widgetToGetMouse);
822 windowPoint = [[tmpView window] convertScreenToBase:globalPoint];
823 }
824 NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil];
825 QPoint qlocalPoint(localPoint.x, localPoint.y);
826
827 if (widgetToGetMouse->testAttribute(Qt::WA_TransparentForMouseEvents)) {
828 // Simulate passing the event through since Cocoa doesn't do that for us.
829 // Start by building a tree up.
830 NSView *candidateView = [theView viewUnderTransparentForMouseView:tmpView
831 widget:widgetToGetMouse
832 withWindowPoint:windowPoint];
833 if (candidateView != nil) {
834 // Fast-track our views, since dispatching trough the normal ways
835 // would just end up going through here anyway.
836 if ([candidateView isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) {
837 return qt_mac_handleMouseEvent(candidateView, theEvent, eventType, button);
838 } else {
839 switch (eventType) {
840 default:
841 qWarning("not handled! %d", eventType);
842 break;
843 case QEvent::MouseMove:
844 [candidateView mouseMoved:theEvent];
845 break;
846 case QEvent::MouseButtonPress:
847 if (button == Qt::LeftButton)
848 [candidateView mouseDown:theEvent];
849 else if (button == Qt::RightButton)
850 [candidateView rightMouseDown:theEvent];
851 else
852 [candidateView otherMouseDown:theEvent];
853 break;
854 case QEvent::MouseButtonRelease:
855 if (button == Qt::LeftButton)
856 [candidateView mouseUp:theEvent];
857 else if (button == Qt::RightButton)
858 [candidateView rightMouseUp:theEvent];
859 else
860 [candidateView otherMouseUp:theEvent];
861 break;
862 }
863 return true; // We've done the dispatching, no need go further.
864 }
865 }
866 // Nothing below me return false
867 return false;
868 }
869
870
871 EventRef carbonEvent = static_cast<EventRef>(const_cast<void *>([theEvent eventRef]));
872 if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent))
873 return true;
874
875 // Yay! All the special cases are handled, it really is just a normal mouse event.
876 Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
877 NSInteger clickCount = [theEvent clickCount];
878 Qt::MouseButtons buttons = 0;
879 {
880 UInt32 mac_buttons;
881 if (GetEventParameter(carbonEvent, kEventParamMouseChord, typeUInt32, 0,
882 sizeof(mac_buttons), 0, &mac_buttons) == noErr)
883 buttons = qt_mac_get_buttons(mac_buttons);
884 }
885 switch (eventType) {
886 default:
887 qWarning("not handled! %d", eventType);
888 break;
889 case QEvent::MouseMove:
890 break;
891 case QEvent::MouseButtonPress:
892 [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = theView;
893 [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = theEvent;
894#ifndef QT_NAMESPACE
895 Q_ASSERT(clickCount > 0);
896#endif
897 if (clickCount % 2 == 0)
898 eventType = QEvent::MouseButtonDblClick;
899 if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) {
900 button = Qt::RightButton;
901 [theView qt_setLeftButtonIsRightButton: true];
902 }
903 break;
904 case QEvent::MouseButtonRelease:
905 if (button == Qt::LeftButton && [theView qt_leftButtonIsRightButton]) {
906 button = Qt::RightButton;
907 [theView qt_setLeftButtonIsRightButton: false];
908 }
909 break;
910 }
911 [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint;
912 QPoint qglobalPoint(flipPoint(globalPoint).toPoint());
913 QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods);
914 qt_sendSpontaneousEvent(widgetToGetMouse, &qme);
915 if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) {
916 QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods);
917 qt_sendSpontaneousEvent(widgetToGetMouse, &qcme);
918 }
919 return qme.isAccepted();
920#endif
921}
922
923bool qt_mac_handleTabletEvent(void * /*QCocoaView * */view, void * /*NSEvent * */tabletEvent)
924{
925#ifndef QT_MAC_USE_COCOA
926 Q_UNUSED(view);
927 Q_UNUSED(tabletEvent);
928 return false;
929#else
930 QT_MANGLE_NAMESPACE(QCocoaView) *theView = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view);
931 NSView *theNSView = static_cast<NSView *>(view);
932 NSEvent *theTabletEvent = static_cast<NSEvent *>(tabletEvent);
933
934 NSEventType eventType = [theTabletEvent type];
935 if (eventType != NSTabletPoint && [theTabletEvent subtype] != NSTabletPointEventSubtype)
936 return false; // Not a tablet event.
937
938 NSPoint windowPoint = [theTabletEvent locationInWindow];
939 NSPoint globalPoint = [[theTabletEvent window] convertBaseToScreen:windowPoint];
940
941 QWidget *qwidget = [theView qt_qwidget];
942 QWidget *widgetToGetMouse = qwidget;
943 QWidget *popup = qAppInstance()->activePopupWidget();
944 if (popup && popup != qwidget->window())
945 widgetToGetMouse = popup;
946
947 if (qt_mac_sendMacEventToWidget(widgetToGetMouse,
948 static_cast<EventRef>(const_cast<void *>([theTabletEvent eventRef]))))
949 return true;
950 if (widgetToGetMouse != qwidget) {
951 theNSView = qt_mac_nativeview_for(widgetToGetMouse);
952 windowPoint = [[theNSView window] convertScreenToBase:globalPoint];
953 }
954 NSPoint localPoint = [theNSView convertPoint:windowPoint fromView:nil];
955 // Tablet events do not handle WA_TransparentForMouseEvents ATM
956 // In theory, people who set the WA_TransparentForMouseEvents attribute won't handle
957 // tablet events either in which case they will fall into the mouse event case and get
958 // them passed on. This will NOT handle the raw events, but that might not be a big problem.
959
960 const QMacTabletHash *tabletHash = qt_mac_tablet_hash();
961 if (!tabletHash->contains([theTabletEvent deviceID])) {
962 qWarning("QCocoaView handleTabletEvent: This tablet device is unknown"
963 " (received no proximity event for it). Discarding event.");
964 return false;
965 }
966 const QTabletDeviceData &deviceData = tabletHash->value([theTabletEvent deviceID]);
967
968
969 QEvent::Type qType;
970 switch (eventType) {
971 case NSLeftMouseDown:
972 case NSRightMouseDown:
973 qType = QEvent::TabletPress;
974 break;
975 case NSLeftMouseUp:
976 case NSRightMouseUp:
977 qType = QEvent::TabletRelease;
978 break;
979 case NSMouseMoved:
980 case NSTabletPoint:
981 case NSLeftMouseDragged:
982 case NSRightMouseDragged:
983 default:
984 qType = QEvent::TabletMove;
985 break;
986 }
987
988 qreal pressure;
989 if (eventType != NSMouseMoved) {
990 pressure = [theTabletEvent pressure];
991 } else {
992 pressure = 0.0;
993 }
994
995 NSPoint tilt = [theTabletEvent tilt];
996 int xTilt = qRound(tilt.x * 60.0);
997 int yTilt = qRound(tilt.y * -60.0);
998 qreal tangentialPressure = 0;
999 qreal rotation = 0;
1000 int z = 0;
1001 if (deviceData.capabilityMask & 0x0200)
1002 z = [theTabletEvent absoluteZ];
1003
1004 if (deviceData.capabilityMask & 0x0800)
1005 tangentialPressure = [theTabletEvent tangentialPressure];
1006
1007 rotation = [theTabletEvent rotation];
1008 QPointF hiRes = flipPoint(globalPoint);
1009 QTabletEvent qtabletEvent(qType, QPoint(localPoint.x, localPoint.y),
1010 hiRes.toPoint(), hiRes,
1011 deviceData.tabletDeviceType, deviceData.tabletPointerType,
1012 pressure, xTilt, yTilt, tangentialPressure, rotation, z,
1013 qt_cocoaModifiers2QtModifiers([theTabletEvent modifierFlags]),
1014 deviceData.tabletUniqueID);
1015
1016 qt_sendSpontaneousEvent(widgetToGetMouse, &qtabletEvent);
1017 return qtabletEvent.isAccepted();
1018#endif
1019}
1020
1021void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics)
1022{
1023 OSWindowRef theWindow = static_cast<OSWindowRef>(window);
1024#if !defined(QT_MAC_USE_COCOA)
1025# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
1026 if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
1027 ::HIWindowSetContentBorderThickness(theWindow, &metrics);
1028 }
1029# else
1030 Q_UNUSED(window);
1031 Q_UNUSED(metrics);
1032# endif
1033#else
1034 if ([theWindow styleMask] & NSTexturedBackgroundWindowMask)
1035 [theWindow setContentBorderThickness:metrics.top forEdge:NSMaxYEdge];
1036 [theWindow setContentBorderThickness:metrics.bottom forEdge:NSMinYEdge];
1037#endif
1038}
1039
1040QStringList qt_mac_NSArrayToQStringList(void *nsarray)
1041{
1042 QStringList result;
1043 NSArray *array = static_cast<NSArray *>(nsarray);
1044 for (NSUInteger i=0; i<[array count]; ++i)
1045 result << qt_mac_NSStringToQString([array objectAtIndex:i]);
1046 return result;
1047}
1048
1049void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
1050{
1051 NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()];
1052 for (int i=0; i<list.size(); ++i){
1053 [result addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(list[i]))];
1054 }
1055 return result;
1056}
1057
1058void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow)
1059{
1060 if (!widgetForWindow)
1061 return;
1062
1063 Qt::WindowFlags flags = widgetForWindow->windowFlags();
1064 bool customize = flags & Qt::CustomizeWindowHint;
1065
1066 NSButton *btn = [window standardWindowButton:NSWindowZoomButton];
1067 // BOOL is not an int, so the bitwise AND doesn't work.
1068 bool go = uint(customize && !(flags & Qt::WindowMaximizeButtonHint)) == 0;
1069 [btn setEnabled:go];
1070
1071 btn = [window standardWindowButton:NSWindowMiniaturizeButton];
1072 go = uint(customize && !(flags & Qt::WindowMinimizeButtonHint)) == 0;
1073 [btn setEnabled:go];
1074
1075 btn = [window standardWindowButton:NSWindowCloseButton];
1076 go = uint(customize && !(flags & Qt::WindowSystemMenuHint
1077 || flags & Qt::WindowCloseButtonHint)) == 0;
1078 [btn setEnabled:go];
1079
1080 [window setShowsToolbarButton:uint(flags & Qt::MacWindowToolBarButtonHint) != 0];
1081}
1082
1083// Carbon: Make sure you call QDEndContext on the context when done with it.
1084CGContextRef qt_mac_graphicsContextFor(QWidget *widget)
1085{
1086 if (!widget)
1087 return 0;
1088
1089#ifndef QT_MAC_USE_COCOA
1090 CGContextRef context;
1091 CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
1092 QDBeginCGContext(port, &context);
1093#else
1094 CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort];
1095#endif
1096 return context;
1097}
1098
1099QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.