Fixed crash in GL 2 paint engine on Intel Atom.
[profile/ivi/qtbase.git] / src / widgets / platforms / mac / qapplication_mac.mm
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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 "qurl.h"
108 #include "private/qmacinputcontext_p.h"
109 #include "private/qpaintengine_mac_p.h"
110 #include "private/qcursor_p.h"
111 #include "private/qapplication_p.h"
112 #include "private/qcolor_p.h"
113 #include "private/qwidget_p.h"
114 #include "private/qkeymapper_p.h"
115 #include "private/qeventdispatcher_mac_p.h"
116 #include "private/qeventdispatcher_unix_p.h"
117 #include <private/qcocoamenuloader_mac_p.h>
118 #include <private/qcocoaapplication_mac_p.h>
119 #include <private/qcocoaapplicationdelegate_mac_p.h>
120 #include <private/qt_cocoa_helpers_mac_p.h>
121 #include <private/qcocoawindow_mac_p.h>
122 #include <private/qpixmap_mac_p.h>
123 #include <private/qdesktopwidget_mac_p.h>
124 #include <private/qeventdispatcher_mac_p.h>
125 #include <qvarlengtharray.h>
126
127 #ifndef QT_NO_ACCESSIBILITY
128 #  include "qaccessible.h"
129 #endif
130
131 #ifndef QT_NO_THREAD
132 #  include "qmutex.h"
133 #endif
134
135 #include <unistd.h>
136 #include <string.h>
137 #include <sys/time.h>
138 #include <sys/select.h>
139
140 /*****************************************************************************
141   QApplication debug facilities
142  *****************************************************************************/
143 //#define DEBUG_EVENTS //like EventDebug but more specific to Qt
144 //#define DEBUG_DROPPED_EVENTS
145 //#define DEBUG_MOUSE_MAPS
146 //#define DEBUG_MODAL_EVENTS
147 //#define DEBUG_PLATFORM_SETTINGS
148
149 #define QMAC_SPEAK_TO_ME
150 #ifdef QMAC_SPEAK_TO_ME
151 #include "qregexp.h"
152 #endif
153
154 #ifndef kThemeBrushAlternatePrimaryHighlightColor
155 #define kThemeBrushAlternatePrimaryHighlightColor -5
156 #endif
157
158 #define kCMDeviceUnregisteredNotification CFSTR("CMDeviceUnregisteredNotification")
159 #define kCMDefaultDeviceNotification CFSTR("CMDefaultDeviceNotification")
160 #define kCMDeviceProfilesNotification CFSTR("CMDeviceProfilesNotification")
161 #define kCMDefaultDeviceProfileNotification CFSTR("CMDefaultDeviceProfileNotification")
162
163 QT_BEGIN_NAMESPACE
164
165 //for qt_mac.h
166 QPaintDevice *qt_mac_safe_pdev = 0;
167 QList<QMacWindowChangeEvent*> *QMacWindowChangeEvent::change_events = 0;
168 QPointer<QWidget> topLevelAt_cache = 0;
169
170 /*****************************************************************************
171   Internal variables and functions
172  *****************************************************************************/
173 static struct {
174     bool use_qt_time_limit;
175     QPointer<QWidget> last_widget;
176     int last_x, last_y;
177     int last_modifiers, last_button;
178     EventTime last_time;
179 } qt_mac_dblclick = { false, 0, -1, -1, 0, 0, -2 };
180
181 static bool app_do_modal = false;       // modal mode
182 extern QWidgetList *qt_modal_stack;     // stack of modal widgets
183 extern bool qt_tab_all_widgets;         // from qapplication.cpp
184 bool qt_scrollbar_jump_to_pos = false;
185 static bool qt_mac_collapse_on_dblclick = true;
186 extern int qt_antialiasing_threshold; // from qapplication.cpp
187 QWidget * qt_button_down;                // widget got last button-down
188 QPointer<QWidget> qt_last_mouse_receiver;
189 #if defined(QT_DEBUG)
190 static bool        appNoGrab        = false;        // mouse/keyboard grabbing
191 #endif
192 static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL;
193 static EventHandlerRef tablet_proximity_handler = 0;
194 static EventHandlerUPP tablet_proximity_UPP = 0;
195 bool QApplicationPrivate::native_modal_dialog_active;
196
197 Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
198
199 /*****************************************************************************
200   External functions
201  *****************************************************************************/
202 extern void qt_mac_beep(); //qsound_mac.mm
203 extern Qt::KeyboardModifiers qt_mac_get_modifiers(int keys); //qkeymapper_mac.cpp
204 extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
205 extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
206 extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
207 extern QWidget *qt_mac_find_window(OSWindowRef); //qwidget_mac.cpp
208 extern void qt_mac_set_cursor(const QCursor *); //qcursor_mac.cpp
209 extern bool qt_mac_is_macsheet(const QWidget *); //qwidget_mac.cpp
210 extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
211 extern void qt_mac_command_set_enabled(MenuRef, UInt32, bool); //qmenu_mac.cpp
212 extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); // qapplication.cpp
213 extern void qt_mac_update_cursor(); // qcursor_mac.mm
214
215 // Forward Decls
216 void onApplicationWindowChangedActivation( QWidget*widget, bool activated );
217 void onApplicationChangedActivation( bool activated );
218
219 static void qt_mac_read_fontsmoothing_settings()
220 {
221     qt_applefontsmoothing_enabled = true;
222     int w = 10, h = 10;
223     QImage image(w, h, QImage::Format_RGB32);
224     image.fill(0xffffffff);
225     QPainter p(&image);
226     p.drawText(0, h, "X\\");
227     p.end();
228
229     const int *bits = (const int *) ((const QImage &) image).bits();
230     int bpl = image.bytesPerLine() / 4;
231     for (int y=0; y<w; ++y) {
232         for (int x=0; x<h; ++x) {
233             int r = qRed(bits[x]);
234             int g = qGreen(bits[x]);
235             int b = qBlue(bits[x]);
236             if (r != g || r != b) {
237                 qt_applefontsmoothing_enabled = true;
238                 return;
239             }
240         }
241         bits += bpl;
242     }
243     qt_applefontsmoothing_enabled = false;
244 }
245
246 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
247     OSStatus err;
248     AEDesc scriptTextDesc;
249     ComponentInstance theComponent = 0;
250     OSAID scriptID = kOSANullScript, resultID = kOSANullScript;
251
252     // set up locals to a known state
253     AECreateDesc(typeNull, 0, 0, &scriptTextDesc);
254     scriptID = kOSANullScript;
255     resultID = kOSANullScript;
256
257     // open the scripting component
258     theComponent = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
259     if (!theComponent) {
260         err = paramErr;
261         goto bail;
262     }
263
264     // put the script text into an aedesc
265     err = AECreateDesc(typeUTF8Text, script, script_len, &scriptTextDesc);
266     if (err != noErr)
267         goto bail;
268
269     // compile the script
270     err = OSACompile(theComponent, &scriptTextDesc, kOSAModeNull, &scriptID);
271     if (err != noErr)
272         goto bail;
273
274     // run the script
275     err = OSAExecute(theComponent, scriptID, kOSANullScript, kOSAModeNull, &resultID);
276
277     // collect the results - if any
278     if (ret) {
279         AECreateDesc(typeNull, 0, 0, ret);
280         if (err == errOSAScriptError)
281             OSAScriptError(theComponent, kOSAErrorMessage, typeChar, ret);
282         else if (err == noErr && resultID != kOSANullScript)
283             OSADisplay(theComponent, resultID, typeChar, kOSAModeNull, ret);
284     }
285 bail:
286     AEDisposeDesc(&scriptTextDesc);
287     if (scriptID != kOSANullScript)
288         OSADispose(theComponent, scriptID);
289     if (resultID != kOSANullScript)
290         OSADispose(theComponent, resultID);
291     if (theComponent)
292         CloseComponent(theComponent);
293     return err == noErr;
294 }
295
296 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, AEDesc *ret)
297 {
298     return qt_mac_execute_apple_script(script, qstrlen(script), ret);
299 }
300
301 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret)
302 {
303     const QByteArray l = script.toUtf8(); return qt_mac_execute_apple_script(l.constData(), l.size(), ret);
304 }
305
306 /* Resolution change magic */
307 void qt_mac_display_change_callbk(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void *)
308 {
309 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
310     const bool resized = flags & kCGDisplayDesktopShapeChangedFlag;
311 #else
312     Q_UNUSED(flags);
313     const bool resized = true;
314 #endif
315     if (resized && qApp) {
316         if (QDesktopWidget *dw = qApp->desktop()) {
317             QResizeEvent *re = new QResizeEvent(dw->size(), dw->size());
318             QApplication::postEvent(dw, re);
319             QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
320         }
321     }
322 }
323
324 #ifdef DEBUG_PLATFORM_SETTINGS
325 static void qt_mac_debug_palette(const QPalette &pal, const QPalette &pal2, const QString &where)
326 {
327     const char *const groups[] = {"Active", "Disabled", "Inactive" };
328     const char *const roles[] = { "WindowText", "Button", "Light", "Midlight", "Dark", "Mid",
329                             "Text", "BrightText", "ButtonText", "Base", "Window", "Shadow",
330                             "Highlight", "HighlightedText", "Link", "LinkVisited" };
331     if (!where.isNull())
332         qDebug("qt-internal: %s", where.toLatin1().constData());
333     for(int grp = 0; grp < QPalette::NColorGroups; grp++) {
334         for(int role = 0; role < QPalette::NColorRoles; role++) {
335             QBrush b = pal.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role);
336             QPixmap pm = b.texture();
337             qDebug("  %s::%s %d::%d::%d [%p]%s", groups[grp], roles[role], b.color().red(),
338                    b.color().green(), b.color().blue(), pm.isNull() ? 0 : &pm,
339                    pal2.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role) != b ? " (*)" : "");
340         }
341     }
342
343 }
344 #else
345 #define qt_mac_debug_palette(x, y, z)
346 #endif
347
348 //raise a notification
349 void qt_mac_send_notification()
350 {
351     QMacCocoaAutoReleasePool pool;
352     [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
353 }
354
355 void qt_mac_cancel_notification()
356 {
357     QMacCocoaAutoReleasePool pool;
358     [[NSApplication sharedApplication] cancelUserAttentionRequest:NSInformationalRequest];
359 }
360
361 void qt_mac_set_app_icon(const QPixmap &pixmap)
362 {
363     QMacCocoaAutoReleasePool pool;
364     NSImage *image = NULL;
365     if (pixmap.isNull()) {
366         // Get Application icon from bundle
367         image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; // released below
368     } else {
369         image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
370     }
371
372     [NSApp setApplicationIconImage:image];
373     [image release];
374 }
375
376 Q_GUI_EXPORT void qt_mac_set_press_and_hold_context(bool b)
377 {
378     Q_UNUSED(b);
379     qWarning("qt_mac_set_press_and_hold_context: This functionality is no longer available");
380 }
381
382 bool qt_nograb()                                // application no-grab option
383 {
384 #if defined(QT_DEBUG)
385     return appNoGrab;
386 #else
387     return false;
388 #endif
389 }
390
391 void qt_mac_update_os_settings()
392 {
393     if (!qApp)
394         return;
395     if (!QApplication::startingUp()) {
396         static bool needToPolish = true;
397         if (needToPolish) {
398             QApplication::style()->polish(qApp);
399             needToPolish = false;
400         }
401     }
402     //focus mode
403     /* First worked as of 10.2.3 */
404     QSettings appleSettings(QLatin1String("apple.com"));
405     QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0);
406     qt_tab_all_widgets = (appleValue.toInt() & 0x2);
407     //paging mode
408     /* First worked as of 10.2.3 */
409     appleValue = appleSettings.value(QLatin1String("AppleScrollerPagingBehavior"), false);
410     qt_scrollbar_jump_to_pos = appleValue.toBool();
411     //collapse
412     /* First worked as of 10.3.3 */
413     appleValue = appleSettings.value(QLatin1String("AppleMiniaturizeOnDoubleClick"), true);
414     qt_mac_collapse_on_dblclick = appleValue.toBool();
415
416     // Anti-aliasing threshold
417     appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
418     if (appleValue.isValid())
419         qt_antialiasing_threshold = appleValue.toInt();
420
421 #ifdef DEBUG_PLATFORM_SETTINGS
422     qDebug("qt_mac_update_os_settings *********************************************************************");
423 #endif
424     { // setup the global palette
425         QColor qc;
426         (void) QApplication::style();  // trigger creation of application style and system palettes
427         QPalette pal = *QApplicationPrivate::sys_pal;
428
429         pal.setBrush( QPalette::Active, QPalette::Highlight, qcolorForTheme(kThemeBrushPrimaryHighlightColor) );
430         pal.setBrush( QPalette::Inactive, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
431
432         pal.setBrush( QPalette::Disabled, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
433         pal.setBrush( QPalette::Active, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonActiveDarkShadow) );
434
435         pal.setBrush( QPalette::Inactive, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
436         pal.setBrush( QPalette::Disabled, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
437
438         qc = qcolorForThemeTextColor(kThemeTextColorDialogActive);
439         pal.setColor(QPalette::Active, QPalette::Text, qc);
440         pal.setColor(QPalette::Active, QPalette::WindowText, qc);
441         pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
442
443         qc = qcolorForThemeTextColor(kThemeTextColorDialogInactive);
444         pal.setColor(QPalette::Inactive, QPalette::Text, qc);
445         pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
446         pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
447         pal.setColor(QPalette::Disabled, QPalette::Text, qc);
448         pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
449         pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
450         pal.setBrush(QPalette::ToolTipBase, QColor(255, 255, 199));
451
452         if (!QApplicationPrivate::sys_pal || *QApplicationPrivate::sys_pal != pal) {
453             QApplicationPrivate::setSystemPalette(pal);
454             QApplication::setPalette(pal);
455         }
456 #ifdef DEBUG_PLATFORM_SETTINGS
457         qt_mac_debug_palette(pal, QApplication::palette(), "Global Palette");
458 #endif
459     }
460
461     QFont fnt = qfontForThemeFont(kThemeApplicationFont);
462 #ifdef DEBUG_PLATFORM_SETTINGS
463     qDebug("qt-internal: Font for Application [%s::%d::%d::%d]",
464            fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
465 #endif
466     if (!QApplicationPrivate::sys_font || *QApplicationPrivate::sys_font != fnt)
467         QApplicationPrivate::setSystemFont(fnt);
468
469     { //setup the fonts
470         struct FontMap {
471             FontMap(const char *qc, short fk) : qt_class(qc), font_key(fk) { }
472             const char *const qt_class;
473             short font_key;
474         } mac_widget_fonts[] = {
475             FontMap("QPushButton", kThemePushButtonFont),
476             FontMap("QListView", kThemeViewsFont),
477             FontMap("QListBox", kThemeViewsFont),
478             FontMap("QTitleBar", kThemeWindowTitleFont),
479             FontMap("QMenuBar", kThemeMenuTitleFont),
480             FontMap("QMenu", kThemeMenuItemFont),
481             FontMap("QComboMenuItem", kThemeSystemFont),
482             FontMap("QHeaderView", kThemeSmallSystemFont),
483             FontMap("Q3Header", kThemeSmallSystemFont),
484             FontMap("QTipLabel", kThemeSmallSystemFont),
485             FontMap("QLabel", kThemeSystemFont),
486             FontMap("QToolButton", kThemeSmallSystemFont),
487             FontMap("QMenuItem", kThemeMenuItemFont),  // It doesn't exist, but its unique.
488             FontMap("QComboLineEdit", kThemeViewsFont),  // It doesn't exist, but its unique.
489             FontMap("QSmallFont", kThemeSmallSystemFont),  // It doesn't exist, but its unique.
490             FontMap("QMiniFont", kThemeMiniSystemFont),  // It doesn't exist, but its unique.
491             FontMap(0, 0) };
492         for(int i = 0; mac_widget_fonts[i].qt_class; i++) {
493             QFont fnt = qfontForThemeFont(mac_widget_fonts[i].font_key);
494             bool set_font = true;
495             FontHash *hash = qt_app_fonts_hash();
496             if (!hash->isEmpty()) {
497                 FontHash::const_iterator it
498                                         = hash->constFind(mac_widget_fonts[i].qt_class);
499                 if (it != hash->constEnd())
500                     set_font = (fnt != *it);
501             }
502             if (set_font) {
503                 QApplication::setFont(fnt, mac_widget_fonts[i].qt_class);
504 #ifdef DEBUG_PLATFORM_SETTINGS
505                 qDebug("qt-internal: Font for %s [%s::%d::%d::%d]", mac_widget_fonts[i].qt_class,
506                        fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
507 #endif
508             }
509         }
510     }
511     QApplicationPrivate::initializeWidgetPaletteHash();
512 #ifdef DEBUG_PLATFORM_SETTINGS
513     qDebug("qt_mac_update_os_settings END !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
514 #endif
515 }
516
517 void QApplicationPrivate::initializeWidgetPaletteHash()
518 {
519     { //setup the palette
520         struct PaletteMap {
521             inline PaletteMap(const char *qc, ThemeBrush a, ThemeBrush i) :
522                 qt_class(qc), active(a), inactive(i) { }
523             const char *const qt_class;
524             ThemeBrush active, inactive;
525         } mac_widget_colors[] = {
526             PaletteMap("QToolButton", kThemeTextColorBevelButtonActive, kThemeTextColorBevelButtonInactive),
527             PaletteMap("QAbstractButton", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
528             PaletteMap("QHeaderView", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
529             PaletteMap("Q3Header", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
530             PaletteMap("QComboBox", kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive),
531             PaletteMap("QAbstractItemView", kThemeTextColorListView, kThemeTextColorDialogInactive),
532             PaletteMap("QMessageBoxLabel", kThemeTextColorAlertActive, kThemeTextColorAlertInactive),
533             PaletteMap("QTabBar", kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive),
534             PaletteMap("QLabel", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
535             PaletteMap("QGroupBox", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
536             PaletteMap("QMenu", kThemeTextColorPopupLabelActive, kThemeTextColorPopupLabelInactive),
537             PaletteMap("QTextEdit", 0, 0),
538             PaletteMap("QTextControl", 0, 0),
539             PaletteMap("QLineEdit", 0, 0),
540             PaletteMap(0, 0, 0) };
541         QColor qc;
542         for(int i = 0; mac_widget_colors[i].qt_class; i++) {
543             QPalette pal;
544             if (mac_widget_colors[i].active != 0) {
545                 qc = qcolorForThemeTextColor(mac_widget_colors[i].active);
546                 pal.setColor(QPalette::Active, QPalette::Text, qc);
547                 pal.setColor(QPalette::Active, QPalette::WindowText, qc);
548                 pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
549                 qc = qcolorForThemeTextColor(mac_widget_colors[i].inactive);
550                 pal.setColor(QPalette::Inactive, QPalette::Text, qc);
551                 pal.setColor(QPalette::Disabled, QPalette::Text, qc);
552                 pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
553                 pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
554                 pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
555                 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
556             }
557             if (!strcmp(mac_widget_colors[i].qt_class, "QMenu")) {
558                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemActive);
559                 pal.setBrush(QPalette::ButtonText, qc);
560                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
561                 pal.setBrush(QPalette::HighlightedText, qc);
562                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemDisabled);
563                 pal.setBrush(QPalette::Disabled, QPalette::Text, qc);
564             } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractButton")
565                       || !strcmp(mac_widget_colors[i].qt_class, "QHeaderView")
566                       || !strcmp(mac_widget_colors[i].qt_class, "Q3Header")) { //special
567                 pal.setColor(QPalette::Disabled, QPalette::ButtonText,
568                              pal.color(QPalette::Disabled, QPalette::Text));
569                 pal.setColor(QPalette::Inactive, QPalette::ButtonText,
570                              pal.color(QPalette::Inactive, QPalette::Text));
571                 pal.setColor(QPalette::Active, QPalette::ButtonText,
572                              pal.color(QPalette::Active, QPalette::Text));
573             } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractItemView")) {
574                 pal.setBrush(QPalette::Active, QPalette::Highlight,
575                              qcolorForTheme(kThemeBrushAlternatePrimaryHighlightColor));
576                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
577                 pal.setBrush(QPalette::Active, QPalette::HighlightedText, qc);
578 #if 1
579                 pal.setBrush(QPalette::Inactive, QPalette::Text,
580                               pal.brush(QPalette::Active, QPalette::Text));
581                 pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
582                               pal.brush(QPalette::Active, QPalette::Text));
583 #endif
584             } else if (!strcmp(mac_widget_colors[i].qt_class, "QTextEdit")
585                        || !strcmp(mac_widget_colors[i].qt_class, "QTextControl")) {
586                 pal.setBrush(QPalette::Inactive, QPalette::Text,
587                               pal.brush(QPalette::Active, QPalette::Text));
588                 pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
589                               pal.brush(QPalette::Active, QPalette::Text));
590             } else if (!strcmp(mac_widget_colors[i].qt_class, "QLineEdit")) {
591                 pal.setBrush(QPalette::Disabled, QPalette::Base,
592                              pal.brush(QPalette::Active, QPalette::Base));
593             }
594
595             bool set_palette = true;
596             PaletteHash *phash = qt_app_palettes_hash();
597             if (!phash->isEmpty()) {
598                 PaletteHash::const_iterator it
599                                     = phash->constFind(mac_widget_colors[i].qt_class);
600                 if (it != phash->constEnd())
601                     set_palette = (pal != *it);
602             }
603             if (set_palette) {
604                 QApplication::setPalette(pal, mac_widget_colors[i].qt_class);
605 #ifdef DEBUG_PLATFORM_SETTINGS
606                 qt_mac_debug_palette(pal, QApplication::palette(), QLatin1String("Palette for ") + QString::fromLatin1(mac_widget_colors[i].qt_class));
607 #endif
608             }
609         }
610     }
611 }
612
613 static void qt_mac_event_release(EventRef &event)
614 {
615     ReleaseEvent(event);
616     event = 0;
617 }
618
619 /* sheets */
620 void qt_event_request_showsheet(QWidget *w)
621 {
622     Q_ASSERT(qt_mac_is_macsheet(w));
623     [NSApp beginSheet:qt_mac_window_for(w) modalForWindow:qt_mac_window_for(w->parentWidget())
624         modalDelegate:nil didEndSelector:nil contextInfo:0];
625 }
626
627 static void qt_post_window_change_event(QWidget *widget)
628 {
629     qt_widget_private(widget)->needWindowChange = true;
630     QEvent *glWindowChangeEvent = new QEvent(QEvent::MacGLWindowChange);
631     QApplication::postEvent(widget, glWindowChangeEvent);
632 }
633
634 /*
635     Posts updates to all child and grandchild OpenGL widgets for the given widget.
636 */
637 static void qt_mac_update_child_gl_widgets(QWidget *widget)
638 {
639     // Update all OpenGL child widgets for the given widget.
640     QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
641     QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
642     QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
643
644     for (;it != end; ++it) {
645         qt_post_window_change_event(it->widget);
646     }
647 }
648
649 /*
650     Sends updates to all child and grandchild gl widgets that have updates pending.
651 */
652 void qt_mac_send_posted_gl_updates(QWidget *widget)
653 {
654     QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
655     QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
656     QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
657
658     for (;it != end; ++it) {
659         QWidget *glWidget = it->widget;
660         if (qt_widget_private(glWidget)->needWindowChange) {
661             QEvent glChangeEvent(QEvent::MacGLWindowChange);
662             QApplication::sendEvent(glWidget, &glChangeEvent);
663         }
664     }
665 }
666
667 /*
668     Posts updates to all OpenGL widgets within the window that the given widget intersects.
669 */
670 static void qt_mac_update_intersected_gl_widgets(QWidget *widget)
671 {
672     Q_UNUSED(widget);
673 }
674
675 /*
676     Posts a kEventQtRequestWindowChange event to the main Carbon event queue.
677 */
678 static EventRef request_window_change_pending = 0;
679 Q_GUI_EXPORT void qt_event_request_window_change()
680 {
681     if(request_window_change_pending)
682         return;
683
684     CreateEvent(0, kEventClassQt, kEventQtRequestWindowChange, GetCurrentEventTime(),
685                 kEventAttributeUserEvent, &request_window_change_pending);
686     PostEventToQueue(GetMainEventQueue(), request_window_change_pending, kEventPriorityHigh);
687 }
688
689 /* window changing. This is a hack around Apple's missing functionality, pending the toolbox
690    team fix. --Sam */
691 Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget)
692 {
693     if (!widget)
694         return;
695
696     // Post a kEventQtRequestWindowChange event. This event is semi-public,
697     // don't remove this line!
698     qt_event_request_window_change();
699
700     // Post update request on gl widgets unconditionally.
701     if (qt_widget_private(widget)->isGLWidget == true) {
702         qt_post_window_change_event(widget);
703         return;
704     }
705
706     qt_mac_update_child_gl_widgets(widget);
707     qt_mac_update_intersected_gl_widgets(widget);
708 }
709
710 /* activation */
711 static struct {
712     QPointer<QWidget> widget;
713     EventRef event;
714     EventLoopTimerRef timer;
715     EventLoopTimerUPP timerUPP;
716 } request_activate_pending = { 0, 0, 0, 0 };
717 bool qt_event_remove_activate()
718 {
719     if (request_activate_pending.timer) {
720         RemoveEventLoopTimer(request_activate_pending.timer);
721         request_activate_pending.timer = 0;
722     }
723     if (request_activate_pending.event)
724         qt_mac_event_release(request_activate_pending.event);
725     return true;
726 }
727
728 void qt_event_activate_timer_callbk(EventLoopTimerRef r, void *)
729 {
730     EventLoopTimerRef otc = request_activate_pending.timer;
731     qt_event_remove_activate();
732     if (r == otc && !request_activate_pending.widget.isNull()) {
733         const QWidget *tlw = request_activate_pending.widget->window();
734         Qt::WindowType wt = tlw->windowType();
735         if (tlw->isVisible()
736                && ((wt != Qt::Desktop && wt != Qt::Popup && wt != Qt::Tool) || tlw->isModal())) {
737             CreateEvent(0, kEventClassQt, kEventQtRequestActivate, GetCurrentEventTime(),
738                         kEventAttributeUserEvent, &request_activate_pending.event);
739             PostEventToQueue(GetMainEventQueue(), request_activate_pending.event, kEventPriorityHigh);
740         }
741     }
742 }
743
744 void qt_event_request_activate(QWidget *w)
745 {
746     if (w == request_activate_pending.widget)
747         return;
748
749     /* We put these into a timer because due to order of events being sent we need to be sure this
750        comes from inside of the event loop */
751     qt_event_remove_activate();
752     if (!request_activate_pending.timerUPP)
753         request_activate_pending.timerUPP = NewEventLoopTimerUPP(qt_event_activate_timer_callbk);
754     request_activate_pending.widget = w;
755     InstallEventLoopTimer(GetMainEventLoop(), 0, 0, request_activate_pending.timerUPP, 0, &request_activate_pending.timer);
756 }
757
758
759 /* menubars */
760 void qt_event_request_menubarupdate()
761 {
762     // Just call this. The request has the benefit that we don't call this multiple times, but
763     // we can optimize this.
764     QMenuBar::macUpdateMenuBar();
765 }
766
767
768 void QApplicationPrivate::createEventDispatcher()
769 {
770     Q_Q(QApplication);
771     if (q->type() != QApplication::Tty)
772         eventDispatcher = new QEventDispatcherMac(q);
773     else
774         eventDispatcher = new QEventDispatcherUNIX(q);
775 }
776
777 /* clipboard */
778 void qt_event_send_clipboard_changed()
779 {
780 }
781
782 /* app menu */
783 static QMenu *qt_mac_dock_menu = 0;
784 Q_GUI_EXPORT void qt_mac_set_dock_menu(QMenu *menu)
785 {
786     qt_mac_dock_menu = menu;
787     [NSApp setDockMenu:menu->macMenu()];
788 }
789
790 /* events that hold pointers to widgets, must be cleaned up like this */
791 void qt_mac_event_release(QWidget *w)
792 {
793     if (w) {
794         if (w == qt_mac_dock_menu) {
795             qt_mac_dock_menu = 0;
796             [NSApp setDockMenu:0];
797         }
798     }
799 }
800
801 struct QMacAppleEventTypeSpec {
802     AEEventClass mac_class;
803     AEEventID mac_id;
804 } app_apple_events[] = {
805     { kCoreEventClass, kAEQuitApplication },
806     { kCoreEventClass, kAEOpenDocuments },
807     { kInternetEventClass, kAEGetURL },
808 };
809
810 static void qt_init_tablet_proximity_handler()
811 {
812     EventTypeSpec       tabletProximityEvent = { kEventClassTablet, kEventTabletProximity };
813     InstallEventHandler(GetEventMonitorTarget(), tablet_proximity_UPP,
814                         1, &tabletProximityEvent, qApp, &tablet_proximity_handler);
815 }
816
817 static void qt_release_tablet_proximity_handler()
818 {
819     RemoveEventHandler(tablet_proximity_handler);
820 }
821
822 QString QApplicationPrivate::appName() const
823 {
824     static QString applName;
825     if (applName.isEmpty()) {
826         applName = QCoreApplicationPrivate::macMenuBarName();
827         ProcessSerialNumber psn;
828         if (applName.isEmpty() && qt_is_gui_used && GetCurrentProcess(&psn) == noErr) {
829             QCFString cfstr;
830             CopyProcessName(&psn, &cfstr);
831             applName = cfstr;
832         }
833     }
834     return applName;
835 }
836
837 void qt_release_app_proc_handler()
838 {
839 }
840
841 void qt_color_profile_changed(CFNotificationCenterRef, void *, CFStringRef, const void *,
842                               CFDictionaryRef)
843 {
844     QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
845 }
846 /* platform specific implementations */
847 void qt_init(QApplicationPrivate *priv, int)
848 {
849     if (qt_is_gui_used) {
850         CGDisplayRegisterReconfigurationCallback(qt_mac_display_change_callbk, 0);
851         CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
852         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
853                                         kCMDeviceUnregisteredNotification, 0,
854                                         CFNotificationSuspensionBehaviorDeliverImmediately);
855         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
856                                         kCMDefaultDeviceNotification, 0,
857                                         CFNotificationSuspensionBehaviorDeliverImmediately);
858         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
859                                         kCMDeviceProfilesNotification, 0,
860                                         CFNotificationSuspensionBehaviorDeliverImmediately);
861         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
862                                         kCMDefaultDeviceProfileNotification, 0,
863                                         CFNotificationSuspensionBehaviorDeliverImmediately);
864         ProcessSerialNumber psn;
865         if (GetCurrentProcess(&psn) == noErr) {
866             // Jambi needs to transform itself since most people aren't "used"
867             // to putting things in bundles, but other people may actually not
868             // want to tranform the process (running as a helper or something)
869             // so don't do that for them. This means checking both LSUIElement
870             // and LSBackgroundOnly. If you set them both... well, you
871             // shouldn't do that.
872
873             bool forceTransform = true;
874             CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
875                                                                    CFSTR("LSUIElement"));
876             if (value) {
877                 CFTypeID valueType = CFGetTypeID(value);
878                 // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
879                 // A number less so, but OK.
880                 if (valueType == CFStringGetTypeID())
881                     forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
882                 else if (valueType == CFBooleanGetTypeID())
883                     forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
884                 else if (valueType == CFNumberGetTypeID()) {
885                     int valueAsInt;
886                     CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
887                     forceTransform = !valueAsInt;
888                 }
889             }
890
891             if (forceTransform) {
892                 value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
893                                                              CFSTR("LSBackgroundOnly"));
894                 if (value) {
895                     CFTypeID valueType = CFGetTypeID(value);
896                     if (valueType == CFBooleanGetTypeID())
897                         forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
898                     else if (valueType == CFStringGetTypeID())
899                         forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
900                     else if (valueType == CFNumberGetTypeID()) {
901                         int valueAsInt;
902                         CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
903                         forceTransform = !valueAsInt;
904                     }
905                 }
906             }
907
908
909             if (forceTransform) {
910                 TransformProcessType(&psn, kProcessTransformToForegroundApplication);
911             }
912         }
913     }
914
915     char **argv = priv->argv;
916
917     // Get command line params
918     if (int argc = priv->argc) {
919         int i, j = 1;
920         QString passed_psn;
921         for(i=1; i < argc; i++) {
922             if (argv[i] && *argv[i] != '-') {
923                 argv[j++] = argv[i];
924                 continue;
925             }
926             QByteArray arg(argv[i]);
927 #if defined(QT_DEBUG)
928             if (arg == "-nograb")
929                 appNoGrab = !appNoGrab;
930             else
931 #endif // QT_DEBUG
932                 if (arg.left(5) == "-psn_") {
933                     passed_psn = QString::fromLatin1(arg.mid(6));
934                 } else {
935                     argv[j++] = argv[i];
936                 }
937         }
938         if (j < priv->argc) {
939             priv->argv[j] = 0;
940             priv->argc = j;
941         }
942
943         //special hack to change working directory (for an app bundle) when running from finder
944         if (!passed_psn.isNull() && QDir::currentPath() == QLatin1String("/")) {
945             QCFType<CFURLRef> bundleURL(CFBundleCopyBundleURL(CFBundleGetMainBundle()));
946             QString qbundlePath = QCFString(CFURLCopyFileSystemPath(bundleURL,
947                                             kCFURLPOSIXPathStyle));
948             if (qbundlePath.endsWith(QLatin1String(".app")))
949                 QDir::setCurrent(qbundlePath.section(QLatin1Char('/'), 0, -2));
950         }
951    }
952
953     QMacPasteboardMime::initialize();
954
955     qApp->setObjectName(priv->appName());
956     if (qt_is_gui_used) {
957         QColormap::initialize();
958         QFont::initialize();
959         QCursorData::initialize();
960         QCoreGraphicsPaintEngine::initialize();
961 #ifndef QT_NO_ACCESSIBILITY
962         QAccessible::initialize();
963 #endif
964         QMacInputContext::initialize();
965         QApplicationPrivate::inputContext = new QMacInputContext;
966
967         if (QApplication::desktopSettingsAware())
968             qt_mac_update_os_settings();
969         if (!app_proc_ae_handlerUPP && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
970             app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor);
971             for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) {
972                 // Install apple event handler, but avoid overwriting an already
973                 // existing handler (it means a 3rd party application has installed one):
974                 SRefCon refCon = 0;
975                 AEEventHandlerUPP current_handler = NULL;
976                 AEGetEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, &current_handler, &refCon, false);
977                 if (!current_handler)
978                     AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
979                             app_proc_ae_handlerUPP, SRefCon(qApp), false);
980             }
981         }
982
983         if (QApplicationPrivate::app_style) {
984             QEvent ev(QEvent::Style);
985             qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
986         }
987     }
988     if (QApplication::desktopSettingsAware())
989         QApplicationPrivate::qt_mac_apply_settings();
990
991     // Cocoa application delegate
992     NSApplication *cocoaApp = [QNSApplication sharedApplication];
993     qt_redirectNSApplicationSendEvent();
994
995     QMacCocoaAutoReleasePool pool;
996     id oldDelegate = [cocoaApp delegate];
997     QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
998     Q_ASSERT(newDelegate);
999     [newDelegate setQtPrivate:priv];
1000     // Only do things that make sense to do once, otherwise we crash.
1001     if (oldDelegate != newDelegate && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
1002         [newDelegate setReflectionDelegate:oldDelegate];
1003         [cocoaApp setDelegate:newDelegate];
1004
1005         QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
1006         if ([NSBundle loadNibNamed:@"qt_menu" owner:qtMenuLoader] == false) {
1007             qFatal("Qt internal error: qt_menu.nib could not be loaded. The .nib file"
1008                    " should be placed in QtGui.framework/Versions/Current/Resources/ "
1009                    " or in the resources directory of your application bundle.");
1010         }
1011
1012         [cocoaApp setMenu:[qtMenuLoader menu]];
1013         [newDelegate setMenuLoader:qtMenuLoader];
1014         [qtMenuLoader release];
1015     }
1016     // Register for Carbon tablet proximity events on the event monitor target.
1017     // This means that we should receive proximity events even when we aren't the active application.
1018     if (!tablet_proximity_handler) {
1019         tablet_proximity_UPP = NewEventHandlerUPP(QApplicationPrivate::tabletProximityCallback);
1020         qt_init_tablet_proximity_handler();
1021     }
1022    priv->native_modal_dialog_active = false;
1023
1024    qt_mac_read_fontsmoothing_settings();
1025 }
1026
1027 void qt_release_apple_event_handler()
1028 {
1029     if(app_proc_ae_handlerUPP) {
1030         for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
1031             AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
1032                     app_proc_ae_handlerUPP, true);
1033         DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP);
1034         app_proc_ae_handlerUPP = 0;
1035     }
1036 }
1037
1038 /*****************************************************************************
1039   qt_cleanup() - cleans up when the application is finished
1040  *****************************************************************************/
1041
1042 void qt_cleanup()
1043 {
1044     CGDisplayRemoveReconfigurationCallback(qt_mac_display_change_callbk, 0);
1045     CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
1046     CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceUnregisteredNotification, 0);
1047     CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceNotification, 0);
1048     CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceProfilesNotification, 0);
1049     CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceProfileNotification, 0);
1050
1051     qt_release_apple_event_handler();
1052     qt_release_tablet_proximity_handler();
1053     if (tablet_proximity_UPP)
1054         DisposeEventHandlerUPP(tablet_proximity_UPP);
1055
1056     QPixmapCache::clear();
1057     if (qt_is_gui_used) {
1058 #ifndef QT_NO_ACCESSIBILITY
1059         QAccessible::cleanup();
1060 #endif
1061         QMacInputContext::cleanup();
1062         QCursorData::cleanup();
1063         QFont::cleanup();
1064         QColormap::cleanup();
1065         if (qt_mac_safe_pdev) {
1066             delete qt_mac_safe_pdev;
1067             qt_mac_safe_pdev = 0;
1068         }
1069         extern void qt_mac_unregister_widget(); // qapplication_mac.cpp
1070         qt_mac_unregister_widget();
1071     }
1072 }
1073
1074 /*****************************************************************************
1075   Platform specific global and internal functions
1076  *****************************************************************************/
1077 void qt_updated_rootinfo()
1078 {
1079 }
1080
1081 bool qt_wstate_iconified(WId)
1082 {
1083     return false;
1084 }
1085
1086 /*****************************************************************************
1087   Platform specific QApplication members
1088  *****************************************************************************/
1089 extern QWidget * mac_mouse_grabber;
1090 extern QWidget * mac_keyboard_grabber;
1091
1092 #ifndef QT_NO_CURSOR
1093
1094 /*****************************************************************************
1095   QApplication cursor stack
1096  *****************************************************************************/
1097
1098 void QApplication::setOverrideCursor(const QCursor &cursor)
1099 {
1100     qApp->d_func()->cursor_list.prepend(cursor);
1101
1102     qt_mac_update_cursor();
1103 }
1104
1105 void QApplication::restoreOverrideCursor()
1106 {
1107     if (qApp->d_func()->cursor_list.isEmpty())
1108         return;
1109     qApp->d_func()->cursor_list.removeFirst();
1110
1111     qt_mac_update_cursor();
1112 }
1113 #endif // QT_NO_CURSOR
1114
1115 QWidget *QApplication::topLevelAt(const QPoint &p)
1116 {
1117     // Use a cache to avoid iterate through the whole list of windows for all
1118     // calls to to topLevelAt. We e.g. do this for each and every mouse
1119     // move since we need to find the widget under mouse:
1120     if (topLevelAt_cache && topLevelAt_cache->frameGeometry().contains(p))
1121         return topLevelAt_cache;
1122
1123     // INVARIANT: Cache miss. Go through the list if windows instead:
1124     QMacCocoaAutoReleasePool pool;
1125     NSPoint cocoaPoint = flipPoint(p);
1126     NSInteger windowCount;
1127     NSCountWindows(&windowCount);
1128     if (windowCount <= 0)
1129         return 0;  // There's no window to find!
1130
1131     QVarLengthArray<NSInteger> windowList(windowCount);
1132     NSWindowList(windowCount, windowList.data());
1133     int firstQtWindowFound = -1;
1134     for (int i = 0; i < windowCount; ++i) {
1135         NSWindow *window = [NSApp windowWithWindowNumber:windowList[i]];
1136         if (window) {
1137             QWidget *candidateWindow = [window QT_MANGLE_NAMESPACE(qt_qwidget)];
1138             if (candidateWindow && firstQtWindowFound == -1)
1139                 firstQtWindowFound = i;
1140
1141             if (NSPointInRect(cocoaPoint, [window frame])) {
1142                 // Check to see if there's a hole in the window where the mask is.
1143                 // If there is, we should just continue to see if there is a window below.
1144                 if (candidateWindow && !candidateWindow->mask().isEmpty()) {
1145                     QPoint localPoint = candidateWindow->mapFromGlobal(p);
1146                     if (!candidateWindow->mask().contains(localPoint))
1147                         continue;
1148                     else
1149                         return candidateWindow;
1150                 } else {
1151                     if (i == firstQtWindowFound) {
1152                         // The cache will only work when the window under mouse is
1153                         // top most (that is, not partially obscured by other windows.
1154                         // And we only set it if no mask is present to optimize for the common case:
1155                         topLevelAt_cache = candidateWindow;
1156                     }
1157                     return candidateWindow;
1158                 }
1159             }
1160         }
1161     }
1162
1163     topLevelAt_cache = 0;
1164     return 0;
1165 }
1166
1167 /*****************************************************************************
1168   Main event loop
1169  *****************************************************************************/
1170
1171 bool QApplicationPrivate::modalState()
1172 {
1173     return app_do_modal;
1174 }
1175
1176
1177 void QApplicationPrivate::enterModal_sys(QWidget *widget)
1178 {
1179 #ifdef DEBUG_MODAL_EVENTS
1180     Q_ASSERT(widget);
1181     qDebug("Entering modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
1182             widget, qt_modal_stack ? (int)qt_modal_stack->count() : -1);
1183 #endif
1184     if (!qt_modal_stack)
1185         qt_modal_stack = new QWidgetList;
1186
1187     dispatchEnterLeave(0, qt_last_mouse_receiver);
1188     qt_last_mouse_receiver = 0;
1189
1190     qt_modal_stack->insert(0, widget);
1191     if (!app_do_modal)
1192         qt_event_request_menubarupdate();
1193     app_do_modal = true;
1194     qt_button_down = 0;
1195
1196     if (!qt_mac_is_macsheet(widget))
1197         QEventDispatcherMacPrivate::beginModalSession(widget);
1198 }
1199
1200 void QApplicationPrivate::leaveModal_sys(QWidget *widget)
1201 {
1202     if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
1203 #ifdef DEBUG_MODAL_EVENTS
1204         qDebug("Leaving modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
1205                widget, qt_modal_stack->count());
1206 #endif
1207         if (qt_modal_stack->isEmpty()) {
1208             delete qt_modal_stack;
1209             qt_modal_stack = 0;
1210             QPoint p(QCursor::pos());
1211             app_do_modal = false;
1212             QWidget* w = 0;
1213             if (QWidget *grabber = QWidget::mouseGrabber())
1214                 w = grabber;
1215             else
1216                 w = QApplication::widgetAt(p.x(), p.y());
1217             dispatchEnterLeave(w, qt_last_mouse_receiver); // send synthetic enter event
1218             qt_last_mouse_receiver = w;
1219         }
1220         if (!qt_mac_is_macsheet(widget))
1221             QEventDispatcherMacPrivate::endModalSession(widget);
1222     }
1223 #ifdef DEBUG_MODAL_EVENTS
1224     else qDebug("Failure to remove %s::%s::%p -- %p", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(), widget, qt_modal_stack);
1225 #endif
1226     app_do_modal = (qt_modal_stack != 0);
1227     if (!app_do_modal)
1228         qt_event_request_menubarupdate();
1229 }
1230
1231 QWidget *QApplicationPrivate::tryModalHelper_sys(QWidget *top)
1232 {
1233     return top;
1234 }
1235
1236
1237 OSStatus QApplicationPrivate::tabletProximityCallback(EventHandlerCallRef, EventRef carbonEvent,
1238                                                       void *)
1239 {
1240     OSType eventClass = GetEventClass(carbonEvent);
1241     UInt32 eventKind = GetEventKind(carbonEvent);
1242     if (eventClass != kEventClassTablet || eventKind != kEventTabletProximity)
1243         return eventNotHandledErr;
1244
1245     // Get the current point of the device and its unique ID.
1246     ::TabletProximityRec proxRec;
1247     GetEventParameter(carbonEvent, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
1248                       sizeof(proxRec), 0, &proxRec);
1249     qt_dispatchTabletProximityEvent(proxRec);
1250     return noErr;
1251 }
1252
1253 OSStatus
1254 QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event, void *data)
1255 {
1256     Q_UNUSED(er);
1257     Q_UNUSED(event);
1258     Q_UNUSED(data);
1259     return eventNotHandledErr;
1260 }
1261
1262 void QApplicationPrivate::qt_initAfterNSAppStarted()
1263 {
1264     setupAppleEvents();
1265     qt_mac_update_cursor();
1266 }
1267
1268 void QApplicationPrivate::setupAppleEvents()
1269 {
1270     // This function is called from the event dispatcher when NSApplication has
1271     // finished initialization, which appears to be just after [NSApplication run] has
1272     // started to execute. By setting up our apple events handlers this late, we override
1273     // the ones set up by NSApplication.
1274
1275     // If Qt is used as a plugin, we let the 3rd party application handle events
1276     // like quit and open file events. Otherwise, if we install our own handlers, we
1277     // easily end up breaking functionallity the 3rd party application depend on:
1278     if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
1279         return;
1280
1281     QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
1282     NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
1283     [eventManager setEventHandler:newDelegate andSelector:@selector(appleEventQuit:withReplyEvent:)
1284      forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
1285     [eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
1286       forEventClass:kInternetEventClass andEventID:kAEGetURL];
1287 }
1288
1289 // In Carbon this is your one stop for apple events.
1290 // In Cocoa, it ISN'T. This is the catch-all Apple Event handler that exists
1291 // for the time between instantiating the NSApplication, but before the
1292 // NSApplication has installed it's OWN Apple Event handler. When Cocoa has
1293 // that set up, we remove this.  So, if you are debugging problems, you likely
1294 // want to check out QCocoaApplicationDelegate instead.
1295 OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, AppleEvent *, long handlerRefcon)
1296 {
1297     QApplication *app = (QApplication *)handlerRefcon;
1298     bool handled_event=false;
1299     OSType aeID=typeWildCard, aeClass=typeWildCard;
1300     AEGetAttributePtr(ae, keyEventClassAttr, typeType, 0, &aeClass, sizeof(aeClass), 0);
1301     AEGetAttributePtr(ae, keyEventIDAttr, typeType, 0, &aeID, sizeof(aeID), 0);
1302     if(aeClass == kCoreEventClass) {
1303         switch(aeID) {
1304         case kAEQuitApplication: {
1305             extern bool qt_mac_quit_menu_item_enabled; // qmenu_mac.cpp
1306             if (qt_mac_quit_menu_item_enabled) {
1307                 QCloseEvent ev;
1308                 QApplication::sendSpontaneousEvent(app, &ev);
1309                 if(ev.isAccepted()) {
1310                     handled_event = true;
1311                     app->quit();
1312                 }
1313             } else {
1314                 QApplication::beep();  // Sorry, you can't quit right now.
1315             }
1316             break; }
1317         case kAEOpenDocuments: {
1318             AEDescList docs;
1319             if(AEGetParamDesc(ae, keyDirectObject, typeAEList, &docs) == noErr) {
1320                 long cnt = 0;
1321                 AECountItems(&docs, &cnt);
1322                 UInt8 *str_buffer = NULL;
1323                 for(int i = 0; i < cnt; i++) {
1324                     FSRef ref;
1325                     if(AEGetNthPtr(&docs, i+1, typeFSRef, 0, 0, &ref, sizeof(ref), 0) != noErr)
1326                         continue;
1327                     if(!str_buffer)
1328                         str_buffer = (UInt8 *)malloc(1024);
1329                     FSRefMakePath(&ref, str_buffer, 1024);
1330                     QFileOpenEvent ev(QString::fromUtf8((const char *)str_buffer));
1331                     QApplication::sendSpontaneousEvent(app, &ev);
1332                 }
1333                 if(str_buffer)
1334                     free(str_buffer);
1335             }
1336             break; }
1337         default:
1338             break;
1339         }
1340     } else if (aeClass == kInternetEventClass) {
1341         switch (aeID) {
1342         case kAEGetURL: {
1343             char urlData[1024];
1344             Size actualSize;
1345             if (AEGetParamPtr(ae, keyDirectObject, typeChar, 0, urlData,
1346                     sizeof(urlData) - 1, &actualSize) == noErr) {
1347                 urlData[actualSize] = 0;
1348                 QFileOpenEvent ev(QUrl(QString::fromUtf8(urlData)));
1349                 QApplication::sendSpontaneousEvent(app, &ev);
1350             }
1351             break;
1352         }
1353         default:
1354             break;
1355         }
1356     }
1357 #ifdef DEBUG_EVENTS
1358     qDebug("Qt: internal: %shandled Apple event! %c%c%c%c %c%c%c%c", handled_event ? "(*)" : "",
1359            char(aeID >> 24), char((aeID >> 16) & 255), char((aeID >> 8) & 255),char(aeID & 255),
1360            char(aeClass >> 24), char((aeClass >> 16) & 255), char((aeClass >> 8) & 255),char(aeClass & 255));
1361 #else
1362     if(!handled_event) //let the event go through
1363         return eventNotHandledErr;
1364     return noErr; //we eat the event
1365 #endif
1366 }
1367
1368 /*!
1369     \fn bool QApplication::macEventFilter(EventHandlerCallRef caller, EventRef event)
1370
1371     \warning This virtual function is only used under Mac OS X, and behaves different
1372     depending on if Qt is based on Carbon or Cocoa.
1373
1374     For the Carbon port, If you create an application that inherits QApplication and reimplement
1375     this function, you get direct access to all Carbon Events that Qt registers
1376     for from Mac OS X with this function being called with the \a caller and
1377     the \a event.
1378
1379     For the Cocoa port, If you create an application that inherits QApplication and reimplement
1380     this function, you get direct access to all Cocoa Events that Qt receives
1381     from Mac OS X with this function being called with the \a caller being 0 and
1382     the \a event being an NSEvent pointer:
1383
1384     NSEvent *e = reinterpret_cast<NSEvent *>(event);
1385
1386     Return true if you want to stop the event from being processed.
1387     Return false for normal event dispatching. The default
1388     implementation returns false.
1389 */
1390 bool QApplication::macEventFilter(EventHandlerCallRef, EventRef)
1391 {
1392     return false;
1393 }
1394
1395 /*!
1396     \internal
1397 */
1398 void QApplicationPrivate::openPopup(QWidget *popup)
1399 {
1400     if (!QApplicationPrivate::popupWidgets)                        // create list
1401         QApplicationPrivate::popupWidgets = new QWidgetList;
1402     QApplicationPrivate::popupWidgets->append(popup);                // add to end of list
1403
1404     // popups are not focus-handled by the window system (the first
1405     // popup grabbed the keyboard), so we have to do that manually: A
1406     // new popup gets the focus
1407     if (popup->focusWidget()) {
1408         popup->focusWidget()->setFocus(Qt::PopupFocusReason);
1409     } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
1410         popup->setFocus(Qt::PopupFocusReason);
1411     }
1412 }
1413
1414 /*!
1415     \internal
1416 */
1417 void QApplicationPrivate::closePopup(QWidget *popup)
1418 {
1419     Q_Q(QApplication);
1420     if (!QApplicationPrivate::popupWidgets)
1421         return;
1422
1423     QApplicationPrivate::popupWidgets->removeAll(popup);
1424     if (popup == qt_button_down)
1425         qt_button_down = 0;
1426     if (QApplicationPrivate::popupWidgets->isEmpty()) {  // this was the last popup
1427         delete QApplicationPrivate::popupWidgets;
1428         QApplicationPrivate::popupWidgets = 0;
1429
1430         // Special case for Tool windows: since they are activated and deactived together
1431         // with a normal window they never become the QApplicationPrivate::active_window.
1432         QWidget *appFocusWidget = QApplication::focusWidget();
1433         if (appFocusWidget && appFocusWidget->window()->windowType() == Qt::Tool) {
1434             appFocusWidget->setFocus(Qt::PopupFocusReason);
1435         } else if (QApplicationPrivate::active_window) {
1436             if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
1437                 if (fw != QApplication::focusWidget()) {
1438                     fw->setFocus(Qt::PopupFocusReason);
1439                 } else {
1440                     QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
1441                     q->sendEvent(fw, &e);
1442                 }
1443             }
1444         }
1445     } else {
1446         // popups are not focus-handled by the window system (the
1447         // first popup grabbed the keyboard), so we have to do that
1448         // manually: A popup was closed, so the previous popup gets
1449         // the focus.
1450         QWidget* aw = QApplicationPrivate::popupWidgets->last();
1451         if (QWidget *fw = aw->focusWidget())
1452             fw->setFocus(Qt::PopupFocusReason);
1453     }
1454 }
1455
1456 void QApplication::beep()
1457 {
1458     qt_mac_beep();
1459 }
1460
1461 void QApplication::alert(QWidget *widget, int duration)
1462 {
1463     if (!QApplicationPrivate::checkInstance("alert"))
1464         return;
1465
1466     QWidgetList windowsToMark;
1467     if (!widget)
1468         windowsToMark += topLevelWidgets();
1469     else
1470         windowsToMark.append(widget->window());
1471
1472     bool needNotification = false;
1473     for (int i = 0; i < windowsToMark.size(); ++i) {
1474         QWidget *window = windowsToMark.at(i);
1475         if (!window->isActiveWindow() && window->isVisible()) {
1476             needNotification = true; // yeah, we may set it multiple times, but that's OK.
1477             if (duration != 0) {
1478                QTimer *timer = new QTimer(qApp);
1479                timer->setSingleShot(true);
1480                connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
1481                if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(widget)) {
1482                    qApp->d_func()->alertTimerHash.remove(widget);
1483                    delete oldTimer;
1484                }
1485                qApp->d_func()->alertTimerHash.insert(widget, timer);
1486                timer->start(duration);
1487             }
1488         }
1489     }
1490     if (needNotification)
1491         qt_mac_send_notification();
1492 }
1493
1494 void QApplicationPrivate::_q_alertTimeOut()
1495 {
1496     if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
1497         QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
1498         while (it != alertTimerHash.end()) {
1499             if (it.value() == timer) {
1500                 alertTimerHash.erase(it);
1501                 timer->deleteLater();
1502                 break;
1503             }
1504             ++it;
1505         }
1506         if (alertTimerHash.isEmpty()) {
1507             qt_mac_cancel_notification();
1508         }
1509     }
1510 }
1511
1512 void  QApplication::setCursorFlashTime(int msecs)
1513 {
1514     QApplicationPrivate::cursor_flash_time = msecs;
1515 }
1516
1517 int QApplication::cursorFlashTime()
1518 {
1519     return QApplicationPrivate::cursor_flash_time;
1520 }
1521
1522 void QApplication::setDoubleClickInterval(int ms)
1523 {
1524     qt_mac_dblclick.use_qt_time_limit = true;
1525     QApplicationPrivate::mouse_double_click_time = ms;
1526 }
1527
1528 int QApplication::doubleClickInterval()
1529 {
1530     if (!qt_mac_dblclick.use_qt_time_limit) { //get it from the system
1531         QSettings appleSettings(QLatin1String("apple.com"));
1532         /* First worked as of 10.3.3 */
1533         double dci = appleSettings.value(QLatin1String("com/apple/mouse/doubleClickThreshold"), 0.5).toDouble();
1534         return int(dci * 1000);
1535     }
1536     return QApplicationPrivate::mouse_double_click_time;
1537 }
1538
1539 void QApplication::setKeyboardInputInterval(int ms)
1540 {
1541     QApplicationPrivate::keyboard_input_time = ms;
1542 }
1543
1544 int QApplication::keyboardInputInterval()
1545 {
1546     // FIXME: get from the system
1547     return QApplicationPrivate::keyboard_input_time;
1548 }
1549
1550 #ifndef QT_NO_WHEELEVENT
1551 void QApplication::setWheelScrollLines(int n)
1552 {
1553     QApplicationPrivate::wheel_scroll_lines = n;
1554 }
1555
1556 int QApplication::wheelScrollLines()
1557 {
1558     return QApplicationPrivate::wheel_scroll_lines;
1559 }
1560 #endif
1561
1562 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
1563 {
1564     switch (effect) {
1565     case Qt::UI_FadeMenu:
1566         QApplicationPrivate::fade_menu = enable;
1567         break;
1568     case Qt::UI_AnimateMenu:
1569         QApplicationPrivate::animate_menu = enable;
1570         break;
1571     case Qt::UI_FadeTooltip:
1572         QApplicationPrivate::fade_tooltip = enable;
1573         break;
1574     case Qt::UI_AnimateTooltip:
1575         QApplicationPrivate::animate_tooltip = enable;
1576         break;
1577     case Qt::UI_AnimateCombo:
1578         QApplicationPrivate::animate_combo = enable;
1579         break;
1580     case Qt::UI_AnimateToolBox:
1581         QApplicationPrivate::animate_toolbox = enable;
1582         break;
1583     case Qt::UI_General:
1584         QApplicationPrivate::fade_tooltip = true;
1585         break;
1586     default:
1587         QApplicationPrivate::animate_ui = enable;
1588         break;
1589     }
1590
1591     if (enable)
1592         QApplicationPrivate::animate_ui = true;
1593 }
1594
1595 bool QApplication::isEffectEnabled(Qt::UIEffect effect)
1596 {
1597     if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
1598         return false;
1599
1600     switch(effect) {
1601     case Qt::UI_AnimateMenu:
1602         return QApplicationPrivate::animate_menu;
1603     case Qt::UI_FadeMenu:
1604         return QApplicationPrivate::fade_menu;
1605     case Qt::UI_AnimateCombo:
1606         return QApplicationPrivate::animate_combo;
1607     case Qt::UI_AnimateTooltip:
1608         return QApplicationPrivate::animate_tooltip;
1609     case Qt::UI_FadeTooltip:
1610         return QApplicationPrivate::fade_tooltip;
1611     case Qt::UI_AnimateToolBox:
1612         return QApplicationPrivate::animate_toolbox;
1613     default:
1614         break;
1615     }
1616     return QApplicationPrivate::animate_ui;
1617 }
1618
1619 /*!
1620     \internal
1621 */
1622 bool QApplicationPrivate::qt_mac_apply_settings()
1623 {
1624     QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
1625     settings.beginGroup(QLatin1String("Qt"));
1626
1627     /*
1628       Qt settings.  This is how they are written into the datastream.
1629       Palette/ *             - QPalette
1630       font                   - QFont
1631       libraryPath            - QStringList
1632       style                  - QString
1633       doubleClickInterval    - int
1634       cursorFlashTime        - int
1635       wheelScrollLines       - int
1636       colorSpec              - QString
1637       defaultCodec           - QString
1638       globalStrut/width      - int
1639       globalStrut/height     - int
1640       GUIEffects             - QStringList
1641       Font Substitutions/ *  - QStringList
1642       Font Substitutions/... - QStringList
1643     */
1644
1645     // read library (ie. plugin) path list
1646     QString libpathkey =
1647         QString::fromLatin1("%1.%2/libraryPath")
1648                     .arg(QT_VERSION >> 16)
1649                     .arg((QT_VERSION & 0xff00) >> 8);
1650     QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
1651     if (!pathlist.isEmpty()) {
1652         QStringList::ConstIterator it = pathlist.begin();
1653         while(it != pathlist.end())
1654             QApplication::addLibraryPath(*it++);
1655     }
1656
1657     QString defaultcodec = settings.value(QLatin1String("defaultCodec"), QVariant(QLatin1String("none"))).toString();
1658     if (defaultcodec != QLatin1String("none")) {
1659         QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1().constData());
1660         if (codec)
1661             QTextCodec::setCodecForTr(codec);
1662     }
1663
1664     if (qt_is_gui_used) {
1665         QString str;
1666         QStringList strlist;
1667         int num;
1668
1669         // read new palette
1670         int i;
1671         QPalette pal(QApplication::palette());
1672         strlist = settings.value(QLatin1String("Palette/active")).toStringList();
1673         if (strlist.count() == QPalette::NColorRoles) {
1674             for (i = 0; i < QPalette::NColorRoles; i++)
1675                 pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
1676                             QColor(strlist[i]));
1677         }
1678         strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
1679         if (strlist.count() == QPalette::NColorRoles) {
1680             for (i = 0; i < QPalette::NColorRoles; i++)
1681                 pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
1682                             QColor(strlist[i]));
1683         }
1684         strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
1685         if (strlist.count() == QPalette::NColorRoles) {
1686             for (i = 0; i < QPalette::NColorRoles; i++)
1687                 pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
1688                             QColor(strlist[i]));
1689         }
1690
1691         if (pal != QApplication::palette())
1692             QApplication::setPalette(pal);
1693
1694         // read new font
1695         QFont font(QApplication::font());
1696         str = settings.value(QLatin1String("font")).toString();
1697         if (!str.isEmpty()) {
1698             font.fromString(str);
1699             if (font != QApplication::font())
1700                 QApplication::setFont(font);
1701         }
1702
1703         // read new QStyle
1704         QString stylename = settings.value(QLatin1String("style")).toString();
1705         if (! stylename.isNull() && ! stylename.isEmpty()) {
1706             QStyle *style = QStyleFactory::create(stylename);
1707             if (style)
1708                 QApplication::setStyle(style);
1709             else
1710                 stylename = QLatin1String("default");
1711         } else {
1712             stylename = QLatin1String("default");
1713         }
1714
1715         num = settings.value(QLatin1String("doubleClickInterval"),
1716                             QApplication::doubleClickInterval()).toInt();
1717         QApplication::setDoubleClickInterval(num);
1718
1719         num = settings.value(QLatin1String("cursorFlashTime"),
1720                             QApplication::cursorFlashTime()).toInt();
1721         QApplication::setCursorFlashTime(num);
1722
1723 #ifndef QT_NO_WHEELEVENT
1724         num = settings.value(QLatin1String("wheelScrollLines"),
1725                             QApplication::wheelScrollLines()).toInt();
1726         QApplication::setWheelScrollLines(num);
1727 #endif
1728
1729         QString colorspec = settings.value(QLatin1String("colorSpec"),
1730                                             QVariant(QLatin1String("default"))).toString();
1731         if (colorspec == QLatin1String("normal"))
1732             QApplication::setColorSpec(QApplication::NormalColor);
1733         else if (colorspec == QLatin1String("custom"))
1734             QApplication::setColorSpec(QApplication::CustomColor);
1735         else if (colorspec == QLatin1String("many"))
1736             QApplication::setColorSpec(QApplication::ManyColor);
1737         else if (colorspec != QLatin1String("default"))
1738             colorspec = QLatin1String("default");
1739
1740         int w = settings.value(QLatin1String("globalStrut/width")).toInt();
1741         int h = settings.value(QLatin1String("globalStrut/height")).toInt();
1742         QSize strut(w, h);
1743         if (strut.isValid())
1744             QApplication::setGlobalStrut(strut);
1745
1746         QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
1747         if (!effects.isEmpty()) {
1748             if (effects.contains(QLatin1String("none")))
1749                 QApplication::setEffectEnabled(Qt::UI_General, false);
1750             if (effects.contains(QLatin1String("general")))
1751                 QApplication::setEffectEnabled(Qt::UI_General, true);
1752             if (effects.contains(QLatin1String("animatemenu")))
1753                 QApplication::setEffectEnabled(Qt::UI_AnimateMenu, true);
1754             if (effects.contains(QLatin1String("fademenu")))
1755                 QApplication::setEffectEnabled(Qt::UI_FadeMenu, true);
1756             if (effects.contains(QLatin1String("animatecombo")))
1757                 QApplication::setEffectEnabled(Qt::UI_AnimateCombo, true);
1758             if (effects.contains(QLatin1String("animatetooltip")))
1759                 QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, true);
1760             if (effects.contains(QLatin1String("fadetooltip")))
1761                 QApplication::setEffectEnabled(Qt::UI_FadeTooltip, true);
1762             if (effects.contains(QLatin1String("animatetoolbox")))
1763                 QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, true);
1764         } else {
1765             QApplication::setEffectEnabled(Qt::UI_General, true);
1766         }
1767
1768         settings.beginGroup(QLatin1String("Font Substitutions"));
1769         QStringList fontsubs = settings.childKeys();
1770         if (!fontsubs.isEmpty()) {
1771             QStringList::Iterator it = fontsubs.begin();
1772             for (; it != fontsubs.end(); ++it) {
1773                 QString fam = QString::fromLatin1((*it).toLatin1().constData());
1774                 QStringList subs = settings.value(fam).toStringList();
1775                 QFont::insertSubstitutions(fam, subs);
1776             }
1777         }
1778         settings.endGroup();
1779     }
1780
1781     settings.endGroup();
1782     return true;
1783 }
1784
1785 // DRSWAT
1786
1787 bool QApplicationPrivate::canQuit()
1788 {
1789     Q_Q(QApplication);
1790     [[NSApp mainMenu] cancelTracking];
1791
1792     bool handle_quit = true;
1793     if (QApplicationPrivate::modalState() && [[[[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate]
1794                                                    menuLoader] quitMenuItem] isEnabled]) {
1795         int visible = 0;
1796         const QWidgetList tlws = QApplication::topLevelWidgets();
1797         for(int i = 0; i < tlws.size(); ++i) {
1798             if (tlws.at(i)->isVisible())
1799                 ++visible;
1800         }
1801         handle_quit = (visible <= 1);
1802     }
1803     if (handle_quit) {
1804         QCloseEvent ev;
1805         QApplication::sendSpontaneousEvent(q, &ev);
1806         if (ev.isAccepted()) {
1807             return true;
1808         }
1809     }
1810     return false;
1811 }
1812
1813 void onApplicationWindowChangedActivation(QWidget *widget, bool activated)
1814 {
1815     if (!widget)
1816         return;
1817
1818     if (activated) {
1819         if (QApplicationPrivate::app_style) {
1820             QEvent ev(QEvent::Style);
1821             qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
1822         }
1823         qApp->setActiveWindow(widget);
1824     } else { // deactivated
1825         if (QApplicationPrivate::active_window == widget)
1826             qApp->setActiveWindow(0);
1827     }
1828
1829     QMenuBar::macUpdateMenuBar();
1830     qt_mac_update_cursor();
1831 }
1832
1833
1834 void onApplicationChangedActivation( bool activated )
1835 {
1836     QApplication    *app    = qApp;
1837
1838 //NSLog(@"App Changed Activation\n");
1839
1840     if ( activated ) {
1841         if (QApplication::desktopSettingsAware())
1842             qt_mac_update_os_settings();
1843
1844         if (qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
1845             QEvent ev(QEvent::Clipboard);
1846             qt_sendSpontaneousEvent(qt_clipboard, &ev);
1847         }
1848
1849         if (app) {
1850             QEvent ev(QEvent::ApplicationActivate);
1851             qt_sendSpontaneousEvent(app, &ev);
1852         }
1853
1854         if (!app->activeWindow()) {
1855             OSWindowRef wp = [NSApp keyWindow];
1856             if (QWidget *tmp_w = qt_mac_find_window(wp))
1857                 app->setActiveWindow(tmp_w);
1858         }
1859         QMenuBar::macUpdateMenuBar();
1860         qt_mac_update_cursor();
1861     } else { // de-activated
1862         QApplicationPrivate *priv = [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] qAppPrivate];
1863         while (priv->inPopupMode())
1864             app->activePopupWidget()->close();
1865         if (app) {
1866             QEvent ev(QEvent::ApplicationDeactivate);
1867             qt_sendSpontaneousEvent(app, &ev);
1868         }
1869         app->setActiveWindow(0);
1870     }
1871 }
1872
1873 void QApplicationPrivate::initializeMultitouch_sys()
1874 { }
1875 void QApplicationPrivate::cleanupMultitouch_sys()
1876 { }
1877
1878 QT_END_NAMESPACE