VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.9 KB
Line 
1/* $Id: VBoxUtils-darwin.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - Utility Classes and Functions specific to Darwin.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QMainWindow>
30#include <QApplication>
31#include <QWidget>
32#include <QToolBar>
33#include <QPainter>
34#include <QPixmap>
35#include <QContextMenuEvent>
36
37/* GUI includes: */
38#include "VBoxUtils-darwin.h"
39#include "VBoxCocoaHelper.h"
40#include "UICocoaApplication.h"
41
42/* Other VBox includes: */
43#include <iprt/mem.h>
44#include <iprt/assert.h>
45
46/* System includes: */
47#include <Carbon/Carbon.h>
48
49NativeNSViewRef darwinToNativeView(QWidget *pWidget)
50{
51 if (pWidget)
52 return reinterpret_cast<NativeNSViewRef>(pWidget->winId());
53 return nil;
54}
55
56NativeNSWindowRef darwinToNativeWindow(QWidget *pWidget)
57{
58 if (pWidget)
59 return ::darwinToNativeWindowImpl(::darwinToNativeView(pWidget));
60 return nil;
61}
62
63NativeNSWindowRef darwinToNativeWindow(NativeNSViewRef aView)
64{
65 return ::darwinToNativeWindowImpl(aView);
66}
67
68NativeNSViewRef darwinToNativeView(NativeNSWindowRef aWindow)
69{
70 return ::darwinToNativeViewImpl(aWindow);
71}
72
73NativeNSWindowRef darwinNativeButtonOfWindow(QWidget *pWidget, StandardWindowButtonType enmButtonType)
74{
75 return ::darwinNativeButtonOfWindowImpl(::darwinToNativeWindow(pWidget), enmButtonType);
76}
77
78void darwinSetShowsToolbarButton(QToolBar *aToolBar, bool fEnabled)
79{
80 QWidget *parent = aToolBar->parentWidget();
81 if (parent)
82 ::darwinSetShowsToolbarButtonImpl(::darwinToNativeWindow(parent), fEnabled);
83}
84
85void darwinLabelWindow(QWidget *pWidget, QPixmap *pPixmap)
86{
87 ::darwinLabelWindow(::darwinToNativeWindow(pWidget), ::darwinToNSImageRef(pPixmap), pPixmap->devicePixelRatio());
88}
89
90void darwinSetHidesAllTitleButtons(QWidget *pWidget)
91{
92 /* Currently only necessary in the Cocoa version */
93 ::darwinSetHidesAllTitleButtonsImpl(::darwinToNativeWindow(pWidget));
94}
95
96void darwinSetShowsWindowTransparent(QWidget *pWidget, bool fEnabled)
97{
98 ::darwinSetShowsWindowTransparentImpl(::darwinToNativeWindow(pWidget), fEnabled);
99}
100
101void darwinSetWindowHasShadow(QWidget *pWidget, bool fEnabled)
102{
103 ::darwinSetWindowHasShadow(::darwinToNativeWindow(pWidget), fEnabled);
104}
105
106void darwinWindowAnimateResize(QWidget *pWidget, const QRect &aTarget)
107{
108 ::darwinWindowAnimateResizeImpl(::darwinToNativeWindow(pWidget), aTarget.x(), aTarget.y(), aTarget.width(), aTarget.height());
109}
110
111void darwinWindowAnimateResizeNew(QWidget *pWidget, int h, bool fAnimate)
112{
113 ::darwinWindowAnimateResizeNewImpl(::darwinToNativeWindow(pWidget), h, fAnimate);
114}
115
116void darwinTest(QWidget *pWidget1, QWidget *pWidget2, int h)
117{
118 ::darwinTest(::darwinToNativeView(pWidget1), ::darwinToNativeView(pWidget2), h);
119}
120
121void darwinWindowInvalidateShape(QWidget *pWidget)
122{
123 /* Here a simple update is enough! */
124 pWidget->update();
125}
126
127void darwinWindowInvalidateShadow(QWidget *pWidget)
128{
129 ::darwinWindowInvalidateShadowImpl(::darwinToNativeWindow(pWidget));
130}
131
132void darwinSetShowsResizeIndicator(QWidget *pWidget, bool fEnabled)
133{
134 ::darwinSetShowsResizeIndicatorImpl(::darwinToNativeWindow(pWidget), fEnabled);
135}
136
137bool darwinIsWindowMaximized(QWidget *pWidget)
138{
139 /* Currently only necessary in the Cocoa version */
140 return ::darwinIsWindowMaximized(::darwinToNativeWindow(pWidget));
141}
142
143void darwinMinaturizeWindow(QWidget *pWidget)
144{
145 return ::darwinMinaturizeWindow(::darwinToNativeWindow(pWidget));
146}
147
148void darwinEnableFullscreenSupport(QWidget *pWidget)
149{
150 return ::darwinEnableFullscreenSupport(::darwinToNativeWindow(pWidget));
151}
152
153void darwinEnableTransienceSupport(QWidget *pWidget)
154{
155 return ::darwinEnableTransienceSupport(::darwinToNativeWindow(pWidget));
156}
157
158void darwinToggleFullscreenMode(QWidget *pWidget)
159{
160 return ::darwinToggleFullscreenMode(::darwinToNativeWindow(pWidget));
161}
162
163void darwinToggleWindowZoom(QWidget *pWidget)
164{
165 return ::darwinToggleWindowZoom(::darwinToNativeWindow(pWidget));
166}
167
168bool darwinIsInFullscreenMode(QWidget *pWidget)
169{
170 return ::darwinIsInFullscreenMode(::darwinToNativeWindow(pWidget));
171}
172
173bool darwinIsOnActiveSpace(QWidget *pWidget)
174{
175 return ::darwinIsOnActiveSpace(::darwinToNativeWindow(pWidget));
176}
177
178void darwinInstallResizeDelegate(QWidget *pWidget)
179{
180 ::darwinInstallResizeDelegate(::darwinToNativeWindow(pWidget));
181}
182
183void darwinUninstallResizeDelegate(QWidget *pWidget)
184{
185 ::darwinUninstallResizeDelegate(::darwinToNativeWindow(pWidget));
186}
187
188bool darwinOpenFile(const QString& strFile)
189{
190 return ::darwinOpenFile(darwinToNativeString(strFile.toUtf8().constData()));
191}
192
193QString darwinSystemLanguage(void)
194{
195 /* Get the locales supported by our bundle */
196 CFArrayRef supportedLocales = ::CFBundleCopyBundleLocalizations(::CFBundleGetMainBundle());
197 /* Check them against the languages currently selected by the user */
198 CFArrayRef preferredLocales = ::CFBundleCopyPreferredLocalizationsFromArray(supportedLocales);
199 /* Get the one which is on top */
200 CFStringRef localeId = (CFStringRef)::CFArrayGetValueAtIndex(preferredLocales, 0);
201 /* Convert them to a C-string */
202 char localeName[20];
203 ::CFStringGetCString(localeId, localeName, sizeof(localeName), kCFStringEncodingUTF8);
204 /* Some cleanup */
205 ::CFRelease(supportedLocales);
206 ::CFRelease(preferredLocales);
207 QString id(localeName);
208 /* Check for some misbehavior */
209 if (id.isEmpty() ||
210 id.toLower() == "english")
211 id = "en";
212 return id;
213}
214
215void darwinDisableIconsInMenus(void)
216{
217 /* No icons in the menu of a mac application. */
218 QApplication::instance()->setAttribute(Qt::AA_DontShowIconsInMenus, true);
219}
220
221int darwinWindowToolBarHeight(QWidget *pWidget)
222{
223 NOREF(pWidget);
224 return 0;
225}
226
227int darwinWindowTitleHeight(QWidget *pWidget)
228{
229 return ::darwinWindowTitleHeight(::darwinToNativeWindow(pWidget));
230}
231
232bool darwinIsToolbarVisible(QToolBar *pToolBar)
233{
234 bool fResult = false;
235 QWidget *pParent = pToolBar->parentWidget();
236 if (pParent)
237 fResult = ::darwinIsToolbarVisible(::darwinToNativeWindow(pParent));
238 return fResult;
239}
240
241
242bool darwinSetFrontMostProcess()
243{
244 ProcessSerialNumber psn = { 0, kCurrentProcess };
245 return ::SetFrontProcess(&psn) == 0;
246}
247
248uint64_t darwinGetCurrentProcessId()
249{
250 uint64_t processId = 0;
251 ProcessSerialNumber psn = { 0, kCurrentProcess };
252 if (::GetCurrentProcess(&psn) == 0)
253 processId = RT_MAKE_U64(psn.lowLongOfPSN, psn.highLongOfPSN);
254 return processId;
255}
256
257/* Proxy icon creation */
258QPixmap darwinCreateDragPixmap(const QPixmap& aPixmap, const QString &aText)
259{
260 QFontMetrics fm(qApp->font());
261 QRect tbRect = fm.boundingRect(aText);
262 const int h = qMax(aPixmap.height(), fm.ascent() + 1);
263 const int m = 2;
264 QPixmap dragPixmap(aPixmap.width() + tbRect.width() + m, h);
265 dragPixmap.fill(Qt::transparent);
266 QPainter painter(&dragPixmap);
267 painter.drawPixmap(0, qAbs(h - aPixmap.height()) / 2.0, aPixmap);
268 painter.setPen(Qt::white);
269 painter.drawText(QRect(aPixmap.width() + m, 1, tbRect.width(), h - 1), Qt::AlignLeft | Qt::AlignVCenter, aText);
270 painter.setPen(Qt::black);
271 painter.drawText(QRect(aPixmap.width() + m, 0, tbRect.width(), h - 1), Qt::AlignLeft | Qt::AlignVCenter, aText);
272 painter.end();
273 return dragPixmap;
274}
275
276/**
277 * Callback for deleting the QImage object when CGImageCreate is done
278 * with it (which is probably not until the returned CFGImageRef is released).
279 *
280 * @param info Pointer to the QImage.
281 */
282static void darwinDataProviderReleaseQImage(void *info, const void *, size_t)
283{
284 QImage *qimg = (QImage *)info;
285 delete qimg;
286}
287
288/**
289 * Converts a QPixmap to a CGImage.
290 *
291 * @returns CGImageRef for the new image. (Remember to release it when finished with it.)
292 * @param aPixmap Pointer to the QPixmap instance to convert.
293 */
294CGImageRef darwinToCGImageRef(const QImage *pImage)
295{
296 QImage *imageCopy = new QImage(*pImage);
297 /** @todo this code assumes 32-bit image input, the lazy bird convert image to 32-bit method is anything but optimal... */
298 if (imageCopy->format() != QImage::Format_ARGB32)
299 *imageCopy = imageCopy->convertToFormat(QImage::Format_ARGB32);
300 Assert(!imageCopy->isNull());
301
302 CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
303 CGDataProviderRef dp = CGDataProviderCreateWithData(imageCopy, pImage->bits(), pImage->sizeInBytes(),
304 darwinDataProviderReleaseQImage);
305
306 CGBitmapInfo bmpInfo = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
307 CGImageRef ir = CGImageCreate(imageCopy->width(), imageCopy->height(), 8, 32, imageCopy->bytesPerLine(), cs,
308 bmpInfo, dp, 0 /*decode */, 0 /* shouldInterpolate */,
309 kCGRenderingIntentDefault);
310 CGColorSpaceRelease(cs);
311 CGDataProviderRelease(dp);
312
313 Assert(ir);
314 return ir;
315}
316
317/**
318 * Converts a QPixmap to a CGImage.
319 *
320 * @returns CGImageRef for the new image. (Remember to release it when finished with it.)
321 * @param aPixmap Pointer to the QPixmap instance to convert.
322 */
323CGImageRef darwinToCGImageRef(const QPixmap *pPixmap)
324{
325 /* It seems Qt releases the memory to an returned CGImageRef when the
326 * associated QPixmap is destroyed. This shouldn't happen as long a
327 * CGImageRef has a retrain count. As a workaround we make a real copy. */
328 int bitmapBytesPerRow = pPixmap->width() * 4;
329 int bitmapByteCount = (bitmapBytesPerRow * pPixmap->height());
330 /* Create a memory block for the temporary image. It is initialized by zero
331 * which means black & zero alpha. */
332 void *pBitmapData = RTMemAllocZ(bitmapByteCount);
333 CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
334 /* Create a context to paint on */
335 CGContextRef ctx = CGBitmapContextCreate(pBitmapData,
336 pPixmap->width(),
337 pPixmap->height(),
338 8,
339 bitmapBytesPerRow,
340 cs,
341 kCGImageAlphaPremultipliedFirst);
342 /* Get the CGImageRef from Qt */
343 CGImageRef qtPixmap = pPixmap->toImage().toCGImage();
344 /* Draw the image from Qt & convert the context back to a new CGImageRef. */
345 CGContextDrawImage(ctx, CGRectMake(0, 0, pPixmap->width(), pPixmap->height()), qtPixmap);
346 CGImageRef newImage = CGBitmapContextCreateImage(ctx);
347 /* Now release all used resources */
348 CGImageRelease(qtPixmap);
349 CGContextRelease(ctx);
350 CGColorSpaceRelease(cs);
351 RTMemFree(pBitmapData);
352
353 /* Return the new CGImageRef */
354 return newImage;
355}
356
357/**
358 * Loads an image using Qt and converts it to a CGImage.
359 *
360 * @returns CGImageRef for the new image. (Remember to release it when finished with it.)
361 * @param aSource The source name.
362 */
363CGImageRef darwinToCGImageRef(const char *pczSource)
364{
365 QPixmap qpm(QString(":/") + pczSource);
366 Assert(!qpm.isNull());
367 return ::darwinToCGImageRef(&qpm);
368}
369
370void darwinRegisterForUnifiedToolbarContextMenuEvents(QMainWindow *pWindow)
371{
372 UICocoaApplication::instance()->registerForNativeEvents(RT_BIT_32(3) /* NSRightMouseDown */, ::darwinUnifiedToolbarEvents, pWindow);
373}
374
375void darwinUnregisterForUnifiedToolbarContextMenuEvents(QMainWindow *pWindow)
376{
377 UICocoaApplication::instance()->unregisterForNativeEvents(RT_BIT_32(3) /* NSRightMouseDown */, ::darwinUnifiedToolbarEvents, pWindow);
378}
379
380void darwinMouseGrab(QWidget *pWidget)
381{
382 CGAssociateMouseAndMouseCursorPosition(false);
383 UICocoaApplication::instance()->registerForNativeEvents(RT_BIT_32(1) | /* NSLeftMouseDown */
384 RT_BIT_32(2) | /* NSLeftMouseUp */
385 RT_BIT_32(3) | /* NSRightMouseDown */
386 RT_BIT_32(4) | /* NSRightMouseUp */
387 RT_BIT_32(5) | /* NSMouseMoved */
388 RT_BIT_32(6) | /* NSLeftMouseDragged */
389 RT_BIT_32(7) | /* NSRightMouseDragged */
390 RT_BIT_32(25) | /* NSOtherMouseDown */
391 RT_BIT_32(26) | /* NSOtherMouseUp */
392 RT_BIT_32(27) | /* NSOtherMouseDragged */
393 RT_BIT_32(22), /* NSScrollWheel */
394 ::darwinMouseGrabEvents, pWidget);
395}
396
397void darwinMouseRelease(QWidget *pWidget)
398{
399 UICocoaApplication::instance()->unregisterForNativeEvents(RT_BIT_32(1) | /* NSLeftMouseDown */
400 RT_BIT_32(2) | /* NSLeftMouseUp */
401 RT_BIT_32(3) | /* NSRightMouseDown */
402 RT_BIT_32(4) | /* NSRightMouseUp */
403 RT_BIT_32(5) | /* NSMouseMoved */
404 RT_BIT_32(6) | /* NSLeftMouseDragged */
405 RT_BIT_32(7) | /* NSRightMouseDragged */
406 RT_BIT_32(25) | /* NSOtherMouseDown */
407 RT_BIT_32(26) | /* NSOtherMouseUp */
408 RT_BIT_32(27) | /* NSOtherMouseDragged */
409 RT_BIT_32(22), /* NSScrollWheel */
410 ::darwinMouseGrabEvents, pWidget);
411 CGAssociateMouseAndMouseCursorPosition(true);
412}
413
414void darwinSendMouseGrabEvents(QWidget *pWidget, int type, int button, int buttons, int x, int y)
415{
416 QEvent::Type qtType = QEvent::None;
417 Qt::MouseButtons qtButtons = Qt::NoButton;
418 Qt::MouseButton qtButton = Qt::NoButton;
419 Qt::MouseButton qtExtraButton = Qt::NoButton;
420 Qt::Orientation qtOrientation = Qt::Horizontal;
421 int wheelDelta = 0;
422 /* Which button is used in the NSOtherMouse... cases? */
423 if (button == 0)
424 qtExtraButton = Qt::LeftButton;
425 else if (button == 1)
426 qtExtraButton = Qt::RightButton;
427 else if (button == 2)
428 qtExtraButton = Qt::MiddleButton;
429 else if (button == 3)
430 qtExtraButton = Qt::XButton1;
431 else if (button == 4)
432 qtExtraButton = Qt::XButton2;
433 /* Map the NSEvent to a QEvent and define the Qt::Buttons when necessary. */
434 switch(type)
435 {
436 case 1: /* NSLeftMouseDown */
437 {
438 qtType = QEvent::MouseButtonPress;
439 qtButton = Qt::LeftButton;
440 break;
441 }
442 case 2: /* NSLeftMouseUp */
443 {
444 qtType = QEvent::MouseButtonRelease;
445 qtButton = Qt::LeftButton;
446 break;
447 }
448 case 3: /* NSRightMouseDown */
449 {
450 qtType = QEvent::MouseButtonPress;
451 qtButton = Qt::RightButton;
452 break;
453 }
454 case 4: /* NSRightMouseUp */
455 {
456 qtType = QEvent::MouseButtonRelease;
457 qtButton = Qt::RightButton;
458 break;
459 }
460 case 5: /* NSMouseMoved */
461 {
462 qtType = QEvent::MouseMove;
463 break;
464 }
465 case 6: /* NSLeftMouseDragged */
466 {
467 qtType = QEvent::MouseMove;
468 qtButton = Qt::LeftButton;
469 break;
470 }
471 case 7: /* NSRightMouseDragged */
472 {
473 qtType = QEvent::MouseMove;
474 qtButton = Qt::RightButton;
475 break;
476 }
477 case 22: /* NSScrollWheel */
478 {
479 qtType = QEvent::Wheel;
480 if (y != 0)
481 {
482 wheelDelta = y;
483 qtOrientation = Qt::Vertical;
484 }
485 else if (x != 0)
486 {
487 wheelDelta = x;
488 qtOrientation = Qt::Horizontal;
489 }
490 x = y = 0;
491 break;
492 }
493 case 25: /* NSOtherMouseDown */
494 {
495 qtType = QEvent::MouseButtonPress;
496 qtButton = qtExtraButton;
497 break;
498 }
499 case 26: /* NSOtherMouseUp */
500 {
501 qtType = QEvent::MouseButtonRelease;
502 qtButton = qtExtraButton;
503 break;
504 }
505 case 27: /* NSOtherMouseDragged */
506 {
507 qtType = QEvent::MouseMove;
508 qtButton = qtExtraButton;
509 break;
510 }
511 default: return;
512 }
513 /* Create a Qt::MouseButtons Mask. */
514 if ((buttons & RT_BIT_32(0)) == RT_BIT_32(0))
515 qtButtons |= Qt::LeftButton;
516 if ((buttons & RT_BIT_32(1)) == RT_BIT_32(1))
517 qtButtons |= Qt::RightButton;
518 if ((buttons & RT_BIT_32(2)) == RT_BIT_32(2))
519 qtButtons |= Qt::MiddleButton;
520 if ((buttons & RT_BIT_32(3)) == RT_BIT_32(3))
521 qtButtons |= Qt::XButton1;
522 if ((buttons & RT_BIT_32(4)) == RT_BIT_32(4))
523 qtButtons |= Qt::XButton2;
524 /* Create a new mouse delta event and send it to the widget. */
525 UIGrabMouseEvent *pEvent = new UIGrabMouseEvent(qtType, qtButton, qtButtons, x, y, wheelDelta, qtOrientation);
526 qApp->sendEvent(pWidget, pEvent);
527}
528
529void darwinCreateContextMenuEvent(void *pvUser, int x, int y)
530{
531 QWidget *pWin = static_cast<QWidget*>(pvUser);
532 QPoint global(x, y);
533 QPoint local = pWin->mapFromGlobal(global);
534 qApp->postEvent(pWin, new QContextMenuEvent(QContextMenuEvent::Mouse, local, global));
535}
536
537QString darwinResolveAlias(const QString &strFile)
538{
539 OSErr err = noErr;
540 FSRef fileRef;
541 QString strTarget;
542 do
543 {
544 Boolean fDir;
545 if ((err = FSPathMakeRef((const UInt8*)strFile.toUtf8().constData(), &fileRef, &fDir)) != noErr)
546 break;
547 Boolean fAlias = FALSE;
548 if ((err = FSIsAliasFile(&fileRef, &fAlias, &fDir)) != noErr)
549 break;
550 if (fAlias == TRUE)
551 {
552 if ((err = FSResolveAliasFile(&fileRef, TRUE, &fAlias, &fDir)) != noErr)
553 break;
554 char pszPath[1024];
555 if ((err = FSRefMakePath(&fileRef, (UInt8*)pszPath, 1024)) != noErr)
556 break;
557 strTarget = QString::fromUtf8(pszPath);
558 }
559 else
560 strTarget = strFile;
561 }while(0);
562
563 return strTarget;
564}
565
566
567/********************************************************************************
568 *
569 * Old carbon stuff. Have to convert soon!
570 *
571 ********************************************************************************/
572
573/* Event debugging stuff. Borrowed from Knuts Qt patch. */
574#if defined (DEBUG)
575
576# define MY_CASE(a) case a: return #a
577const char * DarwinDebugEventName(UInt32 ekind)
578{
579 switch (ekind)
580 {
581# if !__LP64__
582 MY_CASE(kEventWindowUpdate );
583 MY_CASE(kEventWindowDrawContent );
584# endif
585 MY_CASE(kEventWindowActivated );
586 MY_CASE(kEventWindowDeactivated );
587 MY_CASE(kEventWindowHandleActivate );
588 MY_CASE(kEventWindowHandleDeactivate );
589 MY_CASE(kEventWindowGetClickActivation );
590 MY_CASE(kEventWindowGetClickModality );
591 MY_CASE(kEventWindowShowing );
592 MY_CASE(kEventWindowHiding );
593 MY_CASE(kEventWindowShown );
594 MY_CASE(kEventWindowHidden );
595 MY_CASE(kEventWindowCollapsing );
596 MY_CASE(kEventWindowCollapsed );
597 MY_CASE(kEventWindowExpanding );
598 MY_CASE(kEventWindowExpanded );
599 MY_CASE(kEventWindowZoomed );
600 MY_CASE(kEventWindowBoundsChanging );
601 MY_CASE(kEventWindowBoundsChanged );
602 MY_CASE(kEventWindowResizeStarted );
603 MY_CASE(kEventWindowResizeCompleted );
604 MY_CASE(kEventWindowDragStarted );
605 MY_CASE(kEventWindowDragCompleted );
606 MY_CASE(kEventWindowClosed );
607 MY_CASE(kEventWindowTransitionStarted );
608 MY_CASE(kEventWindowTransitionCompleted );
609# if !__LP64__
610 MY_CASE(kEventWindowClickDragRgn );
611 MY_CASE(kEventWindowClickResizeRgn );
612 MY_CASE(kEventWindowClickCollapseRgn );
613 MY_CASE(kEventWindowClickCloseRgn );
614 MY_CASE(kEventWindowClickZoomRgn );
615 MY_CASE(kEventWindowClickContentRgn );
616 MY_CASE(kEventWindowClickProxyIconRgn );
617 MY_CASE(kEventWindowClickToolbarButtonRgn );
618 MY_CASE(kEventWindowClickStructureRgn );
619# endif
620 MY_CASE(kEventWindowCursorChange );
621 MY_CASE(kEventWindowCollapse );
622 MY_CASE(kEventWindowCollapseAll );
623 MY_CASE(kEventWindowExpand );
624 MY_CASE(kEventWindowExpandAll );
625 MY_CASE(kEventWindowClose );
626 MY_CASE(kEventWindowCloseAll );
627 MY_CASE(kEventWindowZoom );
628 MY_CASE(kEventWindowZoomAll );
629 MY_CASE(kEventWindowContextualMenuSelect );
630 MY_CASE(kEventWindowPathSelect );
631 MY_CASE(kEventWindowGetIdealSize );
632 MY_CASE(kEventWindowGetMinimumSize );
633 MY_CASE(kEventWindowGetMaximumSize );
634 MY_CASE(kEventWindowConstrain );
635# if !__LP64__
636 MY_CASE(kEventWindowHandleContentClick );
637# endif
638 MY_CASE(kEventWindowGetDockTileMenu );
639 MY_CASE(kEventWindowProxyBeginDrag );
640 MY_CASE(kEventWindowProxyEndDrag );
641 MY_CASE(kEventWindowToolbarSwitchMode );
642 MY_CASE(kEventWindowFocusAcquired );
643 MY_CASE(kEventWindowFocusRelinquish );
644 MY_CASE(kEventWindowFocusContent );
645 MY_CASE(kEventWindowFocusToolbar );
646 MY_CASE(kEventWindowFocusDrawer );
647 MY_CASE(kEventWindowSheetOpening );
648 MY_CASE(kEventWindowSheetOpened );
649 MY_CASE(kEventWindowSheetClosing );
650 MY_CASE(kEventWindowSheetClosed );
651 MY_CASE(kEventWindowDrawerOpening );
652 MY_CASE(kEventWindowDrawerOpened );
653 MY_CASE(kEventWindowDrawerClosing );
654 MY_CASE(kEventWindowDrawerClosed );
655 MY_CASE(kEventWindowDrawFrame );
656 MY_CASE(kEventWindowDrawPart );
657 MY_CASE(kEventWindowGetRegion );
658 MY_CASE(kEventWindowHitTest );
659 MY_CASE(kEventWindowInit );
660 MY_CASE(kEventWindowDispose );
661 MY_CASE(kEventWindowDragHilite );
662 MY_CASE(kEventWindowModified );
663 MY_CASE(kEventWindowSetupProxyDragImage );
664 MY_CASE(kEventWindowStateChanged );
665 MY_CASE(kEventWindowMeasureTitle );
666 MY_CASE(kEventWindowDrawGrowBox );
667 MY_CASE(kEventWindowGetGrowImageRegion );
668 MY_CASE(kEventWindowPaint );
669 }
670 static char s_sz[64];
671 sprintf(s_sz, "kind=%u", (uint)ekind);
672 return s_sz;
673}
674# undef MY_CASE
675
676/* Convert a class into the 4 char code defined in
677 * 'Developer/Headers/CFMCarbon/CarbonEvents.h' to
678 * identify the event. */
679const char * darwinDebugClassName(UInt32 eclass)
680{
681 char *pclass = (char*)&eclass;
682 static char s_sz[11];
683 sprintf(s_sz, "class=%c%c%c%c", pclass[3],
684 pclass[2],
685 pclass[1],
686 pclass[0]);
687 return s_sz;
688}
689
690void darwinDebugPrintEvent(const char *psz, EventRef evtRef)
691{
692 if (!evtRef)
693 return;
694 UInt32 ekind = GetEventKind(evtRef), eclass = GetEventClass(evtRef);
695 if (eclass == kEventClassWindow)
696 {
697 switch (ekind)
698 {
699# if !__LP64__
700 case kEventWindowDrawContent:
701 case kEventWindowUpdate:
702# endif
703 case kEventWindowBoundsChanged:
704 break;
705 default:
706 {
707 WindowRef wid = NULL;
708 GetEventParameter(evtRef, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &wid);
709 QWidget *widget = QWidget::find((WId)wid);
710 printf("%d %s: (%s) %#x win=%p wid=%p (%s)\n", (int)time(NULL), psz, darwinDebugClassName(eclass), (uint)ekind, wid, widget, DarwinDebugEventName(ekind));
711 break;
712 }
713 }
714 }
715 else if (eclass == kEventClassCommand)
716 {
717 WindowRef wid = NULL;
718 GetEventParameter(evtRef, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &wid);
719 QWidget *widget = QWidget::find((WId)wid);
720 const char *name = "Unknown";
721 switch (ekind)
722 {
723 case kEventCommandProcess:
724 name = "kEventCommandProcess";
725 break;
726 case kEventCommandUpdateStatus:
727 name = "kEventCommandUpdateStatus";
728 break;
729 }
730 printf("%d %s: (%s) %#x win=%p wid=%p (%s)\n", (int)time(NULL), psz, darwinDebugClassName(eclass), (uint)ekind, wid, widget, name);
731 }
732 else if (eclass == kEventClassKeyboard)
733 {
734 printf("%d %s: %#x(%s) %#x (kEventClassKeyboard)", (int)time(NULL), psz, (uint)eclass, darwinDebugClassName(eclass), (uint)ekind);
735
736 UInt32 keyCode = 0;
737 ::GetEventParameter(evtRef, kEventParamKeyCode, typeUInt32, NULL,
738 sizeof(keyCode), NULL, &keyCode);
739 printf(" keyCode=%d (%#x) ", (int)keyCode, (unsigned)keyCode);
740
741 char macCharCodes[8] = {0,0,0,0, 0,0,0,0};
742 ::GetEventParameter(evtRef, kEventParamKeyCode, typeChar, NULL,
743 sizeof(macCharCodes), NULL, &macCharCodes[0]);
744 printf(" macCharCodes={");
745 for (unsigned i =0; i < 8 && macCharCodes[i]; i++)
746 printf( i == 0 ? "%02x" : ",%02x", macCharCodes[i]);
747 printf("}");
748
749 UInt32 modifierMask = 0;
750 ::GetEventParameter(evtRef, kEventParamKeyModifiers, typeUInt32, NULL,
751 sizeof(modifierMask), NULL, &modifierMask);
752 printf(" modifierMask=%08x", (unsigned)modifierMask);
753
754 UniChar keyUnicodes[8] = {0,0,0,0, 0,0,0,0};
755 ::GetEventParameter(evtRef, kEventParamKeyUnicodes, typeUnicodeText, NULL,
756 sizeof(keyUnicodes), NULL, &keyUnicodes[0]);
757 printf(" keyUnicodes={");
758 for (unsigned i =0; i < 8 && keyUnicodes[i]; i++)
759 printf( i == 0 ? "%02x" : ",%02x", keyUnicodes[i]);
760 printf("}");
761
762 UInt32 keyboardType = 0;
763 ::GetEventParameter(evtRef, kEventParamKeyboardType, typeUInt32, NULL,
764 sizeof(keyboardType), NULL, &keyboardType);
765 printf(" keyboardType=%08x", (unsigned)keyboardType);
766
767 EventHotKeyID evtHotKeyId = {0,0};
768 ::GetEventParameter(evtRef, typeEventHotKeyID, typeEventHotKeyID, NULL,
769 sizeof(evtHotKeyId), NULL, &evtHotKeyId);
770 printf(" evtHotKeyId={signature=%08x, .id=%08x}", (unsigned)evtHotKeyId.signature, (unsigned)evtHotKeyId.id);
771 printf("\n");
772 }
773 else
774 printf("%d %s: %#x(%s) %#x\n", (int)time(NULL), psz, (uint)eclass, darwinDebugClassName(eclass), (uint)ekind);
775}
776
777#endif /* DEBUG */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use