Windows QPA plugin: Fix logging.
[profile/ivi/qtbase.git] / src / plugins / platforms / windows / qwindowsintegration.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 plugins 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 "qwindowsintegration.h"
43 #include "qwindowsbackingstore.h"
44 #include "qwindowswindow.h"
45 #include "qwindowscontext.h"
46 #include "qwindowsglcontext.h"
47 #include "qwindowsscreen.h"
48 #include "qwindowstheme.h"
49 #include "qwindowsservices.h"
50 #ifndef QT_NO_FREETYPE
51 #include "qwindowsfontdatabase_ft.h"
52 #endif
53 #include "qwindowsfontdatabase.h"
54 #include "qwindowsguieventdispatcher.h"
55 #include "qwindowsclipboard.h"
56 #include "qwindowsdrag.h"
57 #include "qwindowsinputcontext.h"
58 #include "qwindowskeymapper.h"
59 #include "accessible/qwindowsaccessibility.h"
60
61 #include <QtGui/QPlatformNativeInterface>
62 #include <QtGui/QWindowSystemInterface>
63 #include <QtGui/QBackingStore>
64 #include <QtGui/private/qpixmap_raster_p.h>
65 #include <QtGui/private/qguiapplication_p.h>
66
67 #include <QtCore/private/qeventdispatcher_win_p.h>
68 #include <QtCore/QDebug>
69
70 QT_BEGIN_NAMESPACE
71
72 /*!
73     \class QWindowsNativeInterface
74     \brief Provides access to native handles.
75
76     Currently implemented keys
77     \list
78     \li handle (HWND)
79     \li getDC (DC)
80     \li releaseDC Releases the previously acquired DC and returns 0.
81     \endlist
82
83     \ingroup qt-lighthouse-win
84 */
85
86 class QWindowsNativeInterface : public QPlatformNativeInterface
87 {
88     Q_OBJECT
89 public:
90     virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
91     virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
92     virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs);
93     virtual EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter)
94         { return QWindowsContext::instance()->setEventFilter(eventType, filter); }
95
96     Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
97                                           const QString &windowName,
98                                           void *eventProc) const;
99 };
100
101 void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
102 {
103     if (!window || !window->handle()) {
104         qWarning("%s: '%s' requested for null window or window without handle.", __FUNCTION__, resource.constData());
105         return 0;
106     }
107     QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle());
108     if (resource == "handle")
109         return bw->handle();
110     if (window->surfaceType() == QWindow::RasterSurface) {
111         if (resource == "getDC")
112             return bw->getDC();
113         if (resource == "releaseDC") {
114             bw->releaseDC();
115             return 0;
116         }
117     }
118     qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
119     return 0;
120 }
121
122 void *QWindowsNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
123 {
124     if (!bs || !bs->handle()) {
125         qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
126         return 0;
127     }
128     QWindowsBackingStore *wbs = static_cast<QWindowsBackingStore *>(bs->handle());
129     if (resource == "getDC")
130         return wbs->getDC();
131     qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
132     return 0;
133 }
134
135 void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
136 {
137     if (!context || !context->handle()) {
138         qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
139         return 0;
140     }
141     QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
142     if (resource == "renderingContext")
143         return windowsContext->renderingContext();
144
145     qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
146     return 0;
147 }
148
149 /*!
150     \brief Creates a non-visible window handle for filtering messages.
151 */
152
153 void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTemplate,
154                                                    const QString &windowName,
155                                                    void *eventProc) const
156 {
157     QWindowsContext *ctx = QWindowsContext::instance();
158     const HWND hwnd = ctx->createDummyWindow(classNameTemplate,
159                                              (wchar_t*)windowName.utf16(),
160                                              (WNDPROC)eventProc);
161     return hwnd;
162 }
163
164 /*!
165     \class QWindowsIntegration
166     \brief QPlatformIntegration implementation for Windows.
167     \ingroup qt-lighthouse-win
168 */
169
170 struct QWindowsIntegrationPrivate
171 {
172     typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
173
174     QWindowsIntegrationPrivate();
175     ~QWindowsIntegrationPrivate();
176
177     QWindowsContext m_context;
178     QPlatformFontDatabase *m_fontDatabase;
179     QWindowsNativeInterface m_nativeInterface;
180     QWindowsClipboard m_clipboard;
181     QWindowsDrag m_drag;
182     QWindowsGuiEventDispatcher *m_eventDispatcher;
183     QOpenGLStaticContextPtr m_staticOpenGLContext;
184     QWindowsInputContext m_inputContext;
185     QWindowsAccessibility m_accessibility;
186     QWindowsServices m_services;
187 };
188
189 QWindowsIntegrationPrivate::QWindowsIntegrationPrivate()
190     : m_fontDatabase(0), m_eventDispatcher(new QWindowsGuiEventDispatcher)
191 {
192 }
193
194 QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate()
195 {
196     if (m_fontDatabase)
197         delete m_fontDatabase;
198 }
199
200 QWindowsIntegration::QWindowsIntegration() :
201     d(new QWindowsIntegrationPrivate)
202 {
203     QGuiApplicationPrivate::instance()->setEventDispatcher(d->m_eventDispatcher);
204     d->m_clipboard.registerViewer();
205     d->m_context.screenManager().handleScreenChanges();
206 }
207
208 QWindowsIntegration::~QWindowsIntegration()
209 {
210     if (QWindowsContext::verboseIntegration)
211         qDebug("%s", __FUNCTION__);
212 }
213
214 bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
215 {
216     switch (cap) {
217     case ThreadedPixmaps:
218         return true;
219     case OpenGL:
220         return true;
221     case ThreadedOpenGL:
222         return true;
223     default:
224         return QPlatformIntegration::hasCapability(cap);
225     }
226     return false;
227 }
228
229 QPlatformPixmap *QWindowsIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
230 {
231     return new QRasterPlatformPixmap(type);
232 }
233
234 QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
235 {
236     QWindowsWindow::WindowData requested;
237     requested.flags = window->windowFlags();
238     requested.geometry = window->geometry();
239     const QWindowsWindow::WindowData obtained
240             = QWindowsWindow::WindowData::create(window, requested, window->windowTitle());
241     if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
242         qDebug().nospace()
243             << __FUNCTION__ << ' ' << window << '\n'
244             << "    Requested: " << requested.geometry << " Flags="
245             << QWindowsWindow::debugWindowFlags(requested.flags) << '\n'
246             << "    Obtained : " << obtained.geometry << " Margins "
247             << obtained.frame  << " Flags="
248             << QWindowsWindow::debugWindowFlags(obtained.flags)
249             << " Handle=" << obtained.hwnd << '\n';
250     if (!obtained.hwnd)
251         return 0;
252     if (requested.flags != obtained.flags)
253         window->setWindowFlags(obtained.flags);
254     if (requested.geometry != obtained.geometry)
255         QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
256     return new QWindowsWindow(window, obtained);
257 }
258
259 QPlatformBackingStore *QWindowsIntegration::createPlatformBackingStore(QWindow *window) const
260 {
261     if (QWindowsContext::verboseIntegration)
262         qDebug() << __FUNCTION__ << window;
263     return new QWindowsBackingStore(window);
264 }
265
266 QPlatformOpenGLContext
267     *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
268 {
269     if (QWindowsContext::verboseIntegration)
270         qDebug() << __FUNCTION__ << context->format();
271     if (d->m_staticOpenGLContext.isNull())
272         d->m_staticOpenGLContext =
273             QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
274     QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
275     if (result->isValid())
276         return result.take();
277     return 0;
278 }
279
280 QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const
281 {
282     if (!d->m_fontDatabase) {
283 #ifndef QT_NO_FREETYPE
284         const QVariant argument = d->m_nativeInterface.property("fontengine");
285         if (argument.isValid() && argument.toString() == QLatin1String("freetype"))
286             d->m_fontDatabase = new QWindowsFontDatabaseFT();
287         else
288             d->m_fontDatabase = new QWindowsFontDatabase();
289 #else
290         d->m_fontDatabase = new QWindowsFontDatabase();
291 #endif
292     }
293     return d->m_fontDatabase;
294 }
295
296 static inline int keyBoardAutoRepeatRateMS()
297 {
298   DWORD time = 0;
299   if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0))
300       return time ? 1000 / static_cast<int>(time) : 500;
301   return 30;
302 }
303
304 QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
305 {
306     switch (hint) {
307     case QPlatformIntegration::CursorFlashTime:
308         if (const unsigned timeMS = GetCaretBlinkTime())
309             return QVariant(int(timeMS));
310         break;
311     case KeyboardAutoRepeatRate:
312         return QVariant(keyBoardAutoRepeatRateMS());
313     case QPlatformIntegration::StartDragTime:
314     case QPlatformIntegration::StartDragDistance:
315     case QPlatformIntegration::MouseDoubleClickInterval:
316     case QPlatformIntegration::KeyboardInputInterval:
317     case QPlatformIntegration::ShowIsFullScreen:
318         break; // Not implemented
319     case QPlatformIntegration::FontSmoothingGamma:
320         return QVariant(QWindowsFontDatabase::fontSmoothingGamma());
321     }
322     return QPlatformIntegration::styleHint(hint);
323 }
324
325 Qt::KeyboardModifiers QWindowsIntegration::queryKeyboardModifiers() const
326 {
327     return QWindowsKeyMapper::queryKeyboardModifiers();
328 }
329
330 QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const
331 {
332     return &d->m_nativeInterface;
333 }
334
335 QPlatformClipboard * QWindowsIntegration::clipboard() const
336 {
337     return &d->m_clipboard;
338 }
339
340 QPlatformDrag *QWindowsIntegration::drag() const
341 {
342     return &d->m_drag;
343 }
344
345 QPlatformInputContext * QWindowsIntegration::inputContext() const
346 {
347     return &d->m_inputContext;
348 }
349
350 QPlatformAccessibility *QWindowsIntegration::accessibility() const
351 {
352     return &d->m_accessibility;
353 }
354
355 QWindowsIntegration *QWindowsIntegration::instance()
356 {
357     return static_cast<QWindowsIntegration *>(QGuiApplicationPrivate::platformIntegration());
358 }
359
360 QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const
361 {
362     return d->m_eventDispatcher;
363 }
364
365 QStringList QWindowsIntegration::themeNames() const
366 {
367     return QStringList(QLatin1String(QWindowsTheme::name));
368 }
369
370 QPlatformTheme *QWindowsIntegration::createPlatformTheme(const QString &name) const
371 {
372     if (name == QLatin1String(QWindowsTheme::name))
373         return new QWindowsTheme;
374     return QPlatformIntegration::createPlatformTheme(name);
375 }
376
377 QPlatformServices *QWindowsIntegration::services() const
378 {
379     return &d->m_services;
380 }
381
382 QT_END_NAMESPACE
383
384 #include "qwindowsintegration.moc"