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