05e1274fef6ef154f445b81aa1333f6392e4a5a5
[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         QWeakPointer<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                     ? QWeakPointer<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     reportScreenOrientationChange(s);
1800 }
1801
1802 void QGuiApplicationPrivate::reportScreenOrientationChange(QScreen *s)
1803 {
1804     emit s->orientationChanged(s->orientation());
1805
1806     QScreenOrientationChangeEvent event(s, s->orientation());
1807     QCoreApplication::sendEvent(QCoreApplication::instance(), &event);
1808 }
1809
1810 void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e)
1811 {
1812     // This operation only makes sense after the QGuiApplication constructor runs
1813     if (QCoreApplication::startingUp())
1814         return;
1815
1816     if (!e->screen)
1817         return;
1818
1819     QScreen *s = e->screen.data();
1820     s->d_func()->geometry = e->geometry;
1821
1822     Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
1823     Qt::ScreenOrientation orientation = s->orientation();
1824     s->d_func()->updatePrimaryOrientation();
1825
1826     emit s->sizeChanged(s->size());
1827     emit s->geometryChanged(s->geometry());
1828     emit s->physicalDotsPerInchXChanged(s->physicalDotsPerInchX());
1829     emit s->physicalDotsPerInchYChanged(s->physicalDotsPerInchY());
1830     emit s->physicalDotsPerInchChanged(s->physicalDotsPerInch());
1831     emit s->availableSizeChanged(s->availableSize());
1832     emit s->availableGeometryChanged(s->availableGeometry());
1833
1834     if (s->primaryOrientation() != primaryOrientation)
1835         emit s->primaryOrientationChanged(s->primaryOrientation());
1836
1837     if (s->orientation() != orientation)
1838         reportScreenOrientationChange(s);
1839 }
1840
1841 void QGuiApplicationPrivate::reportAvailableGeometryChange(
1842         QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e)
1843 {
1844     // This operation only makes sense after the QGuiApplication constructor runs
1845     if (QCoreApplication::startingUp())
1846         return;
1847
1848     if (!e->screen)
1849         return;
1850
1851     QScreen *s = e->screen.data();
1852     s->d_func()->availableGeometry = e->availableGeometry;
1853
1854     emit s->availableSizeChanged(s->availableSize());
1855     emit s->availableGeometryChanged(s->availableGeometry());
1856 }
1857
1858 void QGuiApplicationPrivate::reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e)
1859 {
1860     // This operation only makes sense after the QGuiApplication constructor runs
1861     if (QCoreApplication::startingUp())
1862         return;
1863
1864     if (!e->screen)
1865         return;
1866
1867     QScreen *s = e->screen.data();
1868     s->d_func()->logicalDpi = QDpi(e->dpiX, e->dpiY);
1869
1870     emit s->logicalDotsPerInchXChanged(s->logicalDotsPerInchX());
1871     emit s->logicalDotsPerInchYChanged(s->logicalDotsPerInchY());
1872     emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch());
1873 }
1874
1875 void QGuiApplicationPrivate::reportRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e)
1876 {
1877     // This operation only makes sense after the QGuiApplication constructor runs
1878     if (QCoreApplication::startingUp())
1879         return;
1880
1881     if (!e->screen)
1882         return;
1883
1884     QScreen *s = e->screen.data();
1885     s->d_func()->refreshRate = e->rate;
1886
1887     emit s->refreshRateChanged(s->refreshRate());
1888 }
1889
1890 void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e)
1891 {
1892     if (!e->exposed)
1893         return;
1894
1895     QWindow *window = e->exposed.data();
1896     QWindowPrivate *p = qt_window_private(window);
1897
1898     if (!p->receivedExpose) {
1899         if (p->resizeEventPending) {
1900             // as a convenience for plugins, send a resize event before the first expose event if they haven't done so
1901             QSize size = p->geometry.size();
1902             QResizeEvent e(size, size);
1903             QGuiApplication::sendSpontaneousEvent(window, &e);
1904
1905             p->resizeEventPending = false;
1906         }
1907
1908         p->receivedExpose = true;
1909     }
1910
1911     p->exposed = e->isExposed;
1912
1913     QExposeEvent exposeEvent(e->region);
1914     QCoreApplication::sendSpontaneousEvent(window, &exposeEvent);
1915 }
1916
1917 #ifndef QT_NO_DRAGANDDROP
1918
1919 QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
1920 {
1921     static QPointer<QWindow> currentDragWindow;
1922     static Qt::DropAction lastAcceptedDropAction = Qt::IgnoreAction;
1923     QPlatformDrag *platformDrag = platformIntegration()->drag();
1924     if (!platformDrag) {
1925         lastAcceptedDropAction = Qt::IgnoreAction;
1926         return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
1927     }
1928
1929     if (!dropData) {
1930         if (currentDragWindow.data() == w)
1931             currentDragWindow = 0;
1932         QDragLeaveEvent e;
1933         QGuiApplication::sendEvent(w, &e);
1934         lastAcceptedDropAction = Qt::IgnoreAction;
1935         return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
1936     }
1937     QDragMoveEvent me(p, supportedActions, dropData,
1938                       QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1939
1940     if (w != currentDragWindow) {
1941         lastAcceptedDropAction = Qt::IgnoreAction;
1942         if (currentDragWindow) {
1943             QDragLeaveEvent e;
1944             QGuiApplication::sendEvent(currentDragWindow, &e);
1945         }
1946         currentDragWindow = w;
1947         QDragEnterEvent e(p, supportedActions, dropData,
1948                           QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1949         QGuiApplication::sendEvent(w, &e);
1950         if (e.isAccepted() && e.dropAction() != Qt::IgnoreAction)
1951             lastAcceptedDropAction = e.dropAction();
1952     }
1953
1954     // Handling 'DragEnter' should suffice for the application.
1955     if (lastAcceptedDropAction != Qt::IgnoreAction
1956         && (supportedActions & lastAcceptedDropAction)) {
1957         me.setDropAction(lastAcceptedDropAction);
1958         me.accept();
1959     }
1960     QGuiApplication::sendEvent(w, &me);
1961     lastAcceptedDropAction = me.isAccepted() ?
1962                              me.dropAction() :  Qt::IgnoreAction;
1963     return QPlatformDragQtResponse(me.isAccepted(), lastAcceptedDropAction, me.answerRect());
1964 }
1965
1966 QPlatformDropQtResponse QGuiApplicationPrivate::processDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
1967 {
1968     QDropEvent de(p, supportedActions, dropData,
1969                   QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1970     QGuiApplication::sendEvent(w, &de);
1971
1972     Qt::DropAction acceptedAction = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
1973     QPlatformDropQtResponse response(de.isAccepted(),acceptedAction);
1974     return response;
1975 }
1976
1977 #endif // QT_NO_DRAGANDDROP
1978
1979 #ifndef QT_NO_CLIPBOARD
1980 /*!
1981     Returns the object for interacting with the clipboard.
1982 */
1983 QClipboard * QGuiApplication::clipboard()
1984 {
1985     if (QGuiApplicationPrivate::qt_clipboard == 0) {
1986         if (!qApp) {
1987             qWarning("QGuiApplication: Must construct a QGuiApplication before accessing a QClipboard");
1988             return 0;
1989         }
1990         QGuiApplicationPrivate::qt_clipboard = new QClipboard(0);
1991     }
1992     return QGuiApplicationPrivate::qt_clipboard;
1993 }
1994 #endif
1995
1996 /*!
1997     Returns the default application palette.
1998
1999     \sa setPalette()
2000 */
2001
2002 QPalette QGuiApplication::palette()
2003 {
2004     initPalette();
2005     return *QGuiApplicationPrivate::app_pal;
2006 }
2007
2008 /*!
2009     Changes the default application palette to \a palette.
2010
2011     \sa palette()
2012 */
2013 void QGuiApplication::setPalette(const QPalette &pal)
2014 {
2015     if (QGuiApplicationPrivate::app_pal && pal.isCopyOf(*QGuiApplicationPrivate::app_pal))
2016         return;
2017     if (!QGuiApplicationPrivate::app_pal)
2018         QGuiApplicationPrivate::app_pal = new QPalette(pal);
2019     else
2020         *QGuiApplicationPrivate::app_pal = pal;
2021     applicationResourceFlags |= ApplicationPaletteExplicitlySet;
2022 }
2023
2024 /*!
2025     Returns the default application font.
2026
2027     \sa setFont()
2028 */
2029 QFont QGuiApplication::font()
2030 {
2031     QMutexLocker locker(&applicationFontMutex);
2032     initFontUnlocked();
2033     return *QGuiApplicationPrivate::app_font;
2034 }
2035
2036 /*!
2037     Changes the default application font to \a font.
2038
2039     \sa font()
2040 */
2041 void QGuiApplication::setFont(const QFont &font)
2042 {
2043     QMutexLocker locker(&applicationFontMutex);
2044     if (!QGuiApplicationPrivate::app_font)
2045         QGuiApplicationPrivate::app_font = new QFont(font);
2046     else
2047         *QGuiApplicationPrivate::app_font = font;
2048     applicationResourceFlags |= ApplicationFontExplicitlySet;
2049 }
2050
2051 /*!
2052     \fn bool QGuiApplication::isRightToLeft()
2053
2054     Returns true if the application's layout direction is
2055     Qt::RightToLeft; otherwise returns false.
2056
2057     \sa layoutDirection(), isLeftToRight()
2058 */
2059
2060 /*!
2061     \fn bool QGuiApplication::isLeftToRight()
2062
2063     Returns true if the application's layout direction is
2064     Qt::LeftToRight; otherwise returns false.
2065
2066     \sa layoutDirection(), isRightToLeft()
2067 */
2068
2069 void QGuiApplicationPrivate::notifyLayoutDirectionChange()
2070 {
2071 }
2072
2073 void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
2074 {
2075 }
2076
2077
2078 /*!
2079     \property QGuiApplication::quitOnLastWindowClosed
2080
2081     \brief whether the application implicitly quits when the last window is
2082     closed.
2083
2084     The default is true.
2085
2086     If this property is true, the applications quits when the last visible
2087     primary window (i.e. window with no parent) is closed.
2088
2089     \sa quit(), QWindow::close()
2090  */
2091
2092 void QGuiApplication::setQuitOnLastWindowClosed(bool quit)
2093 {
2094     QCoreApplication::setQuitLockEnabled(quit);
2095 }
2096
2097
2098
2099 bool QGuiApplication::quitOnLastWindowClosed()
2100 {
2101     return QCoreApplication::isQuitLockEnabled();
2102 }
2103
2104
2105
2106 void QGuiApplicationPrivate::emitLastWindowClosed()
2107 {
2108     if (qGuiApp && qGuiApp->d_func()->in_exec) {
2109         emit qGuiApp->lastWindowClosed();
2110     }
2111 }
2112
2113 bool QGuiApplicationPrivate::shouldQuit()
2114 {
2115     /* if there is no visible top-level window left, we allow the quit */
2116     QWindowList list = QGuiApplication::topLevelWindows();
2117     for (int i = 0; i < list.size(); ++i) {
2118         QWindow *w = list.at(i);
2119         if (w->isVisible())
2120             return false;
2121     }
2122     return true;
2123 }
2124
2125 /*!
2126     \property QGuiApplication::layoutDirection
2127     \brief the default layout direction for this application
2128
2129     On system start-up, the default layout direction depends on the
2130     application's language.
2131
2132     \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
2133  */
2134
2135 void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
2136 {
2137     if (layout_direction == direction || direction == Qt::LayoutDirectionAuto)
2138         return;
2139
2140     layout_direction = direction;
2141
2142     QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
2143 }
2144
2145 Qt::LayoutDirection QGuiApplication::layoutDirection()
2146 {
2147     return layout_direction;
2148 }
2149
2150 /*!
2151     \fn QCursor *QGuiApplication::overrideCursor()
2152
2153     Returns the active application override cursor.
2154
2155     This function returns 0 if no application cursor has been defined (i.e. the
2156     internal cursor stack is empty).
2157
2158     \sa setOverrideCursor(), restoreOverrideCursor()
2159 */
2160 #ifndef QT_NO_CURSOR
2161 QCursor *QGuiApplication::overrideCursor()
2162 {
2163     return qGuiApp->d_func()->cursor_list.isEmpty() ? 0 : &qGuiApp->d_func()->cursor_list.first();
2164 }
2165
2166 /*!
2167     Changes the currently active application override cursor to \a cursor.
2168
2169     This function has no effect if setOverrideCursor() was not called.
2170
2171     \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
2172     QWidget::setCursor()
2173  */
2174 void QGuiApplication::changeOverrideCursor(const QCursor &cursor)
2175 {
2176     if (qGuiApp->d_func()->cursor_list.isEmpty())
2177         return;
2178     qGuiApp->d_func()->cursor_list.removeFirst();
2179     setOverrideCursor(cursor);
2180 }
2181 #endif
2182
2183
2184 #ifndef QT_NO_CURSOR
2185 static inline void applyCursor(QWindow *w, QCursor c)
2186 {
2187     if (const QScreen *screen = w->screen())
2188         if (QPlatformCursor *cursor = screen->handle()->cursor())
2189             cursor->changeCursor(&c, w);
2190 }
2191
2192 static inline void applyCursor(const QList<QWindow *> &l, const QCursor &c)
2193 {
2194     for (int i = 0; i < l.size(); ++i) {
2195         QWindow *w = l.at(i);
2196         if (w->handle() && w->windowType() != Qt::Desktop)
2197             applyCursor(w, c);
2198     }
2199 }
2200
2201 /*!
2202     \fn void QGuiApplication::setOverrideCursor(const QCursor &cursor)
2203
2204     Sets the application override cursor to \a cursor.
2205
2206     Application override cursors are intended for showing the user that the
2207     application is in a special state, for example during an operation that
2208     might take some time.
2209
2210     This cursor will be displayed in all the application's widgets until
2211     restoreOverrideCursor() or another setOverrideCursor() is called.
2212
2213     Application cursors are stored on an internal stack. setOverrideCursor()
2214     pushes the cursor onto the stack, and restoreOverrideCursor() pops the
2215     active cursor off the stack. changeOverrideCursor() changes the curently
2216     active application override cursor.
2217
2218     Every setOverrideCursor() must eventually be followed by a corresponding
2219     restoreOverrideCursor(), otherwise the stack will never be emptied.
2220
2221     Example:
2222     \snippet code/src_gui_kernel_qapplication_x11.cpp 0
2223
2224     \sa overrideCursor(), restoreOverrideCursor(), changeOverrideCursor(),
2225     QWidget::setCursor()
2226 */
2227 void QGuiApplication::setOverrideCursor(const QCursor &cursor)
2228 {
2229     qGuiApp->d_func()->cursor_list.prepend(cursor);
2230     applyCursor(QGuiApplicationPrivate::window_list, cursor);
2231 }
2232
2233 /*!
2234     \fn void QGuiApplication::restoreOverrideCursor()
2235
2236     Undoes the last setOverrideCursor().
2237
2238     If setOverrideCursor() has been called twice, calling
2239     restoreOverrideCursor() will activate the first cursor set. Calling this
2240     function a second time restores the original widgets' cursors.
2241
2242     \sa setOverrideCursor(), overrideCursor()
2243 */
2244 void QGuiApplication::restoreOverrideCursor()
2245 {
2246     if (qGuiApp->d_func()->cursor_list.isEmpty())
2247         return;
2248     qGuiApp->d_func()->cursor_list.removeFirst();
2249     QCursor c(qGuiApp->d_func()->cursor_list.value(0, QCursor()));
2250     applyCursor(QGuiApplicationPrivate::window_list, c);
2251 }
2252 #endif// QT_NO_CURSOR
2253
2254 /*!
2255   Returns the application's style hints.
2256
2257   The style hints encapsulate a set of platform dependent properties
2258   such as double click intervals, full width selection and others.
2259
2260   The hints can be used to integrate tighter with the underlying platform.
2261
2262   \sa QStyleHints
2263   */
2264 QStyleHints *QGuiApplication::styleHints()
2265 {
2266     if (!qGuiApp->d_func()->styleHints)
2267         qGuiApp->d_func()->styleHints = new QStyleHints();
2268     return qGuiApp->d_func()->styleHints;
2269 }
2270
2271 /*!
2272     Sets whether Qt should use the system's standard colors, fonts, etc., to
2273     \a on. By default, this is true.
2274
2275     This function must be called before creating the QGuiApplication object, like
2276     this:
2277
2278     \snippet code/src_gui_kernel_qapplication.cpp 6
2279
2280     \sa desktopSettingsAware()
2281 */
2282 void QGuiApplication::setDesktopSettingsAware(bool on)
2283 {
2284     QGuiApplicationPrivate::obey_desktop_settings = on;
2285 }
2286
2287 /*!
2288     Returns true if Qt is set to use the system's standard colors, fonts, etc.;
2289     otherwise returns false. The default is true.
2290
2291     \sa setDesktopSettingsAware()
2292 */
2293 bool QGuiApplication::desktopSettingsAware()
2294 {
2295     return QGuiApplicationPrivate::obey_desktop_settings;
2296 }
2297
2298 /*!
2299   returns the input method.
2300
2301   The input method returns properties about the state and position of
2302   the virtual keyboard. It also provides information about the position of the
2303   current focused input element.
2304
2305   \sa QInputPanel
2306   */
2307 QInputMethod *QGuiApplication::inputMethod()
2308 {
2309     if (!qGuiApp->d_func()->inputMethod)
2310         qGuiApp->d_func()->inputMethod = new QInputMethod();
2311     return qGuiApp->d_func()->inputMethod;
2312 }
2313
2314 /*!
2315   \fn QInputPanel *QGuiApplication::inputPanel() const
2316   returns the input panel.
2317
2318   The input panel returns properties about the state and position of
2319   the virtual keyboard. It also provides information about the position of the
2320   current focused input element.
2321
2322   \obsolete
2323
2324   \sa inputMethod()
2325   */
2326
2327 /*!
2328     \fn void QGuiApplication::fontDatabaseChanged()
2329
2330     This signal is emitted when application fonts are loaded or removed.
2331
2332     \sa QFontDatabase::addApplicationFont(),
2333     QFontDatabase::addApplicationFontFromData(),
2334     QFontDatabase::removeAllApplicationFonts(),
2335     QFontDatabase::removeApplicationFont()
2336 */
2337
2338 // These pixmaps approximate the images in the Windows User Interface Guidelines.
2339
2340 // XPM
2341
2342 static const char * const move_xpm[] = {
2343 "11 20 3 1",
2344 ".        c None",
2345 "a        c #FFFFFF",
2346 "X        c #000000", // X11 cursor is traditionally black
2347 "aa.........",
2348 "aXa........",
2349 "aXXa.......",
2350 "aXXXa......",
2351 "aXXXXa.....",
2352 "aXXXXXa....",
2353 "aXXXXXXa...",
2354 "aXXXXXXXa..",
2355 "aXXXXXXXXa.",
2356 "aXXXXXXXXXa",
2357 "aXXXXXXaaaa",
2358 "aXXXaXXa...",
2359 "aXXaaXXa...",
2360 "aXa..aXXa..",
2361 "aa...aXXa..",
2362 "a.....aXXa.",
2363 "......aXXa.",
2364 ".......aXXa",
2365 ".......aXXa",
2366 "........aa."};
2367
2368
2369 /* XPM */
2370 static const char * const copy_xpm[] = {
2371 "24 30 3 1",
2372 ".        c None",
2373 "a        c #000000",
2374 "X        c #FFFFFF",
2375 "XX......................",
2376 "XaX.....................",
2377 "XaaX....................",
2378 "XaaaX...................",
2379 "XaaaaX..................",
2380 "XaaaaaX.................",
2381 "XaaaaaaX................",
2382 "XaaaaaaaX...............",
2383 "XaaaaaaaaX..............",
2384 "XaaaaaaaaaX.............",
2385 "XaaaaaaXXXX.............",
2386 "XaaaXaaX................",
2387 "XaaXXaaX................",
2388 "XaX..XaaX...............",
2389 "XX...XaaX...............",
2390 "X.....XaaX..............",
2391 "......XaaX..............",
2392 ".......XaaX.............",
2393 ".......XaaX.............",
2394 "........XX...aaaaaaaaaaa",
2395 ".............aXXXXXXXXXa",
2396 ".............aXXXXXXXXXa",
2397 ".............aXXXXaXXXXa",
2398 ".............aXXXXaXXXXa",
2399 ".............aXXaaaaaXXa",
2400 ".............aXXXXaXXXXa",
2401 ".............aXXXXaXXXXa",
2402 ".............aXXXXXXXXXa",
2403 ".............aXXXXXXXXXa",
2404 ".............aaaaaaaaaaa"};
2405
2406 /* XPM */
2407 static const char * const link_xpm[] = {
2408 "24 30 3 1",
2409 ".        c None",
2410 "a        c #000000",
2411 "X        c #FFFFFF",
2412 "XX......................",
2413 "XaX.....................",
2414 "XaaX....................",
2415 "XaaaX...................",
2416 "XaaaaX..................",
2417 "XaaaaaX.................",
2418 "XaaaaaaX................",
2419 "XaaaaaaaX...............",
2420 "XaaaaaaaaX..............",
2421 "XaaaaaaaaaX.............",
2422 "XaaaaaaXXXX.............",
2423 "XaaaXaaX................",
2424 "XaaXXaaX................",
2425 "XaX..XaaX...............",
2426 "XX...XaaX...............",
2427 "X.....XaaX..............",
2428 "......XaaX..............",
2429 ".......XaaX.............",
2430 ".......XaaX.............",
2431 "........XX...aaaaaaaaaaa",
2432 ".............aXXXXXXXXXa",
2433 ".............aXXXaaaaXXa",
2434 ".............aXXXXaaaXXa",
2435 ".............aXXXaaaaXXa",
2436 ".............aXXaaaXaXXa",
2437 ".............aXXaaXXXXXa",
2438 ".............aXXaXXXXXXa",
2439 ".............aXXXaXXXXXa",
2440 ".............aXXXXXXXXXa",
2441 ".............aaaaaaaaaaa"};
2442
2443 QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)
2444 {
2445     Q_UNUSED(cshape);
2446     return QPixmap();
2447 }
2448
2449 void QGuiApplicationPrivate::notifyThemeChanged()
2450 {
2451     if (!(applicationResourceFlags & ApplicationPaletteExplicitlySet)) {
2452         clearPalette();
2453         initPalette();
2454     }
2455     if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
2456         QMutexLocker locker(&applicationFontMutex);
2457         clearFontUnlocked();
2458         initFontUnlocked();
2459     }
2460 }
2461
2462 const QDrawHelperGammaTables *QGuiApplicationPrivate::gammaTables()
2463 {
2464     QDrawHelperGammaTables *result = m_gammaTables.load();
2465     if (!result){
2466         QDrawHelperGammaTables *tables = new QDrawHelperGammaTables(fontSmoothingGamma);
2467         if (!m_gammaTables.testAndSetRelease(0, tables))
2468             delete tables;
2469         result = m_gammaTables.load();
2470     }
2471     return result;
2472 }
2473
2474 void QGuiApplicationPrivate::q_updateFocusObject(QObject *object)
2475 {
2476     Q_Q(QGuiApplication);
2477
2478     bool enabled = false;
2479     if (object) {
2480         QInputMethodQueryEvent query(Qt::ImEnabled);
2481         QGuiApplication::sendEvent(object, &query);
2482         enabled = query.value(Qt::ImEnabled).toBool();
2483     }
2484
2485     QPlatformInputContextPrivate::setInputMethodAccepted(enabled);
2486     QPlatformInputContext *inputContext = platformIntegration()->inputContext();
2487     if (inputContext)
2488         inputContext->setFocusObject(object);
2489     emit q->focusObjectChanged(object);
2490 }
2491
2492 int QGuiApplicationPrivate::mouseEventCaps(QMouseEvent *event)
2493 {
2494     return event->caps;
2495 }
2496
2497 QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event)
2498 {
2499     return event->velocity;
2500 }
2501
2502 void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity)
2503 {
2504     event->caps = caps;
2505     event->velocity = velocity;
2506 }
2507
2508 void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, QMouseEvent *other)
2509 {
2510     event->caps = other->caps;
2511     event->velocity = other->velocity;
2512 }
2513
2514
2515 #include "moc_qguiapplication.cpp"
2516
2517 QT_END_NAMESPACE