Only quit if there are no visible widgets or windows.
[profile/ivi/qtbase.git] / src / gui / kernel / qguiapplication.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qguiapplication.h"
43
44 #include "private/qguiapplication_p.h"
45 #include <qpa/qplatformintegrationfactory_p.h>
46 #include "private/qevent_p.h"
47 #include "qfont.h"
48 #include <qpa/qplatformfontdatabase.h>
49 #include <qpa/qplatformwindow.h>
50 #include <qpa/qplatformnativeinterface.h>
51 #include <qpa/qplatformtheme.h>
52 #include <qpa/qplatformintegration.h>
53 #include <qpa/qplatformdrag.h>
54
55 #include <QtCore/QAbstractEventDispatcher>
56 #include <QtCore/QVariant>
57 #include <QtCore/private/qcoreapplication_p.h>
58 #include <QtCore/private/qabstracteventdispatcher_p.h>
59 #include <QtCore/qmutex.h>
60 #include <QtCore/private/qthread_p.h>
61 #include <QtCore/qdir.h>
62 #include <QtDebug>
63 #include <qpalette.h>
64 #include <qscreen.h>
65 #include <private/qscreen_p.h>
66 #include <private/qdrawhelper_p.h>
67
68 #include <qpa/qplatformintegration.h>
69 #include <QtGui/QGenericPluginFactory>
70 #include <QtGui/qstylehints.h>
71 #include <QtGui/qinputpanel.h>
72 #include <QtGui/qpixmapcache.h>
73 #include <qpa/qplatformtheme.h>
74 #include <qpa/qplatforminputcontext.h>
75 #include <qpa/qplatforminputcontext_p.h>
76
77 #include <QWindowSystemInterface>
78 #include "private/qwindowsysteminterface_qpa_p.h"
79 #include "private/qwindow_p.h"
80 #include "private/qcursor_p.h"
81
82 #include "private/qdnd_p.h"
83 #include <qpa/qplatformthemefactory_p.h>
84 #include <qpa/qplatformdrag.h>
85
86 #ifndef QT_NO_CURSOR
87 #include <qpa/qplatformcursor.h>
88 #endif
89
90 #include <QtGui/QPixmap>
91
92 #ifndef QT_NO_CLIPBOARD
93 #include <QtGui/QClipboard>
94 #endif
95
96 QT_BEGIN_NAMESPACE
97
98 Q_GUI_EXPORT bool qt_is_gui_used = true;
99
100 Qt::MouseButtons QGuiApplicationPrivate::mouse_buttons = Qt::NoButton;
101 Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
102
103 QPointF QGuiApplicationPrivate::lastCursorPosition(0.0, 0.0);
104
105 bool QGuiApplicationPrivate::tabletState = false;
106 QWindow *QGuiApplicationPrivate::tabletPressTarget = 0;
107
108 QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
109 QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0;
110
111 QList<QObject *> QGuiApplicationPrivate::generic_plugin_list;
112
113 enum ApplicationResourceFlags
114 {
115     ApplicationPaletteExplicitlySet = 0x1,
116     ApplicationFontExplicitlySet = 0x2
117 };
118
119 static unsigned applicationResourceFlags = 0;
120
121 QString *QGuiApplicationPrivate::platform_name = 0;
122
123 QPalette *QGuiApplicationPrivate::app_pal = 0;        // default application palette
124
125 Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton;
126 ulong QGuiApplicationPrivate::mousePressTime = 0;
127 Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton;
128 int QGuiApplicationPrivate::mousePressX = 0;
129 int QGuiApplicationPrivate::mousePressY = 0;
130 int QGuiApplicationPrivate::mouse_double_click_distance = 5;
131
132 static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
133 static bool force_reverse = false;
134
135 QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
136 QTouchDevice *QGuiApplicationPrivate::m_fakeTouchDevice = 0;
137 int QGuiApplicationPrivate::m_fakeMouseSourcePointId = 0;
138
139 #ifndef QT_NO_CLIPBOARD
140 QClipboard *QGuiApplicationPrivate::qt_clipboard = 0;
141 #endif
142
143 QList<QScreen *> QGuiApplicationPrivate::screen_list;
144
145 QWindowList QGuiApplicationPrivate::window_list;
146 QWindow *QGuiApplicationPrivate::focus_window = 0;
147
148 static QBasicMutex applicationFontMutex;
149 QFont *QGuiApplicationPrivate::app_font = 0;
150 bool QGuiApplicationPrivate::obey_desktop_settings = true;
151
152 static qreal fontSmoothingGamma = 1.7;
153
154 extern void qRegisterGuiVariant();
155 extern void qInitDrawhelperAsm();
156 extern void qInitImageConversions();
157
158 static bool qt_detectRTLLanguage()
159 {
160     return force_reverse ^
161         (QCoreApplication::tr("QT_LAYOUT_DIRECTION",
162                          "Translate this string to the string 'LTR' in left-to-right"
163                          " languages or to 'RTL' in right-to-left languages (such as Hebrew"
164                          " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
165 }
166
167 static void initPalette()
168 {
169     if (!QGuiApplicationPrivate::app_pal)
170         if (const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette())
171             QGuiApplicationPrivate::app_pal = new QPalette(*themePalette);
172     if (!QGuiApplicationPrivate::app_pal)
173         QGuiApplicationPrivate::app_pal = new QPalette(Qt::black);
174 }
175
176 static inline void clearPalette()
177 {
178     delete QGuiApplicationPrivate::app_pal;
179     QGuiApplicationPrivate::app_pal = 0;
180 }
181
182 static void initFontUnlocked()
183 {
184     if (!QGuiApplicationPrivate::app_font) {
185         if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
186             if (const QFont *font = theme->font(QPlatformTheme::SystemFont))
187                 QGuiApplicationPrivate::app_font = new QFont(*font);
188     }
189     if (!QGuiApplicationPrivate::app_font)
190         QGuiApplicationPrivate::app_font =
191             new QFont(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFont());
192 }
193
194 static inline void clearFontUnlocked()
195 {
196     delete QGuiApplicationPrivate::app_font;
197     QGuiApplicationPrivate::app_font = 0;
198 }
199
200 /*!
201     \class QGuiApplication
202     \brief The QGuiApplication class manages the GUI application's control
203     flow and main settings.
204
205     \inmodule QtGui
206     \since 5.0
207
208     QGuiApplication contains the main event loop, where all events from the window
209     system and other sources are processed and dispatched. It also handles the
210     application's initialization and finalization. In addition, QGuiApplication handles
211     most of the system-wide and application-wide settings.
212
213     For any GUI application using Qt, there is precisely \b one QGuiApplication
214     object no matter whether the application has 0, 1, 2 or more windows at
215     any given time. For non-GUI Qt applications, use QCoreApplication instead,
216     as it does not depend on the \l QtGui library.
217
218     The QGuiApplication object is accessible through the instance() function, which
219     returns a pointer equivalent to the global \l qApp pointer.
220
221     QGuiApplication's main areas of responsibility are:
222         \list
223             \li  It initializes the application with the user's desktop settings,
224                 such as palette(), font() and styleHints(). It keeps
225                 track of these properties in case the user changes the desktop
226                 globally, for example, through some kind of control panel.
227
228             \li  It performs event handling, meaning that it receives events
229                 from the underlying window system and dispatches them to the
230                 relevant widgets. You can send your own events to windows by
231                 using sendEvent() and postEvent().
232
233             \li  It parses common command line arguments and sets its internal
234                 state accordingly. See the \l{QGuiApplication::QGuiApplication()}
235                 {constructor documentation} below for more details.
236
237             \li  It provides localization of strings that are visible to the
238                 user via translate().
239
240             \li  It provides some magical objects like the clipboard().
241
242             \li  It knows about the application's windows. You can ask which
243                 window is at a certain position using topLevelAt(), get a list of
244                 topLevelWindows(), etc.
245
246             \li  It manages the application's mouse cursor handling, see
247                 setOverrideCursor()
248         \endlist
249
250     Since the QGuiApplication object does so much initialization, it \e{must} be
251     created before any other objects related to the user interface are created.
252     QGuiApplication also deals with common command line arguments. Hence, it is
253     usually a good idea to create it \e before any interpretation or
254     modification of \c argv is done in the application itself.
255
256     \table
257     \header
258         \li{2,1} Groups of functions
259
260         \row
261         \li  System settings
262         \li  desktopSettingsAware(),
263             setDesktopSettingsAware(),
264             styleHints(),
265             palette(),
266             setPalette(),
267             font(),
268             setFont().
269
270         \row
271         \li  Event handling
272         \li  exec(),
273             processEvents(),
274             exit(),
275             quit().
276             sendEvent(),
277             postEvent(),
278             sendPostedEvents(),
279             removePostedEvents(),
280             hasPendingEvents(),
281             notify().
282
283         \row
284         \li  Windows
285         \li  allWindows(),
286             topLevelWindows(),
287             focusWindow(),
288             clipboard(),
289             topLevelAt().
290
291         \row
292         \li  Advanced cursor handling
293         \li  overrideCursor(),
294             setOverrideCursor(),
295             restoreOverrideCursor().
296
297         \row
298         \li  Miscellaneous
299         \li  startingUp(),
300             closingDown(),
301             type().
302     \endtable
303
304     \sa QCoreApplication, QAbstractEventDispatcher, QEventLoop
305 */
306
307 /*!
308     Initializes the window system and constructs an application object with
309     \a argc command line arguments in \a argv.
310
311     \warning The data referred to by \a argc and \a argv must stay valid for
312     the entire lifetime of the QGuiApplication object. In addition, \a argc must
313     be greater than zero and \a argv must contain at least one valid character
314     string.
315
316     The global \c qApp pointer refers to this application object. Only one
317     application object should be created.
318
319     This application object must be constructed before any \l{QPaintDevice}
320     {paint devices} (including pixmaps, bitmaps etc.).
321
322     \note \a argc and \a argv might be changed as Qt removes command line
323     arguments that it recognizes.
324
325     All Qt programs automatically support the following command line options:
326     \list
327         \li  -reverse, sets the application's layout direction to
328             Qt::RightToLeft
329         \li  -qmljsdebugger=, activates the QML/JS debugger with a specified port.
330             The value must be of format port:1234[,block], where block is optional
331             and will make the application wait until a debugger connects to it.
332     \endlist
333
334     \sa arguments()
335 */
336 QGuiApplication::QGuiApplication(int &argc, char **argv, int flags)
337     : QCoreApplication(*new QGuiApplicationPrivate(argc, argv, flags))
338 {
339     d_func()->init();
340
341     QCoreApplicationPrivate::eventDispatcher->startingUp();
342 }
343
344 QGuiApplication::QGuiApplication(QGuiApplicationPrivate &p)
345     : QCoreApplication(p)
346 {
347     d_func()->init(); }
348
349 /*!
350     Destructs the application.
351 */
352 QGuiApplication::~QGuiApplication()
353 {
354     Q_D(QGuiApplication);
355
356     d->eventDispatcher->closingDown();
357     d->eventDispatcher = 0;
358
359 #ifndef QT_NO_CLIPBOARD
360     delete QGuiApplicationPrivate::qt_clipboard;
361     QGuiApplicationPrivate::qt_clipboard = 0;
362 #endif
363
364     clearPalette();
365
366 #ifndef QT_NO_CURSOR
367     d->cursor_list.clear();
368 #endif
369
370     delete QGuiApplicationPrivate::platform_name;
371     QGuiApplicationPrivate::platform_name = 0;
372 }
373
374 QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags)
375     : QCoreApplicationPrivate(argc, argv, flags),
376       styleHints(0),
377       inputMethod(0),
378       lastTouchType(QEvent::TouchEnd)
379 {
380     self = this;
381     application_type = QCoreApplication::GuiClient;
382 }
383
384 /*!
385     Returns the most recently shown modal window. If no modal windows are
386     visible, this function returns zero.
387
388     A modal window is a window which has its
389     \l{QWindow::windowModality}{windowModality} property set to Qt::WindowModal
390     or Qt::ApplicationModal. A modal window must be closed before the user can
391     continue with other parts of the program.
392
393     Modal window are organized in a stack. This function returns the modal
394     window at the top of the stack.
395
396     \sa Qt::WindowModality, QWindow::setWindowModality()
397 */
398 QWindow *QGuiApplication::modalWindow()
399 {
400     if (QGuiApplicationPrivate::self->modalWindowList.isEmpty())
401         return 0;
402     return QGuiApplicationPrivate::self->modalWindowList.first();
403 }
404
405 void QGuiApplicationPrivate::showModalWindow(QWindow *window)
406 {
407     self->modalWindowList.prepend(window);
408
409     QEvent e(QEvent::WindowBlocked);
410     QWindowList windows = QGuiApplication::topLevelWindows();
411     for (int i = 0; i < windows.count(); ++i) {
412         QWindow *window = windows.at(i);
413         if (!window->d_func()->blockedByModalWindow && window->windowType() != Qt::Tool && self->isWindowBlocked(window)) {
414             window->d_func()->blockedByModalWindow = true;
415             QGuiApplication::sendEvent(window, &e);
416         }
417     }
418 }
419
420 void QGuiApplicationPrivate::hideModalWindow(QWindow *window)
421 {
422     self->modalWindowList.removeAll(window);
423
424     QEvent e(QEvent::WindowUnblocked);
425     QWindowList windows = QGuiApplication::topLevelWindows();
426     for (int i = 0; i < windows.count(); ++i) {
427         QWindow *window = windows.at(i);
428         if (window->d_func()->blockedByModalWindow && window->windowType() != Qt::Tool && !self->isWindowBlocked(window)) {
429             window->d_func()->blockedByModalWindow = false;
430             QGuiApplication::sendEvent(window, &e);
431         }
432     }
433 }
434
435 /*
436     Returns true if \a window is blocked by a modal window. If \a
437     blockingWindow is non-zero, *blockingWindow will be set to the blocking
438     window (or to zero if \a window is not blocked).
439 */
440 bool QGuiApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWindow) const
441 {
442     QWindow *unused = 0;
443     if (!blockingWindow)
444         blockingWindow = &unused;
445
446     if (modalWindowList.isEmpty()) {
447         *blockingWindow = 0;
448         return false;
449     }
450
451     for (int i = 0; i < modalWindowList.count(); ++i) {
452         QWindow *modalWindow = modalWindowList.at(i);
453
454         {
455             // check if the modal window is our window or a (transient) parent of our window
456             QWindow *w = window;
457             while (w) {
458                 if (w == modalWindow) {
459                     *blockingWindow = 0;
460                     return false;
461                 }
462                 QWindow *p = w->parent();
463                 if (!p)
464                     p = w->transientParent();
465                 w = p;
466             }
467         }
468
469         Qt::WindowModality windowModality = modalWindow->windowModality();
470         switch (windowModality) {
471         case Qt::ApplicationModal:
472         {
473             if (modalWindow != window) {
474                 *blockingWindow = modalWindow;
475                 return true;
476             }
477             break;
478         }
479         case Qt::WindowModal:
480         {
481             QWindow *w = window;
482             do {
483                 QWindow *m = modalWindow;
484                 do {
485                     if (m == w) {
486                         *blockingWindow = m;
487                         return true;
488                     }
489                     QWindow *p = m->parent();
490                     if (!p)
491                         p = m->transientParent();
492                     m = p;
493                 } while (m);
494                 QWindow *p = w->parent();
495                 if (!p)
496                     p = w->transientParent();
497                 w = p;
498             } while (w);
499             break;
500         }
501         default:
502             Q_ASSERT_X(false, "QGuiApplication", "internal error, a modal widget cannot be modeless");
503             break;
504         }
505     }
506     *blockingWindow = 0;
507     return false;
508 }
509
510 /*!
511     Returns the QWindow that receives events tied to focus,
512     such as key events.
513 */
514 QWindow *QGuiApplication::focusWindow()
515 {
516     return QGuiApplicationPrivate::focus_window;
517 }
518
519 /*!
520     \fn QGuiApplication::focusObjectChanged(QObject *focusObject)
521
522     This signal is emitted when final receiver of events tied to focus is changed.
523     \sa focusObject()
524 */
525
526 /*!
527     \fn QGuiApplication::focusWindowChanged(QWindow *focusWindow)
528
529     This signal is emitted when the focused window changes.
530     \sa focusWindow()
531 */
532
533 /*!
534     Returns the QObject in currently active window that will be final receiver of events
535     tied to focus, such as key events.
536  */
537 QObject *QGuiApplication::focusObject()
538 {
539     if (focusWindow())
540         return focusWindow()->focusObject();
541     return 0;
542 }
543
544 /*!
545     \fn QGuiApplication::allWindows()
546
547     Returns a list of all the windows in the application.
548
549     The list is empty if there are no windows.
550
551     \sa topLevelWindows()
552  */
553 QWindowList QGuiApplication::allWindows()
554 {
555     return QGuiApplicationPrivate::window_list;
556 }
557
558 /*!
559     \fn QGuiApplication::topLevelWindows()
560
561     Returns a list of the top-level windows in the application.
562
563     \sa allWindows()
564  */
565 QWindowList QGuiApplication::topLevelWindows()
566 {
567     const QWindowList &list = QGuiApplicationPrivate::window_list;
568     QWindowList topLevelWindows;
569     for (int i = 0; i < list.size(); i++) {
570         if (!list.at(i)->parent())
571             topLevelWindows.prepend(list.at(i));
572     }
573     return topLevelWindows;
574 }
575
576 /*!
577     Returns the primary (or default) screen of the application.
578
579     This will be the screen where QWindows are shown, unless otherwise specified.
580 */
581 QScreen *QGuiApplication::primaryScreen()
582 {
583     if (QGuiApplicationPrivate::screen_list.isEmpty())
584         return 0;
585     return QGuiApplicationPrivate::screen_list.at(0);
586 }
587
588 /*!
589     Returns a list of all the screens associated with the
590     windowing system the application is connected to.
591 */
592 QList<QScreen *> QGuiApplication::screens()
593 {
594     return QGuiApplicationPrivate::screen_list;
595 }
596
597 /*!
598     Returns the top level window at the given position, if any.
599 */
600 QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
601 {
602     QList<QScreen *> screens = QGuiApplication::screens();
603     QList<QScreen *>::const_iterator screen = screens.constBegin();
604     QList<QScreen *>::const_iterator end = screens.constEnd();
605
606     while (screen != end) {
607         if ((*screen)->geometry().contains(pos))
608             return (*screen)->handle()->topLevelAt(pos);
609         ++screen;
610     }
611     return 0;
612 }
613
614 /*!
615     \property QGuiApplication::platformName
616     \brief The name of the underlying platform plugin.
617 */
618
619 QString QGuiApplication::platformName()
620 {
621     return QGuiApplicationPrivate::platform_name ?
622            *QGuiApplicationPrivate::platform_name : QString();
623 }
624
625 static void init_platform(const QString &pluginArgument, const QString &platformPluginPath)
626 {
627     // Split into platform name and arguments
628     QString name;
629     QStringList arguments;
630     foreach (const QString &token, pluginArgument.split(QLatin1Char(':'))) {
631         if (name.isEmpty()) {
632             name = token;
633         } else {
634             arguments.push_back(token);
635         }
636     }
637
638    // Create the platform integration.
639     QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, platformPluginPath);
640     if (QGuiApplicationPrivate::platform_integration) {
641         QGuiApplicationPrivate::platform_name = new QString(name);
642     } else {
643         QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
644         QString fatalMessage =
645             QString::fromLatin1("Failed to load platform plugin \"%1\". Available platforms are: \n").arg(name);
646         foreach(const QString &key, keys) {
647             fatalMessage.append(key + QLatin1Char('\n'));
648         }
649         qFatal("%s", fatalMessage.toLocal8Bit().constData());
650         return;
651     }
652
653     // Create the platform theme:
654     // 1) Ask the platform integration for a list of names.
655     const QStringList themeNames = QGuiApplicationPrivate::platform_integration->themeNames();
656     foreach (const QString &themeName, themeNames) {
657         QGuiApplicationPrivate::platform_theme = QPlatformThemeFactory::create(themeName, platformPluginPath);
658         if (QGuiApplicationPrivate::platform_theme)
659             break;
660     }
661
662     // 2) If none found, look for a theme plugin. Theme plugins are located in the
663     // same directory as platform plugins.
664     if (!QGuiApplicationPrivate::platform_theme) {
665         foreach (const QString &themeName, themeNames) {
666             QGuiApplicationPrivate::platform_theme = QGuiApplicationPrivate::platform_integration->createPlatformTheme(themeName);
667             if (QGuiApplicationPrivate::platform_theme)
668                 break;
669         }
670         // No error message; not having a theme plugin is allowed.
671     }
672
673     // 3) Fall back on the built-in "null" platform theme.
674     if (!QGuiApplicationPrivate::platform_theme)
675         QGuiApplicationPrivate::platform_theme = new QPlatformTheme;
676
677 #ifndef QT_NO_PROPERTIES
678     // Set arguments as dynamic properties on the native interface as
679     // boolean 'foo' or strings: 'foo=bar'
680     if (!arguments.isEmpty()) {
681         QObject *nativeInterface = QGuiApplicationPrivate::platform_integration->nativeInterface();
682         foreach (const QString &argument, arguments) {
683             const int equalsPos = argument.indexOf(QLatin1Char('='));
684             const QByteArray name =
685                 equalsPos != -1 ? argument.left(equalsPos).toUtf8() : argument.toUtf8();
686             const QVariant value =
687                 equalsPos != -1 ? QVariant(argument.mid(equalsPos + 1)) : QVariant(true);
688             nativeInterface->setProperty(name.constData(), value);
689         }
690     }
691 #endif
692
693     fontSmoothingGamma = QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::FontSmoothingGamma).toReal();
694 }
695
696 static void init_plugins(const QList<QByteArray> &pluginList)
697 {
698     for (int i = 0; i < pluginList.count(); ++i) {
699         QByteArray pluginSpec = pluginList.at(i);
700         int colonPos = pluginSpec.indexOf(':');
701         QObject *plugin;
702         if (colonPos < 0)
703             plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec), QString());
704         else
705             plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)),
706                                                    QLatin1String(pluginSpec.mid(colonPos+1)));
707         if (plugin)
708             QGuiApplicationPrivate::generic_plugin_list.append(plugin);
709     }
710 }
711
712 void QGuiApplicationPrivate::createPlatformIntegration()
713 {
714     // Use the Qt menus by default. Platform plugins that
715     // want to enable a native menu implementation can clear
716     // this flag.
717     QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
718
719     // Load the platform integration
720     QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
721
722     // On Mac, look inside the application bundle for the platform plugin.
723     // TODO (msorvig): Create proper cross-platform solution for loading
724     // deployed platform plugins
725 #ifdef Q_OS_MAC
726     const QString bundlePluginPath = QCoreApplication::applicationDirPath() + QLatin1String("../Plugins/");
727     if (platformPluginPath.isEmpty() && QDir(bundlePluginPath).exists()) {
728         platformPluginPath = bundlePluginPath;
729     }
730 #endif
731
732     QByteArray platformName;
733 #ifdef QT_QPA_DEFAULT_PLATFORM_NAME
734     platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
735 #endif
736     QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
737     if (!platformNameEnv.isEmpty()) {
738         platformName = platformNameEnv;
739     }
740
741     // Get command line params
742
743     int j = argc ? 1 : 0;
744     for (int i=1; i<argc; i++) {
745         if (argv[i] && *argv[i] != '-') {
746             argv[j++] = argv[i];
747             continue;
748         }
749         QByteArray arg = argv[i];
750         if (arg == "-platformpluginpath") {
751             if (++i < argc)
752                 platformPluginPath = QLatin1String(argv[i]);
753         } else if (arg == "-platform") {
754             if (++i < argc)
755                 platformName = argv[i];
756         } else {
757             argv[j++] = argv[i];
758         }
759     }
760
761     if (j < argc) {
762         argv[j] = 0;
763         argc = j;
764     }
765
766     init_platform(QLatin1String(platformName), platformPluginPath);
767
768 }
769
770 void QGuiApplicationPrivate::createEventDispatcher()
771 {
772     if (platform_integration == 0)
773         createPlatformIntegration();
774
775     if (!eventDispatcher) {
776         QAbstractEventDispatcher *eventDispatcher = platform_integration->guiThreadEventDispatcher();
777         setEventDispatcher(eventDispatcher);
778     }
779 }
780
781 void QGuiApplicationPrivate::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
782 {
783     Q_Q(QGuiApplication);
784
785     if (!QCoreApplicationPrivate::eventDispatcher) {
786         QCoreApplicationPrivate::eventDispatcher = eventDispatcher;
787         QCoreApplicationPrivate::eventDispatcher->setParent(q);
788         threadData->eventDispatcher = eventDispatcher;
789     }
790
791 }
792
793 void QGuiApplicationPrivate::init()
794 {
795     QList<QByteArray> pluginList;
796     // Get command line params
797
798     int j = argc ? 1 : 0;
799     for (int i=1; i<argc; i++) {
800         if (argv[i] && *argv[i] != '-') {
801             argv[j++] = argv[i];
802             continue;
803         }
804         QByteArray arg = argv[i];
805         if (arg == "-plugin") {
806             if (++i < argc)
807                 pluginList << argv[i];
808         } else if (arg == "-reverse") {
809             force_reverse = true;
810             QGuiApplication::setLayoutDirection(Qt::RightToLeft);
811         } else {
812             argv[j++] = argv[i];
813         }
814     }
815
816     if (j < argc) {
817         argv[j] = 0;
818         argc = j;
819     }
820
821     // Load environment exported generic plugins
822     foreach (const QByteArray &plugin, qgetenv("QT_QPA_GENERIC_PLUGINS").split(','))
823         pluginList << plugin;
824
825     if (platform_integration == 0)
826         createPlatformIntegration();
827
828     // Set up which span functions should be used in raster engine...
829     qInitDrawhelperAsm();
830     // and QImage conversion functions
831     qInitImageConversions();
832
833     QFont::initialize();
834
835 #ifndef QT_NO_CURSOR
836     QCursorData::initialize();
837 #endif
838
839     // trigger registering of QVariant's GUI types
840     qRegisterGuiVariant();
841
842     QWindowSystemInterfacePrivate::eventTime.start();
843
844     is_app_running = true;
845     init_plugins(pluginList);
846     QWindowSystemInterface::sendWindowSystemEvents(QCoreApplicationPrivate::eventDispatcher, QEventLoop::AllEvents);
847 }
848
849 extern void qt_cleanupFontDatabase();
850
851 QGuiApplicationPrivate::~QGuiApplicationPrivate()
852 {
853     is_app_closing = true;
854     is_app_running = false;
855
856     for (int i = 0; i < generic_plugin_list.count(); ++i)
857         delete generic_plugin_list.at(i);
858     generic_plugin_list.clear();
859
860     clearFontUnlocked();
861
862     QFont::cleanup();
863
864 #ifndef QT_NO_CURSOR
865     QCursorData::cleanup();
866 #endif
867
868     layout_direction = Qt::LeftToRight;
869
870     cleanupThreadData();
871
872     delete styleHints;
873     delete inputMethod;
874
875     qt_cleanupFontDatabase();
876
877     QPixmapCache::clear();
878
879     delete  platform_theme;
880     delete platform_integration;
881     platform_integration = 0;
882     delete m_gammaTables.load();
883 }
884
885 #if 0
886 #ifndef QT_NO_CURSOR
887 QCursor *overrideCursor();
888 void setOverrideCursor(const QCursor &);
889 void changeOverrideCursor(const QCursor &);
890 void restoreOverrideCursor();
891 #endif
892
893 static QFont font();
894 static QFont font(const QWidget*);
895 static QFont font(const char *className);
896 static void setFont(const QFont &, const char* className = 0);
897 static QFontMetrics fontMetrics();
898
899 #ifndef QT_NO_CLIPBOARD
900 static QClipboard *clipboard();
901 #endif
902 #endif
903
904 /*!
905     Returns the current state of the modifier keys on the keyboard. The current
906     state is updated sychronously as the event queue is emptied of events that
907     will spontaneously change the keyboard state (QEvent::KeyPress and
908     QEvent::KeyRelease events).
909
910     It should be noted this may not reflect the actual keys held on the input
911     device at the time of calling but rather the modifiers as last reported in
912     one of the above events. If no keys are being held Qt::NoModifier is
913     returned.
914
915     \sa mouseButtons(), queryKeyboardModifiers()
916 */
917 Qt::KeyboardModifiers QGuiApplication::keyboardModifiers()
918 {
919     return QGuiApplicationPrivate::modifier_buttons;
920 }
921
922 /*!
923     \fn Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
924
925     Queries and returns the state of the modifier keys on the keyboard.
926     Unlike keyboardModifiers, this method returns the actual keys held
927     on the input device at the time of calling the method.
928
929     It does not rely on the keypress events having been received by this
930     process, which makes it possible to check the modifiers while moving
931     a window, for instance. Note that in most cases, you should use
932     keyboardModifiers(), which is faster and more accurate since it contains
933     the state of the modifiers as they were when the currently processed
934     event was received.
935
936     \sa keyboardModifiers()
937 */
938 Qt::KeyboardModifiers QGuiApplication::queryKeyboardModifiers()
939 {
940     QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
941     return pi->queryKeyboardModifiers();
942 }
943
944 /*!
945     Returns the current state of the buttons on the mouse. The current state is
946     updated syncronously as the event queue is emptied of events that will
947     spontaneously change the mouse state (QEvent::MouseButtonPress and
948     QEvent::MouseButtonRelease events).
949
950     It should be noted this may not reflect the actual buttons held on the
951     input device at the time of calling but rather the mouse buttons as last
952     reported in one of the above events. If no mouse buttons are being held
953     Qt::NoButton is returned.
954
955     \sa keyboardModifiers()
956 */
957 Qt::MouseButtons QGuiApplication::mouseButtons()
958 {
959     return QGuiApplicationPrivate::mouse_buttons;
960 }
961
962 /*!
963     Returns the platform's native interface, for platform specific
964     functionality.
965 */
966 QPlatformNativeInterface *QGuiApplication::platformNativeInterface()
967 {
968     QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
969     return pi->nativeInterface();
970 }
971
972 /*!
973     Enters the main event loop and waits until exit() is called, and then
974     returns the value that was set to exit() (which is 0 if exit() is called
975     via quit()).
976
977     It is necessary to call this function to start event handling. The main
978     event loop receives events from the window system and dispatches these to
979     the application widgets.
980
981     Generally, no user interaction can take place before calling exec().
982
983     To make your application perform idle processing, e.g., executing a special
984     function whenever there are no pending events, use a QTimer with 0 timeout.
985     More advanced idle processing schemes can be achieved using processEvents().
986
987     We recommend that you connect clean-up code to the
988     \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your
989     application's \c{main()} function. This is because, on some platforms, the
990     QApplication::exec() call may not return.
991
992     \sa quitOnLastWindowClosed, quit(), exit(), processEvents(),
993         QCoreApplication::exec()
994 */
995 int QGuiApplication::exec()
996 {
997     return QCoreApplication::exec();
998 }
999
1000 /*! \reimp
1001 */
1002 bool QGuiApplication::notify(QObject *object, QEvent *event)
1003 {
1004 #ifndef QT_NO_SHORTCUT
1005     if (event->type() == QEvent::KeyPress) {
1006         // Try looking for a Shortcut before sending key events
1007         QWindow *w = qobject_cast<QWindow *>(object);
1008         QObject *focus = w ? w->focusObject() : 0;
1009         if (!focus)
1010             focus = object;
1011         if (QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focus, static_cast<QKeyEvent *>(event)))
1012             return true;
1013     }
1014 #endif
1015
1016     if (object->isWindowType())
1017         QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(object), event);
1018     return QCoreApplication::notify(object, event);
1019 }
1020
1021 /*! \reimp
1022 */
1023 bool QGuiApplication::event(QEvent *e)
1024 {
1025     if(e->type() == QEvent::LanguageChange) {
1026         setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
1027     }
1028     return QCoreApplication::event(e);
1029 }
1030
1031 /*!
1032     \internal
1033 */
1034 bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1035 {
1036     return QCoreApplication::compressEvent(event, receiver, postedEvents);
1037 }
1038
1039 void QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event)
1040 {
1041     if (!window)
1042         return;
1043     QPlatformWindow *platformWindow = window->handle();
1044     if (!platformWindow)
1045         return;
1046     // spontaneous events come from the platform integration already, we don't need to send the events back
1047     if (event->spontaneous())
1048         return;
1049     // let the platform window do any handling it needs to as well
1050     platformWindow->windowEvent(event);
1051 }
1052
1053 bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result)
1054 {
1055     return window->nativeEvent(eventType, message, result);
1056 }
1057
1058 void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
1059 {
1060     switch(e->type) {
1061     case QWindowSystemInterfacePrivate::Mouse:
1062         QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
1063         break;
1064     case QWindowSystemInterfacePrivate::Wheel:
1065         QGuiApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterfacePrivate::WheelEvent *>(e));
1066         break;
1067     case QWindowSystemInterfacePrivate::Key:
1068         QGuiApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e));
1069         break;
1070     case QWindowSystemInterfacePrivate::Touch:
1071         QGuiApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterfacePrivate::TouchEvent *>(e));
1072         break;
1073     case QWindowSystemInterfacePrivate::GeometryChange:
1074         QGuiApplicationPrivate::processGeometryChangeEvent(static_cast<QWindowSystemInterfacePrivate::GeometryChangeEvent*>(e));
1075         break;
1076     case QWindowSystemInterfacePrivate::Enter:
1077         QGuiApplicationPrivate::processEnterEvent(static_cast<QWindowSystemInterfacePrivate::EnterEvent *>(e));
1078         break;
1079     case QWindowSystemInterfacePrivate::Leave:
1080         QGuiApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
1081         break;
1082     case QWindowSystemInterfacePrivate::ActivatedWindow:
1083         QGuiApplicationPrivate::processActivatedEvent(static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>(e));
1084         break;
1085     case QWindowSystemInterfacePrivate::WindowStateChanged:
1086         QGuiApplicationPrivate::processWindowStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowStateChangedEvent *>(e));
1087         break;
1088     case QWindowSystemInterfacePrivate::Close:
1089         QGuiApplicationPrivate::processCloseEvent(
1090                 static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e));
1091         break;
1092     case QWindowSystemInterfacePrivate::ScreenOrientation:
1093         QGuiApplicationPrivate::reportScreenOrientationChange(
1094                 static_cast<QWindowSystemInterfacePrivate::ScreenOrientationEvent *>(e));
1095         break;
1096     case QWindowSystemInterfacePrivate::ScreenGeometry:
1097         QGuiApplicationPrivate::reportGeometryChange(
1098                 static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
1099         break;
1100     case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
1101         QGuiApplicationPrivate::reportAvailableGeometryChange(
1102                 static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
1103         break;
1104     case QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInch:
1105         QGuiApplicationPrivate::reportLogicalDotsPerInchChange(
1106                 static_cast<QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *>(e));
1107         break;
1108     case QWindowSystemInterfacePrivate::ScreenRefreshRate:
1109         QGuiApplicationPrivate::reportRefreshRateChange(
1110                 static_cast<QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *>(e));
1111         break;
1112     case QWindowSystemInterfacePrivate::ThemeChange:
1113         QGuiApplicationPrivate::processThemeChanged(
1114                     static_cast<QWindowSystemInterfacePrivate::ThemeChangeEvent *>(e));
1115         break;
1116     case QWindowSystemInterfacePrivate::Expose:
1117         QGuiApplicationPrivate::processExposeEvent(static_cast<QWindowSystemInterfacePrivate::ExposeEvent *>(e));
1118         break;
1119     case QWindowSystemInterfacePrivate::Tablet:
1120         QGuiApplicationPrivate::processTabletEvent(
1121                     static_cast<QWindowSystemInterfacePrivate::TabletEvent *>(e));
1122         break;
1123     case QWindowSystemInterfacePrivate::TabletEnterProximity:
1124         QGuiApplicationPrivate::processTabletEnterProximityEvent(
1125                     static_cast<QWindowSystemInterfacePrivate::TabletEnterProximityEvent *>(e));
1126         break;
1127     case QWindowSystemInterfacePrivate::TabletLeaveProximity:
1128         QGuiApplicationPrivate::processTabletLeaveProximityEvent(
1129                     static_cast<QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *>(e));
1130         break;
1131     default:
1132         qWarning() << "Unknown user input event type:" << e->type;
1133         break;
1134     }
1135 }
1136
1137 void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
1138 {
1139     QEvent::Type type;
1140     // move first
1141     Qt::MouseButtons stateChange = e->buttons ^ buttons;
1142     if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
1143         QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
1144                 new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons, e->modifiers);
1145         QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
1146         stateChange = Qt::NoButton;
1147     }
1148
1149     QWindow *window = e->window.data();
1150     modifier_buttons = e->modifiers;
1151
1152     QPointF localPoint = e->localPos;
1153     QPointF globalPoint = e->globalPos;
1154
1155     if (!window) {
1156         window = QGuiApplication::topLevelAt(globalPoint.toPoint());
1157         if (window) {
1158             QPointF delta = globalPoint - globalPoint.toPoint();
1159             localPoint = window->mapFromGlobal(globalPoint.toPoint()) + delta;
1160         }
1161     }
1162
1163     Qt::MouseButton button = Qt::NoButton;
1164     bool doubleClick = false;
1165
1166     if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) {
1167         type = QEvent::MouseMove;
1168         QGuiApplicationPrivate::lastCursorPosition = globalPoint;
1169         if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
1170             qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
1171             mousePressButton = Qt::NoButton;
1172     } else { // Check to see if a new button has been pressed/released.
1173         for (int check = Qt::LeftButton;
1174             check <= int(Qt::MaxMouseButton);
1175              check = check << 1) {
1176             if (check & stateChange) {
1177                 button = Qt::MouseButton(check);
1178                 break;
1179             }
1180         }
1181         if (button == Qt::NoButton) {
1182             // Ignore mouse events that don't change the current state.
1183             return;
1184         }
1185         buttons = e->buttons;
1186         if (button & e->buttons) {
1187             ulong doubleClickInterval = static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval());
1188             doubleClick = e->timestamp - mousePressTime < doubleClickInterval && button == mousePressButton;
1189             type = QEvent::MouseButtonPress;
1190             mousePressTime = e->timestamp;
1191             mousePressButton = button;
1192             const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint();
1193             mousePressX = point.x();
1194             mousePressY = point.y();
1195         } else {
1196             type = QEvent::MouseButtonRelease;
1197         }
1198     }
1199
1200     if (window) {
1201         if (window->d_func()->blockedByModalWindow) {
1202             // a modal window is blocking this window, don't allow mouse events through
1203             return;
1204         }
1205
1206         QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
1207         ev.setTimestamp(e->timestamp);
1208 #ifndef QT_NO_CURSOR
1209         if (const QScreen *screen = window->screen())
1210             if (QPlatformCursor *cursor = screen->handle()->cursor())
1211                 cursor->pointerEvent(ev);
1212 #endif
1213         QGuiApplication::sendSpontaneousEvent(window, &ev);
1214         if (!e->synthetic && !ev.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) {
1215             if (!m_fakeTouchDevice) {
1216                 m_fakeTouchDevice = new QTouchDevice;
1217                 QWindowSystemInterface::registerTouchDevice(m_fakeTouchDevice);
1218             }
1219             QList<QWindowSystemInterface::TouchPoint> points;
1220             QWindowSystemInterface::TouchPoint point;
1221             point.id = 1;
1222             point.area = QRectF(globalPoint.x() - 2, globalPoint.y() - 2, 4, 4);
1223
1224             // only translate left button related events to
1225             // avoid strange touch event sequences when several
1226             // buttons are pressed
1227             if (type == QEvent::MouseButtonPress && button == Qt::LeftButton) {
1228                 point.state = Qt::TouchPointPressed;
1229             } else if (type == QEvent::MouseButtonRelease && button == Qt::LeftButton) {
1230                 point.state = Qt::TouchPointReleased;
1231             } else if (type == QEvent::MouseMove && (buttons & Qt::LeftButton)) {
1232                 point.state = Qt::TouchPointMoved;
1233             } else {
1234                 return;
1235             }
1236
1237             points << point;
1238
1239             QEvent::Type type;
1240             QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
1241
1242             QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers);
1243             fake.synthetic = true;
1244             processTouchEvent(&fake);
1245         }
1246         if (doubleClick) {
1247             mousePressButton = Qt::NoButton;
1248             QMouseEvent dblClickEvent(QEvent::MouseButtonDblClick, localPoint, localPoint, globalPoint,
1249                                       button, buttons, e->modifiers);
1250             dblClickEvent.setTimestamp(e->timestamp);
1251             QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
1252         }
1253     }
1254 }
1255
1256 void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
1257 {
1258     if (!e->window)
1259         return;
1260
1261     QPointF globalPoint = e->globalPos;
1262     QGuiApplicationPrivate::lastCursorPosition = globalPoint;
1263     modifier_buttons = e->modifiers;
1264
1265     QWindow *window = e->window.data();
1266
1267     if (window) {
1268         if (window->d_func()->blockedByModalWindow) {
1269             // a modal window is blocking this window, don't allow wheel events through
1270             return;
1271         }
1272
1273          QWheelEvent ev(e->localPos, e->globalPos, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers);
1274          ev.setTimestamp(e->timestamp);
1275          QGuiApplication::sendSpontaneousEvent(window, &ev);
1276          return;
1277      }
1278 }
1279
1280 // Remember, Qt convention is:  keyboard state is state *before*
1281
1282 void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
1283 {
1284     QWindow *window = e->window.data();
1285     modifier_buttons = e->modifiers;
1286     if (e->nullWindow)
1287         window = QGuiApplication::focusWindow();
1288     if (!window)
1289         return;
1290     if (window->d_func()->blockedByModalWindow) {
1291         // a modal window is blocking this window, don't allow key events through
1292         return;
1293     }
1294
1295     QKeyEvent ev(e->keyType, e->key, e->modifiers,
1296                  e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers,
1297                  e->unicode, e->repeat, e->repeatCount);
1298     ev.setTimestamp(e->timestamp);
1299     QGuiApplication::sendSpontaneousEvent(window, &ev);
1300 }
1301
1302 void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
1303 {
1304     if (!e->enter)
1305         return;
1306     if (e->enter.data()->d_func()->blockedByModalWindow) {
1307         // a modal window is blocking this window, don't allow enter events through
1308         return;
1309     }
1310
1311     QEvent event(QEvent::Enter);
1312     QCoreApplication::sendSpontaneousEvent(e->enter.data(), &event);
1313 }
1314
1315 void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
1316 {
1317     if (!e->leave)
1318         return;
1319     if (e->leave.data()->d_func()->blockedByModalWindow) {
1320         // a modal window is blocking this window, don't allow leave events through
1321         return;
1322     }
1323
1324     QEvent event(QEvent::Leave);
1325     QCoreApplication::sendSpontaneousEvent(e->leave.data(), &event);
1326 }
1327
1328 void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
1329 {
1330     QWindow *previous = QGuiApplicationPrivate::focus_window;
1331     QWindow *newFocus = e->activated.data();
1332
1333     if (previous == newFocus)
1334         return;
1335
1336     QObject *previousFocusObject = previous ? previous->focusObject() : 0;
1337
1338     if (previous) {
1339         QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange);
1340         QCoreApplication::sendSpontaneousEvent(previous, &focusAboutToChange);
1341     }
1342
1343     QGuiApplicationPrivate::focus_window = newFocus;
1344
1345     if (previous) {
1346         QFocusEvent focusOut(QEvent::FocusOut);
1347         QCoreApplication::sendSpontaneousEvent(previous, &focusOut);
1348         QObject::disconnect(previous, SIGNAL(focusObjectChanged(QObject*)),
1349                             qApp, SLOT(q_updateFocusObject(QObject*)));
1350     } else {
1351         QEvent appActivate(QEvent::ApplicationActivate);
1352         qApp->sendSpontaneousEvent(qApp, &appActivate);
1353     }
1354
1355     if (QGuiApplicationPrivate::focus_window) {
1356         QFocusEvent focusIn(QEvent::FocusIn);
1357         QCoreApplication::sendSpontaneousEvent(QGuiApplicationPrivate::focus_window, &focusIn);
1358         QObject::connect(QGuiApplicationPrivate::focus_window, SIGNAL(focusObjectChanged(QObject*)),
1359                          qApp, SLOT(q_updateFocusObject(QObject*)));
1360     } else {
1361         QEvent appActivate(QEvent::ApplicationDeactivate);
1362         qApp->sendSpontaneousEvent(qApp, &appActivate);
1363     }
1364
1365     if (self) {
1366         self->notifyActiveWindowChange(previous);
1367
1368         if (previousFocusObject != qApp->focusObject())
1369             self->q_updateFocusObject(qApp->focusObject());
1370     }
1371
1372     emit qApp->focusWindowChanged(newFocus);
1373 }
1374
1375 void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
1376 {
1377     if (QWindow *window  = wse->window.data()) {
1378         QWindowStateChangeEvent e(window->windowState());
1379         window->d_func()->windowState = wse->newState;
1380         QGuiApplication::sendSpontaneousEvent(window, &e);
1381     }
1382 }
1383
1384 void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce)
1385 {
1386     if (self)
1387         self->notifyThemeChanged();
1388     if (QWindow *window  = tce->window.data()) {
1389         QEvent e(QEvent::ThemeChange);
1390         QGuiApplication::sendSpontaneousEvent(window, &e);
1391     }
1392 }
1393
1394 void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
1395 {
1396     if (e->tlw.isNull())
1397        return;
1398
1399     QWindow *window = e->tlw.data();
1400     if (!window)
1401         return;
1402
1403     QRect newRect = e->newGeometry;
1404     QRect cr = window->d_func()->geometry;
1405
1406     bool isResize = cr.size() != newRect.size();
1407     bool isMove = cr.topLeft() != newRect.topLeft();
1408
1409     window->d_func()->geometry = newRect;
1410
1411     if (isResize || window->d_func()->resizeEventPending) {
1412         QResizeEvent e(newRect.size(), cr.size());
1413         QGuiApplication::sendSpontaneousEvent(window, &e);
1414
1415         window->d_func()->resizeEventPending = false;
1416
1417         if (cr.width() != newRect.width())
1418             window->widthChanged(newRect.width());
1419         if (cr.height() != newRect.height())
1420             window->heightChanged(newRect.height());
1421     }
1422
1423     if (isMove) {
1424         //### frame geometry
1425         QMoveEvent e(newRect.topLeft(), cr.topLeft());
1426         QGuiApplication::sendSpontaneousEvent(window, &e);
1427
1428         if (cr.x() != newRect.x())
1429             window->xChanged(newRect.x());
1430         if (cr.y() != newRect.y())
1431             window->yChanged(newRect.y());
1432     }
1433 }
1434
1435 void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
1436 {
1437     if (e->window.isNull())
1438         return;
1439     if (e->window.data()->d_func()->blockedByModalWindow) {
1440         // a modal window is blocking this window, don't allow close events through
1441         return;
1442     }
1443
1444     QCloseEvent event;
1445     QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
1446 }
1447
1448 void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e)
1449 {
1450     if (e->fileName.isEmpty())
1451         return;
1452
1453     QFileOpenEvent event(e->fileName);
1454     QGuiApplication::sendSpontaneousEvent(qApp, &event);
1455 }
1456
1457 void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e)
1458 {
1459 #ifndef QT_NO_TABLETEVENT
1460     QEvent::Type type = QEvent::TabletMove;
1461     if (e->down != tabletState) {
1462         type = e->down ? QEvent::TabletPress : QEvent::TabletRelease;
1463         tabletState = e->down;
1464     }
1465     QWindow *window = e->window.data();
1466     bool localValid = true;
1467     // If window is null, pick one based on the global position and make sure all
1468     // subsequent events up to the release are delivered to that same window.
1469     // If window is given, just send to that.
1470     if (type == QEvent::TabletPress) {
1471         if (!window) {
1472             window = QGuiApplication::topLevelAt(e->global.toPoint());
1473             localValid = false;
1474         }
1475         if (!window)
1476             return;
1477         tabletPressTarget = window;
1478     } else {
1479         if (!window) {
1480             window = tabletPressTarget;
1481             localValid = false;
1482         }
1483         if (type == QEvent::TabletRelease)
1484             tabletPressTarget = 0;
1485         if (!window)
1486             return;
1487     }
1488     QPointF local = e->local;
1489     if (!localValid) {
1490         QPointF delta = e->global - e->global.toPoint();
1491         local = window->mapFromGlobal(e->global.toPoint()) + delta;
1492     }
1493     QTabletEvent ev(type, local, e->global,
1494                     e->device, e->pointerType, e->pressure, e->xTilt, e->yTilt,
1495                     e->tangentialPressure, e->rotation, e->z,
1496                     e->mods, e->uid);
1497     ev.setTimestamp(e->timestamp);
1498     QGuiApplication::sendSpontaneousEvent(window, &ev);
1499 #else
1500     Q_UNUSED(e)
1501 #endif
1502 }
1503
1504 void QGuiApplicationPrivate::processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e)
1505 {
1506 #ifndef QT_NO_TABLETEVENT
1507     QTabletEvent ev(QEvent::TabletEnterProximity, QPointF(), QPointF(),
1508                     e->device, e->pointerType, 0, 0, 0,
1509                     0, 0, 0,
1510                     Qt::NoModifier, e->uid);
1511     ev.setTimestamp(e->timestamp);
1512     QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
1513 #else
1514     Q_UNUSED(e)
1515 #endif
1516 }
1517
1518 void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e)
1519 {
1520 #ifndef QT_NO_TABLETEVENT
1521     QTabletEvent ev(QEvent::TabletLeaveProximity, QPointF(), QPointF(),
1522                     e->device, e->pointerType, 0, 0, 0,
1523                     0, 0, 0,
1524                     Qt::NoModifier, e->uid);
1525     ev.setTimestamp(e->timestamp);
1526     QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
1527 #else
1528     Q_UNUSED(e)
1529 #endif
1530 }
1531
1532 Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k)
1533 {
1534     return qHash(k.device) + k.touchPointId;
1535 }
1536
1537 Q_GUI_EXPORT bool operator==(const QGuiApplicationPrivate::ActiveTouchPointsKey &a,
1538                              const QGuiApplicationPrivate::ActiveTouchPointsKey &b)
1539 {
1540     return a.device == b.device
1541             && a.touchPointId == b.touchPointId;
1542 }
1543
1544 void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
1545 {
1546     QGuiApplicationPrivate *d = self;
1547     modifier_buttons = e->modifiers;
1548
1549     if (e->touchType == QEvent::TouchCancel) {
1550         // The touch sequence has been canceled (e.g. by the compositor).
1551         // Send the TouchCancel to all windows with active touches and clean up.
1552         QTouchEvent touchEvent(QEvent::TouchCancel, e->device, e->modifiers);
1553         touchEvent.setTimestamp(e->timestamp);
1554         QHash<ActiveTouchPointsKey, ActiveTouchPointsValue>::const_iterator it
1555                 = self->activeTouchPoints.constBegin(), ite = self->activeTouchPoints.constEnd();
1556         QSet<QWindow *> windowsNeedingCancel;
1557         while (it != ite) {
1558             QWindow *w = it->window.data();
1559             if (w)
1560                 windowsNeedingCancel.insert(w);
1561             ++it;
1562         }
1563         for (QSet<QWindow *>::const_iterator winIt = windowsNeedingCancel.constBegin(),
1564              winItEnd = windowsNeedingCancel.constEnd(); winIt != winItEnd; ++winIt) {
1565             touchEvent.setWindow(*winIt);
1566             QGuiApplication::sendSpontaneousEvent(*winIt, &touchEvent);
1567         }
1568         if (!self->synthesizedMousePoints.isEmpty() && !e->synthetic) {
1569             for (QHash<QWindow *, SynthesizedMouseData>::const_iterator synthIt = self->synthesizedMousePoints.constBegin(),
1570                  synthItEnd = self->synthesizedMousePoints.constEnd(); synthIt != synthItEnd; ++synthIt) {
1571                 if (!synthIt->window)
1572                     continue;
1573                 QWindowSystemInterfacePrivate::MouseEvent fake(synthIt->window.data(),
1574                                                                e->timestamp,
1575                                                                synthIt->pos,
1576                                                                synthIt->screenPos,
1577                                                                Qt::NoButton,
1578                                                                e->modifiers);
1579                 fake.synthetic = true;
1580                 processMouseEvent(&fake);
1581             }
1582             self->synthesizedMousePoints.clear();
1583         }
1584         self->activeTouchPoints.clear();
1585         self->lastTouchType = e->touchType;
1586         return;
1587     }
1588
1589     // Prevent sending ill-formed event sequences: Cancel can only be followed by a Begin.
1590     if (self->lastTouchType == QEvent::TouchCancel && e->touchType != QEvent::TouchBegin)
1591         return;
1592
1593     self->lastTouchType = e->touchType;
1594
1595     QWindow *window = e->window.data();
1596     typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
1597     QHash<QWindow *, StatesAndTouchPoints> windowsNeedingEvents;
1598
1599     for (int i = 0; i < e->points.count(); ++i) {
1600         QTouchEvent::TouchPoint touchPoint = e->points.at(i);
1601         // explicitly detach from the original touch point that we got, so even
1602         // if the touchpoint structs are reused, we will make a copy that we'll
1603         // deliver to the user (which might want to store the struct for later use).
1604         touchPoint.d = touchPoint.d->detach();
1605
1606         // update state
1607         QPointer<QWindow> w;
1608         QTouchEvent::TouchPoint previousTouchPoint;
1609         ActiveTouchPointsKey touchInfoKey(e->device, touchPoint.id());
1610         ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
1611         switch (touchPoint.state()) {
1612         case Qt::TouchPointPressed:
1613             if (e->device->type() == QTouchDevice::TouchPad) {
1614                 // on touch-pads, send all touch points to the same widget
1615                 w = d->activeTouchPoints.isEmpty()
1616                     ? QPointer<QWindow>()
1617                     : d->activeTouchPoints.constBegin().value().window;
1618             }
1619
1620             if (!w) {
1621                 // determine which window this event will go to
1622                 if (!window)
1623                     window = QGuiApplication::topLevelAt(touchPoint.screenPos().toPoint());
1624                 if (!window)
1625                     continue;
1626                 w = window;
1627             }
1628
1629             touchInfo.window = w;
1630             touchPoint.d->startScreenPos = touchPoint.screenPos();
1631             touchPoint.d->lastScreenPos = touchPoint.screenPos();
1632             touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
1633             touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
1634             if (touchPoint.pressure() < qreal(0.))
1635                 touchPoint.d->pressure = qreal(1.);
1636
1637             touchInfo.touchPoint = touchPoint;
1638             break;
1639
1640         case Qt::TouchPointReleased:
1641             w = touchInfo.window;
1642             if (!w)
1643                 continue;
1644
1645             previousTouchPoint = touchInfo.touchPoint;
1646             touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
1647             touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
1648             touchPoint.d->startPos = previousTouchPoint.startPos();
1649             touchPoint.d->lastPos = previousTouchPoint.pos();
1650             touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
1651             touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
1652             if (touchPoint.pressure() < qreal(0.))
1653                 touchPoint.d->pressure = qreal(0.);
1654
1655             break;
1656
1657         default:
1658             w = touchInfo.window;
1659             if (!w)
1660                 continue;
1661
1662             previousTouchPoint = touchInfo.touchPoint;
1663             touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
1664             touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
1665             touchPoint.d->startPos = previousTouchPoint.startPos();
1666             touchPoint.d->lastPos = previousTouchPoint.pos();
1667             touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
1668             touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
1669             if (touchPoint.pressure() < qreal(0.))
1670                 touchPoint.d->pressure = qreal(1.);
1671
1672             // Stationary points might not be delivered down to the receiving item
1673             // and get their position transformed, keep the old values instead.
1674             if (touchPoint.state() != Qt::TouchPointStationary)
1675                 touchInfo.touchPoint = touchPoint;
1676             break;
1677         }
1678
1679         Q_ASSERT(w.data() != 0);
1680
1681         // make the *scene* functions return the same as the *screen* functions
1682         touchPoint.d->sceneRect = touchPoint.screenRect();
1683         touchPoint.d->startScenePos = touchPoint.startScreenPos();
1684         touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
1685
1686         StatesAndTouchPoints &maskAndPoints = windowsNeedingEvents[w.data()];
1687         maskAndPoints.first |= touchPoint.state();
1688         maskAndPoints.second.append(touchPoint);
1689     }
1690
1691     if (windowsNeedingEvents.isEmpty())
1692         return;
1693
1694     QHash<QWindow *, StatesAndTouchPoints>::ConstIterator it = windowsNeedingEvents.constBegin();
1695     const QHash<QWindow *, StatesAndTouchPoints>::ConstIterator end = windowsNeedingEvents.constEnd();
1696     for (; it != end; ++it) {
1697         QWindow *w = it.key();
1698
1699         QEvent::Type eventType;
1700         switch (it.value().first) {
1701         case Qt::TouchPointPressed:
1702             eventType = QEvent::TouchBegin;
1703             break;
1704         case Qt::TouchPointReleased:
1705             eventType = QEvent::TouchEnd;
1706             break;
1707         case Qt::TouchPointStationary:
1708             // don't send the event if nothing changed
1709             continue;
1710         default:
1711             eventType = QEvent::TouchUpdate;
1712             break;
1713         }
1714
1715         if (w->d_func()->blockedByModalWindow) {
1716             // a modal window is blocking this window, don't allow touch events through
1717             continue;
1718         }
1719
1720         QTouchEvent touchEvent(eventType,
1721                                e->device,
1722                                e->modifiers,
1723                                it.value().first,
1724                                it.value().second);
1725         touchEvent.setTimestamp(e->timestamp);
1726         touchEvent.setWindow(w);
1727
1728         const int pointCount = touchEvent.touchPoints().count();
1729         for (int i = 0; i < pointCount; ++i) {
1730             QTouchEvent::TouchPoint &touchPoint = touchEvent._touchPoints[i];
1731
1732             // preserve the sub-pixel resolution
1733             QRectF rect = touchPoint.screenRect();
1734             const QPointF screenPos = rect.center();
1735             const QPointF delta = screenPos - screenPos.toPoint();
1736
1737             rect.moveCenter(w->mapFromGlobal(screenPos.toPoint()) + delta);
1738             touchPoint.d->rect = rect;
1739             if (touchPoint.state() == Qt::TouchPointPressed) {
1740                 touchPoint.d->startPos = w->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
1741                 touchPoint.d->lastPos = w->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
1742             }
1743         }
1744
1745         QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
1746         if (!e->synthetic && !touchEvent.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) {
1747             // exclude touchpads as those generate their own mouse events
1748             if (touchEvent.device()->type() != QTouchDevice::TouchPad) {
1749                 Qt::MouseButtons b = eventType == QEvent::TouchEnd ? Qt::NoButton : Qt::LeftButton;
1750                 if (b == Qt::NoButton)
1751                     self->synthesizedMousePoints.clear();
1752
1753                 QList<QTouchEvent::TouchPoint> touchPoints = touchEvent.touchPoints();
1754                 if (eventType == QEvent::TouchBegin)
1755                     m_fakeMouseSourcePointId = touchPoints.first().id();
1756
1757                 for (int i = 0; i < touchPoints.count(); ++i) {
1758                     const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
1759                     if (touchPoint.id() == m_fakeMouseSourcePointId) {
1760                         if (b != Qt::NoButton)
1761                             self->synthesizedMousePoints.insert(w, SynthesizedMouseData(
1762                                                                     touchPoint.pos(), touchPoint.screenPos(), w));
1763                         QWindowSystemInterfacePrivate::MouseEvent fake(w, e->timestamp,
1764                                                                        touchPoint.pos(),
1765                                                                        touchPoint.screenPos(),
1766                                                                        b, e->modifiers);
1767                         fake.synthetic = true;
1768                         processMouseEvent(&fake);
1769                         break;
1770                     }
1771                 }
1772             }
1773         }
1774     }
1775
1776     // Remove released points from the hash table only after the event is
1777     // delivered. When the receiver is a widget, QApplication will access
1778     // activeTouchPoints during delivery and therefore nothing can be removed
1779     // before sending the event.
1780     for (int i = 0; i < e->points.count(); ++i) {
1781         QTouchEvent::TouchPoint touchPoint = e->points.at(i);
1782         if (touchPoint.state() == Qt::TouchPointReleased)
1783             d->activeTouchPoints.remove(ActiveTouchPointsKey(e->device, touchPoint.id()));
1784     }
1785 }
1786
1787 void QGuiApplicationPrivate::reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e)
1788 {
1789     // This operation only makes sense after the QGuiApplication constructor runs
1790     if (QCoreApplication::startingUp())
1791         return;
1792
1793     if (!e->screen)
1794         return;
1795
1796     QScreen *s = e->screen.data();
1797     s->d_func()->orientation = e->orientation;
1798
1799     updateFilteredScreenOrientation(s);
1800 }
1801
1802 void QGuiApplicationPrivate::updateFilteredScreenOrientation(QScreen *s)
1803 {
1804     Qt::ScreenOrientation o = s->d_func()->orientation;
1805     if (o == Qt::PrimaryOrientation)
1806         o = s->primaryOrientation();
1807     o = Qt::ScreenOrientation(o & s->orientationUpdateMask());
1808     if (o == Qt::PrimaryOrientation)
1809         return;
1810     if (o == s->d_func()->filteredOrientation)
1811         return;
1812     s->d_func()->filteredOrientation = o;
1813     reportScreenOrientationChange(s);
1814 }
1815
1816 void QGuiApplicationPrivate::reportScreenOrientationChange(QScreen *s)
1817 {
1818     emit s->orientationChanged(s->orientation());
1819
1820     QScreenOrientationChangeEvent event(s, s->orientation());
1821     QCoreApplication::sendEvent(QCoreApplication::instance(), &event);
1822 }
1823
1824 void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e)
1825 {
1826     // This operation only makes sense after the QGuiApplication constructor runs
1827     if (QCoreApplication::startingUp())
1828         return;
1829
1830     if (!e->screen)
1831         return;
1832
1833     QScreen *s = e->screen.data();
1834     s->d_func()->geometry = e->geometry;
1835
1836     Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
1837     s->d_func()->updatePrimaryOrientation();
1838
1839     emit s->sizeChanged(s->size());
1840     emit s->geometryChanged(s->geometry());
1841     emit s->physicalDotsPerInchXChanged(s->physicalDotsPerInchX());
1842     emit s->physicalDotsPerInchYChanged(s->physicalDotsPerInchY());
1843     emit s->physicalDotsPerInchChanged(s->physicalDotsPerInch());
1844     emit s->availableSizeChanged(s->availableSize());
1845     emit s->availableGeometryChanged(s->availableGeometry());
1846
1847     if (s->primaryOrientation() != primaryOrientation)
1848         emit s->primaryOrientationChanged(s->primaryOrientation());
1849
1850     if (s->d_func()->orientation == Qt::PrimaryOrientation)
1851         updateFilteredScreenOrientation(s);
1852 }
1853
1854 void QGuiApplicationPrivate::reportAvailableGeometryChange(
1855         QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e)
1856 {
1857     // This operation only makes sense after the QGuiApplication constructor runs
1858     if (QCoreApplication::startingUp())
1859         return;
1860
1861     if (!e->screen)
1862         return;
1863
1864     QScreen *s = e->screen.data();
1865     s->d_func()->availableGeometry = e->availableGeometry;
1866
1867     emit s->availableSizeChanged(s->availableSize());
1868     emit s->availableGeometryChanged(s->availableGeometry());
1869 }
1870
1871 void QGuiApplicationPrivate::reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e)
1872 {
1873     // This operation only makes sense after the QGuiApplication constructor runs
1874     if (QCoreApplication::startingUp())
1875         return;
1876
1877     if (!e->screen)
1878         return;
1879
1880     QScreen *s = e->screen.data();
1881     s->d_func()->logicalDpi = QDpi(e->dpiX, e->dpiY);
1882
1883     emit s->logicalDotsPerInchXChanged(s->logicalDotsPerInchX());
1884     emit s->logicalDotsPerInchYChanged(s->logicalDotsPerInchY());
1885     emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch());
1886 }
1887
1888 void QGuiApplicationPrivate::reportRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e)
1889 {
1890     // This operation only makes sense after the QGuiApplication constructor runs
1891     if (QCoreApplication::startingUp())
1892         return;
1893
1894     if (!e->screen)
1895         return;
1896
1897     QScreen *s = e->screen.data();
1898     s->d_func()->refreshRate = e->rate;
1899
1900     emit s->refreshRateChanged(s->refreshRate());
1901 }
1902
1903 void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e)
1904 {
1905     if (!e->exposed)
1906         return;
1907
1908     QWindow *window = e->exposed.data();
1909     QWindowPrivate *p = qt_window_private(window);
1910
1911     if (!p->receivedExpose) {
1912         if (p->resizeEventPending) {
1913             // as a convenience for plugins, send a resize event before the first expose event if they haven't done so
1914             QSize size = p->geometry.size();
1915             QResizeEvent e(size, size);
1916             QGuiApplication::sendSpontaneousEvent(window, &e);
1917
1918             p->resizeEventPending = false;
1919         }
1920
1921         p->receivedExpose = true;
1922     }
1923
1924     p->exposed = e->isExposed;
1925
1926     QExposeEvent exposeEvent(e->region);
1927     QCoreApplication::sendSpontaneousEvent(window, &exposeEvent);
1928 }
1929
1930 #ifndef QT_NO_DRAGANDDROP
1931
1932 QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
1933 {
1934     static QPointer<QWindow> currentDragWindow;
1935     static Qt::DropAction lastAcceptedDropAction = Qt::IgnoreAction;
1936     QPlatformDrag *platformDrag = platformIntegration()->drag();
1937     if (!platformDrag) {
1938         lastAcceptedDropAction = Qt::IgnoreAction;
1939         return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
1940     }
1941
1942     if (!dropData) {
1943         if (currentDragWindow.data() == w)
1944             currentDragWindow = 0;
1945         QDragLeaveEvent e;
1946         QGuiApplication::sendEvent(w, &e);
1947         lastAcceptedDropAction = Qt::IgnoreAction;
1948         return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
1949     }
1950     QDragMoveEvent me(p, supportedActions, dropData,
1951                       QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1952
1953     if (w != currentDragWindow) {
1954         lastAcceptedDropAction = Qt::IgnoreAction;
1955         if (currentDragWindow) {
1956             QDragLeaveEvent e;
1957             QGuiApplication::sendEvent(currentDragWindow, &e);
1958         }
1959         currentDragWindow = w;
1960         QDragEnterEvent e(p, supportedActions, dropData,
1961                           QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1962         QGuiApplication::sendEvent(w, &e);
1963         if (e.isAccepted() && e.dropAction() != Qt::IgnoreAction)
1964             lastAcceptedDropAction = e.dropAction();
1965     }
1966
1967     // Handling 'DragEnter' should suffice for the application.
1968     if (lastAcceptedDropAction != Qt::IgnoreAction
1969         && (supportedActions & lastAcceptedDropAction)) {
1970         me.setDropAction(lastAcceptedDropAction);
1971         me.accept();
1972     }
1973     QGuiApplication::sendEvent(w, &me);
1974     lastAcceptedDropAction = me.isAccepted() ?
1975                              me.dropAction() :  Qt::IgnoreAction;
1976     return QPlatformDragQtResponse(me.isAccepted(), lastAcceptedDropAction, me.answerRect());
1977 }
1978
1979 QPlatformDropQtResponse QGuiApplicationPrivate::processDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
1980 {
1981     QDropEvent de(p, supportedActions, dropData,
1982                   QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1983     QGuiApplication::sendEvent(w, &de);
1984
1985     Qt::DropAction acceptedAction = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
1986     QPlatformDropQtResponse response(de.isAccepted(),acceptedAction);
1987     return response;
1988 }
1989
1990 #endif // QT_NO_DRAGANDDROP
1991
1992 #ifndef QT_NO_CLIPBOARD
1993 /*!
1994     Returns the object for interacting with the clipboard.
1995 */
1996 QClipboard * QGuiApplication::clipboard()
1997 {
1998     if (QGuiApplicationPrivate::qt_clipboard == 0) {
1999         if (!qApp) {
2000             qWarning("QGuiApplication: Must construct a QGuiApplication before accessing a QClipboard");
2001             return 0;
2002         }
2003         QGuiApplicationPrivate::qt_clipboard = new QClipboard(0);
2004     }
2005     return QGuiApplicationPrivate::qt_clipboard;
2006 }
2007 #endif
2008
2009 /*!
2010     Returns the default application palette.
2011
2012     \sa setPalette()
2013 */
2014
2015 QPalette QGuiApplication::palette()
2016 {
2017     initPalette();
2018     return *QGuiApplicationPrivate::app_pal;
2019 }
2020
2021 /*!
2022     Changes the default application palette to \a palette.
2023
2024     \sa palette()
2025 */
2026 void QGuiApplication::setPalette(const QPalette &pal)
2027 {
2028     if (QGuiApplicationPrivate::app_pal && pal.isCopyOf(*QGuiApplicationPrivate::app_pal))
2029         return;
2030     if (!QGuiApplicationPrivate::app_pal)
2031         QGuiApplicationPrivate::app_pal = new QPalette(pal);
2032     else
2033         *QGuiApplicationPrivate::app_pal = pal;
2034     applicationResourceFlags |= ApplicationPaletteExplicitlySet;
2035 }
2036
2037 /*!
2038     Returns the default application font.
2039
2040     \sa setFont()
2041 */
2042 QFont QGuiApplication::font()
2043 {
2044     QMutexLocker locker(&applicationFontMutex);
2045     initFontUnlocked();
2046     return *QGuiApplicationPrivate::app_font;
2047 }
2048
2049 /*!
2050     Changes the default application font to \a font.
2051
2052     \sa font()
2053 */
2054 void QGuiApplication::setFont(const QFont &font)
2055 {
2056     QMutexLocker locker(&applicationFontMutex);
2057     if (!QGuiApplicationPrivate::app_font)
2058         QGuiApplicationPrivate::app_font = new QFont(font);
2059     else
2060         *QGuiApplicationPrivate::app_font = font;
2061     applicationResourceFlags |= ApplicationFontExplicitlySet;
2062 }
2063
2064 /*!
2065     \fn bool QGuiApplication::isRightToLeft()
2066
2067     Returns true if the application's layout direction is
2068     Qt::RightToLeft; otherwise returns false.
2069
2070     \sa layoutDirection(), isLeftToRight()
2071 */
2072
2073 /*!
2074     \fn bool QGuiApplication::isLeftToRight()
2075
2076     Returns true if the application's layout direction is
2077     Qt::LeftToRight; otherwise returns false.
2078
2079     \sa layoutDirection(), isRightToLeft()
2080 */
2081
2082 void QGuiApplicationPrivate::notifyLayoutDirectionChange()
2083 {
2084 }
2085
2086 void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
2087 {
2088 }
2089
2090
2091 /*!
2092     \property QGuiApplication::quitOnLastWindowClosed
2093
2094     \brief whether the application implicitly quits when the last window is
2095     closed.
2096
2097     The default is true.
2098
2099     If this property is true, the applications quits when the last visible
2100     primary window (i.e. window with no parent) is closed.
2101
2102     \sa quit(), QWindow::close()
2103  */
2104
2105 void QGuiApplication::setQuitOnLastWindowClosed(bool quit)
2106 {
2107     QCoreApplication::setQuitLockEnabled(quit);
2108 }
2109
2110
2111
2112 bool QGuiApplication::quitOnLastWindowClosed()
2113 {
2114     return QCoreApplication::isQuitLockEnabled();
2115 }
2116
2117
2118
2119 void QGuiApplicationPrivate::emitLastWindowClosed()
2120 {
2121     if (qGuiApp && qGuiApp->d_func()->in_exec) {
2122         emit qGuiApp->lastWindowClosed();
2123     }
2124 }
2125
2126 bool QGuiApplicationPrivate::shouldQuit()
2127 {
2128     /* if there is no visible top-level window left, we allow the quit */
2129     QWindowList list = QGuiApplication::topLevelWindows();
2130     for (int i = 0; i < list.size(); ++i) {
2131         QWindow *w = list.at(i);
2132         if (w->isVisible() && !w->transientParent())
2133             return false;
2134     }
2135     return true;
2136 }
2137
2138 /*!
2139     \property QGuiApplication::layoutDirection
2140     \brief the default layout direction for this application
2141
2142     On system start-up, the default layout direction depends on the
2143     application's language.
2144
2145     \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
2146  */
2147
2148 void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
2149 {
2150     if (layout_direction == direction || direction == Qt::LayoutDirectionAuto)
2151         return;
2152
2153     layout_direction = direction;
2154
2155     QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
2156 }
2157
2158 Qt::LayoutDirection QGuiApplication::layoutDirection()
2159 {
2160     return layout_direction;
2161 }
2162
2163 /*!
2164     \fn QCursor *QGuiApplication::overrideCursor()
2165
2166     Returns the active application override cursor.
2167
2168     This function returns 0 if no application cursor has been defined (i.e. the
2169     internal cursor stack is empty).
2170
2171     \sa setOverrideCursor(), restoreOverrideCursor()
2172 */
2173 #ifndef QT_NO_CURSOR
2174 QCursor *QGuiApplication::overrideCursor()
2175 {
2176     return qGuiApp->d_func()->cursor_list.isEmpty() ? 0 : &qGuiApp->d_func()->cursor_list.first();
2177 }
2178
2179 /*!
2180     Changes the currently active application override cursor to \a cursor.
2181
2182     This function has no effect if setOverrideCursor() was not called.
2183
2184     \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
2185     QWidget::setCursor()
2186  */
2187 void QGuiApplication::changeOverrideCursor(const QCursor &cursor)
2188 {
2189     if (qGuiApp->d_func()->cursor_list.isEmpty())
2190         return;
2191     qGuiApp->d_func()->cursor_list.removeFirst();
2192     setOverrideCursor(cursor);
2193 }
2194 #endif
2195
2196
2197 #ifndef QT_NO_CURSOR
2198 static inline void applyCursor(QWindow *w, QCursor c)
2199 {
2200     if (const QScreen *screen = w->screen())
2201         if (QPlatformCursor *cursor = screen->handle()->cursor())
2202             cursor->changeCursor(&c, w);
2203 }
2204
2205 static inline void applyCursor(const QList<QWindow *> &l, const QCursor &c)
2206 {
2207     for (int i = 0; i < l.size(); ++i) {
2208         QWindow *w = l.at(i);
2209         if (w->handle() && w->windowType() != Qt::Desktop)
2210             applyCursor(w, c);
2211     }
2212 }
2213
2214 /*!
2215     \fn void QGuiApplication::setOverrideCursor(const QCursor &cursor)
2216
2217     Sets the application override cursor to \a cursor.
2218
2219     Application override cursors are intended for showing the user that the
2220     application is in a special state, for example during an operation that
2221     might take some time.
2222
2223     This cursor will be displayed in all the application's widgets until
2224     restoreOverrideCursor() or another setOverrideCursor() is called.
2225
2226     Application cursors are stored on an internal stack. setOverrideCursor()
2227     pushes the cursor onto the stack, and restoreOverrideCursor() pops the
2228     active cursor off the stack. changeOverrideCursor() changes the curently
2229     active application override cursor.
2230
2231     Every setOverrideCursor() must eventually be followed by a corresponding
2232     restoreOverrideCursor(), otherwise the stack will never be emptied.
2233
2234     Example:
2235     \snippet code/src_gui_kernel_qapplication_x11.cpp 0
2236
2237     \sa overrideCursor(), restoreOverrideCursor(), changeOverrideCursor(),
2238     QWidget::setCursor()
2239 */
2240 void QGuiApplication::setOverrideCursor(const QCursor &cursor)
2241 {
2242     qGuiApp->d_func()->cursor_list.prepend(cursor);
2243     applyCursor(QGuiApplicationPrivate::window_list, cursor);
2244 }
2245
2246 /*!
2247     \fn void QGuiApplication::restoreOverrideCursor()
2248
2249     Undoes the last setOverrideCursor().
2250
2251     If setOverrideCursor() has been called twice, calling
2252     restoreOverrideCursor() will activate the first cursor set. Calling this
2253     function a second time restores the original widgets' cursors.
2254
2255     \sa setOverrideCursor(), overrideCursor()
2256 */
2257 void QGuiApplication::restoreOverrideCursor()
2258 {
2259     if (qGuiApp->d_func()->cursor_list.isEmpty())
2260         return;
2261     qGuiApp->d_func()->cursor_list.removeFirst();
2262     QCursor c(qGuiApp->d_func()->cursor_list.value(0, QCursor()));
2263     applyCursor(QGuiApplicationPrivate::window_list, c);
2264 }
2265 #endif// QT_NO_CURSOR
2266
2267 /*!
2268   Returns the application's style hints.
2269
2270   The style hints encapsulate a set of platform dependent properties
2271   such as double click intervals, full width selection and others.
2272
2273   The hints can be used to integrate tighter with the underlying platform.
2274
2275   \sa QStyleHints
2276   */
2277 QStyleHints *QGuiApplication::styleHints()
2278 {
2279     if (!qGuiApp->d_func()->styleHints)
2280         qGuiApp->d_func()->styleHints = new QStyleHints();
2281     return qGuiApp->d_func()->styleHints;
2282 }
2283
2284 /*!
2285     Sets whether Qt should use the system's standard colors, fonts, etc., to
2286     \a on. By default, this is true.
2287
2288     This function must be called before creating the QGuiApplication object, like
2289     this:
2290
2291     \snippet code/src_gui_kernel_qapplication.cpp 6
2292
2293     \sa desktopSettingsAware()
2294 */
2295 void QGuiApplication::setDesktopSettingsAware(bool on)
2296 {
2297     QGuiApplicationPrivate::obey_desktop_settings = on;
2298 }
2299
2300 /*!
2301     Returns true if Qt is set to use the system's standard colors, fonts, etc.;
2302     otherwise returns false. The default is true.
2303
2304     \sa setDesktopSettingsAware()
2305 */
2306 bool QGuiApplication::desktopSettingsAware()
2307 {
2308     return QGuiApplicationPrivate::obey_desktop_settings;
2309 }
2310
2311 /*!
2312   returns the input method.
2313
2314   The input method returns properties about the state and position of
2315   the virtual keyboard. It also provides information about the position of the
2316   current focused input element.
2317
2318   \sa QInputPanel
2319   */
2320 QInputMethod *QGuiApplication::inputMethod()
2321 {
2322     if (!qGuiApp->d_func()->inputMethod)
2323         qGuiApp->d_func()->inputMethod = new QInputMethod();
2324     return qGuiApp->d_func()->inputMethod;
2325 }
2326
2327 /*!
2328   \fn QInputPanel *QGuiApplication::inputPanel() const
2329   returns the input panel.
2330
2331   The input panel returns properties about the state and position of
2332   the virtual keyboard. It also provides information about the position of the
2333   current focused input element.
2334
2335   \obsolete
2336
2337   \sa inputMethod()
2338   */
2339
2340 /*!
2341     \fn void QGuiApplication::fontDatabaseChanged()
2342
2343     This signal is emitted when application fonts are loaded or removed.
2344
2345     \sa QFontDatabase::addApplicationFont(),
2346     QFontDatabase::addApplicationFontFromData(),
2347     QFontDatabase::removeAllApplicationFonts(),
2348     QFontDatabase::removeApplicationFont()
2349 */
2350
2351 // These pixmaps approximate the images in the Windows User Interface Guidelines.
2352
2353 // XPM
2354
2355 static const char * const move_xpm[] = {
2356 "11 20 3 1",
2357 ".        c None",
2358 "a        c #FFFFFF",
2359 "X        c #000000", // X11 cursor is traditionally black
2360 "aa.........",
2361 "aXa........",
2362 "aXXa.......",
2363 "aXXXa......",
2364 "aXXXXa.....",
2365 "aXXXXXa....",
2366 "aXXXXXXa...",
2367 "aXXXXXXXa..",
2368 "aXXXXXXXXa.",
2369 "aXXXXXXXXXa",
2370 "aXXXXXXaaaa",
2371 "aXXXaXXa...",
2372 "aXXaaXXa...",
2373 "aXa..aXXa..",
2374 "aa...aXXa..",
2375 "a.....aXXa.",
2376 "......aXXa.",
2377 ".......aXXa",
2378 ".......aXXa",
2379 "........aa."};
2380
2381
2382 /* XPM */
2383 static const char * const copy_xpm[] = {
2384 "24 30 3 1",
2385 ".        c None",
2386 "a        c #000000",
2387 "X        c #FFFFFF",
2388 "XX......................",
2389 "XaX.....................",
2390 "XaaX....................",
2391 "XaaaX...................",
2392 "XaaaaX..................",
2393 "XaaaaaX.................",
2394 "XaaaaaaX................",
2395 "XaaaaaaaX...............",
2396 "XaaaaaaaaX..............",
2397 "XaaaaaaaaaX.............",
2398 "XaaaaaaXXXX.............",
2399 "XaaaXaaX................",
2400 "XaaXXaaX................",
2401 "XaX..XaaX...............",
2402 "XX...XaaX...............",
2403 "X.....XaaX..............",
2404 "......XaaX..............",
2405 ".......XaaX.............",
2406 ".......XaaX.............",
2407 "........XX...aaaaaaaaaaa",
2408 ".............aXXXXXXXXXa",
2409 ".............aXXXXXXXXXa",
2410 ".............aXXXXaXXXXa",
2411 ".............aXXXXaXXXXa",
2412 ".............aXXaaaaaXXa",
2413 ".............aXXXXaXXXXa",
2414 ".............aXXXXaXXXXa",
2415 ".............aXXXXXXXXXa",
2416 ".............aXXXXXXXXXa",
2417 ".............aaaaaaaaaaa"};
2418
2419 /* XPM */
2420 static const char * const link_xpm[] = {
2421 "24 30 3 1",
2422 ".        c None",
2423 "a        c #000000",
2424 "X        c #FFFFFF",
2425 "XX......................",
2426 "XaX.....................",
2427 "XaaX....................",
2428 "XaaaX...................",
2429 "XaaaaX..................",
2430 "XaaaaaX.................",
2431 "XaaaaaaX................",
2432 "XaaaaaaaX...............",
2433 "XaaaaaaaaX..............",
2434 "XaaaaaaaaaX.............",
2435 "XaaaaaaXXXX.............",
2436 "XaaaXaaX................",
2437 "XaaXXaaX................",
2438 "XaX..XaaX...............",
2439 "XX...XaaX...............",
2440 "X.....XaaX..............",
2441 "......XaaX..............",
2442 ".......XaaX.............",
2443 ".......XaaX.............",
2444 "........XX...aaaaaaaaaaa",
2445 ".............aXXXXXXXXXa",
2446 ".............aXXXaaaaXXa",
2447 ".............aXXXXaaaXXa",
2448 ".............aXXXaaaaXXa",
2449 ".............aXXaaaXaXXa",
2450 ".............aXXaaXXXXXa",
2451 ".............aXXaXXXXXXa",
2452 ".............aXXXaXXXXXa",
2453 ".............aXXXXXXXXXa",
2454 ".............aaaaaaaaaaa"};
2455
2456 QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)
2457 {
2458     Q_UNUSED(cshape);
2459     return QPixmap();
2460 }
2461
2462 void QGuiApplicationPrivate::notifyThemeChanged()
2463 {
2464     if (!(applicationResourceFlags & ApplicationPaletteExplicitlySet)) {
2465         clearPalette();
2466         initPalette();
2467     }
2468     if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
2469         QMutexLocker locker(&applicationFontMutex);
2470         clearFontUnlocked();
2471         initFontUnlocked();
2472     }
2473 }
2474
2475 const QDrawHelperGammaTables *QGuiApplicationPrivate::gammaTables()
2476 {
2477     QDrawHelperGammaTables *result = m_gammaTables.load();
2478     if (!result){
2479         QDrawHelperGammaTables *tables = new QDrawHelperGammaTables(fontSmoothingGamma);
2480         if (!m_gammaTables.testAndSetRelease(0, tables))
2481             delete tables;
2482         result = m_gammaTables.load();
2483     }
2484     return result;
2485 }
2486
2487 void QGuiApplicationPrivate::q_updateFocusObject(QObject *object)
2488 {
2489     Q_Q(QGuiApplication);
2490
2491     bool enabled = false;
2492     if (object) {
2493         QInputMethodQueryEvent query(Qt::ImEnabled);
2494         QGuiApplication::sendEvent(object, &query);
2495         enabled = query.value(Qt::ImEnabled).toBool();
2496     }
2497
2498     QPlatformInputContextPrivate::setInputMethodAccepted(enabled);
2499     QPlatformInputContext *inputContext = platformIntegration()->inputContext();
2500     if (inputContext)
2501         inputContext->setFocusObject(object);
2502     emit q->focusObjectChanged(object);
2503 }
2504
2505 int QGuiApplicationPrivate::mouseEventCaps(QMouseEvent *event)
2506 {
2507     return event->caps;
2508 }
2509
2510 QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event)
2511 {
2512     return event->velocity;
2513 }
2514
2515 void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity)
2516 {
2517     event->caps = caps;
2518     event->velocity = velocity;
2519 }
2520
2521 void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, QMouseEvent *other)
2522 {
2523     event->caps = other->caps;
2524     event->velocity = other->velocity;
2525 }
2526
2527
2528 #include "moc_qguiapplication.cpp"
2529
2530 QT_END_NAMESPACE