1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the plugins of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
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"
53 #include "qwindowsfontdatabase.h"
54 #include "qwindowsguieventdispatcher.h"
55 #include "qwindowsclipboard.h"
56 #include "qwindowsdrag.h"
57 #include "qwindowsinputcontext.h"
58 #include "qwindowsaccessibility.h"
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>
66 #include <QtCore/private/qeventdispatcher_win_p.h>
67 #include <QtCore/QDebug>
72 \class QWindowsNativeInterface
73 \brief Provides access to native handles.
75 Currently implemented keys
79 \li releaseDC Releases the previously acquired DC and returns 0.
82 \ingroup qt-lighthouse-win
85 class QWindowsNativeInterface : public QPlatformNativeInterface
89 virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
90 virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
91 virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs);
92 virtual EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter)
93 { return QWindowsContext::instance()->setEventFilter(eventType, filter); }
95 Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
96 const QString &windowName,
97 void *eventProc) const;
100 void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
102 if (!window || !window->handle()) {
103 qWarning("%s: '%s' requested for null window or window without handle.", __FUNCTION__, resource.constData());
106 QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle());
107 if (resource == "handle")
109 if (window->surfaceType() == QWindow::RasterSurface) {
110 if (resource == "getDC")
112 if (resource == "releaseDC") {
117 qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
121 void *QWindowsNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
123 if (!bs || !bs->handle()) {
124 qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
127 QWindowsBackingStore *wbs = static_cast<QWindowsBackingStore *>(bs->handle());
128 if (resource == "getDC")
130 qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
134 void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
136 if (!context || !context->handle()) {
137 qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
140 QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
141 if (resource == "renderingContext")
142 return windowsContext->renderingContext();
144 qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
149 \brief Creates a non-visible window handle for filtering messages.
152 void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTemplate,
153 const QString &windowName,
154 void *eventProc) const
156 QWindowsContext *ctx = QWindowsContext::instance();
157 const HWND hwnd = ctx->createDummyWindow(classNameTemplate,
158 (wchar_t*)windowName.utf16(),
164 \class QWindowsIntegration
165 \brief QPlatformIntegration implementation for Windows.
166 \ingroup qt-lighthouse-win
169 struct QWindowsIntegrationPrivate
171 typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
173 QWindowsIntegrationPrivate();
174 ~QWindowsIntegrationPrivate();
176 QWindowsContext m_context;
177 QPlatformFontDatabase *m_fontDatabase;
178 QWindowsNativeInterface m_nativeInterface;
179 QWindowsClipboard m_clipboard;
181 QWindowsGuiEventDispatcher *m_eventDispatcher;
182 QOpenGLStaticContextPtr m_staticOpenGLContext;
183 QWindowsInputContext m_inputContext;
184 QWindowsAccessibility m_accessibility;
185 QWindowsTheme m_theme;
186 QWindowsServices m_services;
189 QWindowsIntegrationPrivate::QWindowsIntegrationPrivate()
190 : m_fontDatabase(0), m_eventDispatcher(new QWindowsGuiEventDispatcher)
194 QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate()
197 delete m_fontDatabase;
200 QWindowsIntegration::QWindowsIntegration() :
201 d(new QWindowsIntegrationPrivate)
203 QGuiApplicationPrivate::instance()->setEventDispatcher(d->m_eventDispatcher);
204 d->m_clipboard.registerViewer();
205 d->m_context.screenManager().handleScreenChanges();
208 QWindowsIntegration::~QWindowsIntegration()
210 if (QWindowsContext::verboseIntegration)
211 qDebug("%s", __FUNCTION__);
214 bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
217 case ThreadedPixmaps:
224 return QPlatformIntegration::hasCapability(cap);
229 QPlatformPixmap *QWindowsIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
231 if (QWindowsContext::verboseIntegration)
232 qDebug() << __FUNCTION__ << type;
233 return new QRasterPlatformPixmap(type);
236 QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
238 QWindowsWindow::WindowData requested;
239 requested.flags = window->windowFlags();
240 requested.geometry = window->geometry();
241 const QWindowsWindow::WindowData obtained
242 = QWindowsWindow::WindowData::create(window, requested, window->windowTitle());
243 if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
245 << __FUNCTION__ << ' ' << window << '\n'
246 << " Requested: " << requested.geometry << " Flags="
247 << QWindowsWindow::debugWindowFlags(requested.flags) << '\n'
248 << " Obtained : " << obtained.geometry << " Margins "
249 << obtained.frame << " Flags="
250 << QWindowsWindow::debugWindowFlags(obtained.flags)
251 << " Handle=" << obtained.hwnd << '\n';
254 if (requested.flags != obtained.flags)
255 window->setWindowFlags(obtained.flags);
256 if (requested.geometry != obtained.geometry)
257 QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
258 return new QWindowsWindow(window, obtained);
261 QPlatformBackingStore *QWindowsIntegration::createPlatformBackingStore(QWindow *window) const
263 if (QWindowsContext::verboseIntegration)
264 qDebug() << __FUNCTION__ << window;
265 return new QWindowsBackingStore(window);
268 QPlatformOpenGLContext
269 *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
271 if (QWindowsContext::verboseIntegration)
272 qDebug() << __FUNCTION__ << context->format();
273 if (d->m_staticOpenGLContext.isNull())
274 d->m_staticOpenGLContext =
275 QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
276 QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
277 if (result->isValid())
278 return result.take();
282 QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const
284 if (!d->m_fontDatabase) {
285 #ifndef QT_NO_FREETYPE
286 if (d->m_nativeInterface.property("fontengine").toString() == QLatin1String("native"))
287 d->m_fontDatabase = new QWindowsFontDatabase();
289 d->m_fontDatabase = new QWindowsFontDatabaseFT();
291 d->m_fontDatabase = new QWindowsFontDatabase();
294 return d->m_fontDatabase;
297 static inline int keyBoardAutoRepeatRateMS()
300 if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0))
301 return time ? 1000 / static_cast<int>(time) : 500;
305 QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
308 case QPlatformIntegration::CursorFlashTime:
309 if (const unsigned timeMS = GetCaretBlinkTime())
310 return QVariant(int(timeMS));
312 case KeyboardAutoRepeatRate:
313 return QVariant(keyBoardAutoRepeatRateMS());
314 case QPlatformIntegration::StartDragTime:
315 case QPlatformIntegration::StartDragDistance:
316 case QPlatformIntegration::MouseDoubleClickInterval:
317 case QPlatformIntegration::KeyboardInputInterval:
318 case QPlatformIntegration::ShowIsFullScreen:
319 break; // Not implemented
321 return QPlatformIntegration::styleHint(hint);
324 QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const
326 return &d->m_nativeInterface;
329 QPlatformClipboard * QWindowsIntegration::clipboard() const
331 return &d->m_clipboard;
334 QPlatformDrag *QWindowsIntegration::drag() const
339 QPlatformInputContext * QWindowsIntegration::inputContext() const
341 return &d->m_inputContext;
344 QPlatformAccessibility *QWindowsIntegration::accessibility() const
346 return &d->m_accessibility;
349 QWindowsIntegration *QWindowsIntegration::instance()
351 return static_cast<QWindowsIntegration *>(QGuiApplicationPrivate::platformIntegration());
354 QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const
356 return d->m_eventDispatcher;
359 QPlatformTheme *QWindowsIntegration::platformTheme() const
364 QPlatformServices *QWindowsIntegration::services() const
366 return &d->m_services;
371 #include "qwindowsintegration.moc"