src/gui/kernel/qapplication_mac.mm
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 <Cocoa/Cocoa.h>
       
    77 
       
    78 #include "qapplication.h"
       
    79 #include "qbitarray.h"
       
    80 #include "qclipboard.h"
       
    81 #include "qcursor.h"
       
    82 #include "qdatastream.h"
       
    83 #include "qdatetime.h"
       
    84 #include "qdesktopwidget.h"
       
    85 #include "qdockwidget.h"
       
    86 #include "qevent.h"
       
    87 #include "qhash.h"
       
    88 #include "qlayout.h"
       
    89 #include "qmenubar.h"
       
    90 #include "qmessagebox.h"
       
    91 #include "qmime.h"
       
    92 #include "qpixmapcache.h"
       
    93 #include "qpointer.h"
       
    94 #include "qsessionmanager.h"
       
    95 #include "qsettings.h"
       
    96 #include "qsocketnotifier.h"
       
    97 #include "qstyle.h"
       
    98 #include "qstylefactory.h"
       
    99 #include "qtextcodec.h"
       
   100 #include "qtoolbar.h"
       
   101 #include "qvariant.h"
       
   102 #include "qwidget.h"
       
   103 #include "qcolormap.h"
       
   104 #include "qdir.h"
       
   105 #include "qdebug.h"
       
   106 #include "qtimer.h"
       
   107 #include "private/qmacinputcontext_p.h"
       
   108 #include "private/qpaintengine_mac_p.h"
       
   109 #include "private/qcursor_p.h"
       
   110 #include "private/qapplication_p.h"
       
   111 #include "private/qcolor_p.h"
       
   112 #include "private/qwidget_p.h"
       
   113 #include "private/qkeymapper_p.h"
       
   114 #include "private/qeventdispatcher_mac_p.h"
       
   115 #include "private/qeventdispatcher_unix_p.h"
       
   116 #include <private/qcocoamenuloader_mac_p.h>
       
   117 #include <private/qcocoaapplication_mac_p.h>
       
   118 #include <private/qcocoaapplicationdelegate_mac_p.h>
       
   119 #include <private/qt_cocoa_helpers_mac_p.h>
       
   120 #include <private/qcocoawindow_mac_p.h>
       
   121 #include <private/qpixmap_mac_p.h>
       
   122 #include <private/qdesktopwidget_mac_p.h>
       
   123 #include <private/qeventdispatcher_mac_p.h>
       
   124 #include <qvarlengtharray.h>
       
   125 
       
   126 #ifndef QT_NO_ACCESSIBILITY
       
   127 #  include "qaccessible.h"
       
   128 #endif
       
   129 
       
   130 #ifndef QT_NO_THREAD
       
   131 #  include "qmutex.h"
       
   132 #endif
       
   133 
       
   134 #include <unistd.h>
       
   135 #include <string.h>
       
   136 #include <sys/time.h>
       
   137 #include <sys/select.h>
       
   138 
       
   139 /*****************************************************************************
       
   140   QApplication debug facilities
       
   141  *****************************************************************************/
       
   142 //#define DEBUG_EVENTS //like EventDebug but more specific to Qt
       
   143 //#define DEBUG_DROPPED_EVENTS
       
   144 //#define DEBUG_MOUSE_MAPS
       
   145 //#define DEBUG_MODAL_EVENTS
       
   146 //#define DEBUG_PLATFORM_SETTINGS
       
   147 
       
   148 #define QMAC_SPEAK_TO_ME
       
   149 #ifdef QMAC_SPEAK_TO_ME
       
   150 #include "qregexp.h"
       
   151 #endif
       
   152 
       
   153 #ifndef kThemeBrushAlternatePrimaryHighlightColor
       
   154 #define kThemeBrushAlternatePrimaryHighlightColor -5
       
   155 #endif
       
   156 
       
   157 #define kCMDeviceUnregisteredNotification CFSTR("CMDeviceUnregisteredNotification")
       
   158 #define kCMDefaultDeviceNotification CFSTR("CMDefaultDeviceNotification")
       
   159 #define kCMDeviceProfilesNotification CFSTR("CMDeviceProfilesNotification")
       
   160 #define kCMDefaultDeviceProfileNotification CFSTR("CMDefaultDeviceProfileNotification")
       
   161 
       
   162 QT_BEGIN_NAMESPACE
       
   163 
       
   164 //for qt_mac.h
       
   165 QPaintDevice *qt_mac_safe_pdev = 0;
       
   166 QList<QMacWindowChangeEvent*> *QMacWindowChangeEvent::change_events = 0;
       
   167 
       
   168 /*****************************************************************************
       
   169   Internal variables and functions
       
   170  *****************************************************************************/
       
   171 static struct {
       
   172     bool use_qt_time_limit;
       
   173     QPointer<QWidget> last_widget;
       
   174     int last_x, last_y;
       
   175     int last_modifiers, last_button;
       
   176     EventTime last_time;
       
   177 } qt_mac_dblclick = { false, 0, -1, -1, 0, 0, -2 };
       
   178 
       
   179 static bool app_do_modal = false;       // modal mode
       
   180 extern QWidgetList *qt_modal_stack;     // stack of modal widgets
       
   181 extern bool qt_tab_all_widgets;         // from qapplication.cpp
       
   182 bool qt_mac_app_fullscreen = false;
       
   183 bool qt_scrollbar_jump_to_pos = false;
       
   184 static bool qt_mac_collapse_on_dblclick = true;
       
   185 extern int qt_antialiasing_threshold; // from qapplication.cpp
       
   186 QPointer<QWidget> qt_button_down;                // widget got last button-down
       
   187 #ifndef QT_MAC_USE_COCOA
       
   188 static bool qt_button_down_in_content; // whether the button_down was in the content area.
       
   189 static bool qt_mac_previous_press_in_popup_mode = false;
       
   190 static bool qt_mac_no_click_through_mode = false;
       
   191 static int tablet_button_state = 0;
       
   192 #endif
       
   193 QPointer<QWidget> qt_mouseover;
       
   194 #if defined(QT_DEBUG)
       
   195 static bool        appNoGrab        = false;        // mouse/keyboard grabbing
       
   196 #endif
       
   197 #ifndef QT_MAC_USE_COCOA
       
   198 static EventHandlerRef app_proc_handler = 0;
       
   199 static EventHandlerUPP app_proc_handlerUPP = 0;
       
   200 #endif
       
   201 static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL;
       
   202 static EventHandlerRef tablet_proximity_handler = 0;
       
   203 static EventHandlerUPP tablet_proximity_UPP = 0;
       
   204 bool QApplicationPrivate::native_modal_dialog_active;
       
   205 
       
   206 Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
       
   207 
       
   208 /*****************************************************************************
       
   209   External functions
       
   210  *****************************************************************************/
       
   211 extern void qt_mac_beep(); //qsound_mac.mm
       
   212 extern Qt::KeyboardModifiers qt_mac_get_modifiers(int keys); //qkeymapper_mac.cpp
       
   213 extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
       
   214 extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
       
   215 extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
       
   216 extern QWidget *qt_mac_find_window(OSWindowRef); //qwidget_mac.cpp
       
   217 extern void qt_mac_set_cursor(const QCursor *, const QPoint &); //qcursor_mac.cpp
       
   218 extern bool qt_mac_is_macsheet(const QWidget *); //qwidget_mac.cpp
       
   219 extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
       
   220 extern void qt_mac_command_set_enabled(MenuRef, UInt32, bool); //qmenu_mac.cpp
       
   221 extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); // qapplication.cpp
       
   222 
       
   223 // Forward Decls
       
   224 void onApplicationWindowChangedActivation( QWidget*widget, bool activated );
       
   225 void onApplicationChangedActivation( bool activated );
       
   226 
       
   227 static void qt_mac_read_fontsmoothing_settings()
       
   228 {
       
   229     NSInteger appleFontSmoothing = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleFontSmoothing"];
       
   230     qt_applefontsmoothing_enabled = (appleFontSmoothing > 0);
       
   231 }
       
   232 
       
   233 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
       
   234     OSStatus err;
       
   235     AEDesc scriptTextDesc;
       
   236     ComponentInstance theComponent = 0;
       
   237     OSAID scriptID = kOSANullScript, resultID = kOSANullScript;
       
   238 
       
   239     // set up locals to a known state
       
   240     AECreateDesc(typeNull, 0, 0, &scriptTextDesc);
       
   241     scriptID = kOSANullScript;
       
   242     resultID = kOSANullScript;
       
   243 
       
   244     // open the scripting component
       
   245     theComponent = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
       
   246     if (!theComponent) {
       
   247         err = paramErr;
       
   248         goto bail;
       
   249     }
       
   250 
       
   251     // put the script text into an aedesc
       
   252     err = AECreateDesc(typeUTF8Text, script, script_len, &scriptTextDesc);
       
   253     if (err != noErr)
       
   254         goto bail;
       
   255 
       
   256     // compile the script
       
   257     err = OSACompile(theComponent, &scriptTextDesc, kOSAModeNull, &scriptID);
       
   258     if (err != noErr)
       
   259         goto bail;
       
   260 
       
   261     // run the script
       
   262     err = OSAExecute(theComponent, scriptID, kOSANullScript, kOSAModeNull, &resultID);
       
   263 
       
   264     // collect the results - if any
       
   265     if (ret) {
       
   266         AECreateDesc(typeNull, 0, 0, ret);
       
   267         if (err == errOSAScriptError)
       
   268             OSAScriptError(theComponent, kOSAErrorMessage, typeChar, ret);
       
   269         else if (err == noErr && resultID != kOSANullScript)
       
   270             OSADisplay(theComponent, resultID, typeChar, kOSAModeNull, ret);
       
   271     }
       
   272 bail:
       
   273     AEDisposeDesc(&scriptTextDesc);
       
   274     if (scriptID != kOSANullScript)
       
   275         OSADispose(theComponent, scriptID);
       
   276     if (resultID != kOSANullScript)
       
   277         OSADispose(theComponent, resultID);
       
   278     if (theComponent)
       
   279         CloseComponent(theComponent);
       
   280     return err == noErr;
       
   281 }
       
   282 
       
   283 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, AEDesc *ret)
       
   284 {
       
   285     return qt_mac_execute_apple_script(script, qstrlen(script), ret);
       
   286 }
       
   287 
       
   288 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret)
       
   289 {
       
   290     const QByteArray l = script.toUtf8(); return qt_mac_execute_apple_script(l.constData(), l.size(), ret);
       
   291 }
       
   292 
       
   293 /* Resolution change magic */
       
   294 void qt_mac_display_change_callbk(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void *)
       
   295 {
       
   296 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
       
   297     const bool resized = flags & kCGDisplayDesktopShapeChangedFlag;
       
   298 #else
       
   299     Q_UNUSED(flags);
       
   300     const bool resized = true;
       
   301 #endif
       
   302     if (resized && qApp) {
       
   303         if (QDesktopWidget *dw = qApp->desktop()) {
       
   304             QResizeEvent *re = new QResizeEvent(dw->size(), dw->size());
       
   305             QApplication::postEvent(dw, re);
       
   306             QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
       
   307         }
       
   308     }
       
   309 }
       
   310 
       
   311 #ifdef DEBUG_PLATFORM_SETTINGS
       
   312 static void qt_mac_debug_palette(const QPalette &pal, const QPalette &pal2, const QString &where)
       
   313 {
       
   314     const char *const groups[] = {"Active", "Disabled", "Inactive" };
       
   315     const char *const roles[] = { "WindowText", "Button", "Light", "Midlight", "Dark", "Mid",
       
   316                             "Text", "BrightText", "ButtonText", "Base", "Window", "Shadow",
       
   317                             "Highlight", "HighlightedText", "Link", "LinkVisited" };
       
   318     if (!where.isNull())
       
   319         qDebug("qt-internal: %s", where.toLatin1().constData());
       
   320     for(int grp = 0; grp < QPalette::NColorGroups; grp++) {
       
   321         for(int role = 0; role < QPalette::NColorRoles; role++) {
       
   322             QBrush b = pal.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role);
       
   323             QPixmap pm = b.texture();
       
   324             qDebug("  %s::%s %d::%d::%d [%p]%s", groups[grp], roles[role], b.color().red(),
       
   325                    b.color().green(), b.color().blue(), pm.isNull() ? 0 : &pm,
       
   326                    pal2.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role) != b ? " (*)" : "");
       
   327         }
       
   328     }
       
   329 
       
   330 }
       
   331 #else
       
   332 #define qt_mac_debug_palette(x, y, z)
       
   333 #endif
       
   334 
       
   335 //raise a notification
       
   336 #ifndef QT_MAC_USE_COCOA
       
   337 static NMRec qt_mac_notification = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
       
   338 #endif
       
   339 void qt_mac_send_notification()
       
   340 {
       
   341 #ifndef QT_MAC_USE_COCOA
       
   342     //send it
       
   343     qt_mac_notification.nmMark = 1; //non-zero magic number
       
   344     qt_mac_notification.qType = nmType;
       
   345     NMInstall(&qt_mac_notification);
       
   346 #else
       
   347     QMacCocoaAutoReleasePool pool;
       
   348     [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
       
   349 #endif
       
   350 }
       
   351 
       
   352 void qt_mac_cancel_notification()
       
   353 {
       
   354 #ifndef QT_MAC_USE_COCOA
       
   355     NMRemove(&qt_mac_notification);
       
   356 #else
       
   357     QMacCocoaAutoReleasePool pool;
       
   358     [[NSApplication sharedApplication] cancelUserAttentionRequest:NSInformationalRequest];
       
   359 #endif
       
   360 }
       
   361 
       
   362 #ifndef QT_MAC_USE_COCOA
       
   363 //find widget (and part) at a given point
       
   364 static short qt_mac_window_at(int x, int y, QWidget **w=0)
       
   365 {
       
   366     Point p;
       
   367     p.h = x;
       
   368     p.v = y;
       
   369     OSWindowRef wp;
       
   370     WindowPartCode wpc;
       
   371     OSStatus err = FindWindowOfClass(&p, kAllWindowClasses, &wp, &wpc);
       
   372     if(err != noErr) {
       
   373         if(w)
       
   374             (*w) = 0;
       
   375         return wpc;
       
   376     }
       
   377     if(w) {
       
   378         if(wp) {
       
   379             *w = qt_mac_find_window(wp);
       
   380 #if 0
       
   381             if(!*w)
       
   382                 qWarning("QApplication: qt_mac_window_at: Couldn't find %d",(int)wp);
       
   383 #endif
       
   384         } else {
       
   385             *w = 0;
       
   386         }
       
   387     }
       
   388     return wpc;
       
   389 }
       
   390 
       
   391 #endif
       
   392 
       
   393 void qt_mac_set_app_icon(const QPixmap &pixmap)
       
   394 {
       
   395 #ifndef QT_MAC_USE_COCOA
       
   396     if(pixmap.isNull()) {
       
   397         RestoreApplicationDockTileImage();
       
   398     } else {
       
   399         CGImageRef img = (CGImageRef)pixmap.macCGHandle();
       
   400         SetApplicationDockTileImage(img);
       
   401         CGImageRelease(img);
       
   402     }
       
   403 #else
       
   404     QMacCocoaAutoReleasePool pool;
       
   405     NSImage *image = NULL;
       
   406     if (pixmap.isNull()) {
       
   407         // Get Application icon from bundle
       
   408         image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; // released below
       
   409     } else {
       
   410         image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
       
   411     }
       
   412 
       
   413     [NSApp setApplicationIconImage:image];
       
   414     [image release];
       
   415 #endif
       
   416 }
       
   417 
       
   418 Q_GUI_EXPORT void qt_mac_set_press_and_hold_context(bool b)
       
   419 {
       
   420     Q_UNUSED(b);
       
   421     qWarning("qt_mac_set_press_and_hold_context: This functionality is no longer available");
       
   422 }
       
   423 
       
   424 bool qt_nograb()                                // application no-grab option
       
   425 {
       
   426 #if defined(QT_DEBUG)
       
   427     return appNoGrab;
       
   428 #else
       
   429     return false;
       
   430 #endif
       
   431 }
       
   432 
       
   433 void qt_mac_update_os_settings()
       
   434 {
       
   435     if (!qApp)
       
   436         return;
       
   437     if (!QApplication::startingUp()) {
       
   438         static bool needToPolish = true;
       
   439         if (needToPolish) {
       
   440             QApplication::style()->polish(qApp);
       
   441             needToPolish = false;
       
   442         }
       
   443     }
       
   444     //focus mode
       
   445     /* First worked as of 10.2.3 */
       
   446     QSettings appleSettings(QLatin1String("apple.com"));
       
   447     QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0);
       
   448     qt_tab_all_widgets = (appleValue.toInt() & 0x2);
       
   449     //paging mode
       
   450     /* First worked as of 10.2.3 */
       
   451     appleValue = appleSettings.value(QLatin1String("AppleScrollerPagingBehavior"), false);
       
   452     qt_scrollbar_jump_to_pos = appleValue.toBool();
       
   453     //collapse
       
   454     /* First worked as of 10.3.3 */
       
   455     appleValue = appleSettings.value(QLatin1String("AppleMiniaturizeOnDoubleClick"), true);
       
   456     qt_mac_collapse_on_dblclick = appleValue.toBool();
       
   457 
       
   458     // Anti-aliasing threshold
       
   459     appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
       
   460     if (appleValue.isValid())
       
   461         qt_antialiasing_threshold = appleValue.toInt();
       
   462 
       
   463 #ifdef DEBUG_PLATFORM_SETTINGS
       
   464     qDebug("qt_mac_update_os_settings *********************************************************************");
       
   465 #endif
       
   466     { // setup the global palette
       
   467         QColor qc;
       
   468         (void) QApplication::style();  // trigger creation of application style and system palettes
       
   469         QPalette pal = *QApplicationPrivate::sys_pal;
       
   470 
       
   471         pal.setBrush( QPalette::Active, QPalette::Highlight, qcolorForTheme(kThemeBrushPrimaryHighlightColor) );
       
   472         pal.setBrush( QPalette::Inactive, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
       
   473 
       
   474         pal.setBrush( QPalette::Disabled, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
       
   475         pal.setBrush( QPalette::Active, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonActiveDarkShadow) );
       
   476 
       
   477         pal.setBrush( QPalette::Inactive, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
       
   478         pal.setBrush( QPalette::Disabled, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
       
   479 
       
   480         qc = qcolorForThemeTextColor(kThemeTextColorDialogActive);
       
   481         pal.setColor(QPalette::Active, QPalette::Text, qc);
       
   482         pal.setColor(QPalette::Active, QPalette::WindowText, qc);
       
   483         pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
       
   484 
       
   485         qc = qcolorForThemeTextColor(kThemeTextColorDialogInactive);
       
   486         pal.setColor(QPalette::Inactive, QPalette::Text, qc);
       
   487         pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
       
   488         pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
       
   489         pal.setColor(QPalette::Disabled, QPalette::Text, qc);
       
   490         pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
       
   491         pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
       
   492         pal.setBrush(QPalette::ToolTipBase, QColor(255, 255, 199));
       
   493 
       
   494         if (!QApplicationPrivate::sys_pal || *QApplicationPrivate::sys_pal != pal) {
       
   495             QApplicationPrivate::setSystemPalette(pal);
       
   496             QApplication::setPalette(pal);
       
   497         }
       
   498 #ifdef DEBUG_PLATFORM_SETTINGS
       
   499         qt_mac_debug_palette(pal, QApplication::palette(), "Global Palette");
       
   500 #endif
       
   501     }
       
   502 
       
   503     QFont fnt = qfontForThemeFont(kThemeApplicationFont);
       
   504 #ifdef DEBUG_PLATFORM_SETTINGS
       
   505     qDebug("qt-internal: Font for Application [%s::%d::%d::%d]",
       
   506            fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
       
   507 #endif
       
   508     if (!QApplicationPrivate::sys_font || *QApplicationPrivate::sys_font != fnt)
       
   509         QApplicationPrivate::setSystemFont(fnt);
       
   510 
       
   511     { //setup the fonts
       
   512         struct FontMap {
       
   513             FontMap(const char *qc, short fk) : qt_class(qc), font_key(fk) { }
       
   514             const char *const qt_class;
       
   515             short font_key;
       
   516         } mac_widget_fonts[] = {
       
   517             FontMap("QPushButton", kThemePushButtonFont),
       
   518             FontMap("QListView", kThemeViewsFont),
       
   519             FontMap("QListBox", kThemeViewsFont),
       
   520             FontMap("QTitleBar", kThemeWindowTitleFont),
       
   521             FontMap("QMenuBar", kThemeMenuTitleFont),
       
   522             FontMap("QMenu", kThemeMenuItemFont),
       
   523             FontMap("QComboMenuItem", kThemeSystemFont),
       
   524             FontMap("QHeaderView", kThemeSmallSystemFont),
       
   525             FontMap("Q3Header", kThemeSmallSystemFont),
       
   526             FontMap("QTipLabel", kThemeSmallSystemFont),
       
   527             FontMap("QLabel", kThemeSystemFont),
       
   528             FontMap("QToolButton", kThemeSmallSystemFont),
       
   529             FontMap("QMenuItem", kThemeMenuItemCmdKeyFont),  // It doesn't exist, but its unique.
       
   530             FontMap("QComboLineEdit", kThemeViewsFont),  // It doesn't exist, but its unique.
       
   531             FontMap("QSmallFont", kThemeSmallSystemFont),  // It doesn't exist, but its unique.
       
   532             FontMap("QMiniFont", kThemeMiniSystemFont),  // It doesn't exist, but its unique.
       
   533             FontMap(0, 0) };
       
   534         for(int i = 0; mac_widget_fonts[i].qt_class; i++) {
       
   535             QFont fnt = qfontForThemeFont(mac_widget_fonts[i].font_key);
       
   536             bool set_font = true;
       
   537             FontHash *hash = qt_app_fonts_hash();
       
   538             if (!hash->isEmpty()) {
       
   539                 FontHash::const_iterator it
       
   540                                         = hash->constFind(mac_widget_fonts[i].qt_class);
       
   541                 if (it != hash->constEnd())
       
   542                     set_font = (fnt != *it);
       
   543             }
       
   544             if (set_font) {
       
   545                 QApplication::setFont(fnt, mac_widget_fonts[i].qt_class);
       
   546 #ifdef DEBUG_PLATFORM_SETTINGS
       
   547                 qDebug("qt-internal: Font for %s [%s::%d::%d::%d]", mac_widget_fonts[i].qt_class,
       
   548                        fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
       
   549 #endif
       
   550             }
       
   551         }
       
   552     }
       
   553     QApplicationPrivate::initializeWidgetPaletteHash();
       
   554 #ifdef DEBUG_PLATFORM_SETTINGS
       
   555     qDebug("qt_mac_update_os_settings END !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
       
   556 #endif
       
   557 }
       
   558 
       
   559 void QApplicationPrivate::initializeWidgetPaletteHash()
       
   560 {
       
   561     { //setup the palette
       
   562         struct PaletteMap {
       
   563             inline PaletteMap(const char *qc, ThemeBrush a, ThemeBrush i) :
       
   564                 qt_class(qc), active(a), inactive(i) { }
       
   565             const char *const qt_class;
       
   566             ThemeBrush active, inactive;
       
   567         } mac_widget_colors[] = {
       
   568             PaletteMap("QToolButton", kThemeTextColorBevelButtonActive, kThemeTextColorBevelButtonInactive),
       
   569             PaletteMap("QAbstractButton", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
       
   570             PaletteMap("QHeaderView", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
       
   571             PaletteMap("Q3Header", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
       
   572             PaletteMap("QComboBox", kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive),
       
   573             PaletteMap("QAbstractItemView", kThemeTextColorListView, kThemeTextColorDialogInactive),
       
   574             PaletteMap("QMessageBoxLabel", kThemeTextColorAlertActive, kThemeTextColorAlertInactive),
       
   575             PaletteMap("QTabBar", kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive),
       
   576             PaletteMap("QLabel", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
       
   577             PaletteMap("QGroupBox", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
       
   578             PaletteMap("QMenu", kThemeTextColorPopupLabelActive, kThemeTextColorPopupLabelInactive),
       
   579             PaletteMap("QTextEdit", 0, 0),
       
   580             PaletteMap("QTextControl", 0, 0),
       
   581             PaletteMap("QLineEdit", 0, 0),
       
   582             PaletteMap(0, 0, 0) };
       
   583         QColor qc;
       
   584         for(int i = 0; mac_widget_colors[i].qt_class; i++) {
       
   585             QPalette pal;
       
   586             if (mac_widget_colors[i].active != 0) {
       
   587                 qc = qcolorForThemeTextColor(mac_widget_colors[i].active);
       
   588                 pal.setColor(QPalette::Active, QPalette::Text, qc);
       
   589                 pal.setColor(QPalette::Active, QPalette::WindowText, qc);
       
   590                 pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
       
   591                 qc = qcolorForThemeTextColor(mac_widget_colors[i].inactive);
       
   592                 pal.setColor(QPalette::Inactive, QPalette::Text, qc);
       
   593                 pal.setColor(QPalette::Disabled, QPalette::Text, qc);
       
   594                 pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
       
   595                 pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
       
   596                 pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
       
   597                 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
       
   598             }
       
   599             if (!strcmp(mac_widget_colors[i].qt_class, "QMenu")) {
       
   600                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemActive);
       
   601                 pal.setBrush(QPalette::ButtonText, qc);
       
   602                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
       
   603                 pal.setBrush(QPalette::HighlightedText, qc);
       
   604                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemDisabled);
       
   605                 pal.setBrush(QPalette::Disabled, QPalette::Text, qc);
       
   606             } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractButton")
       
   607                       || !strcmp(mac_widget_colors[i].qt_class, "QHeaderView")
       
   608                       || !strcmp(mac_widget_colors[i].qt_class, "Q3Header")) { //special
       
   609                 pal.setColor(QPalette::Disabled, QPalette::ButtonText,
       
   610                              pal.color(QPalette::Disabled, QPalette::Text));
       
   611                 pal.setColor(QPalette::Inactive, QPalette::ButtonText,
       
   612                              pal.color(QPalette::Inactive, QPalette::Text));
       
   613                 pal.setColor(QPalette::Active, QPalette::ButtonText,
       
   614                              pal.color(QPalette::Active, QPalette::Text));
       
   615             } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractItemView")) {
       
   616                 pal.setBrush(QPalette::Active, QPalette::Highlight,
       
   617                              qcolorForTheme(kThemeBrushAlternatePrimaryHighlightColor));
       
   618                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
       
   619                 pal.setBrush(QPalette::Active, QPalette::HighlightedText, qc);
       
   620 #if 1
       
   621                 pal.setBrush(QPalette::Inactive, QPalette::Text,
       
   622                               pal.brush(QPalette::Active, QPalette::Text));
       
   623                 pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
       
   624                               pal.brush(QPalette::Active, QPalette::Text));
       
   625 #endif
       
   626             } else if (!strcmp(mac_widget_colors[i].qt_class, "QTextEdit")
       
   627                        || !strcmp(mac_widget_colors[i].qt_class, "QTextControl")) {
       
   628                 pal.setBrush(QPalette::Inactive, QPalette::Text,
       
   629                               pal.brush(QPalette::Active, QPalette::Text));
       
   630                 pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
       
   631                               pal.brush(QPalette::Active, QPalette::Text));
       
   632             } else if (!strcmp(mac_widget_colors[i].qt_class, "QLineEdit")) {
       
   633                 pal.setBrush(QPalette::Disabled, QPalette::Base,
       
   634                              pal.brush(QPalette::Active, QPalette::Base));
       
   635             }
       
   636 
       
   637             bool set_palette = true;
       
   638             PaletteHash *phash = qt_app_palettes_hash();
       
   639             if (!phash->isEmpty()) {
       
   640                 PaletteHash::const_iterator it
       
   641                                     = phash->constFind(mac_widget_colors[i].qt_class);
       
   642                 if (it != phash->constEnd())
       
   643                     set_palette = (pal != *it);
       
   644             }
       
   645             if (set_palette) {
       
   646                 QApplication::setPalette(pal, mac_widget_colors[i].qt_class);
       
   647 #ifdef DEBUG_PLATFORM_SETTINGS
       
   648                 qt_mac_debug_palette(pal, QApplication::palette(), QLatin1String("Palette for ") + QString::fromLatin1(mac_widget_colors[i].qt_class));
       
   649 #endif
       
   650             }
       
   651         }
       
   652     }
       
   653 }
       
   654 
       
   655 static void qt_mac_event_release(EventRef &event)
       
   656 {
       
   657     ReleaseEvent(event);
       
   658     event = 0;
       
   659 }
       
   660 #ifndef QT_MAC_USE_COCOA
       
   661 static void qt_mac_event_release(QWidget *w, EventRef &event)
       
   662 {
       
   663     if (event) {
       
   664         QWidget *widget = 0;
       
   665         if (GetEventParameter(event, kEventParamQWidget, typeQWidget, 0, sizeof(widget), 0, &widget) == noErr
       
   666            && w == widget) {
       
   667             if (IsEventInQueue(GetMainEventQueue(), event))
       
   668                 RemoveEventFromQueue(GetMainEventQueue(), event);
       
   669             qt_mac_event_release(event);
       
   670         }
       
   671     }
       
   672 }
       
   673 
       
   674 static bool qt_mac_event_remove(EventRef &event)
       
   675 {
       
   676     if (event) {
       
   677         if (IsEventInQueue(GetMainEventQueue(), event))
       
   678             RemoveEventFromQueue(GetMainEventQueue(), event);
       
   679         qt_mac_event_release(event);
       
   680         return true;
       
   681     }
       
   682     return false;
       
   683 }
       
   684 #endif
       
   685 
       
   686 /* sheets */
       
   687 #ifndef QT_MAC_USE_COCOA
       
   688 static EventRef request_showsheet_pending = 0;
       
   689 #endif
       
   690 void qt_event_request_showsheet(QWidget *w)
       
   691 {
       
   692     Q_ASSERT(qt_mac_is_macsheet(w));
       
   693 #ifdef QT_MAC_USE_COCOA
       
   694     [NSApp beginSheet:qt_mac_window_for(w) modalForWindow:qt_mac_window_for(w->parentWidget())
       
   695         modalDelegate:nil didEndSelector:nil contextInfo:0];
       
   696 #else
       
   697     qt_mac_event_remove(request_showsheet_pending);
       
   698     CreateEvent(0, kEventClassQt, kEventQtRequestShowSheet, GetCurrentEventTime(),
       
   699                 kEventAttributeUserEvent, &request_showsheet_pending);
       
   700     SetEventParameter(request_showsheet_pending, kEventParamQWidget, typeQWidget, sizeof(w), &w);
       
   701     PostEventToQueue(GetMainEventQueue(), request_showsheet_pending, kEventPriorityStandard);
       
   702 #endif
       
   703 }
       
   704 
       
   705 static void qt_post_window_change_event(QWidget *widget)
       
   706 {
       
   707     qt_widget_private(widget)->needWindowChange = true;
       
   708     QEvent *glWindowChangeEvent = new QEvent(QEvent::MacGLWindowChange);
       
   709     QApplication::postEvent(widget, glWindowChangeEvent);
       
   710 }
       
   711 
       
   712 /*
       
   713     Posts updates to all child and grandchild OpenGL widgets for the given widget.
       
   714 */
       
   715 static void qt_mac_update_child_gl_widgets(QWidget *widget)
       
   716 {
       
   717     if (widget->isWindow())
       
   718         return;
       
   719 
       
   720     // Update all OpenGL child widgets for the given widget.
       
   721     QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
       
   722     QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
       
   723     QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
       
   724 
       
   725     for (;it != end; ++it) {
       
   726         qt_post_window_change_event(it->widget);
       
   727     }
       
   728 }
       
   729 
       
   730 /*
       
   731     Sends updates to all child and grandchild gl widgets that have updates pending.
       
   732 */
       
   733 void qt_mac_send_posted_gl_updates(QWidget *widget)
       
   734 {
       
   735     QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
       
   736     QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
       
   737     QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
       
   738 
       
   739     for (;it != end; ++it) {
       
   740         QWidget *glWidget = it->widget;
       
   741         if (qt_widget_private(glWidget)->needWindowChange) {
       
   742             QEvent glChangeEvent(QEvent::MacGLWindowChange);
       
   743             QApplication::sendEvent(glWidget, &glChangeEvent);
       
   744         }
       
   745     }
       
   746 }
       
   747 
       
   748 /*
       
   749     Posts updates to all OpenGL widgets within the window that the given widget intersects.
       
   750 */
       
   751 static void qt_mac_update_intersected_gl_widgets(QWidget *widget)
       
   752 {
       
   753 #ifndef QT_MAC_USE_COCOA
       
   754     QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget->window())->glWidgets;
       
   755     if (glWidgets.isEmpty())
       
   756         return;
       
   757 
       
   758     // Exit if the window has not been created yet (mapToGlobal/size will force create it)
       
   759     if (widget->testAttribute(Qt::WA_WState_Created) == false || HIViewGetWindow(qt_mac_nativeview_for(widget)) == 0)
       
   760         return;
       
   761 
       
   762     const QRect globalWidgetRect = QRect(widget->mapToGlobal(QPoint(0, 0)), widget->size());
       
   763 
       
   764     QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
       
   765     QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
       
   766 
       
   767     for (;it != end; ++it){
       
   768         QWidget *glWidget = it->widget;
       
   769         const QRect globalGlWidgetRect = QRect(glWidget->mapToGlobal(QPoint(0, 0)), glWidget->size());
       
   770         if (globalWidgetRect.intersects(globalGlWidgetRect)) {
       
   771             qt_post_window_change_event(glWidget);
       
   772             it->lastUpdateWidget = widget;
       
   773         } else if (it->lastUpdateWidget == widget) {
       
   774             // Update the gl wigets that the widget intersected the last time around, 
       
   775             // and that we are not intersecting now. This prevents paint errors when the 
       
   776             // intersecting widget leaves a gl widget.
       
   777             qt_post_window_change_event(glWidget);
       
   778             it->lastUpdateWidget = 0;            
       
   779         }
       
   780     }
       
   781 #else
       
   782     Q_UNUSED(widget);
       
   783 #endif
       
   784 }
       
   785 
       
   786 /*
       
   787     Posts a kEventQtRequestWindowChange event to the main Carbon event queue.
       
   788 */
       
   789 static EventRef request_window_change_pending = 0;
       
   790 Q_GUI_EXPORT void qt_event_request_window_change()
       
   791 {
       
   792     if(request_window_change_pending)
       
   793         return;
       
   794 
       
   795     CreateEvent(0, kEventClassQt, kEventQtRequestWindowChange, GetCurrentEventTime(),
       
   796                 kEventAttributeUserEvent, &request_window_change_pending);
       
   797     PostEventToQueue(GetMainEventQueue(), request_window_change_pending, kEventPriorityHigh);
       
   798 }
       
   799 
       
   800 /* window changing. This is a hack around Apple's missing functionality, pending the toolbox
       
   801    team fix. --Sam */
       
   802 Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget)
       
   803 {
       
   804     if (!widget)
       
   805         return;
       
   806 
       
   807     // Post a kEventQtRequestWindowChange event. This event is semi-public,
       
   808     // don't remove this line!
       
   809     qt_event_request_window_change();
       
   810     
       
   811     // Post update request on gl widgets unconditionally. 
       
   812     if (qt_widget_private(widget)->isGLWidget == true) {
       
   813         qt_post_window_change_event(widget);
       
   814         return;
       
   815     }
       
   816 
       
   817     qt_mac_update_child_gl_widgets(widget);
       
   818     qt_mac_update_intersected_gl_widgets(widget);
       
   819 }
       
   820 
       
   821 /* activation */
       
   822 static struct {
       
   823     QPointer<QWidget> widget;
       
   824     EventRef event;
       
   825     EventLoopTimerRef timer;
       
   826     EventLoopTimerUPP timerUPP;
       
   827 } request_activate_pending = { 0, 0, 0, 0 };
       
   828 bool qt_event_remove_activate()
       
   829 {
       
   830     if (request_activate_pending.timer) {
       
   831         RemoveEventLoopTimer(request_activate_pending.timer);
       
   832         request_activate_pending.timer = 0;
       
   833     }
       
   834     if (request_activate_pending.event)
       
   835         qt_mac_event_release(request_activate_pending.event);
       
   836     return true;
       
   837 }
       
   838 
       
   839 void qt_event_activate_timer_callbk(EventLoopTimerRef r, void *)
       
   840 {
       
   841     EventLoopTimerRef otc = request_activate_pending.timer;
       
   842     qt_event_remove_activate();
       
   843     if (r == otc && !request_activate_pending.widget.isNull()) {
       
   844         const QWidget *tlw = request_activate_pending.widget->window();
       
   845         Qt::WindowType wt = tlw->windowType();
       
   846         if (tlw->isVisible()
       
   847                && ((wt != Qt::Desktop && wt != Qt::Popup && wt != Qt::Tool) || tlw->isModal())) {
       
   848             CreateEvent(0, kEventClassQt, kEventQtRequestActivate, GetCurrentEventTime(),
       
   849                         kEventAttributeUserEvent, &request_activate_pending.event);
       
   850             PostEventToQueue(GetMainEventQueue(), request_activate_pending.event, kEventPriorityHigh);
       
   851         }
       
   852     }
       
   853 }
       
   854 
       
   855 void qt_event_request_activate(QWidget *w)
       
   856 {
       
   857     if (w == request_activate_pending.widget)
       
   858         return;
       
   859 
       
   860     /* We put these into a timer because due to order of events being sent we need to be sure this
       
   861        comes from inside of the event loop */
       
   862     qt_event_remove_activate();
       
   863     if (!request_activate_pending.timerUPP)
       
   864         request_activate_pending.timerUPP = NewEventLoopTimerUPP(qt_event_activate_timer_callbk);
       
   865     request_activate_pending.widget = w;
       
   866     InstallEventLoopTimer(GetMainEventLoop(), 0, 0, request_activate_pending.timerUPP, 0, &request_activate_pending.timer);
       
   867 }
       
   868 
       
   869 
       
   870 /* menubars */
       
   871 #ifndef QT_MAC_USE_COCOA
       
   872 static EventRef request_menubarupdate_pending = 0;
       
   873 #endif
       
   874 void qt_event_request_menubarupdate()
       
   875 {
       
   876 #ifndef QT_MAC_USE_COCOA
       
   877     if (request_menubarupdate_pending) {
       
   878         if (IsEventInQueue(GetMainEventQueue(), request_menubarupdate_pending))
       
   879             return;
       
   880 #ifdef DEBUG_DROPPED_EVENTS
       
   881         qDebug("%s:%d Whoa, we dropped an event on the floor!", __FILE__, __LINE__);
       
   882 #endif
       
   883     }
       
   884 
       
   885     CreateEvent(0, kEventClassQt, kEventQtRequestMenubarUpdate, GetCurrentEventTime(),
       
   886                 kEventAttributeUserEvent, &request_menubarupdate_pending);
       
   887     PostEventToQueue(GetMainEventQueue(), request_menubarupdate_pending, kEventPriorityHigh);
       
   888 #else
       
   889     // Just call this. The request has the benefit that we don't call this multiple times, but
       
   890     // we can optimize this.
       
   891     QMenuBar::macUpdateMenuBar();
       
   892 #endif
       
   893 }
       
   894 
       
   895 #ifndef QT_MAC_USE_COCOA
       
   896 //context menu
       
   897 static EventRef request_context_pending = 0;
       
   898 static void qt_event_request_context(QWidget *w=0, EventRef *where=0)
       
   899 {
       
   900     if (!where)
       
   901         where = &request_context_pending;
       
   902     if (*where)
       
   903         return;
       
   904     CreateEvent(0, kEventClassQt, kEventQtRequestContext, GetCurrentEventTime(),
       
   905                 kEventAttributeUserEvent, where);
       
   906     if (w)
       
   907         SetEventParameter(*where, kEventParamQWidget, typeQWidget, sizeof(w), &w);
       
   908     PostEventToQueue(GetMainEventQueue(), *where, kEventPriorityStandard);
       
   909 }
       
   910 #endif
       
   911 
       
   912 void QApplicationPrivate::createEventDispatcher()
       
   913 {
       
   914     Q_Q(QApplication);
       
   915     if (q->type() != QApplication::Tty)
       
   916         eventDispatcher = new QEventDispatcherMac(q);
       
   917     else
       
   918         eventDispatcher = new QEventDispatcherUNIX(q);
       
   919 }
       
   920 
       
   921 /* clipboard */
       
   922 void qt_event_send_clipboard_changed()
       
   923 {
       
   924 #ifndef QT_MAC_USE_COCOA
       
   925     AppleEvent ae;
       
   926     if (AECreateAppleEvent(kEventClassQt, typeAEClipboardChanged, 0, kAutoGenerateReturnID, kAnyTransactionID, &ae) != noErr)
       
   927         qDebug("Can't happen!!");
       
   928     AppleEvent reply;
       
   929     AESend(&ae, &reply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, 0, 0);
       
   930 #endif
       
   931 }
       
   932 
       
   933 /* app menu */
       
   934 static QMenu *qt_mac_dock_menu = 0;
       
   935 Q_GUI_EXPORT void qt_mac_set_dock_menu(QMenu *menu)
       
   936 {
       
   937     qt_mac_dock_menu = menu;
       
   938 #ifdef QT_MAC_USE_COCOA
       
   939     [NSApp setDockMenu:menu->macMenu()];
       
   940 #else
       
   941     SetApplicationDockTileMenu(menu->macMenu());
       
   942 #endif
       
   943 }
       
   944 
       
   945 /* events that hold pointers to widgets, must be cleaned up like this */
       
   946 void qt_mac_event_release(QWidget *w)
       
   947 {
       
   948     if (w) {
       
   949 #ifndef QT_MAC_USE_COCOA
       
   950         qt_mac_event_release(w, request_showsheet_pending);
       
   951         qt_mac_event_release(w, request_context_pending);
       
   952 #endif
       
   953         if (w == qt_mac_dock_menu) {
       
   954             qt_mac_dock_menu = 0;
       
   955 #ifndef QT_MAC_USE_COCOA
       
   956             SetApplicationDockTileMenu(0);
       
   957 #else
       
   958             [NSApp setDockMenu:0];
       
   959 #endif
       
   960         }
       
   961     }
       
   962 }
       
   963 
       
   964 struct QMacAppleEventTypeSpec {
       
   965     AEEventClass mac_class;
       
   966     AEEventID mac_id;
       
   967 } app_apple_events[] = {
       
   968     { kCoreEventClass, kAEQuitApplication },
       
   969     { kCoreEventClass, kAEOpenDocuments }
       
   970 };
       
   971 
       
   972 #ifndef QT_MAC_USE_COCOA
       
   973 
       
   974 #if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
       
   975 enum
       
   976 {
       
   977     kEventMouseScroll                          = 11,
       
   978     kEventParamMouseWheelSmoothVerticalDelta   = 'saxy',
       
   979     kEventParamMouseWheelSmoothHorizontalDelta = 'saxx',
       
   980 };
       
   981 #endif
       
   982 
       
   983 /* watched events */
       
   984 static EventTypeSpec app_events[] = {
       
   985     { kEventClassQt, kEventQtRequestWindowChange },
       
   986     { kEventClassQt, kEventQtRequestShowSheet },
       
   987     { kEventClassQt, kEventQtRequestContext },
       
   988     { kEventClassQt, kEventQtRequestActivate },
       
   989     { kEventClassQt, kEventQtRequestMenubarUpdate },
       
   990 
       
   991     { kEventClassWindow, kEventWindowActivated },
       
   992     { kEventClassWindow, kEventWindowDeactivated },
       
   993 
       
   994     { kEventClassMouse, kEventMouseScroll },
       
   995     { kEventClassMouse, kEventMouseWheelMoved },
       
   996     { kEventClassMouse, kEventMouseDown },
       
   997     { kEventClassMouse, kEventMouseUp },
       
   998     { kEventClassMouse, kEventMouseDragged },
       
   999     { kEventClassMouse, kEventMouseMoved },
       
  1000 
       
  1001     { kEventClassTablet, kEventTabletProximity },
       
  1002 
       
  1003     { kEventClassApplication, kEventAppActivated },
       
  1004     { kEventClassApplication, kEventAppDeactivated },
       
  1005     { kEventClassApplication, kEventAppAvailableWindowBoundsChanged },
       
  1006 
       
  1007     //    { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
       
  1008     { kEventClassKeyboard, kEventRawKeyModifiersChanged },
       
  1009     { kEventClassKeyboard, kEventRawKeyRepeat },
       
  1010     { kEventClassKeyboard, kEventRawKeyUp },
       
  1011     { kEventClassKeyboard, kEventRawKeyDown },
       
  1012 
       
  1013     { kEventClassCommand, kEventCommandProcess },
       
  1014 
       
  1015     { kEventClassAppleEvent, kEventAppleEvent },
       
  1016 
       
  1017     { kAppearanceEventClass, kAEAppearanceChanged }
       
  1018 };
       
  1019 
       
  1020 void qt_init_app_proc_handler()
       
  1021 {
       
  1022     InstallEventHandler(GetApplicationEventTarget(), app_proc_handlerUPP,
       
  1023                         GetEventTypeCount(app_events), app_events, (void *)qApp,
       
  1024                         &app_proc_handler);
       
  1025 }
       
  1026 #endif // QT_MAC_USE_COCOA
       
  1027 
       
  1028 static void qt_init_tablet_proximity_handler()
       
  1029 {
       
  1030     EventTypeSpec	tabletProximityEvent = { kEventClassTablet, kEventTabletProximity };
       
  1031     InstallEventHandler(GetEventMonitorTarget(), tablet_proximity_UPP,
       
  1032                         1, &tabletProximityEvent, qApp, &tablet_proximity_handler);
       
  1033 }
       
  1034 
       
  1035 static void qt_release_tablet_proximity_handler()
       
  1036 {
       
  1037     RemoveEventHandler(tablet_proximity_handler);
       
  1038 }
       
  1039 
       
  1040 QString QApplicationPrivate::appName() const
       
  1041 {
       
  1042     static QString applName;
       
  1043     if (applName.isEmpty()) {
       
  1044         applName = QCoreApplicationPrivate::macMenuBarName();
       
  1045         ProcessSerialNumber psn;
       
  1046         if (applName.isEmpty() && qt_is_gui_used && GetCurrentProcess(&psn) == noErr) {
       
  1047             QCFString cfstr;
       
  1048             CopyProcessName(&psn, &cfstr);
       
  1049             applName = cfstr;
       
  1050         }
       
  1051     }
       
  1052     return applName;
       
  1053 }
       
  1054 
       
  1055 void qt_release_app_proc_handler()
       
  1056 {
       
  1057 #ifndef QT_MAC_USE_COCOA
       
  1058     if (app_proc_handler) {
       
  1059         RemoveEventHandler(app_proc_handler);
       
  1060         app_proc_handler = 0;
       
  1061     }
       
  1062 #endif
       
  1063 }
       
  1064 
       
  1065 void qt_color_profile_changed(CFNotificationCenterRef, void *, CFStringRef, const void *,
       
  1066                               CFDictionaryRef)
       
  1067 {
       
  1068     QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
       
  1069 }
       
  1070 /* platform specific implementations */
       
  1071 void qt_init(QApplicationPrivate *priv, int)
       
  1072 {
       
  1073     if (qt_is_gui_used) {
       
  1074         CGDisplayRegisterReconfigurationCallback(qt_mac_display_change_callbk, 0);
       
  1075         CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
       
  1076         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
       
  1077                                         kCMDeviceUnregisteredNotification, 0,
       
  1078                                         CFNotificationSuspensionBehaviorDeliverImmediately);
       
  1079         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
       
  1080                                         kCMDefaultDeviceNotification, 0,
       
  1081                                         CFNotificationSuspensionBehaviorDeliverImmediately);
       
  1082         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
       
  1083                                         kCMDeviceProfilesNotification, 0,
       
  1084                                         CFNotificationSuspensionBehaviorDeliverImmediately);
       
  1085         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
       
  1086                                         kCMDefaultDeviceProfileNotification, 0,
       
  1087                                         CFNotificationSuspensionBehaviorDeliverImmediately);
       
  1088         ProcessSerialNumber psn;
       
  1089         if (GetCurrentProcess(&psn) == noErr) {
       
  1090             // Jambi needs to transform itself since most people aren't "used"
       
  1091             // to putting things in bundles, but other people may actually not
       
  1092             // want to tranform the process (running as a helper or something)
       
  1093             // so don't do that for them. This means checking both LSUIElement
       
  1094             // and LSBackgroundOnly. If you set them both... well, you
       
  1095             // shouldn't do that.
       
  1096 
       
  1097             bool forceTransform = true;
       
  1098             CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
       
  1099                                                                    CFSTR("LSUIElement"));
       
  1100             if (value) {
       
  1101                 CFTypeID valueType = CFGetTypeID(value);
       
  1102                 // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
       
  1103                 // A number less so, but OK.
       
  1104                 if (valueType == CFStringGetTypeID())
       
  1105                     forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
       
  1106                 else if (valueType == CFBooleanGetTypeID())
       
  1107                     forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
       
  1108                 else if (valueType == CFNumberGetTypeID()) {
       
  1109                     int valueAsInt;
       
  1110                     CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
       
  1111                     forceTransform = !valueAsInt;
       
  1112                 }
       
  1113             }
       
  1114 
       
  1115             if (forceTransform) {
       
  1116                 value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
       
  1117                                                              CFSTR("LSBackgroundOnly"));
       
  1118                 if (value) {
       
  1119                     CFTypeID valueType = CFGetTypeID(value);
       
  1120                     if (valueType == CFBooleanGetTypeID())
       
  1121                         forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
       
  1122                     else if (valueType == CFStringGetTypeID())
       
  1123                         forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
       
  1124                     else if (valueType == CFNumberGetTypeID()) {
       
  1125                         int valueAsInt;
       
  1126                         CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
       
  1127                         forceTransform = !valueAsInt;
       
  1128                     }
       
  1129                 }
       
  1130             }
       
  1131 
       
  1132 
       
  1133             if (forceTransform) {
       
  1134                 TransformProcessType(&psn, kProcessTransformToForegroundApplication);
       
  1135             }
       
  1136         }
       
  1137     }
       
  1138 
       
  1139     char **argv = priv->argv;
       
  1140 
       
  1141     // Get command line params
       
  1142     if (int argc = priv->argc) {
       
  1143         int i, j = 1;
       
  1144         QString passed_psn;
       
  1145         for(i=1; i < argc; i++) {
       
  1146             if (argv[i] && *argv[i] != '-') {
       
  1147                 argv[j++] = argv[i];
       
  1148                 continue;
       
  1149             }
       
  1150             QByteArray arg(argv[i]);
       
  1151 #if defined(QT_DEBUG)
       
  1152             if (arg == "-nograb")
       
  1153                 appNoGrab = !appNoGrab;
       
  1154             else
       
  1155 #endif // QT_DEBUG
       
  1156                 if (arg.left(5) == "-psn_") {
       
  1157                     passed_psn = QString::fromLatin1(arg.mid(6));
       
  1158                 } else {
       
  1159                     argv[j++] = argv[i];
       
  1160                 }
       
  1161         }
       
  1162         if (j < priv->argc) {
       
  1163             priv->argv[j] = 0;
       
  1164             priv->argc = j;
       
  1165         }
       
  1166 
       
  1167         //special hack to change working directory (for an app bundle) when running from finder
       
  1168         if (!passed_psn.isNull() && QDir::currentPath() == QLatin1String("/")) {
       
  1169             QCFType<CFURLRef> bundleURL(CFBundleCopyBundleURL(CFBundleGetMainBundle()));
       
  1170             QString qbundlePath = QCFString(CFURLCopyFileSystemPath(bundleURL,
       
  1171                                             kCFURLPOSIXPathStyle));
       
  1172             if (qbundlePath.endsWith(QLatin1String(".app")))
       
  1173                 QDir::setCurrent(qbundlePath.section(QLatin1Char('/'), 0, -2));
       
  1174         }
       
  1175    }
       
  1176 
       
  1177     QMacPasteboardMime::initialize();
       
  1178 
       
  1179     qApp->setObjectName(priv->appName());
       
  1180     if (qt_is_gui_used) {
       
  1181         QColormap::initialize();
       
  1182         QFont::initialize();
       
  1183         QCursorData::initialize();
       
  1184         QCoreGraphicsPaintEngine::initialize();
       
  1185 #ifndef QT_NO_ACCESSIBILITY
       
  1186         QAccessible::initialize();
       
  1187 #endif
       
  1188         QMacInputContext::initialize();
       
  1189         QApplicationPrivate::inputContext = new QMacInputContext;
       
  1190 
       
  1191         if (QApplication::desktopSettingsAware())
       
  1192             qt_mac_update_os_settings();
       
  1193 #ifndef QT_MAC_USE_COCOA
       
  1194         if (!app_proc_handler) {
       
  1195             app_proc_handlerUPP = NewEventHandlerUPP(QApplicationPrivate::globalEventProcessor);
       
  1196             qt_init_app_proc_handler();
       
  1197         }
       
  1198 
       
  1199 #endif
       
  1200         if (!app_proc_ae_handlerUPP) {
       
  1201             app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor);
       
  1202             for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
       
  1203                 AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
       
  1204                         app_proc_ae_handlerUPP, SRefCon(qApp), true);
       
  1205         }
       
  1206 
       
  1207         if (QApplicationPrivate::app_style) {
       
  1208             QEvent ev(QEvent::Style);
       
  1209             qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
       
  1210         }
       
  1211     }
       
  1212     if (QApplication::desktopSettingsAware())
       
  1213         QApplicationPrivate::qt_mac_apply_settings();
       
  1214 
       
  1215     qt_mac_read_fontsmoothing_settings();
       
  1216 
       
  1217     // Cocoa application delegate
       
  1218 #ifdef QT_MAC_USE_COCOA
       
  1219     NSApplication *cocoaApp = [NSApplication sharedApplication];
       
  1220     QMacCocoaAutoReleasePool pool;
       
  1221     NSObject *oldDelegate = [cocoaApp delegate];
       
  1222     QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
       
  1223     Q_ASSERT(newDelegate);
       
  1224     [newDelegate setQtPrivate:priv];
       
  1225     // Only do things that make sense to do once, otherwise we crash.
       
  1226     if (oldDelegate != newDelegate && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
       
  1227         [newDelegate setReflectionDelegate:oldDelegate];
       
  1228         [cocoaApp setDelegate:newDelegate];
       
  1229 
       
  1230         QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
       
  1231         if ([NSBundle loadNibNamed:@"qt_menu" owner:qtMenuLoader] == false) {
       
  1232             qFatal("Qt internal error: qt_menu.nib could not be loaded. The .nib file"
       
  1233                    " should be placed in QtGui.framework/Versions/Current/Resources/ "
       
  1234                    " or in the resources directory of your application bundle.");
       
  1235         }
       
  1236 
       
  1237         [cocoaApp setMenu:[qtMenuLoader menu]];
       
  1238         [newDelegate setMenuLoader:qtMenuLoader];
       
  1239         [qtMenuLoader release];
       
  1240     }
       
  1241 #endif
       
  1242     // Register for Carbon tablet proximity events on the event monitor target.
       
  1243     // This means that we should receive proximity events even when we aren't the active application.
       
  1244     if (!tablet_proximity_handler) {
       
  1245         tablet_proximity_UPP = NewEventHandlerUPP(QApplicationPrivate::tabletProximityCallback);
       
  1246         qt_init_tablet_proximity_handler();
       
  1247     }
       
  1248    priv->native_modal_dialog_active = false;
       
  1249 
       
  1250 }
       
  1251 
       
  1252 void qt_release_apple_event_handler()
       
  1253 {
       
  1254     if(app_proc_ae_handlerUPP) {
       
  1255         for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
       
  1256             AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
       
  1257                     app_proc_ae_handlerUPP, true);
       
  1258         DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP);
       
  1259         app_proc_ae_handlerUPP = 0;
       
  1260     }
       
  1261 }
       
  1262 
       
  1263 /*****************************************************************************
       
  1264   qt_cleanup() - cleans up when the application is finished
       
  1265  *****************************************************************************/
       
  1266 
       
  1267 void qt_cleanup()
       
  1268 {
       
  1269     CGDisplayRemoveReconfigurationCallback(qt_mac_display_change_callbk, 0);
       
  1270     CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
       
  1271     CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceUnregisteredNotification, 0);
       
  1272     CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceNotification, 0);
       
  1273     CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceProfilesNotification, 0);
       
  1274     CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceProfileNotification, 0);
       
  1275 
       
  1276 #ifndef QT_MAC_USE_COCOA
       
  1277     qt_release_app_proc_handler();
       
  1278     if (app_proc_handlerUPP) {
       
  1279         DisposeEventHandlerUPP(app_proc_handlerUPP);
       
  1280         app_proc_handlerUPP = 0;
       
  1281     }
       
  1282 #endif
       
  1283     qt_release_apple_event_handler();
       
  1284     qt_release_tablet_proximity_handler();
       
  1285     if (tablet_proximity_UPP)
       
  1286         DisposeEventHandlerUPP(tablet_proximity_UPP);
       
  1287 
       
  1288     QPixmapCache::clear();
       
  1289     if (qt_is_gui_used) {
       
  1290 #ifndef QT_NO_ACCESSIBILITY
       
  1291         QAccessible::cleanup();
       
  1292 #endif
       
  1293         QMacInputContext::cleanup();
       
  1294         QCursorData::cleanup();
       
  1295         QFont::cleanup();
       
  1296         QColormap::cleanup();
       
  1297         if (qt_mac_safe_pdev) {
       
  1298             delete qt_mac_safe_pdev;
       
  1299             qt_mac_safe_pdev = 0;
       
  1300         }
       
  1301         extern void qt_mac_unregister_widget(); // qapplication_mac.cpp
       
  1302         qt_mac_unregister_widget();
       
  1303     }
       
  1304 }
       
  1305 
       
  1306 /*****************************************************************************
       
  1307   Platform specific global and internal functions
       
  1308  *****************************************************************************/
       
  1309 void qt_updated_rootinfo()
       
  1310 {
       
  1311 }
       
  1312 
       
  1313 bool qt_wstate_iconified(WId)
       
  1314 {
       
  1315     return false;
       
  1316 }
       
  1317 
       
  1318 /*****************************************************************************
       
  1319   Platform specific QApplication members
       
  1320  *****************************************************************************/
       
  1321 extern QWidget * mac_mouse_grabber;
       
  1322 extern QWidget * mac_keyboard_grabber;
       
  1323 
       
  1324 #ifdef QT3_SUPPORT
       
  1325 void QApplication::setMainWidget(QWidget *mainWidget)
       
  1326 {
       
  1327     QApplicationPrivate::main_widget = mainWidget;
       
  1328     if (QApplicationPrivate::main_widget && windowIcon().isNull()
       
  1329         && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
       
  1330         setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
       
  1331 }
       
  1332 #endif
       
  1333 #ifndef QT_NO_CURSOR
       
  1334 
       
  1335 /*****************************************************************************
       
  1336   QApplication cursor stack
       
  1337  *****************************************************************************/
       
  1338 void QApplication::setOverrideCursor(const QCursor &cursor)
       
  1339 {
       
  1340     qApp->d_func()->cursor_list.prepend(cursor);
       
  1341 
       
  1342 #ifdef QT_MAC_USE_COCOA
       
  1343     QMacCocoaAutoReleasePool pool;
       
  1344     [static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) push];
       
  1345 #else
       
  1346     if (qApp && qApp->activeWindow())
       
  1347         qt_mac_set_cursor(&qApp->d_func()->cursor_list.first(), QCursor::pos());
       
  1348 #endif
       
  1349 }
       
  1350 
       
  1351 void QApplication::restoreOverrideCursor()
       
  1352 {
       
  1353     if (qApp->d_func()->cursor_list.isEmpty())
       
  1354         return;
       
  1355     qApp->d_func()->cursor_list.removeFirst();
       
  1356 
       
  1357 #ifdef QT_MAC_USE_COCOA
       
  1358     QMacCocoaAutoReleasePool pool;
       
  1359     [NSCursor pop];
       
  1360 #else
       
  1361     if (qApp && qApp->activeWindow()) {
       
  1362         const QCursor def(Qt::ArrowCursor);
       
  1363         qt_mac_set_cursor(qApp->d_func()->cursor_list.isEmpty() ? &def : &qApp->d_func()->cursor_list.first(), QCursor::pos());
       
  1364     }
       
  1365 #endif
       
  1366 }
       
  1367 #endif // QT_NO_CURSOR
       
  1368 
       
  1369 QWidget *QApplication::topLevelAt(const QPoint &p)
       
  1370 {
       
  1371 #ifndef QT_MAC_USE_COCOA
       
  1372     QWidget *widget;
       
  1373     qt_mac_window_at(p.x(), p.y(), &widget);
       
  1374     return widget;
       
  1375 #else
       
  1376     NSInteger windowCount;
       
  1377     NSCountWindows(&windowCount);
       
  1378     if (windowCount <= 0)
       
  1379         return 0;  // There's no window to find!
       
  1380     QMacCocoaAutoReleasePool pool;
       
  1381     NSPoint cocoaPoint = flipPoint(p);
       
  1382     QVarLengthArray<NSInteger> windowList(windowCount);
       
  1383     NSWindowList(windowCount, windowList.data());
       
  1384     for (int i = 0; i < windowCount; ++i) {
       
  1385         NSWindow *window = [NSApp windowWithWindowNumber:windowList[i]];
       
  1386         if (window && NSPointInRect(cocoaPoint, [window frame])) {
       
  1387             QWidget *candidateWindow = [window QT_MANGLE_NAMESPACE(qt_qwidget)];
       
  1388             // Check to see if there's a hole in the window where the mask is.
       
  1389             // If there is, we should just continue to see if there is a window below.
       
  1390             if (candidateWindow && !candidateWindow->mask().isEmpty()) {
       
  1391                 QPoint localPoint = candidateWindow->mapFromGlobal(p);
       
  1392                 if (!candidateWindow->mask().contains(localPoint)) {
       
  1393                     continue;
       
  1394                 }
       
  1395             }
       
  1396             return candidateWindow;
       
  1397         }
       
  1398     }
       
  1399     return 0; // Couldn't find a window at this point
       
  1400 #endif
       
  1401 }
       
  1402 
       
  1403 /*****************************************************************************
       
  1404   Main event loop
       
  1405  *****************************************************************************/
       
  1406 
       
  1407 bool QApplicationPrivate::modalState()
       
  1408 {
       
  1409     return app_do_modal;
       
  1410 }
       
  1411 
       
  1412 #ifdef QT_MAC_USE_COCOA
       
  1413 #endif
       
  1414 
       
  1415 void QApplicationPrivate::enterModal_sys(QWidget *widget)
       
  1416 {
       
  1417 #ifdef DEBUG_MODAL_EVENTS
       
  1418     Q_ASSERT(widget);
       
  1419     qDebug("Entering modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
       
  1420             widget, qt_modal_stack ? (int)qt_modal_stack->count() : -1);
       
  1421 #endif
       
  1422     if (!qt_modal_stack)
       
  1423         qt_modal_stack = new QWidgetList;
       
  1424 
       
  1425     dispatchEnterLeave(0, qt_mouseover);
       
  1426     qt_mouseover = 0;
       
  1427 
       
  1428     qt_modal_stack->insert(0, widget);
       
  1429     if (!app_do_modal)
       
  1430         qt_event_request_menubarupdate();
       
  1431     app_do_modal = true;
       
  1432     qt_button_down = 0;
       
  1433 
       
  1434 #ifdef QT_MAC_USE_COCOA
       
  1435     if (!qt_mac_is_macsheet(widget))
       
  1436         QEventDispatcherMacPrivate::beginModalSession(widget);
       
  1437 #endif
       
  1438 }
       
  1439 
       
  1440 void QApplicationPrivate::leaveModal_sys(QWidget *widget)
       
  1441 {
       
  1442     if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
       
  1443 #ifdef DEBUG_MODAL_EVENTS
       
  1444         qDebug("Leaving modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
       
  1445                widget, qt_modal_stack->count());
       
  1446 #endif
       
  1447         if (qt_modal_stack->isEmpty()) {
       
  1448             delete qt_modal_stack;
       
  1449             qt_modal_stack = 0;
       
  1450             QPoint p(QCursor::pos());
       
  1451             app_do_modal = false;
       
  1452             QWidget* w = 0;
       
  1453             if (QWidget *grabber = QWidget::mouseGrabber())
       
  1454                 w = grabber;
       
  1455             else
       
  1456                 w = QApplication::widgetAt(p.x(), p.y());
       
  1457             dispatchEnterLeave(w, qt_mouseover); // send synthetic enter event
       
  1458             qt_mouseover = w;
       
  1459         }
       
  1460 #ifdef QT_MAC_USE_COCOA
       
  1461         if (!qt_mac_is_macsheet(widget))
       
  1462             QEventDispatcherMacPrivate::endModalSession(widget);
       
  1463 #endif
       
  1464     }
       
  1465 #ifdef DEBUG_MODAL_EVENTS
       
  1466     else qDebug("Failure to remove %s::%s::%p -- %p", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(), widget, qt_modal_stack);
       
  1467 #endif
       
  1468     app_do_modal = (qt_modal_stack != 0);
       
  1469     if (!app_do_modal)
       
  1470         qt_event_request_menubarupdate();
       
  1471 }
       
  1472 
       
  1473 QWidget *QApplicationPrivate::tryModalHelper_sys(QWidget *top)
       
  1474 {
       
  1475 #ifndef QT_MAC_USE_COCOA
       
  1476     if(top && qt_mac_is_macsheet(top) && !IsWindowVisible(qt_mac_window_for(top))) {
       
  1477         if(OSWindowRef wp = GetFrontWindowOfClass(kSheetWindowClass, true)) {
       
  1478             if(QWidget *sheet = qt_mac_find_window(wp))
       
  1479                 top = sheet;
       
  1480         }
       
  1481     }
       
  1482 #endif
       
  1483     return top;
       
  1484 }
       
  1485 
       
  1486 #ifndef QT_MAC_USE_COCOA
       
  1487 static bool qt_try_modal(QWidget *widget, EventRef event)
       
  1488 {
       
  1489     QWidget * top = 0;
       
  1490 
       
  1491     if (QApplicationPrivate::tryModalHelper(widget, &top))
       
  1492         return true;
       
  1493 
       
  1494     // INVARIANT: widget is modally shaddowed within its
       
  1495     // window, and should therefore not handle the event.
       
  1496     // However, if the window is not active, the event
       
  1497     // might suggest that we should bring it to front:
       
  1498 
       
  1499     bool block_event = false;
       
  1500 
       
  1501     if (event) {
       
  1502         switch (GetEventClass(event)) {
       
  1503         case kEventClassMouse:
       
  1504         case kEventClassKeyboard:
       
  1505             block_event = true;
       
  1506             break;
       
  1507         }
       
  1508     }
       
  1509 
       
  1510     QWidget *activeWidget = QApplication::activeWindow();
       
  1511     if ((!activeWidget || QApplicationPrivate::isBlockedByModal(activeWidget)) &&
       
  1512        top->isWindow() && block_event && !QApplicationPrivate::native_modal_dialog_active)
       
  1513         top->raise();
       
  1514 
       
  1515 #ifdef DEBUG_MODAL_EVENTS
       
  1516     qDebug("%s:%d -- final decision! (%s)", __FILE__, __LINE__, block_event ? "false" : "true");
       
  1517 #endif
       
  1518     return !block_event;
       
  1519 }
       
  1520 #endif
       
  1521 
       
  1522 OSStatus QApplicationPrivate::tabletProximityCallback(EventHandlerCallRef, EventRef carbonEvent,
       
  1523                                                       void *)
       
  1524 {
       
  1525     OSType eventClass = GetEventClass(carbonEvent);
       
  1526     UInt32 eventKind = GetEventKind(carbonEvent);
       
  1527     if (eventClass != kEventClassTablet || eventKind != kEventTabletProximity)
       
  1528         return eventNotHandledErr;
       
  1529 
       
  1530     // Get the current point of the device and its unique ID.
       
  1531     ::TabletProximityRec proxRec;
       
  1532     GetEventParameter(carbonEvent, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
       
  1533                       sizeof(proxRec), 0, &proxRec);
       
  1534     qt_dispatchTabletProximityEvent(proxRec);
       
  1535     return noErr;
       
  1536 }
       
  1537 
       
  1538 OSStatus
       
  1539 QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event, void *data)
       
  1540 {
       
  1541 #ifndef QT_MAC_USE_COCOA
       
  1542     QApplication *app = (QApplication *)data;
       
  1543     QScopedLoopLevelCounter loopLevelCounter(app->d_func()->threadData);
       
  1544     long result;
       
  1545     if (app->filterEvent(&event, &result))
       
  1546         return result;
       
  1547     if(app->macEventFilter(er, event)) //someone else ate it
       
  1548         return noErr;
       
  1549     QPointer<QWidget> widget;
       
  1550 
       
  1551     /*We assume all events are handled and in
       
  1552       the code below we set it to false when we know we didn't handle it, this
       
  1553       will let rogue events through (shouldn't really happen, but better safe
       
  1554       than sorry) */
       
  1555     bool handled_event=true;
       
  1556     UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
       
  1557     switch(eclass)
       
  1558     {
       
  1559     case kEventClassQt:
       
  1560         if(ekind == kEventQtRequestShowSheet) {
       
  1561             request_showsheet_pending = 0;
       
  1562             QWidget *widget = 0;
       
  1563             GetEventParameter(event, kEventParamQWidget, typeQWidget, 0,
       
  1564                               sizeof(widget), 0, &widget);
       
  1565             if(widget) {
       
  1566                 if (widget->macEvent(er, event))
       
  1567                     return noErr;
       
  1568                 WindowPtr window = qt_mac_window_for(widget);
       
  1569                 bool just_show = !qt_mac_is_macsheet(widget);
       
  1570                 if(!just_show) {
       
  1571                     OSStatus err = ShowSheetWindow(window, qt_mac_window_for(widget->parentWidget()));
       
  1572                     if(err != noErr)
       
  1573                         qWarning("Qt: QWidget: Unable to show as sheet %s::%s [%ld]", widget->metaObject()->className(),
       
  1574                                  widget->objectName().toLocal8Bit().constData(), long(err));
       
  1575                     just_show = true;
       
  1576                 }
       
  1577                 if(just_show) //at least the window will be visible, but the sheet flag doesn't work sadly (probalby too many sheets)
       
  1578                     ShowHide(window, true);
       
  1579             }
       
  1580         } else if(ekind == kEventQtRequestWindowChange) {
       
  1581             qt_mac_event_release(request_window_change_pending);
       
  1582         } else if(ekind == kEventQtRequestMenubarUpdate) {
       
  1583             qt_mac_event_release(request_menubarupdate_pending);
       
  1584             QMenuBar::macUpdateMenuBar();
       
  1585         } else if(ekind == kEventQtRequestActivate) {
       
  1586             qt_mac_event_release(request_activate_pending.event);
       
  1587             if(request_activate_pending.widget) {
       
  1588                 QWidget *tlw = request_activate_pending.widget->window();
       
  1589                 if (tlw->macEvent(er, event))
       
  1590                     return noErr;
       
  1591                 request_activate_pending.widget = 0;
       
  1592                 tlw->activateWindow();
       
  1593                 SelectWindow(qt_mac_window_for(tlw));
       
  1594             }
       
  1595         } else if(ekind == kEventQtRequestContext) {
       
  1596             bool send = false;
       
  1597             if ((send = (event == request_context_pending)))
       
  1598                 qt_mac_event_release(request_context_pending);
       
  1599             if(send) {
       
  1600                 //figure out which widget to send it to
       
  1601                 QPoint where = QCursor::pos();
       
  1602                 QWidget *widget = 0;
       
  1603                 GetEventParameter(event, kEventParamQWidget, typeQWidget, 0,
       
  1604                                   sizeof(widget), 0, &widget);
       
  1605                 if(!widget) {
       
  1606                     if(qt_button_down)
       
  1607                         widget = qt_button_down;
       
  1608                     else
       
  1609                         widget = QApplication::widgetAt(where.x(), where.y());
       
  1610                 }
       
  1611                 if(widget && !isBlockedByModal(widget)) {
       
  1612                     if (widget->macEvent(er, event))
       
  1613                         return noErr;
       
  1614                     QPoint plocal(widget->mapFromGlobal(where));
       
  1615                     const Qt::KeyboardModifiers keyboardModifiers = qt_mac_get_modifiers(GetCurrentEventKeyModifiers());
       
  1616                     QContextMenuEvent qme(QContextMenuEvent::Mouse, plocal, where, keyboardModifiers);
       
  1617                     QApplication::sendEvent(widget, &qme);
       
  1618                     if(qme.isAccepted()) { //once this happens the events before are pitched
       
  1619                         qt_button_down = 0;
       
  1620                         qt_mac_dblclick.last_widget = 0;
       
  1621                     }
       
  1622                 } else {
       
  1623                     handled_event = false;
       
  1624                 }
       
  1625             }
       
  1626         } else {
       
  1627             handled_event = false;
       
  1628         }
       
  1629         break;
       
  1630     case kEventClassTablet:
       
  1631         switch (ekind) {
       
  1632         case kEventTabletProximity:
       
  1633             // Get the current point of the device and its unique ID.
       
  1634             ::TabletProximityRec proxRec;
       
  1635             GetEventParameter(event, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
       
  1636                               sizeof(proxRec), 0, &proxRec);
       
  1637             qt_dispatchTabletProximityEvent(proxRec);
       
  1638         }
       
  1639         break;
       
  1640     case kEventClassMouse:
       
  1641     {
       
  1642         static const int kEventParamQAppSeenMouseEvent = 'QASM';
       
  1643         // Check if we've seen the event, if we have we shouldn't process
       
  1644         // it again as it may lead to spurious "double events"
       
  1645         bool seenEvent;
       
  1646         if (GetEventParameter(event, kEventParamQAppSeenMouseEvent,
       
  1647                               typeBoolean, 0, sizeof(bool), 0, &seenEvent) == noErr) {
       
  1648             if (seenEvent)
       
  1649                 return eventNotHandledErr;
       
  1650         }
       
  1651         seenEvent = true;
       
  1652         SetEventParameter(event, kEventParamQAppSeenMouseEvent, typeBoolean,
       
  1653                           sizeof(bool), &seenEvent);
       
  1654 
       
  1655         Point where;
       
  1656         bool inNonClientArea = false;
       
  1657         GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0,
       
  1658                           sizeof(where), 0, &where);
       
  1659 #if defined(DEBUG_MOUSE_MAPS)
       
  1660         const char *edesc = 0;
       
  1661         switch(ekind) {
       
  1662         case kEventMouseDown: edesc = "MouseButtonPress"; break;
       
  1663         case kEventMouseUp: edesc = "MouseButtonRelease"; break;
       
  1664         case kEventMouseDragged: case kEventMouseMoved: edesc = "MouseMove"; break;
       
  1665         case kEventMouseScroll: edesc = "MouseWheelScroll"; break;
       
  1666         case kEventMouseWheelMoved: edesc = "MouseWheelMove"; break;
       
  1667         }
       
  1668         if(ekind == kEventMouseDown || ekind == kEventMouseUp)
       
  1669             qDebug("Handling mouse: %s", edesc);
       
  1670 #endif
       
  1671         QEvent::Type etype = QEvent::None;
       
  1672         Qt::KeyboardModifiers modifiers;
       
  1673         {
       
  1674             UInt32 mac_modifiers = 0;
       
  1675             GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
       
  1676                               sizeof(mac_modifiers), 0, &mac_modifiers);
       
  1677             modifiers = qt_mac_get_modifiers(mac_modifiers);
       
  1678         }
       
  1679         Qt::MouseButtons buttons;
       
  1680         {
       
  1681             UInt32 mac_buttons = 0;
       
  1682             GetEventParameter(event, kEventParamMouseChord, typeUInt32, 0,
       
  1683                               sizeof(mac_buttons), 0, &mac_buttons);
       
  1684             buttons = qt_mac_get_buttons(mac_buttons);
       
  1685         }
       
  1686 
       
  1687         int wheel_deltaX = 0;
       
  1688         int wheel_deltaY = 0;
       
  1689         static EventRef compatibilityEvent = 0;
       
  1690 
       
  1691         if (ekind == kEventMouseScroll) {
       
  1692             // kEventMouseScroll is the new way of dealing with mouse wheel
       
  1693             // events (kEventMouseWheelMoved was the old). kEventMouseScroll results
       
  1694             // in much smoother scrolling when using Mighty Mouse or TrackPad. For
       
  1695             // compatibility with older applications, carbon will also send us
       
  1696             // kEventMouseWheelMoved events if we dont eat this event
       
  1697             // (actually two events; one for horizontal and one for vertical).
       
  1698             // As a results of this, and to make sure we dont't receive duplicate events,
       
  1699             // we try to detect when this happend by checking the 'compatibilityEvent'. 
       
  1700             const int scrollFactor = 4 * 8;
       
  1701             SInt32 mdelt = 0;
       
  1702             GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
       
  1703                               sizeof(mdelt), 0, &mdelt);
       
  1704             wheel_deltaX = mdelt * scrollFactor;
       
  1705             mdelt = 0;
       
  1706             GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
       
  1707                               sizeof(mdelt), 0, &mdelt);
       
  1708             wheel_deltaY = mdelt * scrollFactor;
       
  1709             GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
       
  1710                               sizeof(compatibilityEvent), 0, &compatibilityEvent);
       
  1711         } else if (ekind == kEventMouseWheelMoved) {
       
  1712             if (event != compatibilityEvent) {
       
  1713                 compatibilityEvent = 0;
       
  1714                 int mdelt = 0;
       
  1715                 GetEventParameter(event, kEventParamMouseWheelDelta, typeSInt32, 0,
       
  1716                         sizeof(mdelt), 0, &mdelt);
       
  1717                 EventMouseWheelAxis axis;
       
  1718                 GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
       
  1719                         sizeof(axis), 0, &axis);
       
  1720 
       
  1721                 // The 'new' event has acceleration applied by the OS, while the old (on
       
  1722                 // Carbon only), has not. So we introduce acceleration here to be consistent.
       
  1723                 // The acceleration is trying to respect both pixel based and line scrolling,
       
  1724                 // which turns out to be rather difficult.
       
  1725                 int linesToScroll = mdelt > 0 ? 1 : -1;
       
  1726                 static QTime t;
       
  1727                 int elapsed = t.elapsed();
       
  1728                 t.restart();
       
  1729                 if (elapsed < 20)
       
  1730                     linesToScroll *= 120;
       
  1731                 else if (elapsed < 30)
       
  1732                     linesToScroll *= 60;
       
  1733                 else if (elapsed < 50)
       
  1734                     linesToScroll *= 30;
       
  1735                 else if (elapsed < 100)
       
  1736                     linesToScroll *= 6;
       
  1737                 else if (elapsed < 200)
       
  1738                     linesToScroll *= 3;
       
  1739                 else if (elapsed < 300)
       
  1740                     linesToScroll *= 2;
       
  1741 
       
  1742                 if (axis == kEventMouseWheelAxisX)
       
  1743                     wheel_deltaX = linesToScroll * 120;
       
  1744                 else
       
  1745                     wheel_deltaY = linesToScroll * 120;
       
  1746             }
       
  1747         }
       
  1748 
       
  1749         Qt::MouseButton button = Qt::NoButton;
       
  1750         if(ekind == kEventMouseDown || ekind == kEventMouseUp) {
       
  1751             EventMouseButton mac_button = 0;
       
  1752             GetEventParameter(event, kEventParamMouseButton, typeMouseButton, 0,
       
  1753                               sizeof(mac_button), 0, &mac_button);
       
  1754             button = qt_mac_get_button(mac_button);
       
  1755         }
       
  1756 
       
  1757         switch(ekind) {
       
  1758         case kEventMouseDown:
       
  1759             etype = QEvent::MouseButtonPress;
       
  1760             break;
       
  1761         case kEventMouseUp:
       
  1762             etype = QEvent::MouseButtonRelease;
       
  1763             break;
       
  1764         case kEventMouseDragged:
       
  1765         case kEventMouseMoved:
       
  1766             etype = QEvent::MouseMove;
       
  1767             break;
       
  1768         }
       
  1769 
       
  1770         const bool inPopupMode = app->d_func()->inPopupMode();
       
  1771 
       
  1772         // A click outside a popup closes the popup. Make sure
       
  1773         // that no events are generated for the release part of that click.
       
  1774         // (The press goes to the popup and closes it.)
       
  1775         if (etype == QEvent::MouseButtonPress) {
       
  1776             qt_mac_previous_press_in_popup_mode = inPopupMode;
       
  1777         } else if (qt_mac_previous_press_in_popup_mode && !inPopupMode && etype == QEvent::MouseButtonRelease) {
       
  1778             qt_mac_previous_press_in_popup_mode = false;
       
  1779             handled_event = true;
       
  1780 #if defined(DEBUG_MOUSE_MAPS)
       
  1781             qDebug("Bail out early due to qt_mac_previous_press_in_popup_mode");
       
  1782 #endif
       
  1783             break; // break from case kEventClassMouse
       
  1784         }
       
  1785 
       
  1786         //figure out which widget to send it to
       
  1787         if(inPopupMode) {
       
  1788             QWidget *popup = qApp->activePopupWidget();
       
  1789             if (qt_button_down && qt_button_down->window() == popup) {
       
  1790                 widget = qt_button_down;
       
  1791             } else {
       
  1792                 QPoint pos = popup->mapFromGlobal(QPoint(where.h, where.v));
       
  1793                 widget = popup->childAt(pos);
       
  1794             }
       
  1795             if(!widget)
       
  1796                 widget = popup;
       
  1797         } else {
       
  1798             if(mac_mouse_grabber) {
       
  1799                 widget = mac_mouse_grabber;
       
  1800             } else if (qt_button_down) {
       
  1801                 widget = qt_button_down;
       
  1802             } else {
       
  1803                 {
       
  1804                     WindowPtr window = 0;
       
  1805                     if(GetEventParameter(event, kEventParamWindowRef, typeWindowRef, 0,
       
  1806                                          sizeof(window), 0, &window) != noErr)
       
  1807                         FindWindowOfClass(&where, kAllWindowClasses, &window, 0);
       
  1808                     if(window) {
       
  1809                         HIViewRef hiview;
       
  1810                         if(HIViewGetViewForMouseEvent(HIViewGetRoot(window), event, &hiview) == noErr) {
       
  1811                             widget = QWidget::find((WId)hiview);
       
  1812                             if (widget) {
       
  1813                                 // Make sure we didn't pass over a widget with a "fake hole" in it.
       
  1814                                 QWidget *otherWidget = QApplication::widgetAt(where.h, where.v);
       
  1815                                 if (otherWidget && otherWidget->testAttribute(Qt::WA_MouseNoMask))
       
  1816                                     widget = otherWidget;
       
  1817                             }
       
  1818                         }
       
  1819                     }
       
  1820                 }
       
  1821                 if(!widget) //fallback
       
  1822                     widget = QApplication::widgetAt(where.h, where.v);
       
  1823                 if(ekind == kEventMouseUp && widget) {
       
  1824                     short part = qt_mac_window_at(where.h, where.v);
       
  1825                     if(part == inDrag) {
       
  1826                         UInt32 count = 0;
       
  1827                         GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL,
       
  1828                                           sizeof(count), NULL, &count);
       
  1829                         if(count == 2 && qt_mac_collapse_on_dblclick) {
       
  1830                             if (widget->macEvent(er, event))
       
  1831                                 return noErr;
       
  1832                             widget->setWindowState(widget->windowState() | Qt::WindowMinimized);
       
  1833                             //we send a hide to be like X11/Windows
       
  1834                             QEvent e(QEvent::Hide);
       
  1835                             QApplication::sendSpontaneousEvent(widget, &e);
       
  1836                             break;
       
  1837                         }
       
  1838                     }
       
  1839                 }
       
  1840             }
       
  1841         }
       
  1842         if (widget && widget->macEvent(er, event))
       
  1843             return noErr;
       
  1844         WindowPartCode wpc = qt_mac_window_at(where.h, where.v, 0);
       
  1845         if (wpc == inProxyIcon && modifiers == Qt::ControlModifier && buttons != Qt::NoButton) {
       
  1846             QIconDragEvent e;
       
  1847             QApplication::sendSpontaneousEvent(widget, &e);
       
  1848             if (e.isAccepted()) {
       
  1849                 return noErr; // IconDrag ate it.
       
  1850             }
       
  1851         }
       
  1852         if (inPopupMode == false
       
  1853                 && (qt_button_down == 0 || qt_button_down_in_content == false)
       
  1854                 && (wpc != inContent && wpc != inStructure)) {
       
  1855             inNonClientArea = true;
       
  1856             switch (etype) {
       
  1857             case QEvent::MouseButtonPress: {
       
  1858                 UInt32 count = 0;
       
  1859                 GetEventParameter(event, kEventParamClickCount, typeUInt32, 0,
       
  1860                                       sizeof(count), 0, &count);
       
  1861                 if(count % 2 || count == 0) {
       
  1862                     etype = QEvent::NonClientAreaMouseButtonPress;
       
  1863                 } else {
       
  1864                     etype = QEvent::NonClientAreaMouseButtonDblClick;
       
  1865                 }} break;
       
  1866             case QEvent::MouseButtonRelease:
       
  1867                 etype = QEvent::NonClientAreaMouseButtonRelease;
       
  1868                 break;
       
  1869             case QEvent::MouseMove:
       
  1870                 if (widget == 0 || widget->hasMouseTracking())
       
  1871                     etype = QEvent::NonClientAreaMouseMove;
       
  1872                 break;
       
  1873             default:
       
  1874                 break;
       
  1875             }
       
  1876         }
       
  1877 
       
  1878         if(qt_mac_find_window((FrontWindow()))) { //set the cursor up
       
  1879             QCursor cursor(Qt::ArrowCursor);
       
  1880             QWidget *cursor_widget = widget;
       
  1881             if(cursor_widget && cursor_widget == qt_button_down && ekind == kEventMouseUp)
       
  1882                 cursor_widget = QApplication::widgetAt(where.h, where.v);
       
  1883             if(cursor_widget) { //only over the app, do we set a cursor..
       
  1884                 if(!qApp->d_func()->cursor_list.isEmpty()) {
       
  1885                     cursor = qApp->d_func()->cursor_list.first();
       
  1886                 } else {
       
  1887                     for(; cursor_widget; cursor_widget = cursor_widget->parentWidget()) {
       
  1888                         QWExtra *extra = cursor_widget->d_func()->extraData();
       
  1889                         if(extra && extra->curs && cursor_widget->isEnabled()) {
       
  1890                             cursor = *extra->curs;
       
  1891                             break;
       
  1892                         }
       
  1893                     }
       
  1894                 }
       
  1895             }
       
  1896             qt_mac_set_cursor(&cursor, QPoint(where.h, where.v));
       
  1897         }
       
  1898 
       
  1899         //This mouse button state stuff looks like this on purpose
       
  1900         //although it looks hacky it is VERY intentional..
       
  1901         if(widget && app_do_modal && !qt_try_modal(widget, event)) {
       
  1902             if(ekind == kEventMouseDown && qt_mac_is_macsheet(QApplication::activeModalWidget()))
       
  1903                 QApplication::activeModalWidget()->parentWidget()->activateWindow(); //sheets have a parent
       
  1904             handled_event = false;
       
  1905 #if defined(DEBUG_MOUSE_MAPS)
       
  1906             qDebug("Bail out early due to qt_try_modal");
       
  1907 #endif
       
  1908             break;
       
  1909         }
       
  1910 
       
  1911         UInt32 tabletEventType = 0;
       
  1912         GetEventParameter(event, kEventParamTabletEventType, typeUInt32, 0,
       
  1913                           sizeof(tabletEventType), 0, &tabletEventType);
       
  1914         if (tabletEventType == kEventTabletPoint) {
       
  1915             TabletPointRec tabletPointRec;
       
  1916             GetEventParameter(event, kEventParamTabletPointRec, typeTabletPointRec, 0,
       
  1917                               sizeof(tabletPointRec), 0, &tabletPointRec);
       
  1918             QEvent::Type t = QEvent::TabletMove; //default
       
  1919             int new_tablet_button_state = tabletPointRec.buttons ? 1 : 0;
       
  1920             if (new_tablet_button_state != tablet_button_state)
       
  1921                 if (new_tablet_button_state)
       
  1922                     t = QEvent::TabletPress;
       
  1923                 else
       
  1924                     t = QEvent::TabletRelease;
       
  1925             tablet_button_state = new_tablet_button_state;
       
  1926 
       
  1927             QMacTabletHash *tabletHash = qt_mac_tablet_hash();
       
  1928             if (!tabletHash->contains(tabletPointRec.deviceID) && t != QEvent::TabletRelease) {
       
  1929                 // Never discard TabletRelease events as they may be delivered *after* TabletLeaveProximity events
       
  1930                 qWarning("handleTabletEvent: This tablet device is unknown"
       
  1931                          " (received no proximity event for it). Discarding event.");
       
  1932                 return false;
       
  1933             }
       
  1934             QTabletDeviceData &deviceData = tabletHash->operator[](tabletPointRec.deviceID);
       
  1935             if (t == QEvent::TabletPress) {
       
  1936                 deviceData.widgetToGetPress = widget;
       
  1937             } else if (t == QEvent::TabletRelease && deviceData.widgetToGetPress) {
       
  1938                 widget = deviceData.widgetToGetPress;
       
  1939                 deviceData.widgetToGetPress = 0;
       
  1940             }
       
  1941 
       
  1942             if (widget) {
       
  1943                 int tiltX = ((int)tabletPointRec.tiltX)/(32767/64); // 32K -> 60
       
  1944                 int tiltY = ((int)tabletPointRec.tiltY)/(-32767/64); // 32K -> 60
       
  1945                 HIPoint hiPoint;
       
  1946                 GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, 0, sizeof(HIPoint), 0, &hiPoint);
       
  1947                 QPointF hiRes(hiPoint.x, hiPoint.y);
       
  1948                 QPoint global(where.h, where.v);
       
  1949 
       
  1950 
       
  1951 
       
  1952                 QPoint local(widget->mapFromGlobal(global));
       
  1953                 int z = 0;
       
  1954                 qreal rotation = 0.0;
       
  1955                 qreal tp = 0.0;
       
  1956                 // Again from the Wacom.h header
       
  1957 
       
  1958                 if (deviceData.capabilityMask & 0x0200)     // Z-axis
       
  1959                     z = tabletPointRec.absZ;
       
  1960 
       
  1961                 if (deviceData.capabilityMask & 0x0800)  // Tangential pressure
       
  1962                     tp = tabletPointRec.tangentialPressure / 32767.0;
       
  1963 
       
  1964                 if (deviceData.capabilityMask & 0x2000) // Rotation
       
  1965                     rotation = qreal(tabletPointRec.rotation) / 64.0;
       
  1966 
       
  1967                 QTabletEvent e(t, local, global, hiRes, deviceData.tabletDeviceType,
       
  1968                                deviceData.tabletPointerType,
       
  1969                                qreal(tabletPointRec.pressure / qreal(0xffff)), tiltX, tiltY,
       
  1970                                tp, rotation, z, modifiers, deviceData.tabletUniqueID);
       
  1971                 QApplication::sendSpontaneousEvent(widget, &e);
       
  1972                 if (e.isAccepted()) {
       
  1973                     if (t == QEvent::TabletPress) {
       
  1974                         qt_button_down = widget;
       
  1975                     } else if (t == QEvent::TabletRelease) {
       
  1976                         qt_button_down = 0;
       
  1977                     }
       
  1978 #if defined(DEBUG_MOUSE_MAPS)
       
  1979                     qDebug("Bail out early due to tablet acceptance");
       
  1980 #endif
       
  1981                     break;
       
  1982                 }
       
  1983             }
       
  1984         }
       
  1985 
       
  1986         if(ekind == kEventMouseDown) {
       
  1987             qt_mac_no_click_through_mode = false;
       
  1988             const short windowPart = qt_mac_window_at(where.h, where.v, 0);
       
  1989             // Menubar almost always wins.
       
  1990             if (!inPopupMode && windowPart == inMenuBar) {
       
  1991                 MenuSelect(where); //allow menu tracking
       
  1992                 return noErr;
       
  1993             }
       
  1994 
       
  1995             if (widget && !(GetCurrentKeyModifiers() & cmdKey)) {
       
  1996                 extern bool qt_isGenuineQWidget(const QWidget *); // qwidget_mac.cpp
       
  1997                 QWidget *window = widget->window();
       
  1998                 bool genuineQtWidget = qt_isGenuineQWidget(widget);  // the widget, not the window.
       
  1999                 window->raise();
       
  2000 
       
  2001                 bool needActivate = (window->windowType() != Qt::Desktop)
       
  2002                                      && (window->windowType() != Qt::Popup)
       
  2003                                      && !qt_mac_is_macsheet(window);
       
  2004                 if (needActivate && (!window->isModal() && qobject_cast<QDockWidget *>(window)))
       
  2005                     needActivate = false;
       
  2006 
       
  2007                 if (genuineQtWidget && needActivate)
       
  2008                     needActivate = !window->isActiveWindow()
       
  2009                                     || !IsWindowActive(qt_mac_window_for(window));
       
  2010 
       
  2011                 if (needActivate) {
       
  2012                     window->activateWindow();
       
  2013                     if (!qt_mac_can_clickThrough(widget)) {
       
  2014                         qt_mac_no_click_through_mode = true;
       
  2015                         handled_event = false;
       
  2016 #if defined(DEBUG_MOUSE_MAPS)
       
  2017                         qDebug("Bail out early due to qt_mac_canClickThrough %s::%s", widget->metaObject()->className(),
       
  2018                                 widget->objectName().toLocal8Bit().constData());
       
  2019 #endif
       
  2020                         break;
       
  2021                     }
       
  2022                 }
       
  2023             }
       
  2024 
       
  2025             if(qt_mac_dblclick.last_widget &&
       
  2026                qt_mac_dblclick.last_x != -1 && qt_mac_dblclick.last_y != -1 &&
       
  2027                QRect(qt_mac_dblclick.last_x-2, qt_mac_dblclick.last_y-2, 4, 4).contains(QPoint(where.h, where.v))) {
       
  2028                 if(qt_mac_dblclick.use_qt_time_limit) {
       
  2029                     EventTime now = GetEventTime(event);
       
  2030                     if(qt_mac_dblclick.last_time != -2 && qt_mac_dblclick.last_widget == widget &&
       
  2031                        now - qt_mac_dblclick.last_time <= ((double)QApplicationPrivate::mouse_double_click_time)/1000 &&
       
  2032                        qt_mac_dblclick.last_button == button)
       
  2033                         etype = QEvent::MouseButtonDblClick;
       
  2034                 } else {
       
  2035                     UInt32 count = 0;
       
  2036                     GetEventParameter(event, kEventParamClickCount, typeUInt32, 0,
       
  2037                                       sizeof(count), 0, &count);
       
  2038                     if(!(count % 2) && qt_mac_dblclick.last_modifiers == modifiers &&
       
  2039                        qt_mac_dblclick.last_widget == widget && qt_mac_dblclick.last_button == button)
       
  2040                         etype = QEvent::MouseButtonDblClick;
       
  2041                 }
       
  2042                 if(etype == QEvent::MouseButtonDblClick)
       
  2043                     qt_mac_dblclick.last_widget = 0;
       
  2044             }
       
  2045             if(etype != QEvent::MouseButtonDblClick) {
       
  2046                 qt_mac_dblclick.last_x = where.h;
       
  2047                 qt_mac_dblclick.last_y = where.v;
       
  2048             } else {
       
  2049                 qt_mac_dblclick.last_x = qt_mac_dblclick.last_y = -1;
       
  2050             }
       
  2051         } else if(qt_mac_no_click_through_mode) {
       
  2052             if(ekind == kEventMouseUp)
       
  2053                 qt_mac_no_click_through_mode = false;
       
  2054             handled_event = false;
       
  2055 #if defined(DEBUG_MOUSE_MAPS)
       
  2056             qDebug("Bail out early due to qt_mac_no_click_through_mode");
       
  2057 #endif
       
  2058             break;
       
  2059         }
       
  2060 
       
  2061         QPointer<QWidget> leaveAfterRelease = 0;
       
  2062         switch(ekind) {
       
  2063         case kEventMouseUp:
       
  2064             if (!buttons) {
       
  2065                 if (!inPopupMode && !QWidget::mouseGrabber())
       
  2066                     leaveAfterRelease = qt_button_down;
       
  2067                 qt_button_down = 0;
       
  2068             }
       
  2069             break;
       
  2070         case kEventMouseDown: {
       
  2071             if (!qt_button_down)
       
  2072                 qt_button_down = widget;
       
  2073             WindowPartCode wpc = qt_mac_window_at(where.h, where.v, 0);
       
  2074             qt_button_down_in_content = (wpc == inContent || wpc == inStructure);
       
  2075             break;  }
       
  2076         }
       
  2077 
       
  2078         // Check if we should send enter/leave events:
       
  2079         switch(ekind) {
       
  2080         case kEventMouseDragged:
       
  2081         case kEventMouseMoved:
       
  2082         case kEventMouseUp:
       
  2083         case kEventMouseDown: {
       
  2084             // If we are in popup mode, widget will point to the current popup no matter
       
  2085             // where the mouse cursor is. In that case find out if the mouse cursor is
       
  2086             // really over the popup in order to send correct enter / leave envents.
       
  2087             QWidget * const enterLeaveWidget = (inPopupMode || ekind == kEventMouseUp) ?
       
  2088                     QApplication::widgetAt(where.h, where.v) :  static_cast<QWidget*>(widget);
       
  2089 
       
  2090             if ((QWidget *) qt_mouseover != enterLeaveWidget || inNonClientArea) {
       
  2091 #ifdef DEBUG_MOUSE_MAPS
       
  2092                 qDebug("Entering: %p - %s (%s), Leaving %s (%s)", (QWidget*)enterLeaveWidget,
       
  2093                        enterLeaveWidget ? enterLeaveWidget->metaObject()->className() : "none",
       
  2094                        enterLeaveWidget ? enterLeaveWidget->objectName().toLocal8Bit().constData() : "",
       
  2095                        qt_mouseover ? qt_mouseover->metaObject()->className() : "none",
       
  2096                        qt_mouseover ? qt_mouseover->objectName().toLocal8Bit().constData() : "");
       
  2097 #endif
       
  2098 
       
  2099                 QWidget * const mouseGrabber = QWidget::mouseGrabber();
       
  2100 
       
  2101                 if (inPopupMode) {
       
  2102                     QWidget *enter = enterLeaveWidget;
       
  2103                     QWidget *leave = qt_mouseover;
       
  2104                     if (mouseGrabber) {
       
  2105                         QWidget * const popupWidget = qApp->activePopupWidget();
       
  2106                         if (leave == popupWidget)
       
  2107                             enter = mouseGrabber;
       
  2108                         if (enter == popupWidget)
       
  2109                             leave = mouseGrabber;
       
  2110                         if ((enter == mouseGrabber && leave == popupWidget)
       
  2111                             || (leave == mouseGrabber  && enter == popupWidget)) {
       
  2112                             QApplicationPrivate::dispatchEnterLeave(enter, leave);
       
  2113                             qt_mouseover = enter;
       
  2114                         }
       
  2115                     } else {
       
  2116                         QApplicationPrivate::dispatchEnterLeave(enter, leave);
       
  2117                         qt_mouseover = enter;
       
  2118                     }
       
  2119                 } else if ((!qt_button_down || !qt_mouseover) && !mouseGrabber && !leaveAfterRelease) {
       
  2120                     QApplicationPrivate::dispatchEnterLeave(enterLeaveWidget, qt_mouseover);
       
  2121                     qt_mouseover = enterLeaveWidget;
       
  2122                 }
       
  2123             }
       
  2124             break; }
       
  2125         }
       
  2126 
       
  2127         if(widget) {
       
  2128             QPoint p(where.h, where.v);
       
  2129             QPoint plocal(widget->mapFromGlobal(p));
       
  2130             if(etype == QEvent::MouseButtonPress) {
       
  2131                 qt_mac_dblclick.last_widget = widget;
       
  2132                 qt_mac_dblclick.last_modifiers = modifiers;
       
  2133                 qt_mac_dblclick.last_button = button;
       
  2134                 qt_mac_dblclick.last_time = GetEventTime(event);
       
  2135             }
       
  2136 
       
  2137             if (wheel_deltaX || wheel_deltaY) {
       
  2138                 if (wheel_deltaX) {
       
  2139                     QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal);
       
  2140                     QApplication::sendSpontaneousEvent(widget, &qwe);
       
  2141                     if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
       
  2142                         QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
       
  2143                                 wheel_deltaX, buttons, modifiers, Qt::Horizontal);
       
  2144                         QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
       
  2145                         if (!qwe2.isAccepted())
       
  2146                             handled_event = false;
       
  2147                     }
       
  2148                 }
       
  2149                 if (wheel_deltaY) {
       
  2150                     QWheelEvent qwe(plocal, p, wheel_deltaY, buttons, modifiers, Qt::Vertical);
       
  2151                     QApplication::sendSpontaneousEvent(widget, &qwe);
       
  2152                     if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
       
  2153                         QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
       
  2154                                 wheel_deltaY, buttons, modifiers, Qt::Vertical);
       
  2155                         QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
       
  2156                         if (!qwe2.isAccepted())
       
  2157                             handled_event = false;
       
  2158                     }
       
  2159                 }
       
  2160             } else {
       
  2161 #ifdef QMAC_SPEAK_TO_ME
       
  2162                 const int speak_keys = Qt::AltModifier | Qt::ShiftModifier;
       
  2163 		if(etype == QMouseEvent::MouseButtonDblClick && ((modifiers & speak_keys) == speak_keys)) {
       
  2164                     QVariant v = widget->property("displayText");
       
  2165                     if(!v.isValid()) v = widget->property("text");
       
  2166                     if(!v.isValid()) v = widget->property("windowTitle");
       
  2167                     if(v.isValid()) {
       
  2168                         QString s = v.toString();
       
  2169                         s.replace(QRegExp(QString::fromLatin1("(\\&|\\<[^\\>]*\\>)")), QLatin1String(""));
       
  2170                         SpeechChannel ch;
       
  2171                         NewSpeechChannel(0, &ch);
       
  2172                         SpeakText(ch, s.toLatin1().constData(), s.length());
       
  2173                         DisposeSpeechChannel(ch);
       
  2174                     }
       
  2175                 }
       
  2176 #endif
       
  2177                 Qt::MouseButton buttonToSend = button;
       
  2178                 static bool lastButtonTranslated = false;
       
  2179                 if(ekind == kEventMouseDown &&
       
  2180                    button == Qt::LeftButton && (modifiers & Qt::MetaModifier)) {
       
  2181                     buttonToSend = Qt::RightButton;
       
  2182                     lastButtonTranslated = true;
       
  2183                 } else if(ekind == kEventMouseUp && lastButtonTranslated) {
       
  2184                     buttonToSend = Qt::RightButton;
       
  2185                     lastButtonTranslated = false;
       
  2186                 }
       
  2187                 QMouseEvent qme(etype, plocal, p, buttonToSend, buttons, modifiers);
       
  2188                 QApplication::sendSpontaneousEvent(widget, &qme);
       
  2189                 if(!qme.isAccepted() || inNonClientArea)
       
  2190                     handled_event = false;
       
  2191             }
       
  2192 
       
  2193             if (leaveAfterRelease) {
       
  2194                 QWidget *enter = QApplication::widgetAt(where.h, where.v);
       
  2195                 QApplicationPrivate::dispatchEnterLeave(enter, leaveAfterRelease);
       
  2196                 qt_mouseover = enter;
       
  2197                 leaveAfterRelease = 0;
       
  2198             }
       
  2199 
       
  2200             if(ekind == kEventMouseDown &&
       
  2201                ((button == Qt::RightButton) ||
       
  2202                 (button == Qt::LeftButton && (modifiers & Qt::MetaModifier))))
       
  2203                 qt_event_request_context();
       
  2204 
       
  2205 #ifdef DEBUG_MOUSE_MAPS
       
  2206             const char *event_desc = edesc;
       
  2207             if(etype == QEvent::MouseButtonDblClick)
       
  2208                 event_desc = "Double Click";
       
  2209             else if(etype == QEvent::NonClientAreaMouseButtonPress)
       
  2210                 event_desc = "NonClientMousePress";
       
  2211             else if(etype == QEvent::NonClientAreaMouseButtonRelease)
       
  2212                 event_desc = "NonClientMouseRelease";
       
  2213             else if(etype == QEvent::NonClientAreaMouseMove)
       
  2214                 event_desc = "NonClientMouseMove";
       
  2215             else if(etype == QEvent::NonClientAreaMouseButtonDblClick)
       
  2216                 event_desc = "NonClientMouseDblClick";
       
  2217             qDebug("%d %d (%d %d) - Would send (%s) event to %p %s %s (%d 0x%08x 0x%08x %d)", p.x(), p.y(),
       
  2218                    plocal.x(), plocal.y(), event_desc, (QWidget*)widget,
       
  2219                    widget ? widget->objectName().toLocal8Bit().constData() : "*Unknown*",
       
  2220                    widget ? widget->metaObject()->className() : "*Unknown*",
       
  2221                    button, (int)buttons, (int)modifiers, wheel_deltaX);
       
  2222 #endif
       
  2223         } else {
       
  2224             handled_event = false;
       
  2225         }
       
  2226         break;
       
  2227     }
       
  2228     case kEventClassTextInput:
       
  2229     case kEventClassKeyboard: {
       
  2230         EventRef key_event = event;
       
  2231         if(eclass == kEventClassTextInput) {
       
  2232             Q_ASSERT(ekind == kEventTextInputUnicodeForKeyEvent);
       
  2233             OSStatus err = GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, 0,
       
  2234                                              sizeof(key_event), 0, &key_event);
       
  2235             Q_ASSERT(err == noErr);
       
  2236             Q_UNUSED(err);
       
  2237         }
       
  2238         const UInt32 key_ekind = GetEventKind(key_event);
       
  2239         Q_ASSERT(GetEventClass(key_event) == kEventClassKeyboard);
       
  2240 
       
  2241         if(key_ekind == kEventRawKeyDown)
       
  2242             qt_keymapper_private()->updateKeyMap(er, key_event, data);
       
  2243         if(mac_keyboard_grabber)
       
  2244             widget = mac_keyboard_grabber;
       
  2245         else if (app->activePopupWidget())
       
  2246             widget = (app->activePopupWidget()->focusWidget() ?
       
  2247                       app->activePopupWidget()->focusWidget() : app->activePopupWidget());
       
  2248         else if(QApplication::focusWidget())
       
  2249             widget = QApplication::focusWidget();
       
  2250         else
       
  2251             widget = app->activeWindow();
       
  2252 
       
  2253         if (widget) {
       
  2254             if (widget->macEvent(er, event))
       
  2255                 return noErr;
       
  2256         } else {
       
  2257             // Darn, I need to update tho modifier state, even though
       
  2258             // Qt itself isn't getting them, otherwise the keyboard state get inconsistent.
       
  2259             if (key_ekind == kEventRawKeyModifiersChanged) {
       
  2260                 UInt32 modifiers = 0;
       
  2261                 GetEventParameter(key_event, kEventParamKeyModifiers, typeUInt32, 0,
       
  2262                                   sizeof(modifiers), 0, &modifiers);
       
  2263                 extern void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object); // qkeymapper_mac.cpp
       
  2264                 // Just send it to the qApp for the time being.
       
  2265                 qt_mac_send_modifiers_changed(modifiers, qApp);
       
  2266             }
       
  2267             handled_event = false;
       
  2268             break;
       
  2269         }
       
  2270 
       
  2271         if(app_do_modal && !qt_try_modal(widget, key_event))
       
  2272             break;
       
  2273         if (eclass == kEventClassTextInput) {
       
  2274             handled_event = false;
       
  2275         } else {
       
  2276             handled_event = qt_keymapper_private()->translateKeyEvent(widget, er, key_event, data,
       
  2277                                                                       widget == mac_keyboard_grabber);
       
  2278         }
       
  2279         break; }
       
  2280     case kEventClassWindow: {
       
  2281         WindowRef wid = 0;
       
  2282         GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0,
       
  2283                           sizeof(WindowRef), 0, &wid);
       
  2284         widget = qt_mac_find_window(wid);
       
  2285         if (widget && widget->macEvent(er, event))
       
  2286             return noErr;
       
  2287         if(ekind == kEventWindowActivated) {
       
  2288             if(QApplicationPrivate::app_style) {
       
  2289                 QEvent ev(QEvent::Style);
       
  2290                 QApplication::sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
       
  2291             }
       
  2292 
       
  2293             if(widget && app_do_modal && !qt_try_modal(widget, event))
       
  2294                 break;
       
  2295 
       
  2296             if(widget && widget->window()->isVisible()) {
       
  2297                 QWidget *tlw = widget->window();
       
  2298 		if(tlw->isWindow() && !(tlw->windowType() == Qt::Popup)
       
  2299                    && !qt_mac_is_macdrawer(tlw)
       
  2300                    && (!tlw->parentWidget() || tlw->isModal()
       
  2301                        || !(tlw->windowType() == Qt::Tool))) {
       
  2302                     bool just_send_event = false;
       
  2303                     {
       
  2304                         WindowActivationScope scope;
       
  2305                         if(GetWindowActivationScope((WindowRef)wid, &scope) == noErr &&
       
  2306                            scope == kWindowActivationScopeIndependent) {
       
  2307                             if(GetFrontWindowOfClass(kAllWindowClasses, true) != wid)
       
  2308                                 just_send_event = true;
       
  2309                         }
       
  2310                     }
       
  2311                     if(just_send_event) {
       
  2312                         QEvent e(QEvent::WindowActivate);
       
  2313                         QApplication::sendSpontaneousEvent(widget, &e);
       
  2314                     } else {
       
  2315                         app->setActiveWindow(tlw);
       
  2316                     }
       
  2317                 }
       
  2318                 QMenuBar::macUpdateMenuBar();
       
  2319             }
       
  2320         } else if(ekind == kEventWindowDeactivated) {
       
  2321             if(widget && QApplicationPrivate::active_window == widget)
       
  2322                 app->setActiveWindow(0);
       
  2323         } else {
       
  2324             handled_event = false;
       
  2325         }
       
  2326         break; }
       
  2327     case kEventClassApplication:
       
  2328         if(ekind == kEventAppActivated) {
       
  2329             if(QApplication::desktopSettingsAware())
       
  2330                 qt_mac_update_os_settings();
       
  2331             if(qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
       
  2332                 QEvent ev(QEvent::Clipboard);
       
  2333                 QApplication::sendSpontaneousEvent(qt_clipboard, &ev);
       
  2334             }
       
  2335             if(app) {
       
  2336                 QEvent ev(QEvent::ApplicationActivate);
       
  2337                 QApplication::sendSpontaneousEvent(app, &ev);
       
  2338             }
       
  2339             if(!app->activeWindow()) {
       
  2340                 WindowPtr wp = ActiveNonFloatingWindow();
       
  2341                 if(QWidget *tmp_w = qt_mac_find_window(wp))
       
  2342                     app->setActiveWindow(tmp_w);
       
  2343             }
       
  2344             QMenuBar::macUpdateMenuBar();
       
  2345         } else if(ekind == kEventAppDeactivated) {
       
  2346             //qt_mac_no_click_through_mode = false;
       
  2347             while(app->d_func()->inPopupMode())
       
  2348                 app->activePopupWidget()->close();
       
  2349             if(app) {
       
  2350                 QEvent ev(QEvent::ApplicationDeactivate);
       
  2351                 QApplication::sendSpontaneousEvent(app, &ev);
       
  2352             }
       
  2353             app->setActiveWindow(0);
       
  2354         } else if(ekind == kEventAppAvailableWindowBoundsChanged) {
       
  2355             QDesktopWidgetImplementation::instance()->onResize();
       
  2356         } else {
       
  2357             handled_event = false;
       
  2358         }
       
  2359         break;
       
  2360     case kAppearanceEventClass:
       
  2361         if(ekind == kAEAppearanceChanged) {
       
  2362             if(QApplication::desktopSettingsAware())
       
  2363                 qt_mac_update_os_settings();
       
  2364             if(QApplicationPrivate::app_style) {
       
  2365                 QEvent ev(QEvent::Style);
       
  2366                 QApplication::sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
       
  2367             }
       
  2368         } else {
       
  2369             handled_event = false;
       
  2370         }
       
  2371         break;
       
  2372     case kEventClassAppleEvent:
       
  2373         if(ekind == kEventAppleEvent) {
       
  2374             EventRecord erec;
       
  2375             if(!ConvertEventRefToEventRecord(event, &erec))
       
  2376                 qDebug("Qt: internal: WH0A, unexpected condition reached. %s:%d", __FILE__, __LINE__);
       
  2377             else if(AEProcessAppleEvent(&erec) != noErr)
       
  2378                 handled_event = false;
       
  2379         } else {
       
  2380             handled_event = false;
       
  2381         }
       
  2382         break;
       
  2383     case kEventClassCommand:
       
  2384         if(ekind == kEventCommandProcess) {
       
  2385             HICommand cmd;
       
  2386             GetEventParameter(event, kEventParamDirectObject, typeHICommand,
       
  2387                               0, sizeof(cmd), 0, &cmd);
       
  2388             handled_event = false;
       
  2389             if(!cmd.menu.menuRef && GetApplicationDockTileMenu()) {
       
  2390                 EventRef copy = CopyEvent(event);
       
  2391                 HICommand copy_cmd;
       
  2392                 GetEventParameter(event, kEventParamDirectObject, typeHICommand,
       
  2393                                   0, sizeof(copy_cmd), 0, &copy_cmd);
       
  2394                 copy_cmd.menu.menuRef = GetApplicationDockTileMenu();
       
  2395                 SetEventParameter(copy, kEventParamDirectObject, typeHICommand, sizeof(copy_cmd), &copy_cmd);
       
  2396                 if(SendEventToMenu(copy, copy_cmd.menu.menuRef) == noErr)
       
  2397                     handled_event = true;
       
  2398             }
       
  2399             if(!handled_event) {
       
  2400                 if(cmd.commandID == kHICommandQuit) {
       
  2401                     handled_event = true;
       
  2402                     HiliteMenu(0);
       
  2403                     bool handle_quit = true;
       
  2404                     if(QApplicationPrivate::modalState()) {
       
  2405                         int visible = 0;
       
  2406                         const QWidgetList tlws = QApplication::topLevelWidgets();
       
  2407                         for(int i = 0; i < tlws.size(); ++i) {
       
  2408                             if(tlws.at(i)->isVisible())
       
  2409                                 ++visible;
       
  2410                         }
       
  2411                         handle_quit = (visible <= 1);
       
  2412                     }
       
  2413                     if(handle_quit) {
       
  2414                         QCloseEvent ev;
       
  2415                         QApplication::sendSpontaneousEvent(app, &ev);
       
  2416                         if(ev.isAccepted())
       
  2417                             app->quit();
       
  2418                     } else {
       
  2419                         QApplication::beep();
       
  2420                     }
       
  2421                 } else if(cmd.commandID == kHICommandSelectWindow) {
       
  2422                     if((GetCurrentKeyModifiers() & cmdKey))
       
  2423                         handled_event = true;
       
  2424                 } else if(cmd.commandID == kHICommandAbout) {
       
  2425                     QMessageBox::aboutQt(0);
       
  2426                     HiliteMenu(0);
       
  2427                     handled_event = true;
       
  2428                 }
       
  2429             }
       
  2430         }
       
  2431         break;
       
  2432     }
       
  2433 
       
  2434 #ifdef DEBUG_EVENTS
       
  2435     qDebug("%shandled event %c%c%c%c %d", handled_event ? "(*) " : "",
       
  2436            char(eclass >> 24), char((eclass >> 16) & 255), char((eclass >> 8) & 255),
       
  2437            char(eclass & 255), (int)ekind);
       
  2438 #endif
       
  2439     if(!handled_event) //let the event go through
       
  2440         return eventNotHandledErr;
       
  2441     return noErr; //we eat the event
       
  2442 #else
       
  2443     Q_UNUSED(er);
       
  2444     Q_UNUSED(event);
       
  2445     Q_UNUSED(data);
       
  2446     return eventNotHandledErr;
       
  2447 #endif
       
  2448 }
       
  2449 
       
  2450 // In Carbon this is your one stop for apple events.
       
  2451 // In Cocoa, it ISN'T. This is the catch-all Apple Event handler that exists
       
  2452 // for the time between instantiating the NSApplication, but before the
       
  2453 // NSApplication has installed it's OWN Apple Event handler. When Cocoa has
       
  2454 // that set up, we remove this.  So, if you are debugging problems, you likely
       
  2455 // want to check out QCocoaApplicationDelegate instead.
       
  2456 OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, AppleEvent *, long handlerRefcon)
       
  2457 {
       
  2458     QApplication *app = (QApplication *)handlerRefcon;
       
  2459     bool handled_event=false;
       
  2460     OSType aeID=typeWildCard, aeClass=typeWildCard;
       
  2461     AEGetAttributePtr(ae, keyEventClassAttr, typeType, 0, &aeClass, sizeof(aeClass), 0);
       
  2462     AEGetAttributePtr(ae, keyEventIDAttr, typeType, 0, &aeID, sizeof(aeID), 0);
       
  2463     if(aeClass == kCoreEventClass) {
       
  2464         switch(aeID) {
       
  2465         case kAEQuitApplication: {
       
  2466             extern bool qt_mac_quit_menu_item_enabled; // qmenu_mac.cpp
       
  2467             if(!QApplicationPrivate::modalState() && qt_mac_quit_menu_item_enabled) {
       
  2468                 QCloseEvent ev;
       
  2469                 QApplication::sendSpontaneousEvent(app, &ev);
       
  2470                 if(ev.isAccepted()) {
       
  2471                     handled_event = true;
       
  2472                     app->quit();
       
  2473                 }
       
  2474             } else {
       
  2475                 QApplication::beep();  // Sorry, you can't quit right now.
       
  2476             }
       
  2477             break; }
       
  2478         case kAEOpenDocuments: {
       
  2479             AEDescList docs;
       
  2480             if(AEGetParamDesc(ae, keyDirectObject, typeAEList, &docs) == noErr) {
       
  2481                 long cnt = 0;
       
  2482                 AECountItems(&docs, &cnt);
       
  2483                 UInt8 *str_buffer = NULL;
       
  2484                 for(int i = 0; i < cnt; i++) {
       
  2485                     FSRef ref;
       
  2486                     if(AEGetNthPtr(&docs, i+1, typeFSRef, 0, 0, &ref, sizeof(ref), 0) != noErr)
       
  2487                         continue;
       
  2488                     if(!str_buffer)
       
  2489                         str_buffer = (UInt8 *)malloc(1024);
       
  2490                     FSRefMakePath(&ref, str_buffer, 1024);
       
  2491                     QFileOpenEvent ev(QString::fromUtf8((const char *)str_buffer));
       
  2492                     QApplication::sendSpontaneousEvent(app, &ev);
       
  2493                 }
       
  2494                 if(str_buffer)
       
  2495                     free(str_buffer);
       
  2496             }
       
  2497             break; }
       
  2498         default:
       
  2499             break;
       
  2500         }
       
  2501     }
       
  2502 #ifdef DEBUG_EVENTS
       
  2503     qDebug("Qt: internal: %shandled Apple event! %c%c%c%c %c%c%c%c", handled_event ? "(*)" : "",
       
  2504            char(aeID >> 24), char((aeID >> 16) & 255), char((aeID >> 8) & 255),char(aeID & 255),
       
  2505            char(aeClass >> 24), char((aeClass >> 16) & 255), char((aeClass >> 8) & 255),char(aeClass & 255));
       
  2506 #else
       
  2507     if(!handled_event) //let the event go through
       
  2508         return eventNotHandledErr;
       
  2509     return noErr; //we eat the event
       
  2510 #endif
       
  2511 }
       
  2512 
       
  2513 /*!
       
  2514     \fn bool QApplication::macEventFilter(EventHandlerCallRef caller, EventRef event)
       
  2515 
       
  2516     \warning This virtual function is only implemented under Mac OS X when against Carbon.
       
  2517 
       
  2518     If you create an application that inherits QApplication and reimplement
       
  2519     this function, you get direct access to all Carbon Events that Qt registers
       
  2520     for from Mac OS X with this function being called with the \a caller and
       
  2521     the \a event.
       
  2522 
       
  2523     Return true if you want to stop the event from being processed.
       
  2524     Return false for normal event dispatching. The default
       
  2525     implementation returns false.
       
  2526 
       
  2527     Cocoa uses a different event system which means this function is NOT CALLED
       
  2528     when building Qt against Cocoa. If you want similar functionality subclass
       
  2529     NSApplication and reimplement the sendEvent: message to handle all the
       
  2530     NSEvents. You also will need to to instantiate your custom NSApplication
       
  2531     before creating a QApplication. See \l
       
  2532     {http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/Reference/Reference.html}{Apple's
       
  2533     NSApplication Reference} for more information.
       
  2534 
       
  2535 */
       
  2536 bool QApplication::macEventFilter(EventHandlerCallRef, EventRef)
       
  2537 {
       
  2538     return false;
       
  2539 }
       
  2540 
       
  2541 /*!
       
  2542     \internal
       
  2543 */
       
  2544 void QApplicationPrivate::openPopup(QWidget *popup)
       
  2545 {
       
  2546     if (!QApplicationPrivate::popupWidgets)                        // create list
       
  2547         QApplicationPrivate::popupWidgets = new QWidgetList;
       
  2548     QApplicationPrivate::popupWidgets->append(popup);                // add to end of list
       
  2549 
       
  2550     // popups are not focus-handled by the window system (the first
       
  2551     // popup grabbed the keyboard), so we have to do that manually: A
       
  2552     // new popup gets the focus
       
  2553     if (popup->focusWidget()) {
       
  2554         popup->focusWidget()->setFocus(Qt::PopupFocusReason);
       
  2555     } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
       
  2556         popup->setFocus(Qt::PopupFocusReason);
       
  2557     }
       
  2558 }
       
  2559 
       
  2560 /*!
       
  2561     \internal
       
  2562 */
       
  2563 void QApplicationPrivate::closePopup(QWidget *popup)
       
  2564 {
       
  2565     Q_Q(QApplication);
       
  2566     if (!QApplicationPrivate::popupWidgets)
       
  2567         return;
       
  2568 
       
  2569     QApplicationPrivate::popupWidgets->removeAll(popup);
       
  2570     if (popup == qt_button_down)
       
  2571         qt_button_down = 0;
       
  2572     if (QApplicationPrivate::popupWidgets->isEmpty()) {  // this was the last popup
       
  2573         delete QApplicationPrivate::popupWidgets;
       
  2574         QApplicationPrivate::popupWidgets = 0;
       
  2575         
       
  2576         // Special case for Tool windows: since they are activated and deactived together
       
  2577         // with a normal window they never become the QApplicationPrivate::active_window.
       
  2578         QWidget *appFocusWidget = QApplication::focusWidget();
       
  2579         if (appFocusWidget && appFocusWidget->window()->windowType() == Qt::Tool) {
       
  2580             appFocusWidget->setFocus(Qt::PopupFocusReason);
       
  2581         } else if (QApplicationPrivate::active_window) {
       
  2582             if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
       
  2583                 if (fw != QApplication::focusWidget()) {
       
  2584                     fw->setFocus(Qt::PopupFocusReason);
       
  2585                 } else {
       
  2586                     QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
       
  2587                     q->sendEvent(fw, &e);
       
  2588                 }
       
  2589             }
       
  2590         }
       
  2591     } else {
       
  2592         // popups are not focus-handled by the window system (the
       
  2593         // first popup grabbed the keyboard), so we have to do that
       
  2594         // manually: A popup was closed, so the previous popup gets
       
  2595         // the focus.
       
  2596         QWidget* aw = QApplicationPrivate::popupWidgets->last();
       
  2597         if (QWidget *fw = aw->focusWidget())
       
  2598             fw->setFocus(Qt::PopupFocusReason);
       
  2599     }
       
  2600 }
       
  2601 
       
  2602 void QApplication::beep()
       
  2603 {
       
  2604     qt_mac_beep();
       
  2605 }
       
  2606 
       
  2607 void QApplication::alert(QWidget *widget, int duration)
       
  2608 {
       
  2609     if (!QApplicationPrivate::checkInstance("alert"))
       
  2610         return;
       
  2611 
       
  2612     QWidgetList windowsToMark;
       
  2613     if (!widget)
       
  2614         windowsToMark += topLevelWidgets();
       
  2615     else
       
  2616         windowsToMark.append(widget->window());
       
  2617 
       
  2618     bool needNotification = false;
       
  2619     for (int i = 0; i < windowsToMark.size(); ++i) {
       
  2620         QWidget *window = windowsToMark.at(i);
       
  2621         if (!window->isActiveWindow() && window->isVisible()) {
       
  2622             needNotification = true; // yeah, we may set it multiple times, but that's OK.
       
  2623             if (duration != 0) {
       
  2624                QTimer *timer = new QTimer(qApp);
       
  2625                timer->setSingleShot(true);
       
  2626                connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
       
  2627                if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(widget)) {
       
  2628                    qApp->d_func()->alertTimerHash.remove(widget);
       
  2629                    delete oldTimer;
       
  2630                }
       
  2631                qApp->d_func()->alertTimerHash.insert(widget, timer);
       
  2632                timer->start(duration);
       
  2633             }
       
  2634         }
       
  2635     }
       
  2636     if (needNotification)
       
  2637         qt_mac_send_notification();
       
  2638 }
       
  2639 
       
  2640 void QApplicationPrivate::_q_alertTimeOut()
       
  2641 {
       
  2642     if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
       
  2643         QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
       
  2644         while (it != alertTimerHash.end()) {
       
  2645             if (it.value() == timer) {
       
  2646                 alertTimerHash.erase(it);
       
  2647                 timer->deleteLater();
       
  2648                 break;
       
  2649             }
       
  2650             ++it;
       
  2651         }
       
  2652         if (alertTimerHash.isEmpty()) {
       
  2653             qt_mac_cancel_notification();
       
  2654         }
       
  2655     }
       
  2656 }
       
  2657 
       
  2658 void  QApplication::setCursorFlashTime(int msecs)
       
  2659 {
       
  2660     QApplicationPrivate::cursor_flash_time = msecs;
       
  2661 }
       
  2662 
       
  2663 int QApplication::cursorFlashTime()
       
  2664 {
       
  2665     return QApplicationPrivate::cursor_flash_time;
       
  2666 }
       
  2667 
       
  2668 void QApplication::setDoubleClickInterval(int ms)
       
  2669 {
       
  2670     qt_mac_dblclick.use_qt_time_limit = true;
       
  2671     QApplicationPrivate::mouse_double_click_time = ms;
       
  2672 }
       
  2673 
       
  2674 int QApplication::doubleClickInterval()
       
  2675 {
       
  2676     if (!qt_mac_dblclick.use_qt_time_limit) { //get it from the system
       
  2677         QSettings appleSettings(QLatin1String("apple.com"));
       
  2678         /* First worked as of 10.3.3 */
       
  2679         double dci = appleSettings.value(QLatin1String("com/apple/mouse/doubleClickThreshold"), 0.5).toDouble();
       
  2680         return int(dci * 1000);
       
  2681     }
       
  2682     return QApplicationPrivate::mouse_double_click_time;
       
  2683 }
       
  2684 
       
  2685 void QApplication::setKeyboardInputInterval(int ms)
       
  2686 {
       
  2687     QApplicationPrivate::keyboard_input_time = ms;
       
  2688 }
       
  2689 
       
  2690 int QApplication::keyboardInputInterval()
       
  2691 {
       
  2692     // FIXME: get from the system
       
  2693     return QApplicationPrivate::keyboard_input_time;
       
  2694 }
       
  2695 
       
  2696 void QApplication::setWheelScrollLines(int n)
       
  2697 {
       
  2698     Q_UNUSED(n);
       
  2699     // On Mac, acceleration is handled by the OS. Multiplying wheel scroll
       
  2700     // deltas with n will not be as cross platform as one might think! So
       
  2701     // we choose to go native in this case (and let wheel_scroll_lines == 1).
       
  2702     //    QApplicationPrivate::wheel_scroll_lines = n;
       
  2703 }
       
  2704 
       
  2705 int QApplication::wheelScrollLines()
       
  2706 {
       
  2707     return QApplicationPrivate::wheel_scroll_lines;
       
  2708 }
       
  2709 
       
  2710 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
       
  2711 {
       
  2712     switch (effect) {
       
  2713     case Qt::UI_FadeMenu:
       
  2714         QApplicationPrivate::fade_menu = enable;
       
  2715         break;
       
  2716     case Qt::UI_AnimateMenu:
       
  2717         QApplicationPrivate::animate_menu = enable;
       
  2718         break;
       
  2719     case Qt::UI_FadeTooltip:
       
  2720         QApplicationPrivate::fade_tooltip = enable;
       
  2721         break;
       
  2722     case Qt::UI_AnimateTooltip:
       
  2723         QApplicationPrivate::animate_tooltip = enable;
       
  2724         break;
       
  2725     case Qt::UI_AnimateCombo:
       
  2726         QApplicationPrivate::animate_combo = enable;
       
  2727         break;
       
  2728     case Qt::UI_AnimateToolBox:
       
  2729         QApplicationPrivate::animate_toolbox = enable;
       
  2730         break;
       
  2731     case Qt::UI_General:
       
  2732         QApplicationPrivate::fade_tooltip = true;
       
  2733         break;
       
  2734     default:
       
  2735         QApplicationPrivate::animate_ui = enable;
       
  2736         break;
       
  2737     }
       
  2738 
       
  2739     if (enable)
       
  2740         QApplicationPrivate::animate_ui = true;
       
  2741 }
       
  2742 
       
  2743 bool QApplication::isEffectEnabled(Qt::UIEffect effect)
       
  2744 {
       
  2745     if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
       
  2746         return false;
       
  2747 
       
  2748     switch(effect) {
       
  2749     case Qt::UI_AnimateMenu:
       
  2750         return QApplicationPrivate::animate_menu;
       
  2751     case Qt::UI_FadeMenu:
       
  2752         return QApplicationPrivate::fade_menu;
       
  2753     case Qt::UI_AnimateCombo:
       
  2754         return QApplicationPrivate::animate_combo;
       
  2755     case Qt::UI_AnimateTooltip:
       
  2756         return QApplicationPrivate::animate_tooltip;
       
  2757     case Qt::UI_FadeTooltip:
       
  2758         return QApplicationPrivate::fade_tooltip;
       
  2759     case Qt::UI_AnimateToolBox:
       
  2760         return QApplicationPrivate::animate_toolbox;
       
  2761     default:
       
  2762         break;
       
  2763     }
       
  2764     return QApplicationPrivate::animate_ui;
       
  2765 }
       
  2766 
       
  2767 /*!
       
  2768     \internal
       
  2769 */
       
  2770 bool QApplicationPrivate::qt_mac_apply_settings()
       
  2771 {
       
  2772     QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
       
  2773     settings.beginGroup(QLatin1String("Qt"));
       
  2774 
       
  2775     /*
       
  2776       Qt settings.  This is how they are written into the datastream.
       
  2777       Palette/ *             - QPalette
       
  2778       font                   - QFont
       
  2779       libraryPath            - QStringList
       
  2780       style                  - QString
       
  2781       doubleClickInterval    - int
       
  2782       cursorFlashTime        - int
       
  2783       wheelScrollLines       - int
       
  2784       colorSpec              - QString
       
  2785       defaultCodec           - QString
       
  2786       globalStrut/width      - int
       
  2787       globalStrut/height     - int
       
  2788       GUIEffects             - QStringList
       
  2789       Font Substitutions/ *  - QStringList
       
  2790       Font Substitutions/... - QStringList
       
  2791     */
       
  2792 
       
  2793     // read library (ie. plugin) path list
       
  2794     QString libpathkey =
       
  2795         QString::fromLatin1("%1.%2/libraryPath")
       
  2796                     .arg(QT_VERSION >> 16)
       
  2797                     .arg((QT_VERSION & 0xff00) >> 8);
       
  2798     QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
       
  2799     if (!pathlist.isEmpty()) {
       
  2800         QStringList::ConstIterator it = pathlist.begin();
       
  2801         while(it != pathlist.end())
       
  2802             QApplication::addLibraryPath(*it++);
       
  2803     }
       
  2804 
       
  2805     QString defaultcodec = settings.value(QLatin1String("defaultCodec"), QVariant(QLatin1String("none"))).toString();
       
  2806     if (defaultcodec != QLatin1String("none")) {
       
  2807         QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1().constData());
       
  2808         if (codec)
       
  2809             QTextCodec::setCodecForTr(codec);
       
  2810     }
       
  2811 
       
  2812     if (qt_is_gui_used) {
       
  2813         QString str;
       
  2814         QStringList strlist;
       
  2815         int num;
       
  2816 
       
  2817         // read new palette
       
  2818         int i;
       
  2819         QPalette pal(QApplication::palette());
       
  2820         strlist = settings.value(QLatin1String("Palette/active")).toStringList();
       
  2821         if (strlist.count() == QPalette::NColorRoles) {
       
  2822             for (i = 0; i < QPalette::NColorRoles; i++)
       
  2823                 pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
       
  2824                             QColor(strlist[i]));
       
  2825         }
       
  2826         strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
       
  2827         if (strlist.count() == QPalette::NColorRoles) {
       
  2828             for (i = 0; i < QPalette::NColorRoles; i++)
       
  2829                 pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
       
  2830                             QColor(strlist[i]));
       
  2831         }
       
  2832         strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
       
  2833         if (strlist.count() == QPalette::NColorRoles) {
       
  2834             for (i = 0; i < QPalette::NColorRoles; i++)
       
  2835                 pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
       
  2836                             QColor(strlist[i]));
       
  2837         }
       
  2838 
       
  2839         if (pal != QApplication::palette())
       
  2840             QApplication::setPalette(pal);
       
  2841 
       
  2842         // read new font
       
  2843         QFont font(QApplication::font());
       
  2844         str = settings.value(QLatin1String("font")).toString();
       
  2845         if (!str.isEmpty()) {
       
  2846             font.fromString(str);
       
  2847             if (font != QApplication::font())
       
  2848                 QApplication::setFont(font);
       
  2849         }
       
  2850 
       
  2851         // read new QStyle
       
  2852         QString stylename = settings.value(QLatin1String("style")).toString();
       
  2853         if (! stylename.isNull() && ! stylename.isEmpty()) {
       
  2854             QStyle *style = QStyleFactory::create(stylename);
       
  2855             if (style)
       
  2856                 QApplication::setStyle(style);
       
  2857             else
       
  2858                 stylename = QLatin1String("default");
       
  2859         } else {
       
  2860             stylename = QLatin1String("default");
       
  2861         }
       
  2862 
       
  2863         num = settings.value(QLatin1String("doubleClickInterval"),
       
  2864                             QApplication::doubleClickInterval()).toInt();
       
  2865         QApplication::setDoubleClickInterval(num);
       
  2866 
       
  2867         num = settings.value(QLatin1String("cursorFlashTime"),
       
  2868                             QApplication::cursorFlashTime()).toInt();
       
  2869         QApplication::setCursorFlashTime(num);
       
  2870 
       
  2871         num = settings.value(QLatin1String("wheelScrollLines"),
       
  2872                             QApplication::wheelScrollLines()).toInt();
       
  2873         QApplication::setWheelScrollLines(num);
       
  2874 
       
  2875         QString colorspec = settings.value(QLatin1String("colorSpec"),
       
  2876                                             QVariant(QLatin1String("default"))).toString();
       
  2877         if (colorspec == QLatin1String("normal"))
       
  2878             QApplication::setColorSpec(QApplication::NormalColor);
       
  2879         else if (colorspec == QLatin1String("custom"))
       
  2880             QApplication::setColorSpec(QApplication::CustomColor);
       
  2881         else if (colorspec == QLatin1String("many"))
       
  2882             QApplication::setColorSpec(QApplication::ManyColor);
       
  2883         else if (colorspec != QLatin1String("default"))
       
  2884             colorspec = QLatin1String("default");
       
  2885 
       
  2886         int w = settings.value(QLatin1String("globalStrut/width")).toInt();
       
  2887         int h = settings.value(QLatin1String("globalStrut/height")).toInt();
       
  2888         QSize strut(w, h);
       
  2889         if (strut.isValid())
       
  2890             QApplication::setGlobalStrut(strut);
       
  2891 
       
  2892         QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
       
  2893         if (!effects.isEmpty()) {
       
  2894             if (effects.contains(QLatin1String("none")))
       
  2895                 QApplication::setEffectEnabled(Qt::UI_General, false);
       
  2896             if (effects.contains(QLatin1String("general")))
       
  2897                 QApplication::setEffectEnabled(Qt::UI_General, true);
       
  2898             if (effects.contains(QLatin1String("animatemenu")))
       
  2899                 QApplication::setEffectEnabled(Qt::UI_AnimateMenu, true);
       
  2900             if (effects.contains(QLatin1String("fademenu")))
       
  2901                 QApplication::setEffectEnabled(Qt::UI_FadeMenu, true);
       
  2902             if (effects.contains(QLatin1String("animatecombo")))
       
  2903                 QApplication::setEffectEnabled(Qt::UI_AnimateCombo, true);
       
  2904             if (effects.contains(QLatin1String("animatetooltip")))
       
  2905                 QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, true);
       
  2906             if (effects.contains(QLatin1String("fadetooltip")))
       
  2907                 QApplication::setEffectEnabled(Qt::UI_FadeTooltip, true);
       
  2908             if (effects.contains(QLatin1String("animatetoolbox")))
       
  2909                 QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, true);
       
  2910         } else {
       
  2911             QApplication::setEffectEnabled(Qt::UI_General, true);
       
  2912         }
       
  2913 
       
  2914         settings.beginGroup(QLatin1String("Font Substitutions"));
       
  2915         QStringList fontsubs = settings.childKeys();
       
  2916         if (!fontsubs.isEmpty()) {
       
  2917             QStringList::Iterator it = fontsubs.begin();
       
  2918             for (; it != fontsubs.end(); ++it) {
       
  2919                 QString fam = QString::fromLatin1((*it).toLatin1().constData());
       
  2920                 QStringList subs = settings.value(fam).toStringList();
       
  2921                 QFont::insertSubstitutions(fam, subs);
       
  2922             }
       
  2923         }
       
  2924         settings.endGroup();
       
  2925     }
       
  2926 
       
  2927     settings.endGroup();
       
  2928     return true;
       
  2929 }
       
  2930 
       
  2931 // DRSWAT
       
  2932 
       
  2933 bool QApplicationPrivate::canQuit()
       
  2934 {
       
  2935 #ifndef QT_MAC_USE_COCOA
       
  2936     return true;
       
  2937 #else
       
  2938     Q_Q(QApplication);
       
  2939 #ifdef QT_MAC_USE_COCOA
       
  2940     [[NSApp mainMenu] cancelTracking];
       
  2941 #else
       
  2942     HiliteMenu(0);
       
  2943 #endif
       
  2944 
       
  2945     bool handle_quit = true;
       
  2946     if (QApplicationPrivate::modalState() && [[[[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate]
       
  2947                                                    menuLoader] quitMenuItem] isEnabled]) {
       
  2948         int visible = 0;
       
  2949         const QWidgetList tlws = QApplication::topLevelWidgets();
       
  2950         for(int i = 0; i < tlws.size(); ++i) {
       
  2951             if (tlws.at(i)->isVisible())
       
  2952                 ++visible;
       
  2953         }
       
  2954         handle_quit = (visible <= 1);
       
  2955     }
       
  2956     if (handle_quit) {
       
  2957         QCloseEvent ev;
       
  2958         QApplication::sendSpontaneousEvent(q, &ev);
       
  2959         if (ev.isAccepted()) {
       
  2960             return true;
       
  2961         }
       
  2962     }
       
  2963     return false;
       
  2964 #endif
       
  2965 }
       
  2966 
       
  2967 void onApplicationWindowChangedActivation(QWidget *widget, bool activated)
       
  2968 {
       
  2969 #if QT_MAC_USE_COCOA
       
  2970     if (!widget)
       
  2971         return;
       
  2972 
       
  2973     if (activated) {
       
  2974         if (QApplicationPrivate::app_style) {
       
  2975             QEvent ev(QEvent::Style);
       
  2976             qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
       
  2977         }
       
  2978         qApp->setActiveWindow(widget);
       
  2979     } else { // deactivated
       
  2980         if (QApplicationPrivate::active_window == widget)
       
  2981             qApp->setActiveWindow(0);
       
  2982     }
       
  2983 
       
  2984     QMenuBar::macUpdateMenuBar();
       
  2985 
       
  2986 #else
       
  2987     Q_UNUSED(widget);
       
  2988     Q_UNUSED(activated);
       
  2989 #endif
       
  2990 }
       
  2991 
       
  2992 
       
  2993 void onApplicationChangedActivation( bool activated )
       
  2994 {
       
  2995 #if QT_MAC_USE_COCOA
       
  2996     QApplication    *app    = qApp;
       
  2997 
       
  2998 //NSLog(@"App Changed Activation\n");
       
  2999 
       
  3000     if ( activated ) {
       
  3001         if (QApplication::desktopSettingsAware())
       
  3002             qt_mac_update_os_settings();
       
  3003 
       
  3004         if (qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
       
  3005             QEvent ev(QEvent::Clipboard);
       
  3006             qt_sendSpontaneousEvent(qt_clipboard, &ev);
       
  3007         }
       
  3008 
       
  3009         if (app) {
       
  3010             QEvent ev(QEvent::ApplicationActivate);
       
  3011             qt_sendSpontaneousEvent(app, &ev);
       
  3012         }
       
  3013 
       
  3014         if (!app->activeWindow()) {
       
  3015 #if QT_MAC_USE_COCOA
       
  3016             OSWindowRef wp    = [NSApp keyWindow];
       
  3017 #else
       
  3018             OSWindowRef wp = ActiveNonFloatingWindow();
       
  3019 #endif
       
  3020             if (QWidget *tmp_w = qt_mac_find_window(wp))
       
  3021                 app->setActiveWindow(tmp_w);
       
  3022         }
       
  3023         QMenuBar::macUpdateMenuBar();
       
  3024     } else { // de-activated
       
  3025         QApplicationPrivate *priv = [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] qAppPrivate];
       
  3026         while (priv->inPopupMode())
       
  3027             app->activePopupWidget()->close();
       
  3028         if (app) {
       
  3029             QEvent ev(QEvent::ApplicationDeactivate);
       
  3030             qt_sendSpontaneousEvent(app, &ev);
       
  3031         }
       
  3032         app->setActiveWindow(0);
       
  3033     }
       
  3034 #else
       
  3035     Q_UNUSED(activated);
       
  3036 #endif
       
  3037 }
       
  3038 
       
  3039 void QApplicationPrivate::initializeMultitouch_sys()
       
  3040 { }
       
  3041 void QApplicationPrivate::cleanupMultitouch_sys()
       
  3042 { }
       
  3043 
       
  3044 QT_END_NAMESPACE