1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qplatformintegration.h"
41 
42 #include <qpa/qplatformfontdatabase.h>
43 #include <qpa/qplatformclipboard.h>
44 #include <qpa/qplatformaccessibility.h>
45 #include <qpa/qplatformtheme.h>
46 #include <QtGui/private/qguiapplication_p.h>
47 #include <QtGui/private/qpixmap_raster_p.h>
48 
49 #if QT_CONFIG(draganddrop)
50 #include <private/qdnd_p.h>
51 #include <private/qsimpledrag_p.h>
52 #endif
53 
54 #ifndef QT_NO_SESSIONMANAGER
55 # include <qpa/qplatformsessionmanager.h>
56 #endif
57 
58 QT_BEGIN_NAMESPACE
59 
60 /*!
61     Accessor for the platform integration's fontdatabase.
62 
63     Default implementation returns a default QPlatformFontDatabase.
64 
65     \sa QPlatformFontDatabase
66 */
fontDatabase() const67 QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const
68 {
69     static QPlatformFontDatabase *db = nullptr;
70     if (!db) {
71         db = new QPlatformFontDatabase;
72     }
73     return db;
74 }
75 
76 /*!
77     Accessor for the platform integration's clipboard.
78 
79     Default implementation returns a default QPlatformClipboard.
80 
81     \sa QPlatformClipboard
82 
83 */
84 
85 #ifndef QT_NO_CLIPBOARD
86 
clipboard() const87 QPlatformClipboard *QPlatformIntegration::clipboard() const
88 {
89     static QPlatformClipboard *clipboard = nullptr;
90     if (!clipboard) {
91         clipboard = new QPlatformClipboard;
92     }
93     return clipboard;
94 }
95 
96 #endif
97 
98 #if QT_CONFIG(draganddrop)
99 /*!
100     Accessor for the platform integration's drag object.
101 
102     Default implementation returns QSimpleDrag. This class supports only drag
103     and drop operations within the same Qt application.
104 */
drag() const105 QPlatformDrag *QPlatformIntegration::drag() const
106 {
107     static QSimpleDrag *drag = nullptr;
108     if (!drag) {
109         drag = new QSimpleDrag;
110     }
111     return drag;
112 }
113 #endif // QT_CONFIG(draganddrop)
114 
nativeInterface() const115 QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
116 {
117     return nullptr;
118 }
119 
services() const120 QPlatformServices *QPlatformIntegration::services() const
121 {
122     return nullptr;
123 }
124 
125 /*!
126     \class QPlatformIntegration
127     \since 4.8
128     \internal
129     \preliminary
130     \ingroup qpa
131     \brief The QPlatformIntegration class is the entry for WindowSystem specific functionality.
132 
133     QPlatformIntegration is the single entry point for windowsystem specific functionality when
134     using the QPA platform. It has factory functions for creating platform specific pixmaps and
135     windows. The class also controls the font subsystem.
136 
137     QPlatformIntegration is a singleton class which gets instantiated in the QGuiApplication
138     constructor. The QPlatformIntegration instance do not have ownership of objects it creates in
139     functions where the name starts with create. However, functions which don't have a name
140     starting with create acts as accessors to member variables.
141 
142     It is not trivial to create or build a platform plugin outside of the Qt source tree. Therefore
143     the recommended approach for making new platform plugin is to copy an existing plugin inside
144     the QTSRCTREE/src/plugins/platform and develop the plugin inside the source tree.
145 
146     The minimal platform integration is the smallest platform integration it is possible to make,
147     which makes it an ideal starting point for new plugins. For a slightly more advanced plugin,
148     consider reviewing the directfb plugin, or the testlite plugin.
149 */
150 
151 /*!
152     \fn QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
153 
154     Factory function for QPlatformPixmap. PixelType can be either PixmapType or BitmapType.
155     \sa QPlatformPixmap
156 */
157 
158 /*!
159     \fn QPlatformWindow *QPlatformIntegration::createPlatformWindow(QWindow *window) const
160 
161     Factory function for QPlatformWindow. The \a window parameter is a pointer to the window
162     which the QPlatformWindow is supposed to be created for.
163 
164     All windows have to have a QPlatformWindow, and it will be created on-demand when the
165     QWindow is made visible for the first time, or explicitly through calling QWindow::create().
166 
167     In the constructor, of the QPlatformWindow, the window flags, state, title and geometry
168     of the \a window should be applied to the underlying window. If the resulting flags or state
169     differs, the resulting values should be set on the \a window using QWindow::setWindowFlags()
170     or QWindow::setWindowState(), respectively.
171 
172     \sa QPlatformWindow, QPlatformWindowFormat
173     \sa createPlatformBackingStore()
174 */
175 
176 /*!
177     \fn QPlatformBackingStore *QPlatformIntegration::createPlatformBackingStore(QWindow *window) const
178 
179     Factory function for QPlatformBackingStore. The QWindow parameter is a pointer to the
180     top level widget(tlw) the window surface is created for. A QPlatformWindow is always created
181     before the QPlatformBackingStore for tlw where the widget also requires a backing store.
182 
183     \sa QBackingStore
184     \sa createPlatformWindow()
185 */
186 
187 /*!
188     \enum QPlatformIntegration::Capability
189 
190     Capabilities are used to determing specific features of a platform integration
191 
192     \value ThreadedPixmaps The platform uses a pixmap implementation that is reentrant
193     and can be used from multiple threads, like the raster paint engine and QImage based
194     pixmaps.
195 
196     \value OpenGL The platform supports OpenGL
197 
198     \value ThreadedOpenGL The platform supports using OpenGL outside the GUI thread.
199 
200     \value SharedGraphicsCache The platform supports a shared graphics cache
201 
202     \value BufferQueueingOpenGL The OpenGL implementation on the platform will queue
203     up buffers when swapBuffers() is called and block only when its buffer pipeline
204     is full, rather than block immediately.
205 
206     \value MultipleWindows The platform supports multiple QWindows, i.e. does some kind
207     of compositing either client or server side. Some platforms might only support a
208     single fullscreen window.
209 
210     \value ApplicationState The platform handles the application state explicitly.
211     This means that QEvent::ApplicationActivate and QEvent::ApplicationDeativate
212     will not be posted automatically. Instead, the platform must handle application
213     state explicitly by using QWindowSystemInterface::handleApplicationStateChanged().
214     If not set, application state will follow window activation, which is the normal
215     behavior for desktop platforms.
216 
217     \value ForeignWindows The platform allows creating QWindows which represent
218     native windows created by other processes or by using native libraries.
219 
220     \value NonFullScreenWindows The platform supports top-level windows which do not
221     fill the screen. The default implementation returns \c true. Returning false for
222     this will cause all windows, including dialogs and popups, to be resized to fill the
223     screen.
224 
225     \value WindowManagement The platform is based on a system that performs window
226     management.  This includes the typical desktop platforms. Can be set to false on
227     platforms where no window management is available, meaning for example that windows
228     are never repositioned by the window manager. The default implementation returns \c true.
229 
230     \value AllGLFunctionsQueryable Deprecated. Used to indicate whether the QOpenGLContext
231     backend provided by the platform is
232     able to return function pointers from getProcAddress() even for standard OpenGL
233     functions, for example OpenGL 1 functions like glClear() or glDrawArrays(). This is
234     important because the OpenGL specifications do not require this ability from the
235     getProcAddress implementations of the windowing system interfaces (EGL, WGL, GLX). The
236     platform plugins may however choose to enhance the behavior in the backend
237     implementation for QOpenGLContext::getProcAddress() and support returning a function
238     pointer also for the standard, non-extension functions. This capability is a
239     prerequisite for dynamic OpenGL loading. Starting with Qt 5.7, the platform plugin
240     is required to have this capability.
241 
242     \value ApplicationIcon The platform supports setting the application icon. (since 5.5)
243 
244     \value TopStackedNativeChildWindows The platform supports native child windows via
245     QWindowContainer without having to punch a transparent hole in the
246     backingstore. (since 5.10)
247 
248     \value OpenGLOnRasterSurface The platform supports making a QOpenGLContext current
249     in combination with a QWindow of type RasterSurface.
250  */
251 
252 /*!
253 
254     \fn QAbstractEventDispatcher *QPlatformIntegration::createEventDispatcher() const = 0
255 
256     Factory function for the GUI event dispatcher. The platform plugin should create
257     and return a QAbstractEventDispatcher subclass when this function is called.
258 
259     If the platform plugin for some reason creates the event dispatcher outside of
260     this function (for example in the constructor), it needs to handle the case
261     where this function is never called, ensuring that the event dispatcher is
262     still deleted at some point (typically in the destructor).
263 
264     Note that the platform plugin should never explicitly set the event dispatcher
265     itself, using QCoreApplication::setEventDispatcher(), but let QCoreApplication
266     decide when and which event dispatcher to create.
267 
268     \since 5.2
269 */
270 
hasCapability(Capability cap) const271 bool QPlatformIntegration::hasCapability(Capability cap) const
272 {
273     return cap == NonFullScreenWindows || cap == NativeWidgets || cap == WindowManagement
274         || cap == TopStackedNativeChildWindows || cap == WindowActivation;
275 }
276 
createPlatformPixmap(QPlatformPixmap::PixelType type) const277 QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
278 {
279     return new QRasterPlatformPixmap(type);
280 }
281 
282 #ifndef QT_NO_OPENGL
283 /*!
284     Factory function for QPlatformOpenGLContext. The \a context parameter is a pointer to
285     the context for which a platform-specific context backend needs to be
286     created. Configuration settings like the format, share context and screen have to be
287     taken from this QOpenGLContext and the resulting platform context is expected to be
288     backed by a native context that fulfills these criteria.
289 
290     If the context has native handles set, no new native context is expected to be created.
291     Instead, the provided handles have to be used. In this case the ownership of the handle
292     must not be taken and the platform implementation is not allowed to destroy the native
293     context. Configuration parameters like the format are also to be ignored. Instead, the
294     platform implementation is responsible for querying the configuriation from the provided
295     native context.
296 
297     Returns a pointer to a QPlatformOpenGLContext instance or \nullptr if the context could
298     not be created.
299 
300     \sa QOpenGLContext
301 */
createPlatformOpenGLContext(QOpenGLContext * context) const302 QPlatformOpenGLContext *QPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
303 {
304     Q_UNUSED(context);
305     qWarning("This plugin does not support createPlatformOpenGLContext!");
306     return nullptr;
307 }
308 #endif // QT_NO_OPENGL
309 
310 /*!
311    Factory function for QPlatformSharedGraphicsCache. This function will return 0 if the platform
312    integration does not support any shared graphics cache mechanism for the given \a cacheId.
313 */
createPlatformSharedGraphicsCache(const char * cacheId) const314 QPlatformSharedGraphicsCache *QPlatformIntegration::createPlatformSharedGraphicsCache(const char *cacheId) const
315 {
316     qWarning("This plugin does not support createPlatformSharedGraphicsBuffer for cacheId: %s!",
317              cacheId);
318     return nullptr;
319 }
320 
321 /*!
322    Factory function for QPaintEngine. This function will return 0 if the platform
323    integration does not support creating any paint engine the given \a paintDevice.
324 */
createImagePaintEngine(QPaintDevice * paintDevice) const325 QPaintEngine *QPlatformIntegration::createImagePaintEngine(QPaintDevice *paintDevice) const
326 {
327     Q_UNUSED(paintDevice)
328     return nullptr;
329 }
330 
331 /*!
332   Performs initialization steps that depend on having an event dispatcher
333   available. Called after the event dispatcher has been created.
334 
335   Tasks that require an event dispatcher, for example creating socket notifiers, cannot be
336   performed in the constructor. Instead, they should be performed here. The default
337   implementation does nothing.
338 */
initialize()339 void QPlatformIntegration::initialize()
340 {
341 }
342 
343 /*!
344   Called before the platform integration is deleted. Useful when cleanup relies on virtual
345   functions.
346 
347   \since 5.5
348 */
destroy()349 void QPlatformIntegration::destroy()
350 {
351 }
352 
353 /*!
354   Returns the platforms input context.
355 
356   The default implementation returns \nullptr, implying no input method support.
357 */
inputContext() const358 QPlatformInputContext *QPlatformIntegration::inputContext() const
359 {
360     return nullptr;
361 }
362 
363 #ifndef QT_NO_ACCESSIBILITY
364 
365 /*!
366   Returns the platforms accessibility.
367 
368   The default implementation returns QPlatformAccessibility which
369   delegates handling of accessibility to accessiblebridge plugins.
370 */
accessibility() const371 QPlatformAccessibility *QPlatformIntegration::accessibility() const
372 {
373     static QPlatformAccessibility *accessibility = nullptr;
374     if (Q_UNLIKELY(!accessibility)) {
375         accessibility = new QPlatformAccessibility;
376     }
377     return accessibility;
378 }
379 
380 #endif
381 
styleHint(StyleHint hint) const382 QVariant QPlatformIntegration::styleHint(StyleHint hint) const
383 {
384     switch (hint) {
385     case CursorFlashTime:
386         return QPlatformTheme::defaultThemeHint(QPlatformTheme::CursorFlashTime);
387     case KeyboardInputInterval:
388         return QPlatformTheme::defaultThemeHint(QPlatformTheme::KeyboardInputInterval);
389     case KeyboardAutoRepeatRate:
390         return QPlatformTheme::defaultThemeHint(QPlatformTheme::KeyboardAutoRepeatRate);
391     case MouseDoubleClickInterval:
392         return QPlatformTheme::defaultThemeHint(QPlatformTheme::MouseDoubleClickInterval);
393     case StartDragDistance:
394         return QPlatformTheme::defaultThemeHint(QPlatformTheme::StartDragDistance);
395     case StartDragTime:
396         return QPlatformTheme::defaultThemeHint(QPlatformTheme::StartDragTime);
397     case ShowIsFullScreen:
398         return false;
399     case ShowIsMaximized:
400         return false;
401     case ShowShortcutsInContextMenus:
402         return QPlatformTheme::defaultThemeHint(QPlatformTheme::ShowShortcutsInContextMenus);
403     case PasswordMaskDelay:
404         return QPlatformTheme::defaultThemeHint(QPlatformTheme::PasswordMaskDelay);
405     case PasswordMaskCharacter:
406         return QPlatformTheme::defaultThemeHint(QPlatformTheme::PasswordMaskCharacter);
407     case FontSmoothingGamma:
408         return qreal(1.7);
409     case StartDragVelocity:
410         return QPlatformTheme::defaultThemeHint(QPlatformTheme::StartDragVelocity);
411     case UseRtlExtensions:
412         return QVariant(false);
413     case SetFocusOnTouchRelease:
414         return QVariant(false);
415     case MousePressAndHoldInterval:
416         return QPlatformTheme::defaultThemeHint(QPlatformTheme::MousePressAndHoldInterval);
417     case TabFocusBehavior:
418         return QPlatformTheme::defaultThemeHint(QPlatformTheme::TabFocusBehavior);
419     case ReplayMousePressOutsidePopup:
420         return true;
421     case ItemViewActivateItemOnSingleClick:
422         return QPlatformTheme::defaultThemeHint(QPlatformTheme::ItemViewActivateItemOnSingleClick);
423     case UiEffects:
424         return QPlatformTheme::defaultThemeHint(QPlatformTheme::UiEffects);
425     case WheelScrollLines:
426         return QPlatformTheme::defaultThemeHint(QPlatformTheme::WheelScrollLines);
427     case MouseQuickSelectionThreshold:
428         return QPlatformTheme::defaultThemeHint(QPlatformTheme::MouseQuickSelectionThreshold);
429     }
430 
431     return 0;
432 }
433 
defaultWindowState(Qt::WindowFlags flags) const434 Qt::WindowState QPlatformIntegration::defaultWindowState(Qt::WindowFlags flags) const
435 {
436     // Leave popup-windows as is
437     if (flags & Qt::Popup & ~Qt::Window)
438         return Qt::WindowNoState;
439 
440     if (styleHint(QPlatformIntegration::ShowIsFullScreen).toBool())
441         return Qt::WindowFullScreen;
442     else if (styleHint(QPlatformIntegration::ShowIsMaximized).toBool())
443         return Qt::WindowMaximized;
444 
445     return Qt::WindowNoState;
446 }
447 
queryKeyboardModifiers() const448 Qt::KeyboardModifiers QPlatformIntegration::queryKeyboardModifiers() const
449 {
450     return QGuiApplication::keyboardModifiers();
451 }
452 
453 /*!
454   Should be used to obtain a list of possible shortcuts for the given key
455   event. Shortcuts should be encoded as int(Qt::Key + Qt::KeyboardModifiers).
456 
457   One example for more than one possibility is the key combination of Shift+5.
458   That one might trigger a shortcut which is set as "Shift+5" as well as one
459   using %. These combinations depend on the currently set keyboard layout.
460 
461   \note This function should be called only from key event handlers.
462 */
possibleKeys(const QKeyEvent *) const463 QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const
464 {
465     return QList<int>();
466 }
467 
themeNames() const468 QStringList QPlatformIntegration::themeNames() const
469 {
470     return QStringList();
471 }
472 
createPlatformTheme(const QString & name) const473 class QPlatformTheme *QPlatformIntegration::createPlatformTheme(const QString &name) const
474 {
475     Q_UNUSED(name)
476     return new QPlatformTheme;
477 }
478 
479 /*!
480    Factory function for QOffscreenSurface. An offscreen surface will typically be implemented with a
481    pixel buffer (pbuffer). If the platform doesn't support offscreen surfaces, an invisible window
482    will be used by QOffscreenSurface instead.
483 */
createPlatformOffscreenSurface(QOffscreenSurface * surface) const484 QPlatformOffscreenSurface *QPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
485 {
486     Q_UNUSED(surface)
487     return nullptr;
488 }
489 
490 #ifndef QT_NO_SESSIONMANAGER
491 /*!
492    \since 5.2
493 
494    Factory function for QPlatformSessionManager. The default QPlatformSessionManager provides the same
495    functionality as the QSessionManager.
496 */
createPlatformSessionManager(const QString & id,const QString & key) const497 QPlatformSessionManager *QPlatformIntegration::createPlatformSessionManager(const QString &id, const QString &key) const
498 {
499     return new QPlatformSessionManager(id, key);
500 }
501 #endif
502 
503 /*!
504    \since 5.2
505 
506    Function to sync the platform integrations state with the window system.
507 
508    This is often implemented as a roundtrip from the platformintegration to the window system.
509 
510    This function should not call QWindowSystemInterface::flushWindowSystemEvents() or
511    QCoreApplication::processEvents()
512 */
sync()513 void QPlatformIntegration::sync()
514 {
515 }
516 
517 /*!
518    \since 5.7
519 
520     Should sound a bell, using the default volume and sound.
521 
522     \sa QApplication::beep()
523 */
beep() const524 void QPlatformIntegration::beep() const
525 {
526 }
527 
528 #ifndef QT_NO_OPENGL
529 /*!
530   Platform integration function for querying the OpenGL implementation type.
531 
532   Used only when dynamic OpenGL implementation loading is enabled.
533 
534   Subclasses should reimplement this function and return a value based on
535   the OpenGL implementation they have chosen to load.
536 
537   \note The return value does not indicate or limit the types of
538   contexts that can be created by a given implementation. For example
539   a desktop OpenGL implementation may be capable of creating OpenGL
540   ES-compatible contexts too.
541 
542   \sa QOpenGLContext::openGLModuleType(), QOpenGLContext::isOpenGLES()
543 
544   \since 5.3
545  */
openGLModuleType()546 QOpenGLContext::OpenGLModuleType QPlatformIntegration::openGLModuleType()
547 {
548     qWarning("This plugin does not support dynamic OpenGL loading!");
549     return QOpenGLContext::LibGL;
550 }
551 #endif
552 
553 /*!
554     \since 5.5
555 
556     Platform integration function for setting the application icon.
557 
558     \sa QGuiApplication::setWindowIcon()
559 */
setApplicationIcon(const QIcon & icon) const560 void QPlatformIntegration::setApplicationIcon(const QIcon &icon) const
561 {
562     Q_UNUSED(icon);
563 }
564 
565 #if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
566 
567 /*!
568     Factory function for QPlatformVulkanInstance. The \a instance parameter is a
569     pointer to the instance for which a platform-specific backend needs to be
570     created.
571 
572     Returns a pointer to a QPlatformOpenGLContext instance or \nullptr if the context could
573     not be created.
574 
575     \sa QVulkanInstance
576     \since 5.10
577 */
createPlatformVulkanInstance(QVulkanInstance * instance) const578 QPlatformVulkanInstance *QPlatformIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
579 {
580     Q_UNUSED(instance);
581     qWarning("This plugin does not support createPlatformVulkanInstance");
582     return nullptr;
583 }
584 
585 #endif // QT_CONFIG(vulkan)
586 
587 QT_END_NAMESPACE
588