pick up the target window for a mouse event when none is specified
[profile/ivi/qtbase.git] / src / gui / kernel / qguiapplication.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qguiapplication.h"
43
44 #include "private/qguiapplication_p.h"
45 #include "private/qplatformintegrationfactory_qpa_p.h"
46 #include "private/qevent_p.h"
47 #include "qfont.h"
48 #include "qplatformfontdatabase_qpa.h"
49
50 #include <QtCore/QAbstractEventDispatcher>
51 #include <QtCore/private/qcoreapplication_p.h>
52 #include <QtCore/private/qabstracteventdispatcher_p.h>
53 #include <QtCore/qmutex.h>
54 #include <QtCore/private/qthread_p.h>
55 #include <QtDebug>
56 #include <qpalette.h>
57 #include <qscreen.h>
58
59 #include <QtGui/QPlatformIntegration>
60 #include <QtGui/QGenericPluginFactory>
61
62 #include <QWindowSystemInterface>
63 #include "private/qwindowsysteminterface_qpa_p.h"
64 #include "private/qwindow_p.h"
65 #include "private/qkeymapper_p.h"
66 #include "private/qcursor_p.h"
67 #include "private/qdnd_p.h"
68 #ifndef QT_NO_CURSOR
69 #include "qplatformcursor_qpa.h"
70 #endif
71
72 #include <QtGui/QPixmap>
73
74 #ifndef QT_NO_CLIPBOARD
75 #include <QtGui/QClipboard>
76 #endif
77
78 QT_BEGIN_NAMESPACE
79
80 Q_GUI_EXPORT bool qt_is_gui_used = true;
81
82 Qt::MouseButtons QGuiApplicationPrivate::mouse_buttons = Qt::NoButton;
83 Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
84
85 int QGuiApplicationPrivate::keyboard_input_time = 400;
86 int QGuiApplicationPrivate::mouse_double_click_time = 400;
87 QPointF QGuiApplicationPrivate::lastCursorPosition(0.0, 0.0);
88
89 QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
90
91 bool QGuiApplicationPrivate::app_do_modal = false;
92
93 QPalette *QGuiApplicationPrivate::app_pal = 0;        // default application palette
94
95 Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton;
96 ulong QGuiApplicationPrivate::mousePressTime = 0;
97 Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton;
98 int QGuiApplicationPrivate::mousePressX = 0;
99 int QGuiApplicationPrivate::mousePressY = 0;
100 int QGuiApplicationPrivate::mouse_double_click_distance = 5;
101
102 bool QGuiApplicationPrivate::quitOnLastWindowClosed = true;
103
104 static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
105 static bool force_reverse = false;
106
107 QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
108
109 #ifndef QT_NO_CLIPBOARD
110 QClipboard *QGuiApplicationPrivate::qt_clipboard = 0;
111 #endif
112
113 QList<QScreen *> QGuiApplicationPrivate::screen_list;
114
115 QWindowList QGuiApplicationPrivate::window_list;
116 QWindow *QGuiApplicationPrivate::active_window = 0;
117
118 Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
119 QFont *QGuiApplicationPrivate::app_font = 0;
120
121 extern int qRegisterGuiVariant();
122 extern int qUnregisterGuiVariant();
123 extern void qInitDrawhelperAsm();
124 extern void qInitImageConversions();
125
126 static bool qt_detectRTLLanguage()
127 {
128     return force_reverse ^
129         (QCoreApplication::tr("QT_LAYOUT_DIRECTION",
130                          "Translate this string to the string 'LTR' in left-to-right"
131                          " languages or to 'RTL' in right-to-left languages (such as Hebrew"
132                          " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
133 }
134
135
136 QGuiApplication::QGuiApplication(int &argc, char **argv, int flags)
137     : QCoreApplication(*new QGuiApplicationPrivate(argc, argv, flags))
138 {
139     d_func()->init();
140
141     QCoreApplicationPrivate::eventDispatcher->startingUp();
142 }
143
144 QGuiApplication::QGuiApplication(QGuiApplicationPrivate &p)
145     : QCoreApplication(p)
146 {
147     d_func()->init();
148 }
149
150 QGuiApplication::~QGuiApplication()
151 {
152     Q_D(QGuiApplication);
153     // flush clipboard contents
154     if (QGuiApplicationPrivate::qt_clipboard) {
155         QEvent event(QEvent::Clipboard);
156         QGuiApplication::sendEvent(QGuiApplicationPrivate::qt_clipboard, &event);
157     }
158
159     d->eventDispatcher->closingDown();
160     d->eventDispatcher = 0;
161
162     delete QGuiApplicationPrivate::qt_clipboard;
163     QGuiApplicationPrivate::qt_clipboard = 0;
164
165     delete QGuiApplicationPrivate::app_pal;
166     QGuiApplicationPrivate::app_pal = 0;
167
168     qUnregisterGuiVariant();
169
170 #ifndef QT_NO_CURSOR
171     d->cursor_list.clear();
172 #endif
173 }
174
175 QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags)
176     : QCoreApplicationPrivate(argc, argv, flags)
177 {
178     self = this;
179 }
180
181 QWindow *QGuiApplication::activeWindow()
182 {
183     return QGuiApplicationPrivate::active_window;
184 }
185
186 QWindowList QGuiApplication::topLevelWindows()
187 {
188     return QGuiApplicationPrivate::window_list;
189 }
190
191 QScreen *QGuiApplication::primaryScreen()
192 {
193     if (QGuiApplicationPrivate::screen_list.isEmpty())
194         return 0;
195     return QGuiApplicationPrivate::screen_list.at(0);
196 }
197
198 QList<QScreen *> QGuiApplication::screens()
199 {
200     return QGuiApplicationPrivate::screen_list;
201 }
202
203 QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
204 {
205     QList<QScreen *> screens = QGuiApplication::screens();
206     QList<QScreen *>::const_iterator screen = screens.constBegin();
207     QList<QScreen *>::const_iterator end = screens.constEnd();
208
209     while (screen != end) {
210         if ((*screen)->geometry().contains(pos))
211             return (*screen)->handle()->topLevelAt(pos);
212         ++screen;
213     }
214     return 0;
215 }
216
217
218 static void init_platform(QString name, const QString &platformPluginPath)
219 {
220     if (name.isEmpty()) {
221         const QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
222 #if defined(Q_OS_MAC)
223         const QString defaultPlatform = QLatin1String("cocoa");
224 #elif defined (Q_OS_WIN)
225         const QString defaultPlatform = QLatin1String("windows");
226 #else
227         const QString defaultPlatform = QLatin1String("xcb");
228 #endif
229         if (keys.contains(defaultPlatform)) {
230             qWarning("No platform plugin argument was specified, defaulting to \"%s\".",
231                      qPrintable(defaultPlatform));
232             name = defaultPlatform;
233         } else {
234             qFatal("No platform plugin argument was specified and the default plugin \"%s\" is not available",
235                    qPrintable(defaultPlatform));
236         }
237     }
238
239     QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, platformPluginPath);
240     if (!QGuiApplicationPrivate::platform_integration) {
241         QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
242         QString fatalMessage =
243             QString::fromLatin1("Failed to load platform plugin \"%1\". Available platforms are: \n").arg(name);
244         foreach(const QString &key, keys) {
245             fatalMessage.append(key + QLatin1Char('\n'));
246         }
247         qFatal("%s", fatalMessage.toLocal8Bit().constData());
248     }
249 }
250
251 static void init_plugins(const QList<QByteArray> &pluginList)
252 {
253     for (int i = 0; i < pluginList.count(); ++i) {
254         QByteArray pluginSpec = pluginList.at(i);
255         qDebug() << "init_plugins" << i << pluginSpec;
256         int colonPos = pluginSpec.indexOf(':');
257         QObject *plugin;
258         if (colonPos < 0)
259             plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec), QString());
260         else
261             plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)),
262                                                    QLatin1String(pluginSpec.mid(colonPos+1)));
263         qDebug() << "   created" << plugin;
264     }
265 }
266
267 void QGuiApplicationPrivate::createPlatformIntegration()
268 {
269     Q_Q(QGuiApplication);
270
271     // Use the Qt menus by default. Platform plugins that
272     // want to enable a native menu implementation can clear
273     // this flag.
274     q->setAttribute(Qt::AA_DontUseNativeMenuBar, true);
275
276     // Load the platform integration
277     QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
278     QByteArray platformName;
279 #ifdef QT_QPA_DEFAULT_PLATFORM_NAME
280     platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
281 #endif
282     QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
283     if (!platformNameEnv.isEmpty()) {
284         platformName = platformNameEnv;
285     }
286
287     // Get command line params
288
289     int j = argc ? 1 : 0;
290     for (int i=1; i<argc; i++) {
291         if (argv[i] && *argv[i] != '-') {
292             argv[j++] = argv[i];
293             continue;
294         }
295         QByteArray arg = argv[i];
296         if (arg == "-platformpluginpath") {
297             if (++i < argc)
298                 platformPluginPath = QLatin1String(argv[i]);
299         } else if (arg == "-platform") {
300             if (++i < argc)
301                 platformName = argv[i];
302         } else {
303             argv[j++] = argv[i];
304         }
305     }
306
307     if (j < argc) {
308         argv[j] = 0;
309         argc = j;
310     }
311
312     init_platform(QLatin1String(platformName), platformPluginPath);
313
314 }
315
316 void QGuiApplicationPrivate::createEventDispatcher()
317 {
318     if (platform_integration == 0)
319         createPlatformIntegration();
320
321     if (!eventDispatcher) {
322         QAbstractEventDispatcher *eventDispatcher = platform_integration->guiThreadEventDispatcher();
323         setEventDispatcher(eventDispatcher);
324     }
325 }
326
327 void QGuiApplicationPrivate::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
328 {
329     Q_Q(QGuiApplication);
330
331     if (!QCoreApplicationPrivate::eventDispatcher) {
332         QCoreApplicationPrivate::eventDispatcher = eventDispatcher;
333         QCoreApplicationPrivate::eventDispatcher->setParent(q);
334         threadData->eventDispatcher = eventDispatcher;
335     }
336
337 }
338
339 void QGuiApplicationPrivate::init()
340 {
341     QList<QByteArray> pluginList;
342     // Get command line params
343
344     int j = argc ? 1 : 0;
345     for (int i=1; i<argc; i++) {
346         if (argv[i] && *argv[i] != '-') {
347             argv[j++] = argv[i];
348             continue;
349         }
350         QByteArray arg = argv[i];
351         if (arg == "-plugin") {
352             if (++i < argc)
353                 pluginList << argv[i];
354         } else if (arg == "-reverse") {
355             force_reverse = true;
356             QGuiApplication::setLayoutDirection(Qt::RightToLeft);
357         } else {
358             argv[j++] = argv[i];
359         }
360     }
361
362     if (j < argc) {
363         argv[j] = 0;
364         argc = j;
365     }
366
367     if (platform_integration == 0)
368         createPlatformIntegration();
369
370     init_plugins(pluginList);
371
372     // Set up which span functions should be used in raster engine...
373     qInitDrawhelperAsm();
374     // and QImage conversion functions
375     qInitImageConversions();
376
377     QFont::initialize();
378
379 #ifndef QT_NO_CURSOR
380     QCursorData::initialize();
381 #endif
382
383     // trigger registering of QVariant's GUI types
384     qRegisterGuiVariant();
385
386     is_app_running = true;
387 }
388
389 QGuiApplicationPrivate::~QGuiApplicationPrivate()
390 {
391     is_app_closing = true;
392     is_app_running = false;
393
394     QFont::cleanup();
395
396 #ifndef QT_NO_CURSOR
397     QCursorData::cleanup();
398 #endif
399
400     layout_direction = Qt::LeftToRight;
401
402     cleanupThreadData();
403
404     delete platform_integration;
405     platform_integration = 0;
406 }
407
408 #if 0
409 #ifndef QT_NO_CURSOR
410 QCursor *overrideCursor();
411 void setOverrideCursor(const QCursor &);
412 void changeOverrideCursor(const QCursor &);
413 void restoreOverrideCursor();
414 #endif
415
416 static QFont font();
417 static QFont font(const QWidget*);
418 static QFont font(const char *className);
419 static void setFont(const QFont &, const char* className = 0);
420 static QFontMetrics fontMetrics();
421
422 #ifndef QT_NO_CLIPBOARD
423 static QClipboard *clipboard();
424 #endif
425 #endif
426
427 Qt::KeyboardModifiers QGuiApplication::keyboardModifiers()
428 {
429     return QGuiApplicationPrivate::modifier_buttons;
430 }
431
432 Qt::MouseButtons QGuiApplication::mouseButtons()
433 {
434     return QGuiApplicationPrivate::mouse_buttons;
435 }
436
437 void QGuiApplication::setDoubleClickInterval(int ms)
438 {
439     QGuiApplicationPrivate::mouse_double_click_time = ms;
440 }
441
442 int QGuiApplication::doubleClickInterval()
443 {
444     return QGuiApplicationPrivate::mouse_double_click_time;
445 }
446
447 void QGuiApplication::setKeyboardInputInterval(int ms)
448 {
449     QGuiApplicationPrivate::keyboard_input_time = ms;
450 }
451
452 int QGuiApplication::keyboardInputInterval()
453 {
454     return QGuiApplicationPrivate::keyboard_input_time;
455 }
456
457 QPlatformNativeInterface *QGuiApplication::platformNativeInterface()
458 {
459     QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
460     return pi->nativeInterface();
461 }
462
463 int QGuiApplication::exec()
464 {
465     return QCoreApplication::exec();
466 }
467
468 bool QGuiApplication::notify(QObject *object, QEvent *event)
469 {
470     return QCoreApplication::notify(object, event);
471 }
472
473 bool QGuiApplication::event(QEvent *e)
474 {
475     if(e->type() == QEvent::LanguageChange) {
476         setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
477     }
478     return QCoreApplication::event(e);
479 }
480
481 bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
482 {
483     return QCoreApplication::compressEvent(event, receiver, postedEvents);
484 }
485
486 void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
487 {
488     switch(e->type) {
489     case QWindowSystemInterfacePrivate::Mouse:
490         QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
491         break;
492     case QWindowSystemInterfacePrivate::Wheel:
493         QGuiApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterfacePrivate::WheelEvent *>(e));
494         break;
495     case QWindowSystemInterfacePrivate::Key:
496         QGuiApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e));
497         break;
498     case QWindowSystemInterfacePrivate::Touch:
499         QGuiApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterfacePrivate::TouchEvent *>(e));
500         break;
501     case QWindowSystemInterfacePrivate::GeometryChange:
502         QGuiApplicationPrivate::processGeometryChangeEvent(static_cast<QWindowSystemInterfacePrivate::GeometryChangeEvent*>(e));
503         break;
504     case QWindowSystemInterfacePrivate::Enter:
505         QGuiApplicationPrivate::processEnterEvent(static_cast<QWindowSystemInterfacePrivate::EnterEvent *>(e));
506         break;
507     case QWindowSystemInterfacePrivate::Leave:
508         QGuiApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
509         break;
510     case QWindowSystemInterfacePrivate::ActivatedWindow:
511         QGuiApplicationPrivate::processActivatedEvent(static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>(e));
512         break;
513     case QWindowSystemInterfacePrivate::WindowStateChanged:
514         QGuiApplicationPrivate::processWindowStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowStateChangedEvent *>(e));
515         break;
516     case QWindowSystemInterfacePrivate::Close:
517         QGuiApplicationPrivate::processCloseEvent(
518                 static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e));
519         break;
520     case QWindowSystemInterfacePrivate::ScreenCountChange:
521         QGuiApplicationPrivate::reportScreenCount(
522                 static_cast<QWindowSystemInterfacePrivate::ScreenCountEvent *>(e));
523         break;
524     case QWindowSystemInterfacePrivate::ScreenGeometry:
525         QGuiApplicationPrivate::reportGeometryChange(
526                 static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
527         break;
528     case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
529         QGuiApplicationPrivate::reportAvailableGeometryChange(
530                 static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
531         break;
532     case QWindowSystemInterfacePrivate::Map:
533         QGuiApplicationPrivate::processMapEvent(static_cast<QWindowSystemInterfacePrivate::MapEvent *>(e));
534         break;
535     case QWindowSystemInterfacePrivate::Unmap:
536         QGuiApplicationPrivate::processUnmapEvent(static_cast<QWindowSystemInterfacePrivate::UnmapEvent *>(e));
537         break;
538     case QWindowSystemInterfacePrivate::Expose:
539         QGuiApplicationPrivate::processExposeEvent(static_cast<QWindowSystemInterfacePrivate::ExposeEvent *>(e));
540         break;
541     default:
542         qWarning() << "Unknown user input event type:" << e->type;
543         break;
544     }
545 }
546
547 void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
548 {
549     QEvent::Type type;
550     // move first
551     Qt::MouseButtons stateChange = e->buttons ^ buttons;
552     if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
553         QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
554                 new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
555         QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
556         stateChange = Qt::NoButton;
557     }
558
559     QWindow *window = e->window.data();
560
561     if (!window)
562         window = QGuiApplication::topLevelAt(e->globalPos.toPoint());
563
564     QPointF localPoint = e->localPos;
565     QPointF globalPoint = e->globalPos;
566
567     Qt::MouseButton button = Qt::NoButton;
568
569     if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) {
570         type = QEvent::MouseMove;
571         QGuiApplicationPrivate::lastCursorPosition = globalPoint;
572         if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
573             qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
574             mousePressButton = Qt::NoButton;
575     }
576     else { // check to see if a new button has been pressed/released
577         for (int check = Qt::LeftButton;
578              check <= Qt::XButton2;
579              check = check << 1) {
580             if (check & stateChange) {
581                 button = Qt::MouseButton(check);
582                 break;
583             }
584         }
585         if (button == Qt::NoButton) {
586             // Ignore mouse events that don't change the current state
587             return;
588         }
589         buttons = e->buttons;
590         if (button & e->buttons) {
591             if ((e->timestamp - mousePressTime) < static_cast<ulong>(QGuiApplication::doubleClickInterval()) && button == mousePressButton) {
592                 type = QEvent::MouseButtonDblClick;
593                 mousePressButton = Qt::NoButton;
594             }
595             else {
596                 type = QEvent::MouseButtonPress;
597                 mousePressTime = e->timestamp;
598                 mousePressButton = button;
599                 const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint();
600                 mousePressX = point.x();
601                 mousePressY = point.y();
602             }
603         }
604         else
605             type = QEvent::MouseButtonRelease;
606     }
607
608
609     if (window) {
610         QMouseEvent ev(type, localPoint, globalPoint, button, buttons, QGuiApplication::keyboardModifiers());
611 #ifndef QT_NO_CURSOR
612         QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
613         for (int i = 0; i < cursors.count(); ++i)
614             if (cursors.at(i))
615                 cursors.at(i).data()->pointerEvent(ev);
616 #endif
617         QGuiApplication::sendSpontaneousEvent(window, &ev);
618         return;
619     }
620 }
621
622
623 //### there's a lot of duplicated logic here -- refactoring required!
624
625 void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
626 {
627     if (!e->window)
628         return;
629
630     QPointF globalPoint = e->globalPos;
631     QGuiApplicationPrivate::lastCursorPosition = globalPoint;
632
633     QWindow *window = e->window.data();
634
635     if (window) {
636          QWheelEvent ev(e->localPos, e->globalPos, e->delta, buttons, QGuiApplication::keyboardModifiers(),
637                         e->orient);
638          QGuiApplication::sendSpontaneousEvent(window, &ev);
639          return;
640      }
641 }
642
643
644
645 // Remember, Qt convention is:  keyboard state is state *before*
646
647 void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
648 {
649     QWindow *window = e->window.data();
650     if (!window)
651         return;
652
653     QObject *target = window;
654
655     if (e->nativeScanCode || e->nativeVirtualKey || e->nativeModifiers) {
656         QKeyEventEx ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount,
657                        e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers);
658         QGuiApplication::sendSpontaneousEvent(target, &ev);
659     } else {
660         QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
661         QGuiApplication::sendSpontaneousEvent(target, &ev);
662     }
663 }
664
665 void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
666 {
667     if (!e->enter)
668         return;
669
670     QEvent event(QEvent::Enter);
671     QCoreApplication::sendSpontaneousEvent(e->enter.data(), &event);
672 }
673
674 void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
675 {
676     if (!e->leave)
677         return;
678
679     QEvent event(QEvent::Leave);
680     QCoreApplication::sendSpontaneousEvent(e->leave.data(), &event);
681 }
682
683 void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
684 {
685     if (!e->activated)
686         return;
687
688     QWindow *previous = QGuiApplicationPrivate::active_window;
689     QGuiApplicationPrivate::active_window = e->activated.data();
690     if (self)
691         self->notifyActiveWindowChange(previous);
692 }
693
694 void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
695 {
696     if (QWindow *window  = wse->window.data()) {
697         QWindowStateChangeEvent e(window->windowState());
698         window->d_func()->windowState = wse->newState;
699         QGuiApplication::sendSpontaneousEvent(window, &e);
700     }
701 }
702
703 void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
704 {
705     if (e->tlw.isNull())
706        return;
707
708     QWindow *window = e->tlw.data();
709     if (!window)
710         return;
711
712     QRect newRect = e->newGeometry;
713     QRect cr = window->geometry();
714
715     bool isResize = cr.size() != newRect.size();
716     bool isMove = cr.topLeft() != newRect.topLeft();
717
718     window->d_func()->geometry = newRect;
719
720     if (isResize) {
721         QResizeEvent e(newRect.size(), cr.size());
722         QGuiApplication::sendSpontaneousEvent(window, &e);
723     }
724
725     if (isMove) {
726         //### frame geometry
727         QMoveEvent e(newRect.topLeft(), cr.topLeft());
728         QGuiApplication::sendSpontaneousEvent(window, &e);
729     }
730 }
731
732 void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
733 {
734     if (e->window.isNull())
735         return;
736
737     QCloseEvent event;
738     QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
739 }
740
741 void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *)
742 {
743 //    translateRawTouchEvent(e->widget.data(), e->devType, e->points);
744 }
745
746 void QGuiApplicationPrivate::reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *)
747 {
748     // This operation only makes sense after the QGuiApplication constructor runs
749     if (QCoreApplication::startingUp())
750         return;
751
752     //QGuiApplication::desktop()->d_func()->updateScreenList();
753     // signal anything listening for creation or deletion of screens
754     //QDesktopWidget *desktop = QGuiApplication::desktop();
755     //emit desktop->screenCountChanged(e->count);
756 }
757
758 void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *)
759 {
760     // This operation only makes sense after the QGuiApplication constructor runs
761     if (QCoreApplication::startingUp())
762         return;
763 }
764
765 void QGuiApplicationPrivate::reportAvailableGeometryChange(
766         QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *)
767 {
768     // This operation only makes sense after the QGuiApplication constructor runs
769     if (QCoreApplication::startingUp())
770         return;
771 }
772
773 void QGuiApplicationPrivate::processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e)
774 {
775     if (!e->mapped)
776         return;
777
778     QEvent event(QEvent::Map);
779     QCoreApplication::sendSpontaneousEvent(e->mapped.data(), &event);
780 }
781
782 void QGuiApplicationPrivate::processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e)
783 {
784     if (!e->unmapped)
785         return;
786
787     QEvent event(QEvent::Unmap);
788     QCoreApplication::sendSpontaneousEvent(e->unmapped.data(), &event);
789 }
790
791 void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e)
792 {
793     if (!e->exposed)
794         return;
795
796     QExposeEvent event(e->region);
797     QCoreApplication::sendSpontaneousEvent(e->exposed.data(), &event);
798 }
799
800 Qt::DropAction QGuiApplicationPrivate::processDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
801 {
802     static QPointer<QWindow> currentDragWindow;
803     QDragManager *manager = QDragManager::self();
804     if (!dropData) {
805         if (currentDragWindow.data() == w)
806             currentDragWindow = 0;
807         QDragLeaveEvent e;
808         QGuiApplication::sendEvent(w, &e);
809         manager->global_accepted_action = Qt::IgnoreAction;
810         return Qt::IgnoreAction;
811     }
812     QDragMoveEvent me(p, manager->possible_actions, dropData,
813                       QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
814     if (w != currentDragWindow) {
815         if (currentDragWindow) {
816             QDragLeaveEvent e;
817             QGuiApplication::sendEvent(currentDragWindow, &e);
818             manager->global_accepted_action = Qt::IgnoreAction;
819         }
820         currentDragWindow = w;
821         QDragEnterEvent e(p, manager->possible_actions, dropData,
822                           QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
823         QGuiApplication::sendEvent(w, &e);
824         manager->global_accepted_action = e.isAccepted() ? e.dropAction() : Qt::IgnoreAction;
825         if (manager->global_accepted_action != Qt::IgnoreAction) {
826             me.setDropAction(manager->global_accepted_action);
827             me.accept();
828         }
829     }
830     QGuiApplication::sendEvent(w, &me);
831     manager->global_accepted_action = me.isAccepted() ? me.dropAction() : Qt::IgnoreAction;
832     return manager->global_accepted_action;
833 }
834
835 Qt::DropAction QGuiApplicationPrivate::processDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
836 {
837     QDragManager *manager = QDragManager::self();
838     QDropEvent de(p, manager->possible_actions, dropData,
839                   QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
840     QGuiApplication::sendEvent(w, &de);
841     manager->global_accepted_action = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
842     return manager->global_accepted_action;
843 }
844
845 #ifndef QT_NO_CLIPBOARD
846 QClipboard * QGuiApplication::clipboard()
847 {
848     if (QGuiApplicationPrivate::qt_clipboard == 0) {
849         if (!qApp) {
850             qWarning("QGuiApplication: Must construct a QGuiApplication before accessing a QClipboard");
851             return 0;
852         }
853         QGuiApplicationPrivate::qt_clipboard = new QClipboard(0);
854     }
855     return QGuiApplicationPrivate::qt_clipboard;
856 }
857 #endif
858
859 /*!
860     Returns the application palette.
861
862     \sa setPalette(), QWidget::palette()
863 */
864 QPalette QGuiApplication::palette()
865 {
866     if (!QGuiApplicationPrivate::app_pal)
867         QGuiApplicationPrivate::app_pal = new QPalette(Qt::black);
868     return *QGuiApplicationPrivate::app_pal;
869 }
870
871 QFont QGuiApplication::font()
872 {
873     QMutexLocker locker(applicationFontMutex());
874     if (!QGuiApplicationPrivate::app_font)
875         QGuiApplicationPrivate::app_font =
876             new QFont(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFont());
877     return *QGuiApplicationPrivate::app_font;
878 }
879
880 void QGuiApplication::setFont(const QFont &font)
881 {
882     QMutexLocker locker(applicationFontMutex());
883     if (!QGuiApplicationPrivate::app_font)
884         QGuiApplicationPrivate::app_font = new QFont(font);
885     else
886         *QGuiApplicationPrivate::app_font = font;
887 }
888
889 /*!
890     \fn bool QGuiApplication::isRightToLeft()
891
892     Returns true if the application's layout direction is
893     Qt::RightToLeft; otherwise returns false.
894
895     \sa layoutDirection(), isLeftToRight()
896 */
897
898 /*!
899     \fn bool QGuiApplication::isLeftToRight()
900
901     Returns true if the application's layout direction is
902     Qt::LeftToRight; otherwise returns false.
903
904     \sa layoutDirection(), isRightToLeft()
905 */
906
907 void QGuiApplicationPrivate::notifyLayoutDirectionChange()
908 {
909 }
910
911 void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
912 {
913 }
914
915
916 /*!
917     \property QGuiApplication::quitOnLastWindowClosed
918
919     \brief whether the application implicitly quits when the last window is
920     closed.
921
922     The default is true.
923
924     If this property is true, the applications quits when the last visible
925     primary window (i.e. window with no parent) is closed.
926
927     \sa quit(), QWindow::close()
928  */
929
930 void QGuiApplication::setQuitOnLastWindowClosed(bool quit)
931 {
932     QGuiApplicationPrivate::quitOnLastWindowClosed = quit;
933 }
934
935
936
937 bool QGuiApplication::quitOnLastWindowClosed()
938 {
939     return QGuiApplicationPrivate::quitOnLastWindowClosed;
940 }
941
942
943
944 void QGuiApplicationPrivate::emitLastWindowClosed()
945 {
946     if (qGuiApp && qGuiApp->d_func()->in_exec) {
947         if (QGuiApplicationPrivate::quitOnLastWindowClosed) {
948             // get ready to quit, this event might be removed if the
949             // event loop is re-entered, however
950             QGuiApplication::postEvent(qApp, new QEvent(QEvent::Quit));
951         }
952         emit qGuiApp->lastWindowClosed();
953     }
954 }
955
956
957 /*!
958     \property QGuiApplication::layoutDirection
959     \brief the default layout direction for this application
960
961     On system start-up, the default layout direction depends on the
962     application's language.
963
964     \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
965  */
966
967 void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
968 {
969     if (layout_direction == direction || direction == Qt::LayoutDirectionAuto)
970         return;
971
972     layout_direction = direction;
973
974     QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
975 }
976
977 Qt::LayoutDirection QGuiApplication::layoutDirection()
978 {
979     return layout_direction;
980 }
981
982 /*!
983     \fn QCursor *QGuiApplication::overrideCursor()
984
985     Returns the active application override cursor.
986
987     This function returns 0 if no application cursor has been defined (i.e. the
988     internal cursor stack is empty).
989
990     \sa setOverrideCursor(), restoreOverrideCursor()
991 */
992 #ifndef QT_NO_CURSOR
993 QCursor *QGuiApplication::overrideCursor()
994 {
995     return qGuiApp->d_func()->cursor_list.isEmpty() ? 0 : &qGuiApp->d_func()->cursor_list.first();
996 }
997
998 /*!
999     Changes the currently active application override cursor to \a cursor.
1000
1001     This function has no effect if setOverrideCursor() was not called.
1002
1003     \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
1004     QWidget::setCursor()
1005  */
1006 void QGuiApplication::changeOverrideCursor(const QCursor &cursor)
1007 {
1008     if (qGuiApp->d_func()->cursor_list.isEmpty())
1009         return;
1010     qGuiApp->d_func()->cursor_list.removeFirst();
1011     setOverrideCursor(cursor);
1012 }
1013 #endif
1014
1015 /*!
1016     \fn void QGuiApplication::setOverrideCursor(const QCursor &cursor, bool replace)
1017
1018     Use changeOverrideCursor(\a cursor) (if \a replace is true) or
1019     setOverrideCursor(\a cursor) (if \a replace is false).
1020 */
1021
1022 #ifndef QT_NO_CURSOR
1023 void QGuiApplication::setOverrideCursor(const QCursor &cursor)
1024 {
1025     qGuiApp->d_func()->cursor_list.prepend(cursor);
1026 }
1027
1028 void QGuiApplication::restoreOverrideCursor()
1029 {
1030     if (qGuiApp->d_func()->cursor_list.isEmpty())
1031         return;
1032     qGuiApp->d_func()->cursor_list.removeFirst();
1033 }
1034 #endif// QT_NO_CURSOR
1035
1036
1037 // Returns the current platform used by keyBindings
1038 uint QGuiApplicationPrivate::currentKeyPlatform()
1039 {
1040     uint platform = KB_Win;
1041 #ifdef Q_WS_MAC
1042     platform = KB_Mac;
1043 #elif defined Q_WS_X11
1044     platform = KB_X11;
1045     // ## TODO: detect these
1046 #if 0
1047     if (X11->desktopEnvironment == DE_KDE)
1048         platform |= KB_KDE;
1049     if (X11->desktopEnvironment == DE_GNOME)
1050         platform |= KB_Gnome;
1051     if (X11->desktopEnvironment == DE_CDE)
1052         platform |= KB_CDE;
1053 #endif
1054 #endif
1055     return platform;
1056 }
1057
1058 /*!
1059     \since 4.2
1060
1061     Returns the current keyboard input locale.
1062 */
1063 QLocale QGuiApplication::keyboardInputLocale()
1064 {
1065     if (!QGuiApplicationPrivate::checkInstance("keyboardInputLocale"))
1066         return QLocale::c();
1067     return qt_keymapper_private()->keyboardInputLocale;
1068 }
1069
1070 /*!
1071     \since 4.2
1072
1073     Returns the current keyboard input direction.
1074 */
1075 Qt::LayoutDirection QGuiApplication::keyboardInputDirection()
1076 {
1077     if (!QGuiApplicationPrivate::checkInstance("keyboardInputDirection"))
1078         return Qt::LeftToRight;
1079     return qt_keymapper_private()->keyboardInputDirection;
1080 }
1081
1082 /*!
1083     \since 4.5
1084     \fn void QGuiApplication::fontDatabaseChanged()
1085
1086     This signal is emitted when application fonts are loaded or removed.
1087
1088     \sa QFontDatabase::addApplicationFont(),
1089     QFontDatabase::addApplicationFontFromData(),
1090     QFontDatabase::removeAllApplicationFonts(),
1091     QFontDatabase::removeApplicationFont()
1092 */
1093
1094 // These pixmaps approximate the images in the Windows User Interface Guidelines.
1095
1096 // XPM
1097
1098 static const char * const move_xpm[] = {
1099 "11 20 3 1",
1100 ".        c None",
1101 #if defined(Q_WS_WIN)
1102 "a        c #000000",
1103 "X        c #FFFFFF", // Windows cursor is traditionally white
1104 #else
1105 "a        c #FFFFFF",
1106 "X        c #000000", // X11 cursor is traditionally black
1107 #endif
1108 "aa.........",
1109 "aXa........",
1110 "aXXa.......",
1111 "aXXXa......",
1112 "aXXXXa.....",
1113 "aXXXXXa....",
1114 "aXXXXXXa...",
1115 "aXXXXXXXa..",
1116 "aXXXXXXXXa.",
1117 "aXXXXXXXXXa",
1118 "aXXXXXXaaaa",
1119 "aXXXaXXa...",
1120 "aXXaaXXa...",
1121 "aXa..aXXa..",
1122 "aa...aXXa..",
1123 "a.....aXXa.",
1124 "......aXXa.",
1125 ".......aXXa",
1126 ".......aXXa",
1127 "........aa."};
1128
1129 #ifdef Q_WS_WIN
1130 /* XPM */
1131 static const char * const ignore_xpm[] = {
1132 "24 30 3 1",
1133 ".        c None",
1134 "a        c #000000",
1135 "X        c #FFFFFF",
1136 "aa......................",
1137 "aXa.....................",
1138 "aXXa....................",
1139 "aXXXa...................",
1140 "aXXXXa..................",
1141 "aXXXXXa.................",
1142 "aXXXXXXa................",
1143 "aXXXXXXXa...............",
1144 "aXXXXXXXXa..............",
1145 "aXXXXXXXXXa.............",
1146 "aXXXXXXaaaa.............",
1147 "aXXXaXXa................",
1148 "aXXaaXXa................",
1149 "aXa..aXXa...............",
1150 "aa...aXXa...............",
1151 "a.....aXXa..............",
1152 "......aXXa.....XXXX.....",
1153 ".......aXXa..XXaaaaXX...",
1154 ".......aXXa.XaaaaaaaaX..",
1155 "........aa.XaaaXXXXaaaX.",
1156 "...........XaaaaX..XaaX.",
1157 "..........XaaXaaaX..XaaX",
1158 "..........XaaXXaaaX.XaaX",
1159 "..........XaaX.XaaaXXaaX",
1160 "..........XaaX..XaaaXaaX",
1161 "...........XaaX..XaaaaX.",
1162 "...........XaaaXXXXaaaX.",
1163 "............XaaaaaaaaX..",
1164 ".............XXaaaaXX...",
1165 "...............XXXX....."};
1166 #endif
1167
1168 /* XPM */
1169 static const char * const copy_xpm[] = {
1170 "24 30 3 1",
1171 ".        c None",
1172 "a        c #000000",
1173 "X        c #FFFFFF",
1174 #if defined(Q_WS_WIN) // Windows cursor is traditionally white
1175 "aa......................",
1176 "aXa.....................",
1177 "aXXa....................",
1178 "aXXXa...................",
1179 "aXXXXa..................",
1180 "aXXXXXa.................",
1181 "aXXXXXXa................",
1182 "aXXXXXXXa...............",
1183 "aXXXXXXXXa..............",
1184 "aXXXXXXXXXa.............",
1185 "aXXXXXXaaaa.............",
1186 "aXXXaXXa................",
1187 "aXXaaXXa................",
1188 "aXa..aXXa...............",
1189 "aa...aXXa...............",
1190 "a.....aXXa..............",
1191 "......aXXa..............",
1192 ".......aXXa.............",
1193 ".......aXXa.............",
1194 "........aa...aaaaaaaaaaa",
1195 #else
1196 "XX......................",
1197 "XaX.....................",
1198 "XaaX....................",
1199 "XaaaX...................",
1200 "XaaaaX..................",
1201 "XaaaaaX.................",
1202 "XaaaaaaX................",
1203 "XaaaaaaaX...............",
1204 "XaaaaaaaaX..............",
1205 "XaaaaaaaaaX.............",
1206 "XaaaaaaXXXX.............",
1207 "XaaaXaaX................",
1208 "XaaXXaaX................",
1209 "XaX..XaaX...............",
1210 "XX...XaaX...............",
1211 "X.....XaaX..............",
1212 "......XaaX..............",
1213 ".......XaaX.............",
1214 ".......XaaX.............",
1215 "........XX...aaaaaaaaaaa",
1216 #endif
1217 ".............aXXXXXXXXXa",
1218 ".............aXXXXXXXXXa",
1219 ".............aXXXXaXXXXa",
1220 ".............aXXXXaXXXXa",
1221 ".............aXXaaaaaXXa",
1222 ".............aXXXXaXXXXa",
1223 ".............aXXXXaXXXXa",
1224 ".............aXXXXXXXXXa",
1225 ".............aXXXXXXXXXa",
1226 ".............aaaaaaaaaaa"};
1227
1228 /* XPM */
1229 static const char * const link_xpm[] = {
1230 "24 30 3 1",
1231 ".        c None",
1232 "a        c #000000",
1233 "X        c #FFFFFF",
1234 #if defined(Q_WS_WIN) // Windows cursor is traditionally white
1235 "aa......................",
1236 "aXa.....................",
1237 "aXXa....................",
1238 "aXXXa...................",
1239 "aXXXXa..................",
1240 "aXXXXXa.................",
1241 "aXXXXXXa................",
1242 "aXXXXXXXa...............",
1243 "aXXXXXXXXa..............",
1244 "aXXXXXXXXXa.............",
1245 "aXXXXXXaaaa.............",
1246 "aXXXaXXa................",
1247 "aXXaaXXa................",
1248 "aXa..aXXa...............",
1249 "aa...aXXa...............",
1250 "a.....aXXa..............",
1251 "......aXXa..............",
1252 ".......aXXa.............",
1253 ".......aXXa.............",
1254 "........aa...aaaaaaaaaaa",
1255 #else
1256 "XX......................",
1257 "XaX.....................",
1258 "XaaX....................",
1259 "XaaaX...................",
1260 "XaaaaX..................",
1261 "XaaaaaX.................",
1262 "XaaaaaaX................",
1263 "XaaaaaaaX...............",
1264 "XaaaaaaaaX..............",
1265 "XaaaaaaaaaX.............",
1266 "XaaaaaaXXXX.............",
1267 "XaaaXaaX................",
1268 "XaaXXaaX................",
1269 "XaX..XaaX...............",
1270 "XX...XaaX...............",
1271 "X.....XaaX..............",
1272 "......XaaX..............",
1273 ".......XaaX.............",
1274 ".......XaaX.............",
1275 "........XX...aaaaaaaaaaa",
1276 #endif
1277 ".............aXXXXXXXXXa",
1278 ".............aXXXaaaaXXa",
1279 ".............aXXXXaaaXXa",
1280 ".............aXXXaaaaXXa",
1281 ".............aXXaaaXaXXa",
1282 ".............aXXaaXXXXXa",
1283 ".............aXXaXXXXXXa",
1284 ".............aXXXaXXXXXa",
1285 ".............aXXXXXXXXXa",
1286 ".............aaaaaaaaaaa"};
1287
1288 QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)
1289 {
1290 #if defined(Q_WS_X11) || defined(Q_WS_WIN)
1291     if (!move_cursor) {
1292         move_cursor = new QPixmap((const char **)move_xpm);
1293         copy_cursor = new QPixmap((const char **)copy_xpm);
1294         link_cursor = new QPixmap((const char **)link_xpm);
1295 #ifdef Q_WS_WIN
1296         ignore_cursor = new QPixmap((const char **)ignore_xpm);
1297 #endif
1298     }
1299
1300     switch (cshape) {
1301     case Qt::DragMoveCursor:
1302         return *move_cursor;
1303     case Qt::DragCopyCursor:
1304         return *copy_cursor;
1305     case Qt::DragLinkCursor:
1306         return *link_cursor;
1307 #ifdef Q_WS_WIN
1308     case Qt::ForbiddenCursor:
1309         return *ignore_cursor;
1310 #endif
1311     default:
1312         break;
1313     }
1314 #else
1315     Q_UNUSED(cshape);
1316 #endif
1317     return QPixmap();
1318 }
1319
1320 QT_END_NAMESPACE