Cocoa: Fix qmlscene flicker on startup.
[profile/ivi/qtbase.git] / src / gui / kernel / qwindowsysteminterface_qpa.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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include "qwindowsysteminterface_qpa.h"
42 #include "qwindowsysteminterface_qpa_p.h"
43 #include "private/qguiapplication_p.h"
44 #include <QAbstractEventDispatcher>
45 #include <qdebug.h>
46
47 QT_BEGIN_NAMESPACE
48
49
50 QTime QWindowSystemInterfacePrivate::eventTime;
51
52 //------------------------------------------------------------
53 //
54 // Callback functions for plugins:
55 //
56
57 QList<QWindowSystemInterfacePrivate::WindowSystemEvent *> QWindowSystemInterfacePrivate::windowSystemEventQueue;
58 QMutex QWindowSystemInterfacePrivate::queueMutex;
59
60 extern QPointer<QWindow> qt_last_mouse_receiver;
61
62
63 void QWindowSystemInterface::handleEnterEvent(QWindow *tlw)
64 {
65     if (tlw) {
66         QWindowSystemInterfacePrivate::EnterEvent *e = new QWindowSystemInterfacePrivate::EnterEvent(tlw);
67         QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
68     }
69 }
70
71 void QWindowSystemInterface::handleLeaveEvent(QWindow *tlw)
72 {
73     QWindowSystemInterfacePrivate::LeaveEvent *e = new QWindowSystemInterfacePrivate::LeaveEvent(tlw);
74     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
75 }
76
77 void QWindowSystemInterface::handleWindowActivated(QWindow *tlw)
78 {
79     QWindowSystemInterfacePrivate::ActivatedWindowEvent *e = new QWindowSystemInterfacePrivate::ActivatedWindowEvent(tlw);
80     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
81 }
82
83 void QWindowSystemInterface::handleWindowStateChanged(QWindow *tlw, Qt::WindowState newState)
84 {
85     QWindowSystemInterfacePrivate::WindowStateChangedEvent *e =
86         new QWindowSystemInterfacePrivate::WindowStateChangedEvent(tlw, newState);
87     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
88 }
89
90 void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect)
91 {
92     QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect);
93     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
94 }
95
96 void QWindowSystemInterface::handleSynchronousGeometryChange(QWindow *tlw, const QRect &newRect)
97 {
98     QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect);
99     QGuiApplicationPrivate::processWindowSystemEvent(e); // send event immediately.
100 }
101
102 void QWindowSystemInterface::handleCloseEvent(QWindow *tlw)
103 {
104     if (tlw) {
105         QWindowSystemInterfacePrivate::CloseEvent *e =
106                 new QWindowSystemInterfacePrivate::CloseEvent(tlw);
107         QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
108     }
109 }
110
111 /*!
112
113 \a tlw == 0 means that \a ev is in global coords only
114
115
116 */
117 void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b) {
118     unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
119     handleMouseEvent(w, time, local, global, b);
120 }
121
122 void QWindowSystemInterface::handleMouseEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b)
123 {
124     QWindowSystemInterfacePrivate::MouseEvent * e =
125             new QWindowSystemInterfacePrivate::MouseEvent(tlw, timestamp, local, global, b);
126     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
127 }
128
129 void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
130     unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
131     handleKeyEvent(w, time, t, k, mods, text, autorep, count);
132 }
133
134 void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
135 {
136     QWindowSystemInterfacePrivate::KeyEvent * e =
137             new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
138     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
139 }
140
141 void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
142                                                     quint32 nativeScanCode, quint32 nativeVirtualKey,
143                                                     quint32 nativeModifiers,
144                                                     const QString& text, bool autorep,
145                                                     ushort count)
146 {
147     unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
148     handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
149                            text, autorep, count);
150 }
151
152 void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, int key,
153                                                     Qt::KeyboardModifiers modifiers,
154                                                     quint32 nativeScanCode, quint32 nativeVirtualKey,
155                                                     quint32 nativeModifiers,
156                                                     const QString& text, bool autorep,
157                                                     ushort count)
158 {
159     QWindowSystemInterfacePrivate::KeyEvent * e =
160             new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers,
161                 nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
162     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
163 }
164
165 void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o) {
166     unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
167     handleWheelEvent(w, time, local, global, d, o);
168 }
169
170 void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o)
171 {
172     QWindowSystemInterfacePrivate::WheelEvent *e =
173             new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, d, o);
174     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
175 }
176
177 int QWindowSystemInterfacePrivate::windowSystemEventsQueued()
178 {
179     queueMutex.lock();
180     int ret = windowSystemEventQueue.count();
181     queueMutex.unlock();
182     return ret;
183 }
184
185 QWindowSystemInterfacePrivate::WindowSystemEvent * QWindowSystemInterfacePrivate::getWindowSystemEvent()
186 {
187     queueMutex.lock();
188     QWindowSystemInterfacePrivate::WindowSystemEvent *ret;
189     if (windowSystemEventQueue.isEmpty())
190         ret = 0;
191     else
192         ret = windowSystemEventQueue.takeFirst();
193     queueMutex.unlock();
194     return ret;
195 }
196
197 void QWindowSystemInterfacePrivate::queueWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
198 {
199     queueMutex.lock();
200     windowSystemEventQueue.append(ev);
201     queueMutex.unlock();
202
203     QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher();
204     if (dispatcher)
205         dispatcher->wakeUp();
206 }
207
208 void QWindowSystemInterface::handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points) {
209     unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
210     handleTouchEvent(w, time, type, devType, points);
211 }
212
213 void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points)
214 {
215     if (!points.size()) // Touch events must have at least one point
216         return;
217
218     QList<QTouchEvent::TouchPoint> touchPoints;
219     Qt::TouchPointStates states;
220     QTouchEvent::TouchPoint p;
221
222     QList<struct TouchPoint>::const_iterator point = points.constBegin();
223     QList<struct TouchPoint>::const_iterator end = points.constEnd();
224     while (point != end) {
225         p.setId(point->id);
226         p.setPressure(point->pressure);
227         states |= point->state;
228         Qt::TouchPointStates state = point->state;
229         if (point->isPrimary) {
230             state |= Qt::TouchPointPrimary;
231         }
232         p.setState(state);
233         p.setRect(point->area);
234         p.setScreenPos(point->area.center());
235         p.setNormalizedPos(point->normalPosition);
236
237         touchPoints.append(p);
238         ++point;
239     }
240
241     QWindowSystemInterfacePrivate::TouchEvent *e =
242             new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, devType, touchPoints);
243     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
244 }
245
246 void QWindowSystemInterface::handleScreenGeometryChange(int screenIndex)
247 {
248     QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
249             new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screenIndex);
250     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
251 }
252
253 void QWindowSystemInterface::handleScreenAvailableGeometryChange(int screenIndex)
254 {
255     QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e =
256             new QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent(screenIndex);
257     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
258 }
259
260 void QWindowSystemInterface::handleScreenCountChange(int count)
261 {
262     QWindowSystemInterfacePrivate::ScreenCountEvent *e =
263             new QWindowSystemInterfacePrivate::ScreenCountEvent(count);
264     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
265 }
266
267 void QWindowSystemInterface::handleMapEvent(QWindow *tlw)
268 {
269     QWindowSystemInterfacePrivate::MapEvent *e = new QWindowSystemInterfacePrivate::MapEvent(tlw);
270     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
271 }
272
273 void QWindowSystemInterface::handleUnmapEvent(QWindow *tlw)
274 {
275     QWindowSystemInterfacePrivate::UnmapEvent *e = new QWindowSystemInterfacePrivate::UnmapEvent(tlw);
276     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
277 }
278
279 void QWindowSystemInterface::handleSynchronousExposeEvent(QWindow *tlw, const QRegion &region)
280 {
281     QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region);
282     QGuiApplicationPrivate::processWindowSystemEvent(e); // send event immediately.
283 }
284
285 bool QWindowSystemInterface::sendWindowSystemEvents(QAbstractEventDispatcher *eventDispatcher, QEventLoop::ProcessEventsFlags flags)
286 {
287     int nevents = 0;
288
289     // handle gui and posted events
290     QCoreApplication::sendPostedEvents();
291
292     while (true) {
293         QWindowSystemInterfacePrivate::WindowSystemEvent *event;
294         if (!(flags & QEventLoop::ExcludeUserInputEvents)
295             && QWindowSystemInterfacePrivate::windowSystemEventsQueued() > 0) {
296             // process a pending user input event
297             event = QWindowSystemInterfacePrivate::getWindowSystemEvent();
298             if (!event)
299                 break;
300         } else {
301             break;
302         }
303
304         if (eventDispatcher->filterEvent(event)) {
305             delete event;
306             continue;
307         }
308
309         nevents++;
310
311         QGuiApplicationPrivate::processWindowSystemEvent(event);
312         delete event;
313     }
314
315     return (nevents > 0);
316 }
317
318 int QWindowSystemInterface::windowSystemEventsQueued()
319 {
320     return QWindowSystemInterfacePrivate::windowSystemEventsQueued();
321 }
322
323 Qt::DropAction QWindowSystemInterface::handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
324 {
325     return QGuiApplicationPrivate::processDrag(w, dropData, p);
326 }
327
328 Qt::DropAction QWindowSystemInterface::handleDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
329 {
330     return QGuiApplicationPrivate::processDrop(w, dropData, p);
331 }
332
333 QT_END_NAMESPACE