summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/bearer/connman/main.cpp2
-rw-r--r--src/plugins/bearer/connman/qconnmanengine.cpp6
-rw-r--r--src/plugins/bearer/connman/qconnmanengine.h2
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux.cpp12
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux_p.h2
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.mm30
-rw-r--r--src/plugins/bearer/generic/main.cpp4
-rw-r--r--src/plugins/bearer/generic/qgenericengine.cpp16
-rw-r--r--src/plugins/bearer/generic/qgenericengine.h4
-rw-r--r--src/plugins/bearer/linux_common/qofonoservice_linux.cpp6
-rw-r--r--src/plugins/bearer/linux_common/qofonoservice_linux_p.h2
-rw-r--r--src/plugins/bearer/networkmanager/main.cpp2
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp2
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.h2
-rw-r--r--src/plugins/bearer/qbearerengine_impl.h4
-rw-r--r--src/plugins/bearer/qnetworksession_impl.cpp4
-rw-r--r--src/plugins/bearer/qnetworksession_impl.h4
-rw-r--r--src/plugins/generic/tuiotouch/qtuiohandler.cpp1
-rw-r--r--src/plugins/imageformats/gif/main.cpp4
-rw-r--r--src/plugins/imageformats/gif/main.h4
-rw-r--r--src/plugins/imageformats/ico/main.cpp4
-rw-r--r--src/plugins/imageformats/ico/main.h4
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp16
-rw-r--r--src/plugins/imageformats/jpeg/main.cpp4
-rw-r--r--src/plugins/imageformats/jpeg/main.h4
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.pro2
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp235
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h4
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp124
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h38
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibustypes.cpp6
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp57
-rw-r--r--src/plugins/platforms/android/androidjniinput.h2
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp4
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro2
-rw-r--r--src/plugins/platforms/cocoa/main.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaautoreleasepool.h53
-rw-r--r--src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm48
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h12
-rw-r--r--src/plugins/platforms/cocoa/qcocoaclipboard.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.h12
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.h10
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.h10
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h14
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoainputcontext.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoainputcontext.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h51
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm50
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h42
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm19
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h12
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm27
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.h34
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintdevice.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaservices.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm3
-rw-r--r--[-rwxr-xr-x]src/plugins/platforms/cocoa/qcocoasystemtrayicon.h20
-rw-r--r--[-rwxr-xr-x]src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm97
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm3
-rw-r--r--src/plugins/platforms/cocoa/qmultitouch_mac.mm4
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm11
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm6
-rw-r--r--src/plugins/platforms/cocoa/qt_mac_p.h11
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp3
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp2
-rw-r--r--[-rwxr-xr-x]src/plugins/platforms/eglfs/cursor-atlas.pngbin2236 -> 2236 bytes
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp20
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h1
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp30
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h6
-rw-r--r--src/plugins/platforms/eglfs/eglfs_device_lib.pro2
-rw-r--r--src/plugins/platforms/eglfs/qeglfscontext.cpp8
-rw-r--r--src/plugins/platforms/eglfs/qeglfscursor.cpp502
-rw-r--r--src/plugins/platforms/eglfs/qeglfscursor.h141
-rw-r--r--src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp8
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp337
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h65
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp94
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h16
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp79
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h33
-rw-r--r--src/plugins/platforms/haiku/qhaikuclipboard.cpp45
-rw-r--r--src/plugins/platforms/haiku/qhaikuclipboard.h4
-rw-r--r--src/plugins/platforms/haiku/qhaikuwindow.cpp17
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.mm12
-rw-r--r--src/plugins/platforms/ios/qiosclipboard.mm4
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm23
-rw-r--r--src/plugins/platforms/ios/qiosglobal.h2
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm4
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm2
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm4
-rw-r--r--src/plugins/platforms/ios/qiosmenu.mm4
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm8
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm49
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm6
-rw-r--r--src/plugins/platforms/ios/quiaccessibilityelement.h4
-rw-r--r--src/plugins/platforms/ios/quiaccessibilityelement.mm26
-rw-r--r--src/plugins/platforms/ios/quiview.mm4
-rw-r--r--src/plugins/platforms/kms/kms.json3
-rw-r--r--src/plugins/platforms/kms/kms.pro37
-rw-r--r--src/plugins/platforms/kms/main.cpp58
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.cpp217
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.h72
-rw-r--r--src/plugins/platforms/kms/qkmscontext.cpp136
-rw-r--r--src/plugins/platforms/kms/qkmscontext.h71
-rw-r--r--src/plugins/platforms/kms/qkmscursor.cpp116
-rw-r--r--src/plugins/platforms/kms/qkmscursor.h66
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.cpp118
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.h81
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp204
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h108
-rw-r--r--src/plugins/platforms/kms/qkmsnativeinterface.cpp135
-rw-r--r--src/plugins/platforms/kms/qkmsnativeinterface.h64
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.cpp275
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.h122
-rw-r--r--src/plugins/platforms/kms/qkmswindow.cpp66
-rw-r--r--src/plugins/platforms/kms/qkmswindow.h57
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp11
-rw-r--r--src/plugins/platforms/mirclient/mirclient.json3
-rw-r--r--src/plugins/platforms/mirclient/mirclient.pro47
-rw-r--r--src/plugins/platforms/mirclient/qmirclientbackingstore.cpp146
-rw-r--r--src/plugins/platforms/mirclient/qmirclientbackingstore.h70
-rw-r--r--src/plugins/platforms/mirclient/qmirclientclipboard.cpp305
-rw-r--r--src/plugins/platforms/mirclient/qmirclientclipboard.h88
-rw-r--r--src/plugins/platforms/mirclient/qmirclientglcontext.cpp156
-rw-r--r--src/plugins/platforms/mirclient/qmirclientglcontext.h66
-rw-r--r--src/plugins/platforms/mirclient/qmirclientinput.cpp520
-rw-r--r--src/plugins/platforms/mirclient/qmirclientinput.h78
-rw-r--r--src/plugins/platforms/mirclient/qmirclientintegration.cpp264
-rw-r--r--src/plugins/platforms/mirclient/qmirclientintegration.h99
-rw-r--r--src/plugins/platforms/mirclient/qmirclientlogging.h60
-rw-r--r--src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp134
-rw-r--r--src/plugins/platforms/mirclient/qmirclientnativeinterface.h66
-rw-r--r--src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h66
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplatformservices.cpp72
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplatformservices.h54
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplugin.cpp61
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplugin.h53
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreen.cpp296
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreen.h84
-rw-r--r--src/plugins/platforms/mirclient/qmirclienttheme.cpp64
-rw-r--r--src/plugins/platforms/mirclient/qmirclienttheme.h54
-rw-r--r--src/plugins/platforms/mirclient/qmirclientwindow.cpp452
-rw-r--r--src/plugins/platforms/mirclient/qmirclientwindow.h80
-rw-r--r--src/plugins/platforms/platforms.pro2
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp21
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp1
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json27
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp40
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h8
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp41
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp24
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp10
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsscaling.cpp71
-rw-r--r--src/plugins/platforms/windows/qwindowsscaling.h106
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp41
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h14
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp26
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp9
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp127
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h30
-rw-r--r--src/plugins/platforms/windows/windows.pri2
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp23
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp133
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.h22
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp15
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h6
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp157
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.h29
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp173
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h43
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp335
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h33
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp160
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h8
-rw-r--r--src/plugins/platforms/winrt/winrt.pro22
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp4
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp46
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp24
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp33
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp15
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp65
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h18
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp119
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h7
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp82
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h11
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp45
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp279
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h17
-rw-r--r--src/plugins/platforms/xcb/qxlibconvenience.cpp63
-rw-r--r--src/plugins/platforms/xcb/qxlibconvenience.h49
-rw-r--r--src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h5
-rw-r--r--src/plugins/plugins.pro13
-rw-r--r--src/plugins/printsupport/cocoa/main.cpp4
-rw-r--r--src/plugins/printsupport/cups/main.cpp4
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine.cpp8
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine_p.h4
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport.cpp5
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport_p.h3
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.cpp7
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.h5
-rw-r--r--src/plugins/printsupport/printsupport.pro5
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintdevice.cpp4
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintdevice.h3
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/button/core_button_inactive.pngbin2428 -> 2428 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/button/core_button_pressed.pngbin3221 -> 3221 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.pngbin2776 -> 2776 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.pngbin1315 -> 1315 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.pngbin394 -> 394 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/listitem/core_listitem_active.pngbin164 -> 164 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.pngbin135 -> 135 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.pngbin1802 -> 1802 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.pngbin4245 -> 4245 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.pngbin5460 -> 5460 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.pngbin1242 -> 1242 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.pngbin6577 -> 6577 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/button/core_button_inactive.pngbin2262 -> 2262 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/button/core_button_pressed.pngbin2853 -> 2853 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.pngbin2478 -> 2478 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.pngbin1315 -> 1315 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.pngbin394 -> 394 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/listitem/core_listitem_active.pngbin164 -> 164 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.pngbin136 -> 136 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.pngbin1724 -> 1724 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.pngbin3968 -> 3968 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.pngbin4777 -> 4777 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.pngbin1245 -> 1245 bytes
-rw-r--r--[-rwxr-xr-x]src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.pngbin6593 -> 6593 bytes
264 files changed, 6875 insertions, 4251 deletions
diff --git a/src/plugins/bearer/connman/main.cpp b/src/plugins/bearer/connman/main.cpp
index a84121e89b..f1e9d763a7 100644
--- a/src/plugins/bearer/connman/main.cpp
+++ b/src/plugins/bearer/connman/main.cpp
@@ -36,7 +36,6 @@
#include <QtCore/qdebug.h>
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
@@ -78,4 +77,3 @@ QT_END_NAMESPACE
#include "main.moc"
#endif
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp
index 7911857ff5..b7cc5f949c 100644
--- a/src/plugins/bearer/connman/qconnmanengine.cpp
+++ b/src/plugins/bearer/connman/qconnmanengine.cpp
@@ -46,7 +46,6 @@
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusMessage>
#include <QtDBus/QDBusReply>
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
@@ -122,8 +121,10 @@ QList<QNetworkConfigurationPrivate *> QConnmanEngine::getConfigurations()
QMutexLocker locker(&mutex);
QList<QNetworkConfigurationPrivate *> fetchedConfigurations;
QNetworkConfigurationPrivate* cpPriv = 0;
+ const int numFoundConfigurations = foundConfigurations.count();
+ fetchedConfigurations.reserve(numFoundConfigurations);
- for (int i = 0; i < foundConfigurations.count(); ++i) {
+ for (int i = 0; i < numFoundConfigurations; ++i) {
QNetworkConfigurationPrivate *config = new QNetworkConfigurationPrivate;
cpPriv = foundConfigurations.at(i);
@@ -556,4 +557,3 @@ void QConnmanEngine::reEvaluateCellular()
QT_END_NAMESPACE
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h
index 2c1f5490e3..8c79b22bf9 100644
--- a/src/plugins/bearer/connman/qconnmanengine.h
+++ b/src/plugins/bearer/connman/qconnmanengine.h
@@ -53,7 +53,6 @@
#include <QMap>
#include <QVariant>
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
@@ -135,7 +134,6 @@ protected:
QT_END_NAMESPACE
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
#endif
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
index 155e6970fa..10d8285a4a 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp
+++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
@@ -45,7 +45,6 @@
#include "qconnmanservice_linux_p.h"
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
@@ -175,11 +174,10 @@ void QConnmanManagerInterface::connectNotify(const QMetaMethod &signal)
void QConnmanManagerInterface::onServicesChanged(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed)
{
- ConnmanMap connmanobj;
servicesList.clear(); //connman list changes order
- Q_FOREACH (connmanobj, changed) {
+ Q_FOREACH (const ConnmanMap &connmanobj, changed) {
const QString svcPath(connmanobj.objectPath.path());
- servicesList << svcPath;
+ servicesList << svcPath;
}
Q_EMIT servicesChanged(changed, removed);
@@ -221,7 +219,7 @@ QStringList QConnmanManagerInterface::getTechnologies()
QDBusPendingReply<ConnmanMapList> reply = call(QLatin1String("GetTechnologies"));
reply.waitForFinished();
if (!reply.isError()) {
- Q_FOREACH (ConnmanMap map, reply.value()) {
+ Q_FOREACH (const ConnmanMap &map, reply.value()) {
if (!technologiesMap.contains(map.objectPath.path())) {
technologyAdded(map.objectPath, map.propertyMap);
}
@@ -237,7 +235,7 @@ QStringList QConnmanManagerInterface::getServices()
QDBusPendingReply<ConnmanMapList> reply = call(QLatin1String("GetServices"));
reply.waitForFinished();
if (!reply.isError()) {
- Q_FOREACH (ConnmanMap map, reply.value()) {
+ Q_FOREACH (const ConnmanMap &map, reply.value()) {
servicesList << map.objectPath.path();
}
}
@@ -504,5 +502,3 @@ void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call)
QT_END_NAMESPACE
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
-
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h
index 49ca9f391c..1a10a2260a 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h
+++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h
@@ -58,7 +58,6 @@
#include <QtDBus/QDBusContext>
#include <QMap>
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
#ifndef __CONNMAN_DBUS_H
@@ -219,6 +218,5 @@ private:
QT_END_NAMESPACE
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
#endif //QCONNMANSERVICE_H
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm
index eb756db39e..6d16b59d35 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.mm
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -77,12 +77,11 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time
- (id) init
{
[locker lock];
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
notificationCenter = [NSNotificationCenter defaultCenter];
currentInterface = [CWInterface interfaceWithName:nil];
[notificationCenter addObserver:self selector:@selector(notificationHandler:) name:CWPowerDidChangeNotification object:nil];
[locker unlock];
- [autoreleasepool release];
return self;
}
@@ -154,7 +153,7 @@ void QScanThread::quit()
void QScanThread::run()
{
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
QStringList found;
mutex.lock();
CWInterface *currentInterface = [CWInterface interfaceWithName: QCFString::toNSString(interfaceName)];
@@ -236,7 +235,6 @@ void QScanThread::run()
}
}
emit networksChanged();
- [autoreleasepool release];
}
QStringList QScanThread::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose)
@@ -276,7 +274,7 @@ void QScanThread::getUserConfigurations()
{
QMutexLocker locker(&mutex);
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
userProfiles.clear();
NSSet *wifiInterfaces = [CWInterface interfaceNames];
@@ -357,7 +355,6 @@ void QScanThread::getUserConfigurations()
}
}
}
- [autoreleasepool release];
}
QString QScanThread::getSsidFromNetworkName(const QString &name)
@@ -436,7 +433,7 @@ QCoreWlanEngine::~QCoreWlanEngine()
void QCoreWlanEngine::initialize()
{
QMutexLocker locker(&mutex);
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
if ([[CWInterface interfaceNames] count] > 0 && !listener) {
listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init];
@@ -448,7 +445,6 @@ void QCoreWlanEngine::initialize()
storeSession = NULL;
startNetworkChangeLoop();
- [autoreleasepool release];
}
@@ -469,7 +465,7 @@ bool QCoreWlanEngine::hasIdentifier(const QString &id)
void QCoreWlanEngine::connectToId(const QString &id)
{
QMutexLocker locker(&mutex);
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
QString interfaceString = getInterfaceFromId(id);
CWInterface *wifiInterface =
@@ -541,7 +537,6 @@ void QCoreWlanEngine::connectToId(const QString &id)
locker.unlock();
emit connectionError(id, InterfaceLookupError);
- [autoreleasepool release];
}
void QCoreWlanEngine::disconnectFromId(const QString &id)
@@ -554,7 +549,7 @@ void QCoreWlanEngine::disconnectFromId(const QString &id)
emit connectionError(id, DisconnectionError);
return;
}
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
CWInterface *wifiInterface =
[CWInterface interfaceWithName: QCFString::toNSString(interfaceString)];
@@ -563,14 +558,13 @@ void QCoreWlanEngine::disconnectFromId(const QString &id)
[wifiInterface disassociate];
QTimer::singleShot(1000, this,SLOT(checkDisconnect()));
- [autoreleasepool release];
}
void QCoreWlanEngine::checkDisconnect()
{
QMutexLocker locker(&mutex);
if (!disconnectedInterfaceString.isEmpty()) {
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
CWInterface *wifiInterface =
[CWInterface interfaceWithName: QCFString::toNSString(disconnectedInterfaceString)];
@@ -582,7 +576,6 @@ void QCoreWlanEngine::checkDisconnect()
emit connectionError(id, DisconnectionError);
locker.relock();
}
- [autoreleasepool release];
disconnectedInterfaceString.clear();
}
}
@@ -597,7 +590,7 @@ void QCoreWlanEngine::doRequestUpdate()
{
QMutexLocker locker(&mutex);
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
NSSet *wifiInterfaces = [CWInterface interfaceNames];
for (NSString *ifName in wifiInterfaces) {
@@ -607,7 +600,6 @@ void QCoreWlanEngine::doRequestUpdate()
locker.unlock();
if ([wifiInterfaces count] == 0)
networksChanged();
- [autoreleasepool release];
}
bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
@@ -615,12 +607,11 @@ bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
QMutexLocker locker(&mutex);
bool haswifi = false;
if(hasWifi) {
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
CWInterface *defaultInterface = [CWInterface interfaceWithName: QCFString::toNSString(wifiDeviceName)];
if (defaultInterface.powerOn) {
haswifi = true;
}
- [autoreleasepool release];
}
return haswifi;
}
@@ -814,7 +805,7 @@ quint64 QCoreWlanEngine::bytesReceived(const QString &id)
quint64 QCoreWlanEngine::startTime(const QString &identifier)
{
QMutexLocker locker(&mutex);
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacAutoReleasePool pool;
quint64 timestamp = 0;
NSString *filePath = @"/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist";
@@ -861,7 +852,6 @@ quint64 QCoreWlanEngine::startTime(const QString &identifier)
}
}
}
- [autoreleasepool release];
return timestamp;
}
diff --git a/src/plugins/bearer/generic/main.cpp b/src/plugins/bearer/generic/main.cpp
index 112c7420e1..4f79807128 100644
--- a/src/plugins/bearer/generic/main.cpp
+++ b/src/plugins/bearer/generic/main.cpp
@@ -37,8 +37,6 @@
#include <QtCore/qdebug.h>
-#ifndef QT_NO_BEARERMANAGEMENT
-
QT_BEGIN_NAMESPACE
class QGenericEnginePlugin : public QBearerEnginePlugin
@@ -72,5 +70,3 @@ QBearerEngine *QGenericEnginePlugin::create(const QString &key) const
QT_END_NAMESPACE
#include "main.moc"
-
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp
index e1b3d79b38..93b27f16f1 100644
--- a/src/plugins/bearer/generic/qgenericengine.cpp
+++ b/src/plugins/bearer/generic/qgenericengine.cpp
@@ -50,8 +50,10 @@
#ifdef Q_OS_WINCE
typedef ULONG NDIS_OID, *PNDIS_OID;
-#include <nuiouser.h>
-#endif
+# ifndef QT_NO_WINCE_NUIOUSER
+# include <nuiouser.h>
+# endif
+#endif // Q_OS_WINCE
#ifdef Q_OS_LINUX
#include <sys/socket.h>
@@ -61,8 +63,6 @@ typedef ULONG NDIS_OID, *PNDIS_OID;
#include <unistd.h>
#endif
-#ifndef QT_NO_BEARERMANAGEMENT
-
QT_BEGIN_NAMESPACE
#ifndef QT_NO_NETWORKINTERFACE
@@ -73,7 +73,7 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf
NDIS_MEDIUM medium;
NDIS_PHYSICAL_MEDIUM physicalMedium;
-#ifdef Q_OS_WINCE
+#if defined(Q_OS_WINCE) && !defined(QT_NO_WINCE_NUIOUSER)
NDISUIO_QUERY_OID nicGetOid;
HANDLE handle = CreateFile((PTCHAR)NDISUIO_DEVICE_NAME, 0,
FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
@@ -87,7 +87,7 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf
bytesWritten = 0;
-#ifdef Q_OS_WINCE
+#if defined(Q_OS_WINCE) && !defined(QT_NO_WINCE_NUIOUSER)
ZeroMemory(&nicGetOid, sizeof(NDISUIO_QUERY_OID));
nicGetOid.Oid = OID_GEN_MEDIA_SUPPORTED;
nicGetOid.ptcDeviceName = (PTCHAR)interface.utf16();
@@ -105,7 +105,7 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf
bytesWritten = 0;
-#ifdef Q_OS_WINCE
+#if defined(Q_OS_WINCE) && !defined(QT_NO_WINCE_NUIOUSER)
medium = NDIS_MEDIUM( *(LPDWORD)nicGetOid.Data );
ZeroMemory(&nicGetOid, sizeof(NDISUIO_QUERY_OID));
@@ -385,5 +385,3 @@ bool QGenericEngine::requiresPolling() const
}
QT_END_NAMESPACE
-
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/generic/qgenericengine.h b/src/plugins/bearer/generic/qgenericengine.h
index 9acd6c4c2e..4b99c90051 100644
--- a/src/plugins/bearer/generic/qgenericengine.h
+++ b/src/plugins/bearer/generic/qgenericengine.h
@@ -39,8 +39,6 @@
#include <QMap>
#include <QTimer>
-#ifndef QT_NO_BEARERMANAGEMENT
-
QT_BEGIN_NAMESPACE
class QNetworkConfigurationPrivate;
@@ -82,7 +80,5 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_BEARERMANAGEMENT
-
#endif
diff --git a/src/plugins/bearer/linux_common/qofonoservice_linux.cpp b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp
index 6e427544fa..e9e91f9855 100644
--- a/src/plugins/bearer/linux_common/qofonoservice_linux.cpp
+++ b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp
@@ -45,7 +45,6 @@
#include "qofonoservice_linux_p.h"
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QDBusArgument &operator<<(QDBusArgument &argument, const ObjectPathProperties &item)
@@ -98,7 +97,7 @@ QStringList QOfonoManagerInterface::getModems()
QDBusPendingReply<PathPropertiesList> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetModems"), argumentList);
reply.waitForFinished();
if (!reply.isError()) {
- foreach (ObjectPathProperties modem, reply.value()) {
+ foreach (const ObjectPathProperties &modem, reply.value()) {
modemList << modem.path.path();
}
}
@@ -261,7 +260,7 @@ QStringList QOfonoDataConnectionManagerInterface::contexts()
QDBusPendingReply<PathPropertiesList > reply = call(QLatin1String("GetContexts"));
reply.waitForFinished();
if (!reply.isError()) {
- foreach (ObjectPathProperties context, reply.value()) {
+ foreach (const ObjectPathProperties &context, reply.value()) {
contextList << context.path.path();
}
}
@@ -382,4 +381,3 @@ QString QOfonoConnectionContextInterface::name()
QT_END_NAMESPACE
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/linux_common/qofonoservice_linux_p.h b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h
index b051b8feaa..57ea089ec8 100644
--- a/src/plugins/bearer/linux_common/qofonoservice_linux_p.h
+++ b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h
@@ -57,7 +57,6 @@
#include <QtDBus/QDBusContext>
#include <QMap>
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
#define OFONO_SERVICE "org.ofono"
@@ -193,6 +192,5 @@ private slots:
QT_END_NAMESPACE
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
#endif //QOFONOSERVICE_H
diff --git a/src/plugins/bearer/networkmanager/main.cpp b/src/plugins/bearer/networkmanager/main.cpp
index 8a872cf08f..0d22846c44 100644
--- a/src/plugins/bearer/networkmanager/main.cpp
+++ b/src/plugins/bearer/networkmanager/main.cpp
@@ -37,7 +37,6 @@
#include <QtCore/qdebug.h>
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
@@ -77,4 +76,3 @@ QT_END_NAMESPACE
#include "main.moc"
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
index e662d5f2d3..7258877eb7 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
@@ -49,7 +49,6 @@
#include <QDBusReply>
#include "../linux_common/qofonoservice_linux_p.h"
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
@@ -1129,4 +1128,3 @@ void QNetworkManagerEngine::ofonoUnRegistered(const QString &)
QT_END_NAMESPACE
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
index 3d90fcd0e5..1f578890dc 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
@@ -54,7 +54,6 @@
#include <QMap>
#include <QVariant>
-#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
@@ -150,7 +149,6 @@ private:
QT_END_NAMESPACE
#endif // QT_NO_DBUS
-#endif // QT_NO_BEARERMANAGEMENT
#endif
diff --git a/src/plugins/bearer/qbearerengine_impl.h b/src/plugins/bearer/qbearerengine_impl.h
index 6db4d8c6b2..a343474f2c 100644
--- a/src/plugins/bearer/qbearerengine_impl.h
+++ b/src/plugins/bearer/qbearerengine_impl.h
@@ -36,8 +36,6 @@
#include <QtNetwork/private/qbearerengine_p.h>
-#ifndef QT_NO_BEARERMANAGEMENT
-
QT_BEGIN_NAMESPACE
class QBearerEngineImpl : public QBearerEngine
@@ -74,6 +72,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QBearerEngineImpl::ConnectionError)
-#endif // QT_NO_BEARERMANAGEMENT
-
#endif // QBEARERENGINE_IMPL_H
diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp
index f3f3729504..5e9e5e7015 100644
--- a/src/plugins/bearer/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/qnetworksession_impl.cpp
@@ -42,8 +42,6 @@
#include <QtCore/qmutex.h>
#include <QtCore/qstringlist.h>
-#ifndef QT_NO_BEARERMANAGEMENT
-
QT_BEGIN_NAMESPACE
static QBearerEngineImpl *getEngineFromId(const QString &id)
@@ -423,5 +421,3 @@ void QNetworkSessionPrivateImpl::decrementTimeout()
}
QT_END_NAMESPACE
-
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h
index 87a2b29bd4..a26b05ab3b 100644
--- a/src/plugins/bearer/qnetworksession_impl.h
+++ b/src/plugins/bearer/qnetworksession_impl.h
@@ -50,8 +50,6 @@
#include <QtNetwork/private/qnetworkconfigmanager_p.h>
#include <QtNetwork/private/qnetworksession_p.h>
-#ifndef QT_NO_BEARERMANAGEMENT
-
QT_BEGIN_NAMESPACE
class QBearerEngineImpl;
@@ -123,6 +121,4 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_BEARERMANAGEMENT
-
#endif // QNETWORKSESSION_IMPL_H
diff --git a/src/plugins/generic/tuiotouch/qtuiohandler.cpp b/src/plugins/generic/tuiotouch/qtuiohandler.cpp
index 5211ed8381..dd161570e8 100644
--- a/src/plugins/generic/tuiotouch/qtuiohandler.cpp
+++ b/src/plugins/generic/tuiotouch/qtuiohandler.cpp
@@ -317,6 +317,7 @@ void QTuioHandler::process2DCurFseq(const QOscMessage &message)
return;
QList<QWindowSystemInterface::TouchPoint> tpl;
+ tpl.reserve(m_activeCursors.size() + m_deadCursors.size());
foreach (const QTuioCursor &tc, m_activeCursors) {
QWindowSystemInterface::TouchPoint tp = cursorToTouchPoint(tc, win);
diff --git a/src/plugins/imageformats/gif/main.cpp b/src/plugins/imageformats/gif/main.cpp
index 8181900adb..62c4f4b597 100644
--- a/src/plugins/imageformats/gif/main.cpp
+++ b/src/plugins/imageformats/gif/main.cpp
@@ -34,8 +34,6 @@
#include <qimageiohandler.h>
#include <qstringlist.h>
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-
#include "main.h"
#ifdef QT_NO_IMAGEFORMAT_GIF
@@ -69,6 +67,4 @@ QImageIOHandler *QGifPlugin::create(QIODevice *device, const QByteArray &format)
return handler;
}
-#endif // QT_NO_IMAGEFORMATPLUGIN
-
QT_END_NAMESPACE
diff --git a/src/plugins/imageformats/gif/main.h b/src/plugins/imageformats/gif/main.h
index 1b02d5eaf6..56e0655b1f 100644
--- a/src/plugins/imageformats/gif/main.h
+++ b/src/plugins/imageformats/gif/main.h
@@ -34,8 +34,6 @@
#include <qimageiohandler.h>
#include <qstringlist.h>
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-
#ifdef QT_NO_IMAGEFORMAT_GIF
#undef QT_NO_IMAGEFORMAT_GIF
#endif
@@ -56,5 +54,3 @@ public:
};
QT_END_NAMESPACE
-
-#endif // QT_NO_IMAGEFORMATPLUGIN
diff --git a/src/plugins/imageformats/ico/main.cpp b/src/plugins/imageformats/ico/main.cpp
index 80182fb665..03448d4ae1 100644
--- a/src/plugins/imageformats/ico/main.cpp
+++ b/src/plugins/imageformats/ico/main.cpp
@@ -33,8 +33,6 @@
#include "main.h"
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-
QT_BEGIN_NAMESPACE
QImageIOPlugin::Capabilities QICOPlugin::capabilities(QIODevice *device, const QByteArray &format) const
@@ -63,5 +61,3 @@ QImageIOHandler *QICOPlugin::create(QIODevice *device, const QByteArray &format)
}
QT_END_NAMESPACE
-
-#endif /* QT_NO_IMAGEFORMATPLUGIN */
diff --git a/src/plugins/imageformats/ico/main.h b/src/plugins/imageformats/ico/main.h
index a254a626d1..d17dbe824d 100644
--- a/src/plugins/imageformats/ico/main.h
+++ b/src/plugins/imageformats/ico/main.h
@@ -34,8 +34,6 @@
#include <qimageiohandler.h>
#include <qdebug.h>
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-
#ifdef QT_NO_IMAGEFORMAT_ICO
#undef QT_NO_IMAGEFORMAT_ICO
#endif
@@ -53,5 +51,3 @@ public:
};
QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index 4cb5e22bf7..2ddbc4519b 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -96,9 +96,9 @@ public:
QImage iconAt(int index);
static bool canRead(QIODevice *iodev);
- static QList<QImage> read(QIODevice * device);
+ static QVector<QImage> read(QIODevice *device);
- static bool write(QIODevice * device, const QList<QImage> & images);
+ static bool write(QIODevice *device, const QVector<QImage> &images);
private:
bool readHeader();
@@ -612,12 +612,14 @@ QImage ICOReader::iconAt(int index)
\sa write()
*/
-QList<QImage> ICOReader::read(QIODevice * device)
+QVector<QImage> ICOReader::read(QIODevice *device)
{
- QList<QImage> images;
+ QVector<QImage> images;
ICOReader reader(device);
- for (int i = 0; i < reader.count(); i++)
+ const int N = reader.count();
+ images.reserve(N);
+ for (int i = 0; i < N; i++)
images += reader.iconAt(i);
return images;
@@ -636,7 +638,7 @@ QList<QImage> ICOReader::read(QIODevice * device)
\sa read()
*/
-bool ICOReader::write(QIODevice * device, const QList<QImage> & images)
+bool ICOReader::write(QIODevice *device, const QVector<QImage> &images)
{
bool retValue = false;
@@ -849,7 +851,7 @@ bool QtIcoHandler::read(QImage *image)
bool QtIcoHandler::write(const QImage &image)
{
QIODevice *device = QImageIOHandler::device();
- QList<QImage> imgs;
+ QVector<QImage> imgs;
imgs.append(image);
return ICOReader::write(device, imgs);
}
diff --git a/src/plugins/imageformats/jpeg/main.cpp b/src/plugins/imageformats/jpeg/main.cpp
index d009707fa0..c8a575cb43 100644
--- a/src/plugins/imageformats/jpeg/main.cpp
+++ b/src/plugins/imageformats/jpeg/main.cpp
@@ -33,8 +33,6 @@
#include "main.h"
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-
#ifdef QT_NO_IMAGEFORMAT_JPEG
#undef QT_NO_IMAGEFORMAT_JPEG
#endif
@@ -68,5 +66,3 @@ QImageIOHandler *QJpegPlugin::create(QIODevice *device, const QByteArray &format
}
QT_END_NAMESPACE
-
-#endif // QT_NO_IMAGEFORMATPLUGIN
diff --git a/src/plugins/imageformats/jpeg/main.h b/src/plugins/imageformats/jpeg/main.h
index 2d79c84666..77ee33faca 100644
--- a/src/plugins/imageformats/jpeg/main.h
+++ b/src/plugins/imageformats/jpeg/main.h
@@ -34,8 +34,6 @@
#include <qimageiohandler.h>
#include <qstringlist.h>
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-
#ifdef QT_NO_IMAGEFORMAT_JPEG
#undef QT_NO_IMAGEFORMAT_JPEG
#endif
@@ -52,5 +50,3 @@ public:
};
QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
index a9da36c473..a4b5280e64 100644
--- a/src/plugins/platforminputcontexts/compose/compose.pro
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -5,7 +5,7 @@ PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin
load(qt_plugin)
-QT += gui-private
+QT += core-private gui-private
DEFINES += X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"'
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 65020eb848..ad9877eb25 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -36,8 +36,12 @@
#include <QtCore/QByteArray>
#include <QtCore/QTextCodec>
#include <QtCore/QDebug>
+#include <QtCore/QDir>
#include <QtCore/QStringList>
#include <QtCore/QString>
+#include <QtCore/QSaveFile>
+#include <QtCore/QStandardPaths>
+#include <private/qcore_unix_p.h>
#include <algorithm>
@@ -48,12 +52,191 @@
#include <strings.h> // strncasecmp
#include <clocale> // LC_CTYPE
+static const quint32 SupportedCacheVersion = 1;
+
+/*
+ In short on how and why the "Compose" file is cached:
+
+ The "Compose" file is large, for en_US it's likely located at:
+ /usr/share/X11/locale/en_US.UTF-8/Compose
+ and it has about 6000 string lines.
+ Q(Gui)Applications parse this file each time they're created. On modern CPUs
+ it incurs a 4-10 ms startup penalty of each Qt gui app, on older CPUs -
+ tens of ms or more.
+ Since the "Compose" file (almost) never changes using a pre-parsed
+ cache file instead of the "Compose" file is a good idea to improve Qt5
+ application startup time by about 5+ ms (or tens of ms on older CPUs).
+
+ The cache file contains the contents of the QComposeCacheFileHeader struct at the
+ beginning followed by the pre-parsed contents of the "Compose" file.
+
+ struct QComposeCacheFileHeader stores
+ (a) The cache version - in the unlikely event that some day one might need
+ to break compatibility.
+ (b) The (cache) file size.
+ (c) The lastModified field tracks if anything changed since the last time
+ the cache file was saved.
+ If anything did change then we read the compose file and save (cache) it
+ in binary/pre-parsed format, which should happen extremely rarely if at all.
+*/
+
+struct QComposeCacheFileHeader
+{
+ quint32 cacheVersion;
+ // The compiler will add 4 padding bytes anyway.
+ // Reserve them explicitly to possibly use in the future.
+ quint32 reserved;
+ quint64 fileSize;
+ qint64 lastModified;
+};
+
+// localHostName() copied from qtbase/src/corelib/io/qlockfile_unix.cpp
+static QByteArray localHostName()
+{
+ QByteArray hostName(512, Qt::Uninitialized);
+ if (gethostname(hostName.data(), hostName.size()) == -1)
+ return QByteArray();
+ hostName.truncate(strlen(hostName.data()));
+ return hostName;
+}
+
+/*
+ Reads metadata about the Compose file. Later used to determine if the
+ compose cache should be updated. The fileSize field will be zero on failure.
+*/
+static QComposeCacheFileHeader readFileMetadata(const QString &path)
+{
+ QComposeCacheFileHeader info;
+ info.reserved = 0;
+ info.fileSize = 0;
+ const QByteArray pathBytes = QFile::encodeName(path);
+ QT_STATBUF st;
+ if (QT_STAT(pathBytes.data(), &st) != 0)
+ return info;
+ info.lastModified = st.st_mtime;
+ info.fileSize = st.st_size;
+ return info;
+}
+
+static const QString getCacheFilePath()
+{
+ QFile machineIdFile("/var/lib/dbus/machine-id");
+ QString machineId;
+ if (machineIdFile.exists()) {
+ if (machineIdFile.open(QIODevice::ReadOnly))
+ machineId = QString::fromLatin1(machineIdFile.readAll().trimmed());
+ }
+ if (machineId.isEmpty())
+ machineId = localHostName();
+ const QString dirPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
+
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
+ return dirPath + QLatin1String("/qt_compose_cache_big_endian_") + machineId;
+ return dirPath + QLatin1String("/qt_compose_cache_little_endian_") + machineId;
+}
+
+// Returns empty vector on failure
+static QVector<QComposeTableElement> loadCache(const QComposeCacheFileHeader &composeInfo)
+{
+ QVector<QComposeTableElement> vec;
+ const QString cacheFilePath = getCacheFilePath();
+ QFile inputFile(cacheFilePath);
+
+ if (!inputFile.open(QIODevice::ReadOnly))
+ return vec;
+ QComposeCacheFileHeader cacheInfo;
+ // use a "buffer" variable to make the line after this one more readable.
+ char *buffer = reinterpret_cast<char*>(&cacheInfo);
+
+ if (inputFile.read(buffer, sizeof cacheInfo) != sizeof cacheInfo)
+ return vec;
+ if (cacheInfo.fileSize == 0)
+ return vec;
+ // using "!=" just in case someone replaced with a backup that existed before
+ if (cacheInfo.lastModified != composeInfo.lastModified)
+ return vec;
+ if (cacheInfo.cacheVersion != SupportedCacheVersion)
+ return vec;
+ const QByteArray pathBytes = QFile::encodeName(cacheFilePath);
+ QT_STATBUF st;
+ if (QT_STAT(pathBytes.data(), &st) != 0)
+ return vec;
+ const off_t fileSize = st.st_size;
+ if (fileSize > 1024 * 1024 * 5) {
+ // The cache file size is usually about 150KB, so if its size is over
+ // say 5MB then somebody inflated the file, abort.
+ return vec;
+ }
+ const off_t bufferSize = fileSize - (sizeof cacheInfo);
+ const size_t elemSize = sizeof (struct QComposeTableElement);
+ const int elemCount = bufferSize / elemSize;
+ const QByteArray ba = inputFile.read(bufferSize);
+ const char *data = ba.data();
+ // Since we know the number of the (many) elements and their size in
+ // advance calling vector.reserve(..) seems reasonable.
+ vec.reserve(elemCount);
+
+ for (int i = 0; i < elemCount; i++) {
+ const QComposeTableElement *elem =
+ reinterpret_cast<const QComposeTableElement*>(data + (i * elemSize));
+ vec.push_back(*elem);
+ }
+ return vec;
+}
+
+// Returns true on success, false otherwise.
+static bool saveCache(const QComposeCacheFileHeader &info, const QVector<QComposeTableElement> &vec)
+{
+ const QString filePath = getCacheFilePath();
+ QSaveFile outputFile(filePath);
+
+ if (!outputFile.open(QIODevice::WriteOnly))
+ return false;
+ const char *data = reinterpret_cast<const char*>(&info);
+
+ if (outputFile.write(data, sizeof info) != sizeof info)
+ return false;
+ data = reinterpret_cast<const char*>(vec.constData());
+ const qint64 size = vec.size() * (sizeof (struct QComposeTableElement));
+
+ if (outputFile.write(data, size) != size)
+ return false;
+ return outputFile.commit();
+}
+
TableGenerator::TableGenerator() : m_state(NoErrors),
m_systemComposeDir(QString())
{
initPossibleLocations();
- findComposeFile();
- orderComposeTable();
+ QString composeFilePath = findComposeFile();
+#ifdef DEBUG_GENERATOR
+// don't use cache when in debug mode.
+ if (!composeFilePath.isEmpty())
+ qDebug() << "Using Compose file from: " << composeFilePath;
+#else
+ QComposeCacheFileHeader fileInfo = readFileMetadata(composeFilePath);
+ if (fileInfo.fileSize != 0)
+ m_composeTable = loadCache(fileInfo);
+#endif
+ if (m_composeTable.isEmpty() && cleanState()) {
+ if (composeFilePath.isEmpty()) {
+ m_state = MissingComposeFile;
+ } else {
+ QFile composeFile(composeFilePath);
+ composeFile.open(QIODevice::ReadOnly);
+ parseComposeFile(&composeFile);
+ orderComposeTable();
+ if (m_composeTable.isEmpty()) {
+ m_state = EmptyTable;
+#ifndef DEBUG_GENERATOR
+// don't save cache when in debug mode
+ } else {
+ fileInfo.cacheVersion = SupportedCacheVersion;
+ saveCache(fileInfo, m_composeTable);
+#endif
+ }
+ }
+ }
#ifdef DEBUG_GENERATOR
printComposeTable();
#endif
@@ -76,53 +259,39 @@ void TableGenerator::initPossibleLocations()
m_possibleLocations.append(QStringLiteral(X11_PREFIX "/lib/X11/locale"));
}
-void TableGenerator::findComposeFile()
+QString TableGenerator::findComposeFile()
{
- bool found = false;
// check if XCOMPOSEFILE points to a Compose file
if (qEnvironmentVariableIsSet("XCOMPOSEFILE")) {
- QString composeFile(qgetenv("XCOMPOSEFILE"));
- if (composeFile.endsWith(QLatin1String("Compose")))
- found = processFile(composeFile);
+ QString path(qgetenv("XCOMPOSEFILE"));
+ if (path.endsWith(QLatin1String("Compose")))
+ return path;
else
qWarning("Qt Warning: XCOMPOSEFILE doesn't point to a valid Compose file");
-#ifdef DEBUG_GENERATOR
- if (found)
- qDebug() << "Using Compose file from: " << composeFile;
-#endif
}
+
// check if user’s home directory has a file named .XCompose
- if (!found && cleanState()) {
- QString composeFile = qgetenv("HOME") + QStringLiteral("/.XCompose");
- if (QFile(composeFile).exists())
- found = processFile(composeFile);
-#ifdef DEBUG_GENERATOR
- if (found)
- qDebug() << "Using Compose file from: " << composeFile;
-#endif
+ if (cleanState()) {
+ QString path = qgetenv("HOME") + QStringLiteral("/.XCompose");
+ if (QFile(path).exists())
+ return path;
}
+
// check for the system provided compose files
- if (!found && cleanState()) {
+ if (cleanState()) {
QString table = composeTableForLocale();
if (cleanState()) {
if (table.isEmpty())
// no table mappings for the system's locale in the compose.dir
m_state = UnsupportedLocale;
- else
- found = processFile(systemComposeDir() + QLatin1Char('/') + table);
-#ifdef DEBUG_GENERATOR
- if (found)
- qDebug() << "Using Compose file from: " <<
- systemComposeDir() + QLatin1Char('/') + table;
-#endif
+ else {
+ QString path = QDir(systemComposeDir()).filePath(table);
+ if (QFile(path).exists())
+ return path;
+ }
}
}
-
- if (found && m_composeTable.isEmpty())
- m_state = EmptyTable;
-
- if (!found)
- m_state = MissingComposeFile;
+ return QString();
}
QString TableGenerator::composeTableForLocale()
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
index 468da4cad1..8ad081bea5 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
@@ -43,6 +43,8 @@
//#define DEBUG_GENERATOR
+/* Whenever QComposeTableElement gets modified supportedCacheVersion
+ from qtablegenerator.cpp must be bumped. */
struct QComposeTableElement {
uint keys[QT_KEYSEQUENCE_MAX_LEN];
uint value;
@@ -107,7 +109,7 @@ protected:
void parseKeySequence(char *line);
void parseIncludeInstruction(QString line);
- void findComposeFile();
+ QString findComposeFile();
bool findSystemComposeDir();
QString systemComposeDir();
QString composeTableForLocale();
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
index 673942b5d9..27fca7c6ed 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -39,6 +39,10 @@
#include <qwindow.h>
#include <qevent.h>
+#include <qpa/qplatformcursor.h>
+#include <qpa/qplatformscreen.h>
+#include <qpa/qwindowsysteminterface.h>
+
#include "qibusproxy.h"
#include "qibusinputcontextproxy.h"
#include "qibustypes.h"
@@ -48,8 +52,14 @@
#include <QtDBus>
+#ifndef IBUS_RELEASE_MASK
+#define IBUS_RELEASE_MASK (1 << 30)
+#endif
+
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(qtQpaInputMethods, "qt.qpa.input.methods")
+
enum { debug = 0 };
class QIBusPlatformInputContextPrivate
@@ -86,6 +96,13 @@ QIBusPlatformInputContext::QIBusPlatformInputContext ()
}
QInputMethod *p = qApp->inputMethod();
connect(p, SIGNAL(cursorRectangleChanged()), this, SLOT(cursorRectChanged()));
+ m_eventFilterUseSynchronousMode = false;
+ if (qEnvironmentVariableIsSet("IBUS_ENABLE_SYNC_MODE")) {
+ bool ok;
+ int enableSync = qgetenv("IBUS_ENABLE_SYNC_MODE").toInt(&ok);
+ if (ok && enableSync == 1)
+ m_eventFilterUseSynchronousMode = true;
+ }
}
QIBusPlatformInputContext::~QIBusPlatformInputContext (void)
@@ -272,8 +289,7 @@ void QIBusPlatformInputContext::deleteSurroundingText(int offset, uint n_chars)
QCoreApplication::sendEvent(input, &event);
}
-bool
-QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, bool press)
+bool QIBusPlatformInputContext::filterEvent(const QEvent *event)
{
if (!d->valid)
return false;
@@ -281,15 +297,105 @@ QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state,
if (!inputMethodAccepted())
return false;
- if (!press)
- return false;
+ const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
+ quint32 sym = keyEvent->nativeVirtualKey();
+ quint32 code = keyEvent->nativeScanCode();
+ quint32 state = keyEvent->nativeModifiers();
+ quint32 ibusState = state;
+
+ if (keyEvent->type() != QEvent::KeyPress)
+ ibusState |= IBUS_RELEASE_MASK;
+
+ QDBusPendingReply<bool> reply = d->context->ProcessKeyEvent(sym, code - 8, ibusState);
+
+ if (m_eventFilterUseSynchronousMode || reply.isFinished()) {
+ bool retval = reply.value();
+ qCDebug(qtQpaInputMethods) << "filterEvent return" << code << sym << state << retval;
+ return retval;
+ }
+
+ Qt::KeyboardModifiers modifiers = keyEvent->modifiers();
+ const int qtcode = keyEvent->key();
+
+ // From QKeyEvent::modifiers()
+ switch (qtcode) {
+ case Qt::Key_Shift:
+ modifiers ^= Qt::ShiftModifier;
+ break;
+ case Qt::Key_Control:
+ modifiers ^= Qt::ControlModifier;
+ break;
+ case Qt::Key_Alt:
+ modifiers ^= Qt::AltModifier;
+ break;
+ case Qt::Key_Meta:
+ modifiers ^= Qt::MetaModifier;
+ break;
+ case Qt::Key_AltGr:
+ modifiers ^= Qt::GroupSwitchModifier;
+ break;
+ }
+
+ QVariantList args;
+ args << QVariant::fromValue(keyEvent->timestamp());
+ args << QVariant::fromValue(static_cast<uint>(keyEvent->type()));
+ args << QVariant::fromValue(qtcode);
+ args << QVariant::fromValue(code) << QVariant::fromValue(sym) << QVariant::fromValue(state);
+ args << QVariant::fromValue(keyEvent->text());
+ args << QVariant::fromValue(keyEvent->isAutoRepeat());
- keycode -= 8; // ###
- QDBusReply<bool> reply = d->context->ProcessKeyEvent(keyval, keycode, state);
+ QIBusFilterEventWatcher *watcher = new QIBusFilterEventWatcher(reply, this, QGuiApplication::focusWindow(), modifiers, args);
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &QIBusPlatformInputContext::filterEventFinished);
-// qDebug() << "x11FilterEvent return" << reply.value();
+ return true;
+}
+
+void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *call)
+{
+ QIBusFilterEventWatcher *watcher = (QIBusFilterEventWatcher *) call;
+ QDBusPendingReply<bool> reply = *call;
+
+ if (reply.isError()) {
+ call->deleteLater();
+ return;
+ }
- return reply.value();
+ // Use watcher's window instead of the current focused window
+ // since there is a time lag until filterEventFinished() returns.
+ QWindow *window = watcher->window();
+
+ if (!window) {
+ call->deleteLater();
+ return;
+ }
+
+ Qt::KeyboardModifiers modifiers = watcher->modifiers();
+ QVariantList args = watcher->arguments();
+ const ulong time = static_cast<const ulong>(args.at(0).toUInt());
+ const QEvent::Type type = static_cast<const QEvent::Type>(args.at(1).toUInt());
+ const int qtcode = args.at(2).toInt();
+ const quint32 code = args.at(3).toUInt();
+ const quint32 sym = args.at(4).toUInt();
+ const quint32 state = args.at(5).toUInt();
+ const QString string = args.at(6).toString();
+ const bool isAutoRepeat = args.at(7).toBool();
+
+ // copied from QXcbKeyboard::handleKeyEvent()
+ bool retval = reply.value();
+ qCDebug(qtQpaInputMethods) << "filterEventFinished return" << code << sym << state << retval;
+ if (!retval) {
+ if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu
+ && window != NULL) {
+ const QPoint globalPos = window->screen()->handle()->cursor()->pos();
+ const QPoint pos = window->mapFromGlobal(globalPos);
+ QWindowSystemInterface::handleContextMenuEvent(window, false, pos,
+ globalPos, modifiers);
+ }
+ QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
+ code, sym, state, string, isAutoRepeat);
+
+ }
+ call->deleteLater();
}
QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
@@ -340,7 +446,7 @@ QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
{
- QByteArray display(getenv("DISPLAY"));
+ QByteArray display(qgetenv("DISPLAY"));
QByteArray host = "unix";
QByteArray displayNumber = "0";
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
index 816da8d377..127db7df8b 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
@@ -35,11 +35,44 @@
#include <qpa/qplatforminputcontext.h>
+#include <QtCore/qpointer.h>
+#include <QtDBus/qdbuspendingreply.h>
+#include <QLoggingCategory>
+#include <QWindow>
+
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(qtQpaInputMethods)
+
class QIBusPlatformInputContextPrivate;
class QDBusVariant;
+class QIBusFilterEventWatcher: public QDBusPendingCallWatcher
+{
+public:
+ explicit QIBusFilterEventWatcher(const QDBusPendingCall &call,
+ QObject *parent = 0,
+ QWindow *window = 0,
+ const Qt::KeyboardModifiers modifiers = 0,
+ const QVariantList arguments = QVariantList())
+ : QDBusPendingCallWatcher(call, parent)
+ , m_window(window)
+ , m_modifiers(modifiers)
+ , m_arguments(arguments)
+ {}
+ ~QIBusFilterEventWatcher()
+ {}
+
+ inline QWindow *window() const { return m_window; }
+ inline const Qt::KeyboardModifiers modifiers() const { return m_modifiers; }
+ inline const QVariantList arguments() const { return m_arguments; }
+
+private:
+ QPointer<QWindow> m_window;
+ const Qt::KeyboardModifiers m_modifiers;
+ const QVariantList m_arguments;
+};
+
class QIBusPlatformInputContext : public QPlatformInputContext
{
Q_OBJECT
@@ -54,8 +87,7 @@ public:
void reset() Q_DECL_OVERRIDE;
void commit() Q_DECL_OVERRIDE;
void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE;
-
- Q_INVOKABLE bool x11FilterEvent(uint keyval, uint keycode, uint state, bool press);
+ bool filterEvent(const QEvent *event) Q_DECL_OVERRIDE;
public Q_SLOTS:
void commitText(const QDBusVariant &text);
@@ -63,9 +95,11 @@ public Q_SLOTS:
void cursorRectChanged();
void deleteSurroundingText(int offset, uint n_chars);
void surroundingTextRequired();
+ void filterEventFinished(QDBusPendingCallWatcher *call);
private:
QIBusPlatformInputContextPrivate *d;
+ bool m_eventFilterUseSynchronousMode;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
index d6be6cbb31..f88e5ca5a3 100644
--- a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
@@ -225,9 +225,10 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &at
QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const
{
QHash<QPair<int, int>, QTextCharFormat> rangeAttrs;
+ const int numAttributes = attributes.size();
// Merge text fomats for identical ranges into a single QTextFormat.
- for (int i = 0; i < attributes.size(); ++i) {
+ for (int i = 0; i < numAttributes; ++i) {
const QIBusAttribute &attr = attributes.at(i);
const QTextCharFormat &format = attr.format();
@@ -239,8 +240,9 @@ QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const
// Assemble list in original attribute order.
QList<QInputMethodEvent::Attribute> imAttrs;
+ imAttrs.reserve(numAttributes);
- for (int i = 0; i < attributes.size(); ++i) {
+ for (int i = 0; i < numAttributes; ++i) {
const QIBusAttribute &attr = attributes.at(i);
const QTextFormat &format = attr.format();
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 8ee3ff88d1..b410e5f68e 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -70,18 +70,20 @@ namespace QtAndroidInput
candidatesEnd);
}
- void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints)
+ void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
"showSoftwareKeyboard",
- "(IIIII)V",
+ "(IIIIII)V",
left,
top,
width,
height,
- inputHints);
+ inputHints,
+ enterKeyType
+ );
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints;
+ qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
#endif
}
@@ -238,6 +240,52 @@ namespace QtAndroidInput
QWindowSystemInterface::handleTouchEvent(window, touchDevice, m_touchPoints);
}
+ static void tabletEvent(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint deviceId, jlong time, jint action,
+ jint pointerType, jint buttonState, jfloat x, jfloat y, jfloat pressure)
+ {
+ QPointF globalPosF(x, y);
+ QPoint globalPos((int)x, (int)y);
+ QWindow *tlw = topLevelWindowAt(globalPos);
+ QPointF localPos = tlw ? (globalPosF - tlw->position()) : globalPosF;
+
+ // Galaxy Note with plain Android:
+ // 0 1 0 stylus press
+ // 2 1 0 stylus drag
+ // 1 1 0 stylus release
+ // 0 1 2 stylus press with side-button held
+ // 2 1 2 stylus drag with side-button held
+ // 1 1 2 stylus release with side-button held
+ // Galaxy Note 4 with Samsung firmware:
+ // 0 1 0 stylus press
+ // 2 1 0 stylus drag
+ // 1 1 0 stylus release
+ // 211 1 2 stylus press with side-button held
+ // 213 1 2 stylus drag with side-button held
+ // 212 1 2 stylus release with side-button held
+ // when action == ACTION_UP (1) it's a release; otherwise we say which button is pressed
+ Qt::MouseButtons buttons = Qt::NoButton;
+ switch (action) {
+ case 1: // ACTION_UP
+ case 212: // stylus release while side-button held on Galaxy Note 4
+ buttons = Qt::NoButton;
+ break;
+ default: // action is press or drag
+ if (buttonState == 0)
+ buttons = Qt::LeftButton;
+ else // 2 means RightButton
+ buttons = Qt::MouseButtons(buttonState);
+ break;
+ }
+
+#ifdef QT_DEBUG_ANDROID_STYLUS
+ qDebug() << action << pointerType << buttonState << "@" << x << y << "pressure" << pressure << ": buttons" << buttons;
+#endif
+
+ QWindowSystemInterface::handleTabletEvent(tlw, ulong(time),
+ localPos, globalPosF, QTabletEvent::Stylus, pointerType,
+ buttons, pressure, 0, 0, 0., 0., 0, deviceId, Qt::NoModifier);
+ }
+
static int mapAndroidKey(int key)
{
// 0--9 0x00000007 -- 0x00000010
@@ -702,6 +750,7 @@ namespace QtAndroidInput
{"mouseUp", "(III)V", (void *)mouseUp},
{"mouseMove", "(III)V", (void *)mouseMove},
{"longPress", "(III)V", (void *)longPress},
+ {"tabletEvent", "(IIJIIIFFF)V", (void *)tabletEvent},
{"keyDown", "(IIIZ)V", (void *)keyDown},
{"keyUp", "(IIIZ)V", (void *)keyUp},
{"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged}
diff --git a/src/plugins/platforms/android/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h
index b5a2ef06e4..d737dc9c98 100644
--- a/src/plugins/platforms/android/androidjniinput.h
+++ b/src/plugins/platforms/android/androidjniinput.h
@@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE
namespace QtAndroidInput
{
// Software keyboard support
- void showSoftwareKeyboard(int top, int left, int width, int height, int inputHints);
+ void showSoftwareKeyboard(int top, int left, int width, int height, int inputHints, int enterKeyType);
void resetSoftwareKeyboard();
void hideSoftwareKeyboard();
bool isSoftwareKeyboardVisible();
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index a04bf1eccb..cd40b7eec2 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -600,6 +600,11 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state
return;
}
+ if (state == Qt::ApplicationActive)
+ QtAndroidPrivate::handleResume();
+ else if (state == Qt::ApplicationInactive)
+ QtAndroidPrivate::handlePause();
+
if (state <= Qt::ApplicationInactive) {
// NOTE: sometimes we will receive two consecutive suspended notifications,
// In the second suspended notification, QWindowSystemInterface::flushWindowSystemEvents()
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index d264f74d66..b44340106d 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -545,7 +545,9 @@ void QAndroidInputContext::showInputPanel()
rect.top(),
rect.width(),
rect.height(),
- query->value(Qt::ImHints).toUInt());
+ query->value(Qt::ImHints).toUInt(),
+ query->value(Qt::ImEnterKeyType).toUInt()
+ );
}
void QAndroidInputContext::showInputPanelLater(Qt::ApplicationState state)
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index ad6cb3a1fc..ba0e6b001a 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -12,7 +12,6 @@ OBJECTIVE_SOURCES += main.mm \
qcocoawindow.mm \
qnsview.mm \
qnsviewaccessibility.mm \
- qcocoaautoreleasepool.mm \
qnswindowdelegate.mm \
qcocoanativeinterface.mm \
qcocoaeventdispatcher.mm \
@@ -48,7 +47,6 @@ HEADERS += qcocoaintegration.h \
qcocoabackingstore.h \
qcocoawindow.h \
qnsview.h \
- qcocoaautoreleasepool.h \
qnswindowdelegate.h \
qcocoanativeinterface.h \
qcocoaeventdispatcher.h \
diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm
index b7e8fa1fca..43ff715161 100644
--- a/src/plugins/platforms/cocoa/main.mm
+++ b/src/plugins/platforms/cocoa/main.mm
@@ -50,11 +50,9 @@ public:
QPlatformIntegration * QCocoaIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
- Q_UNUSED(paramList);
-
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (system.compare(QLatin1String("cocoa"), Qt::CaseInsensitive) == 0)
- return new QCocoaIntegration;
+ return new QCocoaIntegration(paramList);
return 0;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
index 061dfac156..18ff9aeb29 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
@@ -45,10 +45,10 @@ class QCocoaAccessibility : public QPlatformAccessibility
public:
QCocoaAccessibility();
~QCocoaAccessibility();
- void notifyAccessibilityUpdate(QAccessibleEvent *event);
- void setRootObject(QObject *o);
- void initialize();
- void cleanup();
+ void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE;
+ void setRootObject(QObject *o) Q_DECL_OVERRIDE;
+ void initialize() Q_DECL_OVERRIDE;
+ void cleanup() Q_DECL_OVERRIDE;
};
namespace QCocoaAccessible {
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
index 04e51d5392..abaaba91a5 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
@@ -100,6 +100,7 @@
- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate;
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
- (void) removeAppleEventHandlers;
+- (bool) inLaunch;
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaApplicationDelegate);
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 6c673a4f5d..cac50825af 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -284,6 +284,11 @@ QT_END_NAMESPACE
[eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL];
}
+- (bool) inLaunch
+{
+ return inLaunch;
+}
+
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
Q_UNUSED(aNotification);
diff --git a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
deleted file mode 100644
index 8b2a9f3788..0000000000
--- a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOCOAAUTORELEASEPOOL_H
-#define QCOCOAAUTORELEASEPOOL_H
-
-#undef slots
-#include <qglobal.h>
-#include <Cocoa/Cocoa.h>
-
-QT_BEGIN_NAMESPACE
-class QCocoaAutoReleasePool
-{
-public:
- QCocoaAutoReleasePool();
- ~QCocoaAutoReleasePool();
-
-private:
- NSAutoreleasePool *pool;
-};
-QT_END_NAMESPACE
-
-#endif // QCOCOAAUTORELEASEPOOL_H
diff --git a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm
deleted file mode 100644
index 8f30365186..0000000000
--- a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm
+++ /dev/null
@@ -1,48 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcocoaautoreleasepool.h"
-
-QT_BEGIN_NAMESPACE
-
-QCocoaAutoReleasePool::QCocoaAutoReleasePool()
-{
- pool = [[NSAutoreleasePool alloc] init];
-}
-
-QCocoaAutoReleasePool::~QCocoaAutoReleasePool()
-{
- [pool release];
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 3737584c4c..5a199de4a5 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -49,12 +49,12 @@ public:
QCocoaBackingStore(QWindow *window);
~QCocoaBackingStore();
- QPaintDevice *paintDevice();
- void flush(QWindow *widget, const QRegion &region, const QPoint &offset);
- QImage toImage() const;
- void resize (const QSize &size, const QRegion &);
- bool scroll(const QRegion &area, int dx, int dy);
- void beginPaint(const QRegion &region);
+ QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
+ void flush(QWindow *widget, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ QImage toImage() const Q_DECL_OVERRIDE;
+ void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
+ bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
+ void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
qreal getBackingStoreDevicePixelRatio();
private:
diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.h b/src/plugins/platforms/cocoa/qcocoaclipboard.h
index e3df9a99b1..e53942b068 100644
--- a/src/plugins/platforms/cocoa/qcocoaclipboard.h
+++ b/src/plugins/platforms/cocoa/qcocoaclipboard.h
@@ -47,10 +47,10 @@ class QCocoaClipboard : public QObject, public QPlatformClipboard
public:
QCocoaClipboard();
- QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
- void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
- bool supportsMode(QClipboard::Mode mode) const;
- bool ownsMode(QClipboard::Mode mode) const;
+ QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
+ void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
+ bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
+ bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
private Q_SLOTS:
void handleApplicationStateChanged(Qt::ApplicationState state);
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h
index 3183705330..705f97cd2a 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h
@@ -43,14 +43,14 @@ class QCocoaColorDialogHelper : public QPlatformColorDialogHelper
{
public:
QCocoaColorDialogHelper();
- virtual ~QCocoaColorDialogHelper();
+ ~QCocoaColorDialogHelper();
- void exec();
- bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
- void hide();
+ void exec() Q_DECL_OVERRIDE;
+ bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE;
+ void hide() Q_DECL_OVERRIDE;
- void setCurrentColor(const QColor&);
- QColor currentColor() const;
+ void setCurrentColor(const QColor&) Q_DECL_OVERRIDE;
+ QColor currentColor() const Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.h b/src/plugins/platforms/cocoa/qcocoacursor.h
index cc6cbaf59e..d104939f0c 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.h
+++ b/src/plugins/platforms/cocoa/qcocoacursor.h
@@ -47,9 +47,9 @@ public:
QCocoaCursor();
~QCocoaCursor();
- virtual void changeCursor(QCursor *cursor, QWindow *window);
- virtual QPoint pos() const;
- virtual void setPos(const QPoint &position);
+ void changeCursor(QCursor *cursor, QWindow *window) Q_DECL_OVERRIDE;
+ QPoint pos() const Q_DECL_OVERRIDE;
+ void setPos(const QPoint &position) Q_DECL_OVERRIDE;
private:
QHash<Qt::CursorShape, NSCursor *> m_cursors;
NSCursor *convertCursor(QCursor *cursor);
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index 922809f90d..2098f0dc8c 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -34,7 +34,6 @@
#include "qcocoacursor.h"
#include "qcocoawindow.h"
#include "qcocoahelpers.h"
-#include "qcocoaautoreleasepool.h"
#include <QtGui/QBitmap>
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.h b/src/plugins/platforms/cocoa/qcocoadrag.h
index e087fcee26..c1eeb34679 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.h
+++ b/src/plugins/platforms/cocoa/qcocoadrag.h
@@ -47,13 +47,13 @@ class QCocoaDrag : public QPlatformDrag
{
public:
QCocoaDrag();
- virtual ~QCocoaDrag();
+ ~QCocoaDrag();
- virtual QMimeData *platformDropData();
- virtual Qt::DropAction drag(QDrag *m_drag);
+ QMimeData *platformDropData() Q_DECL_OVERRIDE;
+ Qt::DropAction drag(QDrag *m_drag) Q_DECL_OVERRIDE;
- virtual Qt::DropAction defaultAction(Qt::DropActions possibleActions,
- Qt::KeyboardModifiers modifiers) const;
+ Qt::DropAction defaultAction(Qt::DropActions possibleActions,
+ Qt::KeyboardModifiers modifiers) const Q_DECL_OVERRIDE;
/**
* to meet NSView dragImage:at guarantees, we need to record the original
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index 13a8c89dbb..4a2cb42f87 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -80,7 +80,6 @@
//
#include <QtCore/qabstracteventdispatcher.h>
-#include <QtCore/qhash.h>
#include <QtCore/qstack.h>
#include <QtGui/qwindowdefs.h>
#include <QtCore/private/qabstracteventdispatcher_p.h>
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 52b2e23345..1865624d57 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -66,13 +66,11 @@
****************************************************************************/
#include "qcocoaeventdispatcher.h"
-#include "qcocoaautoreleasepool.h"
#include "qcocoawindow.h"
#include "qcocoahelpers.h"
#include "qguiapplication.h"
#include "qevent.h"
-#include "qhash.h"
#include "qmutex.h"
#include "qsocketnotifier.h"
#include <qpa/qplatformwindow.h>
@@ -365,7 +363,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
if (d->interrupt)
break;
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
NSEvent* event = 0;
// First, send all previously excluded input events, if any:
@@ -623,7 +621,7 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
continue;
if (!info.session) {
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(info.window->handle());
NSWindow *nswindow = cocoaWindow->nativeWindow();
if (!nswindow)
@@ -671,7 +669,7 @@ void QCocoaEventDispatcherPrivate::updateChildrenWorksWhenModal()
// Make the dialog children of the window
// active. And make the dialog children of
// the previous modal dialog unactive again:
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
int size = cocoaModalSessionStack.size();
if (size > 0){
if (QWindow *prevModal = cocoaModalSessionStack[size-1].window)
@@ -692,7 +690,7 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions()
// point they were marked as stopped), is that ending a session
// when no other session runs below it on the stack will make cocoa
// drop some events on the floor.
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
int stackSize = cocoaModalSessionStack.size();
for (int i=stackSize-1; i>=0; --i) {
@@ -927,7 +925,7 @@ void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents()
{
// In case the event dispatcher is waiting for more
// events somewhere, we post a dummy event to wake it up:
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
[NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint
modifierFlags:0 timestamp:0. windowNumber:0 context:0
subtype:QtCocoaEventSubTypeWakeup data1:0 data2:0] atStart:NO];
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 4ece1b5a22..93ee4e8624 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -53,7 +53,6 @@
#include <qvarlengtharray.h>
#include <stdlib.h>
#include <qabstracteventdispatcher.h>
-#include "qcocoaautoreleasepool.h"
#include <QDir>
#include <qpa/qplatformnativeinterface.h>
@@ -557,7 +556,7 @@ QCocoaFileDialogHelper::~QCocoaFileDialogHelper()
{
if (!mDelegate)
return;
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
[mDelegate release];
mDelegate = 0;
}
@@ -687,7 +686,7 @@ bool QCocoaFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate()
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
const SharedPointerFileDialogOptions &opts = options();
const QList<QUrl> selectedFiles = opts->initiallySelectedFiles();
@@ -737,7 +736,7 @@ void QCocoaFileDialogHelper::exec()
// QEventLoop has been interrupted, and the second-most event loop has not
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
// showing a native modal dialog will fail.
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if ([mDelegate runApplicationModalPanel])
emit accept();
else
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
index 5a241bc242..23266cfa79 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
@@ -45,13 +45,13 @@ public:
QCocoaFontDialogHelper();
~QCocoaFontDialogHelper();
- void exec();
+ void exec() Q_DECL_OVERRIDE;
- bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
- void hide();
+ bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE;
+ void hide() Q_DECL_OVERRIDE;
- void setCurrentFont(const QFont &);
- QFont currentFont() const;
+ void setCurrentFont(const QFont &) Q_DECL_OVERRIDE;
+ QFont currentFont() const Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
index 2c8a3e39f3..fa6db018a7 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.h
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -50,22 +50,22 @@ public:
QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, const QVariant &nativeHandle);
~QCocoaGLContext();
- QSurfaceFormat format() const;
+ QSurfaceFormat format() const Q_DECL_OVERRIDE;
- void swapBuffers(QPlatformSurface *surface);
+ void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- bool makeCurrent(QPlatformSurface *surface);
- void doneCurrent();
+ bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ void doneCurrent() Q_DECL_OVERRIDE;
- void (*getProcAddress(const QByteArray &procName)) ();
+ void (*getProcAddress(const QByteArray &procName)) () Q_DECL_OVERRIDE;
void update();
static NSOpenGLPixelFormat *createNSOpenGLPixelFormat(const QSurfaceFormat &format);
NSOpenGLContext *nsOpenGLContext() const;
- bool isSharing() const;
- bool isValid() const;
+ bool isSharing() const Q_DECL_OVERRIDE;
+ bool isValid() const Q_DECL_OVERRIDE;
void windowWasHidden();
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index a3c72c58b9..1d8a1c5e70 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -33,7 +33,6 @@
#include "qcocoaglcontext.h"
#include "qcocoawindow.h"
-#include "qcocoaautoreleasepool.h"
#include "qcocoahelpers.h"
#include <qdebug.h>
#include <QtCore/private/qcore_mac_p.h>
@@ -145,7 +144,7 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
if (m_format.renderableType() != QSurfaceFormat::OpenGL)
return;
- QCocoaAutoReleasePool pool; // For the SG Canvas render thread
+ QMacAutoReleasePool pool; // For the SG Canvas render thread
NSOpenGLPixelFormat *pixelFormat = static_cast <NSOpenGLPixelFormat *>(qcgl_createNSOpenGLPixelFormat(m_format));
m_shareContext = share ? static_cast<QCocoaGLContext *>(share)->nsOpenGLContext() : nil;
@@ -218,7 +217,7 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
{
Q_ASSERT(surface->surface()->supportsOpenGL());
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
setActiveWindow(window);
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 5f97e2996c..bb493ef2be 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -33,7 +33,6 @@
#include "qcocoahelpers.h"
-#include "qcocoaautoreleasepool.h"
#include <QtCore>
#include <QtGui>
@@ -270,10 +269,14 @@ bool operator<(const KeyPair &entry, const Qt::Key &key)
return entry.qtKey < key;
}
-static bool qtKey2CocoaKeySortLessThan(const KeyPair &entry1, const KeyPair &entry2)
+struct qtKey2CocoaKeySortLessThan
{
- return entry1.qtKey < entry2.qtKey;
-}
+ typedef bool result_type;
+ Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW
+ {
+ return entry1.qtKey < entry2.qtKey;
+ }
+};
static const int NumEntries = 59;
static const KeyPair entries[NumEntries] = {
@@ -353,7 +356,7 @@ QChar qt_mac_qtKey2CocoaKey(Qt::Key key)
mustInit = false;
for (int i=0; i<NumEntries; ++i)
rev_entries[i] = entries[i];
- std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan);
+ std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan());
}
const QVector<KeyPair>::iterator i
= std::lower_bound(rev_entries.begin(), rev_entries.end(), key);
@@ -630,7 +633,7 @@ QString qt_mac_applicationName()
int qt_mac_mainScreenHeight()
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
// The first screen in the screens array is documented
// to have the (0,0) origin.
NSRect screenFrame = [[[NSScreen screens] firstObject] frame];
diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.h b/src/plugins/platforms/cocoa/qcocoainputcontext.h
index abe45344a9..c7df823dc4 100644
--- a/src/plugins/platforms/cocoa/qcocoainputcontext.h
+++ b/src/plugins/platforms/cocoa/qcocoainputcontext.h
@@ -46,9 +46,9 @@ public:
explicit QCocoaInputContext();
~QCocoaInputContext();
- virtual bool isValid() const { return true; }
+ bool isValid() const Q_DECL_OVERRIDE { return true; }
- virtual void reset();
+ void reset() Q_DECL_OVERRIDE;
private Q_SLOTS:
void connectSignals();
diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
index c22fe8774b..f072991bdd 100644
--- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
@@ -34,7 +34,6 @@
#include "qnsview.h"
#include "qcocoainputcontext.h"
#include "qcocoanativeinterface.h"
-#include "qcocoaautoreleasepool.h"
#include "qcocoawindow.h"
#include <QtCore/QRect>
@@ -98,7 +97,7 @@ void QCocoaInputContext::reset()
if (!view)
return;
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (NSTextInputContext *ctxt = [NSTextInputContext currentInputContext]) {
[ctxt discardMarkedText];
[view unmarkText];
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 8b5d78826c..32a08dbb0d 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -36,7 +36,6 @@
#include <Cocoa/Cocoa.h>
-#include "qcocoaautoreleasepool.h"
#include "qcocoacursor.h"
#include "qcocoawindow.h"
#include "qcocoanativeinterface.h"
@@ -74,6 +73,7 @@ public:
QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor; }
QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE;
QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; }
+ QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE;
// ----------------------------------------------------
// Additional methods
@@ -98,34 +98,40 @@ public:
class QCocoaIntegration : public QPlatformIntegration
{
public:
- QCocoaIntegration();
+ enum Option {
+ UseFreeTypeFontEngine = 0x1
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
+ QCocoaIntegration(const QStringList &paramList);
~QCocoaIntegration();
static QCocoaIntegration *instance();
+ Options options() const;
- bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
#ifndef QT_NO_OPENGL
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
#endif
- QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const Q_DECL_OVERRIDE;
- QAbstractEventDispatcher *createEventDispatcher() const;
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
- QCoreTextFontDatabase *fontDatabase() const;
- QCocoaNativeInterface *nativeInterface() const;
- QCocoaInputContext *inputContext() const;
- QCocoaAccessibility *accessibility() const;
- QCocoaClipboard *clipboard() const;
- QCocoaDrag *drag() const;
+ QCoreTextFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
+ QCocoaNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE;
+ QCocoaAccessibility *accessibility() const Q_DECL_OVERRIDE;
+ QCocoaClipboard *clipboard() const Q_DECL_OVERRIDE;
+ QCocoaDrag *drag() const Q_DECL_OVERRIDE;
- QStringList themeNames() const;
- QPlatformTheme *createPlatformTheme(const QString &name) const;
- QCocoaServices *services() const;
- QVariant styleHint(StyleHint hint) const;
+ QStringList themeNames() const Q_DECL_OVERRIDE;
+ QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE;
+ QCocoaServices *services() const Q_DECL_OVERRIDE;
+ QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE;
- Qt::KeyboardModifiers queryKeyboardModifiers() const;
- QList<int> possibleKeys(const QKeyEvent *event) const;
+ Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE;
+ QList<int> possibleKeys(const QKeyEvent *event) const Q_DECL_OVERRIDE;
void updateScreens();
QCocoaScreen *screenAtIndex(int index);
@@ -139,13 +145,14 @@ public:
QCocoaWindow *activePopupWindow() const;
QList<QCocoaWindow *> *popupWindowStack();
- void setApplicationIcon(const QIcon &icon) const;
+ void setApplicationIcon(const QIcon &icon) const Q_DECL_OVERRIDE;
private:
static QCocoaIntegration *mInstance;
+ Options mOptions;
QScopedPointer<QCoreTextFontDatabase> mFontDb;
- QScopedPointer<QCocoaInputContext> mInputContext;
+ QScopedPointer<QPlatformInputContext> mInputContext;
#ifndef QT_NO_ACCESSIBILITY
QScopedPointer<QCocoaAccessibility> mAccessibility;
#endif
@@ -161,6 +168,8 @@ private:
QList<QCocoaWindow *> m_popupWindowStack;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QCocoaIntegration::Options)
+
QT_END_NAMESPACE
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index c8f6dd05db..051a1c8710 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -33,7 +33,6 @@
#include "qcocoaintegration.h"
-#include "qcocoaautoreleasepool.h"
#include "qcocoawindow.h"
#include "qcocoabackingstore.h"
#include "qcocoanativeinterface.h"
@@ -48,7 +47,9 @@
#include "qcocoamimetypes.h"
#include "qcocoaaccessibility.h"
+#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatformaccessibility.h>
+#include <qpa/qplatforminputcontextfactory_p.h>
#include <QtCore/qcoreapplication.h>
#include <IOKit/graphics/IOGraphicsLib.h>
@@ -137,11 +138,21 @@ void QCocoaScreen::updateGeometry()
qreal QCocoaScreen::devicePixelRatio() const
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
NSScreen * screen = osScreen();
return qreal(screen ? [screen backingScaleFactor] : 1.0);
}
+QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingTypeHint() const
+{
+ QPlatformScreen::SubpixelAntialiasingType type = QPlatformScreen::subpixelAntialiasingTypeHint();
+ if (type == QPlatformScreen::Subpixel_None) {
+ // Every OSX machine has RGB pixels unless a peculiar or rotated non-Apple screen is attached
+ type = QPlatformScreen::Subpixel_RGB;
+ }
+ return type;
+}
+
QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
{
NSPoint screenPoint = qt_mac_flipPoint(point);
@@ -244,11 +255,25 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height
return windowPixmap;
}
+static QCocoaIntegration::Options parseOptions(const QStringList &paramList)
+{
+ QCocoaIntegration::Options options;
+ foreach (const QString &param, paramList) {
+#ifndef QT_NO_FREETYPE
+ if (param == QLatin1String("fontengine=freetype"))
+ options |= QCocoaIntegration::UseFreeTypeFontEngine;
+ else
+#endif
+ qWarning() << "Unknown option" << param;
+ }
+ return options;
+}
+
QCocoaIntegration *QCocoaIntegration::mInstance = 0;
-QCocoaIntegration::QCocoaIntegration()
- : mFontDb(new QCoreTextFontDatabase())
- , mInputContext(new QCocoaInputContext)
+QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
+ : mOptions(parseOptions(paramList))
+ , mFontDb(new QCoreTextFontDatabase(mOptions.testFlag(UseFreeTypeFontEngine)))
#ifndef QT_NO_ACCESSIBILITY
, mAccessibility(new QCocoaAccessibility)
#endif
@@ -262,8 +287,12 @@ QCocoaIntegration::QCocoaIntegration()
qWarning("Creating multiple Cocoa platform integrations is not supported");
mInstance = this;
+ QString icStr = QPlatformInputContextFactory::requested();
+ icStr.isNull() ? mInputContext.reset(new QCocoaInputContext)
+ : mInputContext.reset(QPlatformInputContextFactory::create(icStr));
+
initResources();
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
qApp->setAttribute(Qt::AA_DontUseNativeMenuBar, false);
@@ -314,7 +343,7 @@ QCocoaIntegration::~QCocoaIntegration()
qt_resetNSApplicationSendEvent();
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
// remove the apple event handlers installed by QCocoaApplicationDelegate
QCocoaApplicationDelegate *delegate = [QCocoaApplicationDelegate sharedDelegate];
@@ -342,6 +371,11 @@ QCocoaIntegration *QCocoaIntegration::instance()
return mInstance;
}
+QCocoaIntegration::Options QCocoaIntegration::options() const
+{
+ return mOptions;
+}
+
/*!
\brief Synchronizes the screen list, adds new screens, removes deleted ones
*/
@@ -463,7 +497,7 @@ QCocoaNativeInterface *QCocoaIntegration::nativeInterface() const
return mNativeInterface.data();
}
-QCocoaInputContext *QCocoaIntegration::inputContext() const
+QPlatformInputContext *QCocoaIntegration::inputContext() const
{
return mInputContext.data();
}
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 59807deb5a..eccc5230b5 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -49,29 +49,29 @@ public:
QCocoaMenu();
~QCocoaMenu();
- inline virtual void setTag(quintptr tag)
- { m_tag = tag; }
- inline virtual quintptr tag() const
- { return m_tag; }
-
- void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before);
- void removeMenuItem(QPlatformMenuItem *menuItem);
- void syncMenuItem(QPlatformMenuItem *menuItem);
- void setEnabled(bool enabled);
- bool isEnabled() const;
- void setVisible(bool visible);
- void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item);
- void dismiss();
-
- void syncSeparatorsCollapsible(bool enable);
+ void setTag(quintptr tag) Q_DECL_OVERRIDE
+ { m_tag = tag; }
+ quintptr tag() const Q_DECL_OVERRIDE
+ { return m_tag; }
+
+ void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE;
+ void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE;
+ void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE;
+ void setEnabled(bool enabled) Q_DECL_OVERRIDE;
+ bool isEnabled() const Q_DECL_OVERRIDE;
+ void setVisible(bool visible) Q_DECL_OVERRIDE;
+ void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE;
+ void dismiss() Q_DECL_OVERRIDE;
+
+ void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE;
void syncModalState(bool modal);
- virtual void setIcon(const QIcon &icon) { Q_UNUSED(icon) }
+ void setIcon(const QIcon &icon) Q_DECL_OVERRIDE { Q_UNUSED(icon) }
- void setText(const QString &text);
- void setMinimumWidth(int width);
- void setFont(const QFont &font);
+ void setText(const QString &text) Q_DECL_OVERRIDE;
+ void setMinimumWidth(int width) Q_DECL_OVERRIDE;
+ void setFont(const QFont &font) Q_DECL_OVERRIDE;
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
@@ -80,8 +80,8 @@ public:
inline bool isVisible() const { return m_visible; }
- virtual QPlatformMenuItem *menuItemAt(int position) const;
- virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const;
+ QPlatformMenuItem *menuItemAt(int position) const Q_DECL_OVERRIDE;
+ QPlatformMenuItem *menuItemForTag(quintptr tag) const Q_DECL_OVERRIDE;
QList<QCocoaMenuItem *> items() const;
QList<QCocoaMenuItem *> merged() const;
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 6668080725..57739f3a58 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -34,7 +34,6 @@
#include "qcocoamenu.h"
#include "qcocoahelpers.h"
-#include "qcocoaautoreleasepool.h"
#include <QtCore/QtDebug>
#include <QtCore/qmetaobject.h>
@@ -235,7 +234,7 @@ QCocoaMenu::QCocoaMenu() :
m_menuBar(0),
m_containingMenuItem(0)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
@@ -255,7 +254,7 @@ QCocoaMenu::~QCocoaMenu()
if (m_containingMenuItem)
m_containingMenuItem->clearMenu(this);
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
[m_nativeItem setSubmenu:nil];
[m_nativeMenu release];
[m_delegate release];
@@ -264,7 +263,7 @@ QCocoaMenu::~QCocoaMenu()
void QCocoaMenu::setText(const QString &text)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QString stripped = qt_mac_removeAmpersandEscapes(text);
[m_nativeMenu setTitle:QCFString::toNSString(stripped)];
[m_nativeItem setTitle:QCFString::toNSString(stripped)];
@@ -286,7 +285,7 @@ void QCocoaMenu::setFont(const QFont &font)
void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
QCocoaMenuItem *beforeItem = static_cast<QCocoaMenuItem *>(before);
@@ -340,7 +339,7 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
if (!m_menuItems.contains(cocoaItem)) {
qWarning() << Q_FUNC_INFO << "Menu does not contain the item to be removed";
@@ -370,7 +369,7 @@ QCocoaMenuItem *QCocoaMenu::itemOrNull(int index) const
void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
if (!m_menuItems.contains(cocoaItem)) {
qWarning() << Q_FUNC_INFO << "Item does not belong to this menu";
@@ -399,7 +398,7 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem)
void QCocoaMenu::syncSeparatorsCollapsible(bool enable)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (enable) {
bool previousIsSeparator = true; // setting to true kills all the separators placed at the top.
NSMenuItem *previousItem = nil;
@@ -457,7 +456,7 @@ void QCocoaMenu::setVisible(bool visible)
void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QPoint pos = QPoint(targetRect.left(), targetRect.top() + targetRect.height());
QCocoaWindow *cocoaWindow = parentWindow ? static_cast<QCocoaWindow *>(parentWindow->handle()) : 0;
@@ -562,7 +561,7 @@ QList<QCocoaMenuItem *> QCocoaMenu::merged() const
void QCocoaMenu::syncModalState(bool modal)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (!m_enabled)
modal = true;
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h
index b5ee21ca52..d5f75abf34 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.h
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.h
@@ -48,13 +48,13 @@ class QCocoaMenuBar : public QPlatformMenuBar
Q_OBJECT
public:
QCocoaMenuBar();
- virtual ~QCocoaMenuBar();
+ ~QCocoaMenuBar();
- virtual void insertMenu(QPlatformMenu *menu, QPlatformMenu* before);
- virtual void removeMenu(QPlatformMenu *menu);
- virtual void syncMenu(QPlatformMenu *menuItem);
- virtual void handleReparent(QWindow *newParentWindow);
- virtual QPlatformMenu *menuForTag(quintptr tag) const;
+ void insertMenu(QPlatformMenu *menu, QPlatformMenu* before) Q_DECL_OVERRIDE;
+ void removeMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE;
+ void syncMenu(QPlatformMenu *menuItem) Q_DECL_OVERRIDE;
+ void handleReparent(QWindow *newParentWindow) Q_DECL_OVERRIDE;
+ QPlatformMenu *menuForTag(quintptr tag) const Q_DECL_OVERRIDE;
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 764a01370d..7775cdbde6 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -37,7 +37,7 @@
#include "qcocoawindow.h"
#include "qcocoamenuloader.h"
#include "qcocoaapplication.h" // for custom application category
-#include "qcocoaautoreleasepool.h"
+#include "qcocoaapplicationdelegate.h"
#include <QtGui/QGuiApplication>
#include <QtCore/QDebug>
@@ -83,7 +83,7 @@ QCocoaMenuBar::~QCocoaMenuBar()
void QCocoaMenuBar::insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (beforeMenu) {
NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeMenu->nsMenuItem()];
@@ -126,7 +126,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
void QCocoaMenuBar::removeNativeMenu(QCocoaMenu *menu)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (menu->menuBar() == this)
menu->setMenuBar(0);
@@ -147,7 +147,7 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCocoaMenu *cocoaMenu = static_cast<QCocoaMenu *>(menu);
Q_FOREACH (QCocoaMenuItem *item, cocoaMenu->items())
@@ -260,13 +260,26 @@ void QCocoaMenuBar::resetKnownMenuItemsToQt()
void QCocoaMenuBar::updateMenuBarImmediately()
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCocoaMenuBar *mb = findGlobalMenubar();
QCocoaWindow *cw = findWindowForMenubar();
QWindow *win = cw ? cw->window() : 0;
- if (win && (win->flags() & Qt::Popup) == Qt::Popup)
- return; // context menus, comboboxes, etc. don't need to update the menubar
+ if (win && (win->flags() & Qt::Popup) == Qt::Popup) {
+ // context menus, comboboxes, etc. don't need to update the menubar,
+ // but if an application has only Qt::Tool window(s) on start,
+ // we still have to update the menubar.
+ if ((win->flags() & Qt::WindowType_Mask) != Qt::Tool)
+ return;
+ typedef QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) AppDelegate;
+ NSApplication *app = [NSApplication sharedApplication];
+ if (![app.delegate isKindOfClass:[AppDelegate class]])
+ return;
+ // We apply this logic _only_ during the startup.
+ AppDelegate *appDelegate = app.delegate;
+ if (!appDelegate.inLaunch)
+ return;
+ }
if (cw && cw->menubar())
mb = cw->menubar();
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h
index 5c85824ab8..289f38fd18 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h
@@ -60,27 +60,27 @@ class QCocoaMenuItem : public QPlatformMenuItem
{
public:
QCocoaMenuItem();
- virtual ~QCocoaMenuItem();
+ ~QCocoaMenuItem();
- inline virtual void setTag(quintptr tag)
+ void setTag(quintptr tag) Q_DECL_OVERRIDE
{ m_tag = tag; }
- inline virtual quintptr tag() const
+ quintptr tag() const Q_DECL_OVERRIDE
{ return m_tag; }
- void setText(const QString &text);
- void setIcon(const QIcon &icon);
- void setMenu(QPlatformMenu *menu);
- void setVisible(bool isVisible);
- void setIsSeparator(bool isSeparator);
- void setFont(const QFont &font);
- void setRole(MenuRole role);
- void setShortcut(const QKeySequence& shortcut);
- void setCheckable(bool checkable) { Q_UNUSED(checkable) }
- void setChecked(bool isChecked);
- void setEnabled(bool isEnabled);
- void setIconSize(int size);
-
- void setNativeContents(WId item);
+ void setText(const QString &text) Q_DECL_OVERRIDE;
+ void setIcon(const QIcon &icon) Q_DECL_OVERRIDE;
+ void setMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE;
+ void setVisible(bool isVisible) Q_DECL_OVERRIDE;
+ void setIsSeparator(bool isSeparator) Q_DECL_OVERRIDE;
+ void setFont(const QFont &font) Q_DECL_OVERRIDE;
+ void setRole(MenuRole role) Q_DECL_OVERRIDE;
+ void setShortcut(const QKeySequence& shortcut) Q_DECL_OVERRIDE;
+ void setCheckable(bool checkable) Q_DECL_OVERRIDE { Q_UNUSED(checkable) }
+ void setChecked(bool isChecked) Q_DECL_OVERRIDE;
+ void setEnabled(bool isEnabled) Q_DECL_OVERRIDE;
+ void setIconSize(int size) Q_DECL_OVERRIDE;
+
+ void setNativeContents(WId item) Q_DECL_OVERRIDE;
inline QString text() const { return m_text; }
inline NSMenuItem * nsItem() { return m_native; }
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index f288ab85c0..942fc8db21 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -37,7 +37,6 @@
#include "qcocoamenubar.h"
#include "messages.h"
#include "qcocoahelpers.h"
-#include "qcocoaautoreleasepool.h"
#include "qt_mac_p.h"
#include "qcocoaapplication.h" // for custom application category
#include "qcocoamenuloader.h"
@@ -104,7 +103,7 @@ QCocoaMenuItem::QCocoaMenuItem() :
QCocoaMenuItem::~QCocoaMenuItem()
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this)
SET_COCOA_MENU_ANCESTOR(m_menu, 0);
@@ -139,7 +138,7 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
m_menu->setContainingMenuItem(0);
}
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(menu);
if (m_menu) {
SET_COCOA_MENU_ANCESTOR(m_menu, this);
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 2250f7c084..d018c05635 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -67,6 +67,8 @@ public:
static void *nsOpenGLContextForContext(QOpenGLContext* context);
#endif
+ QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
+
public Q_SLOTS:
void onAppFocusWindowChanged(QWindow *window);
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 205a49d25a..41ea1fa49c 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -58,6 +58,8 @@
#include <qpa/qplatformprintersupport.h>
#endif
+#include <QtPlatformHeaders/qcocoawindowfunctions.h>
+
#include <Cocoa/Cocoa.h>
QT_BEGIN_NAMESPACE
@@ -217,6 +219,14 @@ void *QCocoaNativeInterface::nsOpenGLContextForContext(QOpenGLContext* context)
}
#endif
+QFunctionPointer QCocoaNativeInterface::platformFunction(const QByteArray &function) const
+{
+ if (function == QCocoaWindowFunctions::bottomLeftClippedByNSWindowOffsetIdentifier())
+ return QFunctionPointer(QCocoaWindowFunctions::BottomLeftClippedByNSWindowOffset(QCocoaWindow::bottomLeftClippedByNSWindowOffsetStatic));
+
+ return Q_NULLPTR;
+}
+
void QCocoaNativeInterface::addToMimeList(void *macPasteboardMime)
{
qt_mac_addToGlobalMimeList(reinterpret_cast<QMacInternalPasteboardMime *>(macPasteboardMime));
@@ -234,7 +244,7 @@ void QCocoaNativeInterface::registerDraggedTypes(const QStringList &types)
void QCocoaNativeInterface::setDockMenu(QPlatformMenu *platformMenu)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCocoaMenu *cocoaPlatformMenu = static_cast<QCocoaMenu *>(platformMenu);
NSMenu *menu = cocoaPlatformMenu->nsMenu();
[NSApp QT_MANGLE_NAMESPACE(qt_setDockMenu): menu];
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
index 4d319e149b..b0d04f6f82 100644
--- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
+++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
@@ -100,7 +100,7 @@ QCocoaPrintDevice::~QCocoaPrintDevice()
{
if (m_ppd)
ppdClose(m_ppd);
- foreach (PMPaper paper, m_macPapers.values())
+ foreach (PMPaper paper, m_macPapers)
PMRelease(paper);
// Releasing the session appears to also release the printer
if (m_session)
@@ -154,7 +154,7 @@ QPageSize QCocoaPrintDevice::createPageSize(const PMPaper &paper) const
void QCocoaPrintDevice::loadPageSizes() const
{
m_pageSizes.clear();
- foreach (PMPaper paper, m_macPapers.values())
+ foreach (PMPaper paper, m_macPapers)
PMRelease(paper);
m_macPapers.clear();
m_printableMargins.clear();
diff --git a/src/plugins/platforms/cocoa/qcocoaservices.h b/src/plugins/platforms/cocoa/qcocoaservices.h
index 331fe810fa..1a447c6242 100644
--- a/src/plugins/platforms/cocoa/qcocoaservices.h
+++ b/src/plugins/platforms/cocoa/qcocoaservices.h
@@ -41,8 +41,8 @@ QT_BEGIN_NAMESPACE
class QCocoaServices : public QPlatformServices
{
public:
- bool openUrl(const QUrl &url);
- bool openDocument(const QUrl &url);
+ bool openUrl(const QUrl &url) Q_DECL_OVERRIDE;
+ bool openDocument(const QUrl &url) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index 65cc9bc38b..93f8b2ba6f 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -33,7 +33,6 @@
#include "qcocoasystemsettings.h"
-#include "qcocoaautoreleasepool.h"
#include "qcocoahelpers.h"
#include <QtCore/private/qcore_mac_p.h>
@@ -45,7 +44,7 @@ QT_BEGIN_NAMESPACE
QColor qt_mac_colorForTheme(ThemeBrush brush)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCFType<CGColorRef> cgClr = 0;
HIThemeBrushCreateCGColor(brush, &cgClr);
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
index b5f038094f..cdfd92c0aa 100755..100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
@@ -51,17 +51,17 @@ class Q_GUI_EXPORT QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon
public:
QCocoaSystemTrayIcon() : m_sys(0) {}
- virtual void init();
- virtual void cleanup();
- virtual void updateIcon(const QIcon &icon);
- virtual void updateToolTip(const QString &toolTip);
- virtual void updateMenu(QPlatformMenu *menu);
- virtual QRect geometry() const;
- virtual void showMessage(const QString &title, const QString &msg,
- const QIcon& icon, MessageIcon iconType, int secs);
+ void init() Q_DECL_OVERRIDE;
+ void cleanup() Q_DECL_OVERRIDE;
+ void updateIcon(const QIcon &icon) Q_DECL_OVERRIDE;
+ void updateToolTip(const QString &toolTip) Q_DECL_OVERRIDE;
+ void updateMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE;
+ QRect geometry() const Q_DECL_OVERRIDE;
+ void showMessage(const QString &title, const QString &msg,
+ const QIcon& icon, MessageIcon iconType, int secs) Q_DECL_OVERRIDE;
- virtual bool isSystemTrayAvailable() const;
- virtual bool supportsMessages() const;
+ bool isSystemTrayAvailable() const Q_DECL_OVERRIDE;
+ bool supportsMessages() const Q_DECL_OVERRIDE;
private:
QSystemTrayIconSys *m_sys;
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 713758cc7e..a3ffb5be66 100755..100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -252,6 +252,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
}
NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(fullHeightPixmap));
+ [nsimage setTemplate:icon.isMask()];
[(NSImageView*)[[m_sys->item item] view] setImage: nsimage];
[nsimage release];
}
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 11749e14de..4b73d0af08 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -47,7 +47,6 @@
#include "qcocoamenu.h"
#include "qcocoamenubar.h"
#include "qcocoahelpers.h"
-#include "qcocoaautoreleasepool.h"
#include <QtCore/qfileinfo.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -253,7 +252,7 @@ QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &siz
QPlatformTheme::IconOptions iconOptions) const
{
Q_UNUSED(iconOptions);
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:QCFString::toNSString(fileInfo.canonicalFilePath())];
if (!iconImage)
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 455d4a8580..51679116b5 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -227,6 +227,9 @@ public:
void updateExposedGeometry();
QWindow *childWindowAt(QPoint windowPoint);
bool shouldRefuseKeyWindowAndFirstResponder();
+
+ static QPoint bottomLeftClippedByNSWindowOffsetStatic(QWindow *window);
+ QPoint bottomLeftClippedByNSWindowOffset() const;
protected:
void recreateWindow(const QPlatformWindow *parentWindow);
QCocoaNSWindow *createNSWindow();
@@ -234,7 +237,7 @@ protected:
bool shouldUseNSPanel();
- QRect windowGeometry() const;
+ QRect nativeWindowGeometry() const;
QCocoaWindow *parentCocoaWindow() const;
void syncWindowState(Qt::WindowState newState);
void reinsertChildWindow(QCocoaWindow *child);
@@ -245,6 +248,8 @@ public: // for QNSView
friend class QCocoaBackingStore;
friend class QCocoaNativeInterface;
+ void removeMonitor();
+
NSView *m_contentView;
QNSView *m_qtView;
QCocoaNSWindow *m_nsWindow;
@@ -269,6 +274,7 @@ public: // for QNSView
bool m_inConstructor;
bool m_inSetVisible;
bool m_inSetGeometry;
+ bool m_inSetStyleMask;
#ifndef QT_NO_OPENGL
QCocoaGLContext *m_glContext;
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 3188463dbe..5606f050a3 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -33,7 +33,6 @@
#include "qcocoawindow.h"
#include "qcocoaintegration.h"
#include "qnswindowdelegate.h"
-#include "qcocoaautoreleasepool.h"
#include "qcocoaeventdispatcher.h"
#ifndef QT_NO_OPENGL
#include "qcocoaglcontext.h"
@@ -350,6 +349,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_inConstructor(true)
, m_inSetVisible(false)
, m_inSetGeometry(false)
+ , m_inSetStyleMask(false)
#ifndef QT_NO_OPENGL
, m_glContext(0)
#endif
@@ -373,7 +373,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
#endif
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (tlw->type() == Qt::ForeignWindow) {
NSView *foreignView = (NSView *)WId(tlw->property("_q_foreignWinId").value<WId>());
@@ -409,7 +409,7 @@ QCocoaWindow::~QCocoaWindow()
qDebug() << "QCocoaWindow::~QCocoaWindow" << this;
#endif
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
[m_nsWindow setContentView:nil];
[m_nsWindow.helper detachFromPlatformWindow];
if (m_isNSWindowChild) {
@@ -419,6 +419,8 @@ QCocoaWindow::~QCocoaWindow()
[m_contentView removeFromSuperview];
}
+ removeMonitor();
+
// Make sure to disconnect observer in all case if view is valid
// to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute
if (m_qtView) {
@@ -499,7 +501,7 @@ QRect QCocoaWindow::geometry() const
void QCocoaWindow::setCocoaGeometry(const QRect &rect)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (m_contentViewIsEmbedded) {
QPlatformWindow::setGeometry(rect);
@@ -604,7 +606,7 @@ void QCocoaWindow::show(bool becauseOfAncestor)
&& !m_hiddenByClipping) { // ... NOR clipped
if (m_isNSWindowChild) {
m_hiddenByAncestor = false;
- setCocoaGeometry(window()->geometry());
+ setCocoaGeometry(windowGeometry());
}
if (!m_hiddenByClipping) { // setCocoaGeometry() can change the clipping status
[m_nsWindow orderFront:nil];
@@ -623,7 +625,7 @@ void QCocoaWindow::setVisible(bool visible)
m_inSetVisible = true;
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QCocoaWindow *parentCocoaWindow = 0;
if (window()->transientParent())
parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle());
@@ -643,7 +645,7 @@ void QCocoaWindow::setVisible(bool visible)
if (parentCocoaWindow) {
// The parent window might have moved while this window was hidden,
// update the window geometry if there is a parent.
- setGeometry(window()->geometry());
+ setGeometry(windowGeometry());
if (window()->type() == Qt::Popup) {
// QTBUG-30266: a window should not be resizable while a transient popup is open
@@ -696,6 +698,7 @@ void QCocoaWindow::setVisible(bool visible)
&& [m_nsWindow isKindOfClass:[NSPanel class]]) {
[(NSPanel *)m_nsWindow setWorksWhenModal:YES];
if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) {
+ removeMonitor();
monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) {
QPointF localPoint = qt_mac_flipPoint([NSEvent mouseLocation]);
QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint,
@@ -744,10 +747,7 @@ void QCocoaWindow::setVisible(bool visible)
} else {
[m_contentView setHidden:YES];
}
- if (monitor && window()->type() == Qt::Popup) {
- [NSEvent removeMonitor:monitor];
- monitor = nil;
- }
+ removeMonitor();
if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip)
QCocoaIntegration::instance()->popupWindowStack()->removeAll(this);
@@ -864,8 +864,8 @@ void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags)
// no-WindowMaximizeButtonHint windows. From a Qt perspective it migth be expected
// that the button would be removed in the latter case, but disabling it is more
// in line with the platform style guidelines.
- bool fixedSizeNoZoom = (window()->minimumSize().isValid() && window()->maximumSize().isValid()
- && window()->minimumSize() == window()->maximumSize());
+ bool fixedSizeNoZoom = (windowMinimumSize().isValid() && windowMaximumSize().isValid()
+ && windowMinimumSize() == windowMaximumSize());
bool customizeNoZoom = ((flags & Qt::CustomizeWindowHint) && !(flags & Qt::WindowMaximizeButtonHint));
[[m_nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:!(fixedSizeNoZoom || customizeNoZoom)];
}
@@ -875,10 +875,14 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
if (m_nsWindow && !m_isNSWindowChild) {
NSUInteger styleMask = windowStyleMask(flags);
NSInteger level = this->windowLevel(flags);
+ // While setting style mask we can have -updateGeometry calls on a content
+ // view with null geometry, reporting an invalid coordinates as a result.
+ m_inSetStyleMask = true;
[m_nsWindow setStyleMask:styleMask];
+ m_inSetStyleMask = false;
[m_nsWindow setLevel:level];
setWindowShadow(flags);
- if (!(styleMask & NSBorderlessWindowMask)) {
+ if (!(flags & Qt::FramelessWindowHint)) {
setWindowTitle(window()->title());
}
@@ -905,7 +909,7 @@ void QCocoaWindow::setWindowState(Qt::WindowState state)
void QCocoaWindow::setWindowTitle(const QString &title)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (!m_nsWindow)
return;
@@ -916,7 +920,7 @@ void QCocoaWindow::setWindowTitle(const QString &title)
void QCocoaWindow::setWindowFilePath(const QString &filePath)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (!m_nsWindow)
return;
@@ -926,7 +930,7 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
void QCocoaWindow::setWindowIcon(const QIcon &icon)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
NSButton *iconButton = [m_nsWindow standardWindowButton:NSWindowDocumentIconButton];
if (iconButton == nil) {
@@ -1044,26 +1048,26 @@ bool QCocoaWindow::isOpaque() const
void QCocoaWindow::propagateSizeHints()
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
if (!m_nsWindow)
return;
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::propagateSizeHints" << this;
- qDebug() << " min/max " << window()->minimumSize() << window()->maximumSize();
- qDebug() << "size increment" << window()->sizeIncrement();
- qDebug() << " basesize" << window()->baseSize();
- qDebug() << " geometry" << geometry();
+ qDebug() << " min/max" << windowMinimumSize() << windowMaximumSize();
+ qDebug() << "size increment" << windowSizeIncrement();
+ qDebug() << " basesize" << windowBaseSize();
+ qDebug() << " geometry" << windowGeometry();
#endif
// Set the minimum content size.
- const QSize minimumSize = window()->minimumSize();
+ const QSize minimumSize = windowMinimumSize();
if (!minimumSize.isValid()) // minimumSize is (-1, -1) when not set. Make that (0, 0) for Cocoa.
[m_nsWindow setContentMinSize : NSMakeSize(0.0, 0.0)];
[m_nsWindow setContentMinSize : NSMakeSize(minimumSize.width(), minimumSize.height())];
// Set the maximum content size.
- const QSize maximumSize = window()->maximumSize();
+ const QSize maximumSize = windowMaximumSize();
[m_nsWindow setContentMaxSize : NSMakeSize(maximumSize.width(), maximumSize.height())];
// The window may end up with a fixed size; in this case the zoom button should be disabled.
@@ -1071,13 +1075,14 @@ void QCocoaWindow::propagateSizeHints()
// sizeIncrement is observed to take values of (-1, -1) and (0, 0) for windows that should be
// resizable and that have no specific size increment set. Cocoa expects (1.0, 1.0) in this case.
- if (!window()->sizeIncrement().isEmpty())
- [m_nsWindow setResizeIncrements : qt_mac_toNSSize(window()->sizeIncrement())];
+ const QSize sizeIncrement = windowSizeIncrement();
+ if (!sizeIncrement.isEmpty())
+ [m_nsWindow setResizeIncrements : qt_mac_toNSSize(sizeIncrement)];
else
[m_nsWindow setResizeIncrements : NSMakeSize(1.0, 1.0)];
QRect rect = geometry();
- QSize baseSize = window()->baseSize();
+ QSize baseSize = windowBaseSize();
if (!baseSize.isNull() && baseSize.isValid()) {
[m_nsWindow setFrame:NSMakeRect(rect.x(), rect.y(), baseSize.width(), baseSize.height()) display:YES];
}
@@ -1323,7 +1328,7 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
| NSWindowCollectionBehaviorFullScreenAuxiliary;
m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
m_nsWindow.collectionBehavior = collectionBehavior;
- setCocoaGeometry(window()->geometry());
+ setCocoaGeometry(windowGeometry());
QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
if (siblings.contains(this)) {
@@ -1337,7 +1342,7 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
} else {
// Child windows have no NSWindow, link the NSViews instead.
[m_parentCocoaWindow->m_contentView addSubview : m_contentView];
- QRect rect = window()->geometry();
+ QRect rect = windowGeometry();
// Prevent setting a (0,0) window size; causes opengl context
// "Invalid Drawable" warnings.
if (rect.isNull())
@@ -1387,9 +1392,9 @@ bool QCocoaWindow::shouldUseNSPanel()
QCocoaNSWindow * QCocoaWindow::createNSWindow()
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
- QRect rect = initialGeometry(window(), window()->geometry(), defaultWindowWidth, defaultWindowHeight);
+ QRect rect = initialGeometry(window(), windowGeometry(), defaultWindowWidth, defaultWindowHeight);
NSRect frame = qt_mac_flipRect(rect);
Qt::WindowType type = window()->type();
@@ -1476,8 +1481,16 @@ void QCocoaWindow::removeChildWindow(QCocoaWindow *child)
[m_nsWindow removeChildWindow:child->m_nsWindow];
}
+void QCocoaWindow::removeMonitor()
+{
+ if (!monitor)
+ return;
+ [NSEvent removeMonitor:monitor];
+ monitor = nil;
+}
+
// Returns the current global screen geometry for the nswindow associated with this window.
-QRect QCocoaWindow::windowGeometry() const
+QRect QCocoaWindow::nativeWindowGeometry() const
{
if (!m_nsWindow || m_isNSWindowChild)
return geometry();
@@ -1560,7 +1573,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
if (m_normalGeometry.width() < 0) {
m_oldWindowFlags = m_windowFlags;
window()->setFlags(window()->flags() | Qt::FramelessWindowHint);
- m_normalGeometry = windowGeometry();
+ m_normalGeometry = nativeWindowGeometry();
setGeometry(screen->geometry());
m_presentationOptions = [NSApp presentationOptions];
[NSApp setPresentationOptions : m_presentationOptions | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock];
@@ -1827,6 +1840,24 @@ bool QCocoaWindow::shouldRefuseKeyWindowAndFirstResponder()
return false;
}
+QPoint QCocoaWindow::bottomLeftClippedByNSWindowOffsetStatic(QWindow *window)
+{
+ if (window->handle())
+ return static_cast<QCocoaWindow *>(window->handle())->bottomLeftClippedByNSWindowOffset();
+ return QPoint();
+}
+
+QPoint QCocoaWindow::bottomLeftClippedByNSWindowOffset() const
+{
+ if (!m_contentView)
+ return QPoint();
+ const NSPoint origin = [m_contentView isFlipped] ? NSMakePoint(0, [m_contentView frame].size.height)
+ : NSMakePoint(0, 0);
+ const NSRect visibleRect = [m_contentView visibleRect];
+
+ return QPoint(visibleRect.origin.x, -visibleRect.origin.y + (origin.y - visibleRect.size.height));
+}
+
QMargins QCocoaWindow::frameMargins() const
{
NSRect frameW = [m_nsWindow frame];
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index 3d88a8d5df..f4fd32ffd1 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -43,7 +43,6 @@
#include <stdlib.h>
#include <string.h>
#include "qcocoahelpers.h"
-#include "qcocoaautoreleasepool.h"
QT_BEGIN_NAMESPACE
@@ -555,7 +554,7 @@ QMacPasteboard::sync() const
QString qt_mac_get_pasteboardString(PasteboardRef paste)
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
NSPasteboard *pb = nil;
CFStringRef pbname;
if (PasteboardCopyName(paste, &pbname) == noErr) {
diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac.mm b/src/plugins/platforms/cocoa/qmultitouch_mac.mm
index 6e7ebcc37c..6099add6bb 100644
--- a/src/plugins/platforms/cocoa/qmultitouch_mac.mm
+++ b/src/plugins/platforms/cocoa/qmultitouch_mac.mm
@@ -173,7 +173,7 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch)
if (_touchCount != _currentTouches.size()) {
// Remove all instances, and basically start from scratch:
touchPoints.clear();
- foreach (QCocoaTouch *qcocoaTouch, _currentTouches.values()) {
+ foreach (QCocoaTouch *qcocoaTouch, _currentTouches) {
if (!_updateInternalStateOnly) {
qcocoaTouch->_touchPoint.state = Qt::TouchPointReleased;
touchPoints.insert(qcocoaTouch->_touchPoint.id, qcocoaTouch->_touchPoint);
@@ -190,7 +190,7 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch)
// touch now (and refake a begin for it later, if needed).
if (_updateInternalStateOnly && !wasUpdateInternalStateOnly && !_currentTouches.isEmpty()) {
- QCocoaTouch *qcocoaTouch = _currentTouches.values().first();
+ QCocoaTouch *qcocoaTouch = _currentTouches.cbegin().value();
qcocoaTouch->_touchPoint.state = Qt::TouchPointReleased;
touchPoints.insert(qcocoaTouch->_touchPoint.id, qcocoaTouch->_touchPoint);
// Since this last touch also will end up being the first
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index f27335d752..4db55c1b73 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -39,7 +39,6 @@
#include "qnsview.h"
#include "qcocoawindow.h"
#include "qcocoahelpers.h"
-#include "qcocoaautoreleasepool.h"
#include "qmultitouch_mac_p.h"
#include "qcocoadrag.h"
#include <qpa/qplatformintegration.h>
@@ -347,6 +346,12 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (m_platformWindow->m_nsWindow && geometry == m_platformWindow->geometry())
return;
+ // It can happen that self.window is nil (if we are changing
+ // styleMask from/to borderless and content view is being re-parented)
+ // - this results in an invalid coordinates.
+ if (m_platformWindow->m_inSetStyleMask && !self.window)
+ return;
+
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QNSView::udpateGeometry" << m_platformWindow << geometry;
#endif
@@ -848,7 +853,7 @@ QT_WARNING_POP
{
[super updateTrackingAreas];
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
// NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early
if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea])
@@ -1789,7 +1794,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
-(void)registerDragTypes
{
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
QStringList customTypes = qt_mac_enabledDraggedTypes();
if (currentCustomDragTypes == 0 || *currentCustomDragTypes != customTypes) {
if (currentCustomDragTypes == 0)
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index 9e8fe8f1c8..edd1d656f0 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -38,7 +38,6 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdebug.h>
-#include "qcocoaautoreleasepool.h"
#ifndef QT_NO_PRINTER
@@ -212,6 +211,9 @@ int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
case QPaintDevice::PdmDevicePixelRatio:
val = 1;
break;
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ val = 1 * QPaintDevice::devicePixelRatioFScale();
+ break;
default:
val = 0;
qWarning("QPrinter::metric: Invalid metric command");
@@ -230,7 +232,7 @@ void QMacPrintEnginePrivate::initialize()
q->gccaps = paintEngine->gccaps;
- QCocoaAutoReleasePool pool;
+ QMacAutoReleasePool pool;
printInfo = [[NSPrintInfo alloc] initWithDictionary:[NSDictionary dictionary]];
QList<int> resolutions = m_printDevice->supportedResolutions();
diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h
index e210f0221f..576e0f9729 100644
--- a/src/plugins/platforms/cocoa/qt_mac_p.h
+++ b/src/plugins/platforms/cocoa/qt_mac_p.h
@@ -103,17 +103,6 @@ public:
}
};
-class Q_WIDGETS_EXPORT QMacCocoaAutoReleasePool
-{
-private:
- void *pool;
-public:
- QMacCocoaAutoReleasePool();
- ~QMacCocoaAutoReleasePool();
-
- inline void *handle() const { return pool; }
-};
-
QString qt_mac_removeMnemonics(const QString &original); //implemented in qmacstyle_mac.cpp
class Q_WIDGETS_EXPORT QMacWindowChangeEvent
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
index fee9ad88fa..40709fc3d0 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
@@ -113,6 +113,9 @@ int QWindowsDirect2DPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric)
case QPaintDevice::PdmDevicePixelRatio:
return 1;
break;
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return 1 * devicePixelRatioFScale();
+ break;
case QPaintDevice::PdmWidthMM:
case QPaintDevice::PdmHeightMM:
return -1;
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index e635d4fd22..e1d97d9628 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -217,7 +217,7 @@ Qt::KeyboardModifiers QDirectFbConvenience::keyboardModifiers(DFBInputDeviceModi
modifiers |= Qt::ControlModifier;
}
if (mask & DIMM_META) {
- modifiers | Qt::MetaModifier;
+ modifiers |= Qt::MetaModifier;
}
return modifiers;
}
diff --git a/src/plugins/platforms/eglfs/cursor-atlas.png b/src/plugins/platforms/eglfs/cursor-atlas.png
index 40c5b6ef4f..40c5b6ef4f 100755..100644
--- a/src/plugins/platforms/eglfs/cursor-atlas.png
+++ b/src/plugins/platforms/eglfs/cursor-atlas.png
Binary files differ
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp
index 18a66e34f5..f3df1f8445 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp
@@ -208,6 +208,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr
}
QList<drmModeModeInfo> modes;
+ modes.reserve(connector->count_modes);
qCDebug(qLcEglfsKmsDebug) << connectorName << "mode count:" << connector->count_modes;
for (int i = 0; i < connector->count_modes; i++) {
const drmModeModeInfo &mode = connector->modes[i];
@@ -282,7 +283,8 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr
selected_mode,
false,
drmModeGetCrtc(m_dri_fd, crtc_id),
- modes
+ modes,
+ connectorProperty(connector, QByteArrayLiteral("DPMS"))
};
m_crtc_allocator |= (1 << output.crtc_id);
@@ -291,6 +293,22 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr
return new QEglFSKmsScreen(m_integration, this, output, pos);
}
+drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name)
+{
+ drmModePropertyPtr prop;
+
+ for (int i = 0; i < connector->count_props; i++) {
+ prop = drmModeGetProperty(m_dri_fd, connector->props[i]);
+ if (!prop)
+ continue;
+ if (strcmp(prop->name, name.constData()) == 0)
+ return prop;
+ drmModeFreeProperty(prop);
+ }
+
+ return Q_NULLPTR;
+}
+
void QEglFSKmsDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
{
Q_UNUSED(fd);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h
index 23fca934e5..411f9a7200 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h
@@ -78,6 +78,7 @@ private:
int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector);
QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos);
+ drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name);
static void pageFlipHandler(int fd,
unsigned int sequence,
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
index 45224ccb87..d1814fb85d 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
@@ -36,8 +36,8 @@
#include "qeglfskmsdevice.h"
#include "qeglfskmsscreen.h"
#include "qeglfskmscursor.h"
+#include "qeglfscursor.h"
-#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtPlatformSupport/private/qdevicediscovery_p.h>
#include <QtCore/QLoggingCategory>
#include <QtCore/QJsonDocument>
@@ -176,7 +176,7 @@ QPlatformCursor *QEglFSKmsIntegration::createCursor(QPlatformScreen *screen) con
if (m_hwCursor)
return Q_NULLPTR;
else
- return new QEGLPlatformCursor(screen);
+ return new QEglFSCursor(screen);
}
void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp
index 5e49c224a0..227c8f9a62 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp
@@ -35,11 +35,11 @@
#include "qeglfskmsscreen.h"
#include "qeglfskmsdevice.h"
#include "qeglfskmscursor.h"
+#include "qeglfsintegration.h"
#include <QtCore/QLoggingCategory>
#include <QtGui/private/qguiapplication_p.h>
-#include <QtPlatformSupport/private/qeglplatformintegration_p.h>
#include <QtPlatformSupport/private/qfbvthandler_p.h>
QT_BEGIN_NAMESPACE
@@ -50,7 +50,7 @@ class QEglFSKmsInterruptHandler : public QObject
{
public:
QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen) : m_screen(screen) {
- m_vtHandler = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler();
+ m_vtHandler = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler();
connect(m_vtHandler, &QFbVtHandler::interrupted, this, &QEglFSKmsInterruptHandler::restoreVideoMode);
connect(m_vtHandler, &QFbVtHandler::suspendRequested, this, &QEglFSKmsInterruptHandler::handleSuspendRequest);
}
@@ -119,6 +119,7 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration,
, m_output(output)
, m_pos(position)
, m_cursor(Q_NULLPTR)
+ , m_powerState(PowerStateOn)
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
{
m_siblings << this;
@@ -126,6 +127,10 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration,
QEglFSKmsScreen::~QEglFSKmsScreen()
{
+ if (m_output.dpms_prop) {
+ drmModeFreeProperty(m_output.dpms_prop);
+ m_output.dpms_prop = Q_NULLPTR;
+ }
restoreMode();
if (m_output.saved_crtc) {
drmModeFreeCrtc(m_output.saved_crtc);
@@ -266,10 +271,12 @@ void QEglFSKmsScreen::flip()
&m_output.connector_id, 1,
&m_output.modes[m_output.mode]);
- if (ret)
+ if (ret) {
qErrnoWarning("Could not set DRM mode!");
- else
+ } else {
m_output.mode_set = true;
+ setPowerState(PowerStateOn);
+ }
}
int ret = drmModePageFlip(m_device->fd(),
@@ -314,4 +321,19 @@ qreal QEglFSKmsScreen::refreshRate() const
return refresh > 0 ? refresh : 60;
}
+QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const
+{
+ return m_powerState;
+}
+
+void QEglFSKmsScreen::setPowerState(QPlatformScreen::PowerState state)
+{
+ if (!m_output.dpms_prop)
+ return;
+
+ drmModeConnectorSetProperty(m_device->fd(), m_output.connector_id,
+ m_output.dpms_prop->prop_id, (int)state);
+ m_powerState = state;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h
index 4c1b0d02ad..2ce8700478 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h
@@ -60,6 +60,7 @@ struct QEglFSKmsOutput
bool mode_set;
drmModeCrtcPtr saved_crtc;
QList<drmModeModeInfo> modes;
+ drmModePropertyPtr dpms_prop;
};
class QEglFSKmsScreen : public QEglFSScreen
@@ -103,6 +104,9 @@ public:
QEglFSKmsOutput &output() { return m_output; }
void restoreMode();
+ QPlatformScreen::PowerState powerState() const Q_DECL_OVERRIDE;
+ void setPowerState(QPlatformScreen::PowerState state) Q_DECL_OVERRIDE;
+
private:
QEglFSKmsIntegration *m_integration;
QEglFSKmsDevice *m_device;
@@ -117,6 +121,8 @@ private:
QList<QPlatformScreen *> m_siblings;
+ PowerState m_powerState;
+
struct FrameBuffer {
FrameBuffer() : fb(0) {}
uint32_t fb;
diff --git a/src/plugins/platforms/eglfs/eglfs_device_lib.pro b/src/plugins/platforms/eglfs/eglfs_device_lib.pro
index 729290706d..22a32663c7 100644
--- a/src/plugins/platforms/eglfs/eglfs_device_lib.pro
+++ b/src/plugins/platforms/eglfs/eglfs_device_lib.pro
@@ -26,6 +26,7 @@ DEFINES += QT_BUILD_EGL_DEVICE_LIB
SOURCES += $$PWD/qeglfsintegration.cpp \
$$PWD/qeglfswindow.cpp \
$$PWD/qeglfsscreen.cpp \
+ $$PWD/qeglfscursor.cpp \
$$PWD/qeglfshooks.cpp \
$$PWD/qeglfscontext.cpp \
$$PWD/qeglfsoffscreenwindow.cpp \
@@ -34,6 +35,7 @@ SOURCES += $$PWD/qeglfsintegration.cpp \
HEADERS += $$PWD/qeglfsintegration.h \
$$PWD/qeglfswindow.h \
$$PWD/qeglfsscreen.h \
+ $$PWD/qeglfscursor.h \
$$PWD/qeglfshooks.h \
$$PWD/qeglfscontext.h \
$$PWD/qeglfsoffscreenwindow.h \
diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp
index 9216b7a85d..e2223aba43 100644
--- a/src/plugins/platforms/eglfs/qeglfscontext.cpp
+++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp
@@ -32,15 +32,13 @@
****************************************************************************/
#include <QtGui/QSurface>
-#include <QtDebug>
-
-#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
+#include "qeglfscontext.h"
#include "qeglfswindow.h"
#include "qeglfshooks.h"
-#include "qeglfscontext.h"
+#include "qeglfscursor.h"
QT_BEGIN_NAMESPACE
@@ -91,7 +89,7 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface)
// draw the cursor
if (surface->surface()->surfaceClass() == QSurface::Window) {
QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
- if (QEGLPlatformCursor *cursor = qobject_cast<QEGLPlatformCursor *>(window->screen()->cursor()))
+ if (QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(window->screen()->cursor()))
cursor->paintOnScreen();
}
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp
new file mode 100644
index 0000000000..eea130a754
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp
@@ -0,0 +1,502 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglfscursor.h"
+#include "qeglfsintegration.h"
+#include "qeglfsscreen.h"
+
+#include <qpa/qwindowsysteminterface.h>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonArray>
+#include <QtCore/QJsonObject>
+
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qopenglvertexarrayobject_p.h>
+
+#ifndef GL_VERTEX_ARRAY_BINDING
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QEglFSCursor::QEglFSCursor(QPlatformScreen *screen)
+ : m_visible(true),
+ m_screen(static_cast<QEglFSScreen *>(screen)),
+ m_program(0),
+ m_textureEntry(0),
+ m_deviceListener(0),
+ m_updateRequested(false)
+{
+ QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
+ if (!hideCursorVal.isEmpty())
+ m_visible = hideCursorVal.toInt() == 0;
+ if (!m_visible)
+ return;
+
+ // Try to load the cursor atlas. If this fails, m_visible is set to false and
+ // paintOnScreen() and setCurrentCursor() become no-ops.
+ initCursorAtlas();
+
+ // initialize the cursor
+#ifndef QT_NO_CURSOR
+ QCursor cursor(Qt::ArrowCursor);
+ setCurrentCursor(&cursor);
+#endif
+
+ m_deviceListener = new QEglFSCursorDeviceListener(this);
+ connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged,
+ m_deviceListener, &QEglFSCursorDeviceListener::onDeviceListChanged);
+ updateMouseStatus();
+}
+
+QEglFSCursor::~QEglFSCursor()
+{
+ resetResources();
+ delete m_deviceListener;
+}
+
+void QEglFSCursor::updateMouseStatus()
+{
+ m_visible = m_deviceListener->hasMouse();
+}
+
+bool QEglFSCursorDeviceListener::hasMouse() const
+{
+ return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0;
+}
+
+void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type)
+{
+ if (type == QInputDeviceManager::DeviceTypePointer)
+ m_cursor->updateMouseStatus();
+}
+
+void QEglFSCursor::resetResources()
+{
+ if (QOpenGLContext::currentContext()) {
+ delete m_program;
+ glDeleteTextures(1, &m_cursor.customCursorTexture);
+ glDeleteTextures(1, &m_cursorAtlas.texture);
+ }
+ m_program = 0;
+ m_cursor.customCursorTexture = 0;
+ m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull();
+ m_cursorAtlas.texture = 0;
+}
+
+void QEglFSCursor::createShaderPrograms()
+{
+ static const char *textureVertexProgram =
+ "attribute highp vec2 vertexCoordEntry;\n"
+ "attribute highp vec2 textureCoordEntry;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " textureCoord = textureCoordEntry;\n"
+ " gl_Position = vec4(vertexCoordEntry, 1.0, 1.0);\n"
+ "}\n";
+
+ static const char *textureFragmentProgram =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
+ "}\n";
+
+ m_program = new QOpenGLShaderProgram;
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ m_program->bindAttributeLocation("vertexCoordEntry", 0);
+ m_program->bindAttributeLocation("textureCoordEntry", 1);
+ m_program->link();
+
+ m_textureEntry = m_program->uniformLocation("texture");
+}
+
+void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
+{
+ if (!*texture)
+ glGenTextures(1, texture);
+ glBindTexture(GL_TEXTURE_2D, *texture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */,
+ GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
+}
+
+void QEglFSCursor::initCursorAtlas()
+{
+ static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR");
+ if (json.isEmpty())
+ json = ":/cursor.json";
+
+ QFile file(QString::fromUtf8(json));
+ if (!file.open(QFile::ReadOnly)) {
+ m_visible = false;
+ return;
+ }
+
+ QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
+ QJsonObject object = doc.object();
+
+ QString atlas = object.value(QLatin1String("image")).toString();
+ Q_ASSERT(!atlas.isEmpty());
+
+ const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble();
+ Q_ASSERT(cursorsPerRow);
+ m_cursorAtlas.cursorsPerRow = cursorsPerRow;
+
+ const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray();
+ Q_ASSERT(hotSpots.count() == Qt::LastCursor + 1);
+ for (int i = 0; i < hotSpots.count(); i++) {
+ QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble());
+ m_cursorAtlas.hotSpots << hotSpot;
+ }
+
+ QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow;
+ m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow) / cursorsPerRow);
+ m_cursorAtlas.width = image.width();
+ m_cursorAtlas.height = image.height();
+ m_cursorAtlas.image = image;
+}
+
+#ifndef QT_NO_CURSOR
+void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
+{
+ Q_UNUSED(window);
+ const QRect oldCursorRect = cursorRect();
+ if (setCurrentCursor(cursor))
+ update(oldCursorRect | cursorRect());
+}
+
+bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
+{
+ if (!m_visible)
+ return false;
+
+ const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
+ if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor)
+ return false;
+
+ if (m_cursor.shape == Qt::BitmapCursor) {
+ m_cursor.customCursorImage = QImage();
+ m_cursor.customCursorPending = false;
+ }
+ m_cursor.shape = newShape;
+ if (newShape != Qt::BitmapCursor) { // standard cursor
+ const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width,
+ hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height;
+ m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow),
+ hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow),
+ ws, hs);
+ m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape];
+ m_cursor.texture = m_cursorAtlas.texture;
+ m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight);
+ } else {
+ QImage image = cursor->pixmap().toImage();
+ m_cursor.textureRect = QRectF(0, 0, 1, 1);
+ m_cursor.hotSpot = cursor->hotSpot();
+ m_cursor.texture = 0; // will get updated in the next render()
+ m_cursor.size = image.size();
+ m_cursor.customCursorImage = image;
+ m_cursor.customCursorPending = true;
+ }
+
+ return true;
+}
+#endif
+
+class CursorUpdateEvent : public QEvent
+{
+public:
+ CursorUpdateEvent(const QPoint &pos, const QRegion &rgn)
+ : QEvent(QEvent::Type(QEvent::User + 1)),
+ m_pos(pos),
+ m_region(rgn)
+ { }
+ QPoint pos() const { return m_pos; }
+ QRegion region() const { return m_region; }
+
+private:
+ QPoint m_pos;
+ QRegion m_region;
+};
+
+bool QEglFSCursor::event(QEvent *e)
+{
+ if (e->type() == QEvent::User + 1) {
+ CursorUpdateEvent *ev = static_cast<CursorUpdateEvent *>(e);
+ m_updateRequested = false;
+ QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region());
+ QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
+ return true;
+ }
+ return QPlatformCursor::event(e);
+}
+
+void QEglFSCursor::update(const QRegion &rgn)
+{
+ if (!m_updateRequested) {
+ // Must not flush the window system events directly from here since we are likely to
+ // be a called directly from QGuiApplication's processMouseEvents. Flushing events
+ // could cause reentering by dispatching more queued mouse events.
+ m_updateRequested = true;
+ QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn));
+ }
+}
+
+QRect QEglFSCursor::cursorRect() const
+{
+ return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size);
+}
+
+QPoint QEglFSCursor::pos() const
+{
+ return m_cursor.pos;
+}
+
+void QEglFSCursor::setPos(const QPoint &pos)
+{
+ QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos);
+ const QRect oldCursorRect = cursorRect();
+ m_cursor.pos = pos;
+ update(oldCursorRect | cursorRect());
+ m_screen->handleCursorMove(m_cursor.pos);
+}
+
+void QEglFSCursor::pointerEvent(const QMouseEvent &event)
+{
+ if (event.type() != QEvent::MouseMove)
+ return;
+ const QRect oldCursorRect = cursorRect();
+ m_cursor.pos = event.screenPos().toPoint();
+ update(oldCursorRect | cursorRect());
+ m_screen->handleCursorMove(m_cursor.pos);
+}
+
+void QEglFSCursor::paintOnScreen()
+{
+ if (!m_visible)
+ return;
+
+ const QRectF cr = cursorRect();
+ const QRect screenRect(m_screen->geometry());
+ const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1;
+ const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1;
+ const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2;
+ const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2;
+ QRectF r(QPointF(x1, y1), QPointF(x2, y2));
+
+ draw(r);
+}
+
+// In order to prevent breaking code doing custom OpenGL rendering while
+// expecting the state in the context unchanged, save and restore all the state
+// we touch. The exception is Qt Quick where the scenegraph is known to be able
+// to deal with the changes we make.
+struct StateSaver
+{
+ StateSaver() {
+ f = QOpenGLContext::currentContext()->functions();
+ vaoHelper = new QOpenGLVertexArrayObjectHelper(QOpenGLContext::currentContext());
+
+ static bool windowsChecked = false;
+ static bool shouldSave = true;
+ if (!windowsChecked) {
+ windowsChecked = true;
+ QWindowList windows = QGuiApplication::allWindows();
+ if (!windows.isEmpty() && windows[0]->inherits("QQuickWindow"))
+ shouldSave = false;
+ }
+ saved = shouldSave;
+ if (!shouldSave)
+ return;
+
+ f->glGetIntegerv(GL_CURRENT_PROGRAM, &program);
+ f->glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);
+ f->glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
+ f->glGetIntegerv(GL_FRONT_FACE, &frontFace);
+ cull = f->glIsEnabled(GL_CULL_FACE);
+ depthTest = f->glIsEnabled(GL_DEPTH_TEST);
+ blend = f->glIsEnabled(GL_BLEND);
+ f->glGetIntegerv(GL_BLEND_SRC_RGB, blendFunc);
+ f->glGetIntegerv(GL_BLEND_SRC_ALPHA, blendFunc + 1);
+ f->glGetIntegerv(GL_BLEND_DST_RGB, blendFunc + 2);
+ f->glGetIntegerv(GL_BLEND_DST_ALPHA, blendFunc + 3);
+ f->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBuf);
+ if (vaoHelper->isValid())
+ f->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao);
+ for (int i = 0; i < 2; ++i) {
+ f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &va[i].enabled);
+ f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &va[i].size);
+ f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &va[i].type);
+ f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &va[i].normalized);
+ f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &va[i].stride);
+ f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &va[i].buffer);
+ f->glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &va[i].pointer);
+ }
+ }
+ ~StateSaver() {
+ if (saved) {
+ f->glUseProgram(program);
+ f->glBindTexture(GL_TEXTURE_2D, texture);
+ f->glActiveTexture(activeTexture);
+ f->glFrontFace(frontFace);
+ if (cull)
+ f->glEnable(GL_CULL_FACE);
+ else
+ f->glDisable(GL_CULL_FACE);
+ if (depthTest)
+ f->glEnable(GL_DEPTH_TEST);
+ else
+ f->glDisable(GL_DEPTH_TEST);
+ if (blend)
+ f->glEnable(GL_BLEND);
+ else
+ f->glDisable(GL_BLEND);
+ f->glBlendFuncSeparate(blendFunc[0], blendFunc[1], blendFunc[2], blendFunc[3]);
+ f->glBindBuffer(GL_ARRAY_BUFFER, arrayBuf);
+ if (vaoHelper->isValid())
+ vaoHelper->glBindVertexArray(vao);
+ for (int i = 0; i < 2; ++i) {
+ if (va[i].enabled)
+ f->glEnableVertexAttribArray(i);
+ else
+ f->glDisableVertexAttribArray(i);
+ f->glBindBuffer(GL_ARRAY_BUFFER, va[i].buffer);
+ f->glVertexAttribPointer(i, va[i].size, va[i].type, va[i].normalized, va[i].stride, va[i].pointer);
+ }
+ }
+ delete vaoHelper;
+ }
+ QOpenGLFunctions *f;
+ QOpenGLVertexArrayObjectHelper *vaoHelper;
+ bool saved;
+ GLint program;
+ GLint texture;
+ GLint activeTexture;
+ GLint frontFace;
+ bool cull;
+ bool depthTest;
+ bool blend;
+ GLint blendFunc[4];
+ GLint vao;
+ GLint arrayBuf;
+ struct { GLint enabled, type, size, normalized, stride, buffer; GLvoid *pointer; } va[2];
+};
+
+void QEglFSCursor::draw(const QRectF &r)
+{
+ StateSaver stateSaver;
+
+ if (!m_program) {
+ // one time initialization
+ initializeOpenGLFunctions();
+
+ createShaderPrograms();
+
+ if (!m_cursorAtlas.texture) {
+ createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image);
+
+ if (m_cursor.shape != Qt::BitmapCursor)
+ m_cursor.texture = m_cursorAtlas.texture;
+ }
+ }
+
+ if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) {
+ // upload the custom cursor
+ createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage);
+ m_cursor.texture = m_cursor.customCursorTexture;
+ m_cursor.customCursorPending = false;
+ }
+
+ Q_ASSERT(m_cursor.texture);
+
+ m_program->bind();
+
+ const GLfloat x1 = r.left();
+ const GLfloat x2 = r.right();
+ const GLfloat y1 = r.top();
+ const GLfloat y2 = r.bottom();
+ const GLfloat cursorCoordinates[] = {
+ x1, y2,
+ x2, y2,
+ x1, y1,
+ x2, y1
+ };
+
+ const GLfloat s1 = m_cursor.textureRect.left();
+ const GLfloat s2 = m_cursor.textureRect.right();
+ const GLfloat t1 = m_cursor.textureRect.top();
+ const GLfloat t2 = m_cursor.textureRect.bottom();
+ const GLfloat textureCoordinates[] = {
+ s1, t2,
+ s2, t2,
+ s1, t1,
+ s2, t1
+ };
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_cursor.texture);
+
+ if (stateSaver.vaoHelper->isValid())
+ stateSaver.vaoHelper->glBindVertexArray(0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ m_program->enableAttributeArray(0);
+ m_program->enableAttributeArray(1);
+ m_program->setAttributeArray(0, cursorCoordinates, 2);
+ m_program->setAttributeArray(1, textureCoordinates, 2);
+
+ m_program->setUniformValue(m_textureEntry, 0);
+
+ glDisable(GL_CULL_FACE);
+ glFrontFace(GL_CCW);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ m_program->disableAttributeArray(0);
+ m_program->disableAttributeArray(1);
+ m_program->release();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.h b/src/plugins/platforms/eglfs/qeglfscursor.h
new file mode 100644
index 0000000000..be5db41b37
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfscursor.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLFSCURSOR_H
+#define QEGLFSCURSOR_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qeglfsglobal.h"
+#include <qpa/qplatformcursor.h>
+#include <qpa/qplatformscreen.h>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/private/qinputdevicemanager_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLShaderProgram;
+class QEglFSCursor;
+class QEglFSScreen;
+
+class QEglFSCursorDeviceListener : public QObject
+{
+ Q_OBJECT
+
+public:
+ QEglFSCursorDeviceListener(QEglFSCursor *cursor) : m_cursor(cursor) { }
+ bool hasMouse() const;
+
+public slots:
+ void onDeviceListChanged(QInputDeviceManager::DeviceType type);
+
+private:
+ QEglFSCursor *m_cursor;
+};
+
+class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor, protected QOpenGLFunctions
+{
+ Q_OBJECT
+public:
+ QEglFSCursor(QPlatformScreen *screen);
+ ~QEglFSCursor();
+
+#ifndef QT_NO_CURSOR
+ void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE;
+#endif
+ void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE;
+ QPoint pos() const Q_DECL_OVERRIDE;
+ void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
+
+ QRect cursorRect() const;
+ void paintOnScreen();
+ void resetResources();
+
+ void updateMouseStatus();
+
+private:
+ bool event(QEvent *e) Q_DECL_OVERRIDE;
+#ifndef QT_NO_CURSOR
+ bool setCurrentCursor(QCursor *cursor);
+#endif
+ void draw(const QRectF &rect);
+ void update(const QRegion &region);
+ void createShaderPrograms();
+ void createCursorTexture(uint *texture, const QImage &image);
+ void initCursorAtlas();
+
+ // current cursor information
+ struct Cursor {
+ Cursor() : texture(0), shape(Qt::BlankCursor), customCursorTexture(0), customCursorPending(false) { }
+ uint texture; // a texture from 'image' or the atlas
+ Qt::CursorShape shape;
+ QRectF textureRect; // normalized rect inside texture
+ QSize size; // size of the cursor
+ QPoint hotSpot;
+ QImage customCursorImage;
+ QPoint pos; // current cursor position
+ uint customCursorTexture;
+ bool customCursorPending;
+ } m_cursor;
+
+ // cursor atlas information
+ struct CursorAtlas {
+ CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { }
+ int cursorsPerRow;
+ uint texture;
+ int width, height; // width and height of the atlas
+ int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
+ QList<QPoint> hotSpots;
+ QImage image; // valid until it's uploaded
+ } m_cursorAtlas;
+
+ bool m_visible;
+ QEglFSScreen *m_screen;
+ QOpenGLShaderProgram *m_program;
+ int m_textureEntry;
+ QEglFSCursorDeviceListener *m_deviceListener;
+ bool m_updateRequested;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLFSCURSOR_H
diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
index 359b90f205..d27c949c8d 100644
--- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
@@ -33,8 +33,8 @@
#include "qeglfsdeviceintegration.h"
#include "qeglfsintegration.h"
+#include "qeglfscursor.h"
#include <QtPlatformSupport/private/qeglconvenience_p.h>
-#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QGuiApplication>
#include <private/qguiapplication_p.h>
#include <QScreen>
@@ -99,6 +99,7 @@ QStringList QEGLDeviceIntegrationFactory::keys(const QString &pluginPath)
qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys:" << list;
return list;
#else
+ Q_UNUSED(pluginPath);
return QStringList();
#endif
}
@@ -117,6 +118,9 @@ QEGLDeviceIntegration *QEGLDeviceIntegrationFactory::create(const QString &key,
qCDebug(qLcEglDevDebug) << "Using EGL device integration" << key;
else
qCWarning(qLcEglDevDebug) << "Failed to load EGL device integration" << key;
+#else
+ Q_UNUSED(key);
+ Q_UNUSED(pluginPath);
#endif
return integration;
}
@@ -282,7 +286,7 @@ bool QEGLDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap)
QPlatformCursor *QEGLDeviceIntegration::createCursor(QPlatformScreen *screen) const
{
- return new QEGLPlatformCursor(screen);
+ return new QEglFSCursor(screen);
}
void QEGLDeviceIntegration::waitForVSync(QPlatformSurface *surface) const
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 5eb8485dc7..5f2cc9abbc 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -39,19 +39,46 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
#include <QtGui/QOffscreenSurface>
-#include <qpa/qplatformcursor.h>
+#include <QtGui/QWindow>
+#include <QtCore/QLoggingCategory>
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatforminputcontextfactory_p.h>
#include "qeglfsintegration.h"
#include "qeglfswindow.h"
#include "qeglfshooks.h"
#include "qeglfscontext.h"
#include "qeglfsoffscreenwindow.h"
+#include "qeglfscursor.h"
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
+
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixservices_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qfbvthandler_p.h>
+#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h>
+
#include <QtPlatformHeaders/QEGLNativeContext>
+#ifndef QT_NO_LIBINPUT
+#include <QtPlatformSupport/private/qlibinputhandler_p.h>
+#endif
+
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
+#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
+#include <QtPlatformSupport/private/qevdevtouchmanager_p.h>
+#endif
+
+#if !defined(QT_NO_TSLIB) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+#include <QtPlatformSupport/private/qtslib_p.h>
+#endif
+
+#include <QtPlatformHeaders/qeglfsfunctions.h>
+
#include <EGL/egl.h>
static void initResources()
@@ -64,21 +91,18 @@ static void initResources()
QT_BEGIN_NAMESPACE
QEglFSIntegration::QEglFSIntegration()
+ : m_display(EGL_NO_DISPLAY),
+ m_inputContext(0),
+ m_fontDb(new QGenericUnixFontDatabase),
+ m_services(new QGenericUnixServices),
+ m_kbdMgr(0),
+ m_disableInputHandlers(false)
{
- mDisableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT");
+ m_disableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT");
initResources();
}
-bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const
-{
- // We assume that devices will have more and not less capabilities
- if (qt_egl_device_integration()->hasCapability(cap))
- return true;
-
- return QEGLPlatformIntegration::hasCapability(cap);
-}
-
void QEglFSIntegration::addScreen(QPlatformScreen *screen)
{
screenAdded(screen);
@@ -93,9 +117,19 @@ void QEglFSIntegration::initialize()
{
qt_egl_device_integration()->platformInit();
- QEGLPlatformIntegration::initialize();
+ m_display = eglGetDisplay(nativeDisplay());
+ if (m_display == EGL_NO_DISPLAY)
+ qFatal("Could not open egl display");
+
+ EGLint major, minor;
+ if (!eglInitialize(m_display, &major, &minor))
+ qFatal("Could not initialize egl display");
- if (!mDisableInputHandlers)
+ m_inputContext = QPlatformInputContextFactory::create();
+
+ m_vtHandler.reset(new QFbVtHandler);
+
+ if (!m_disableInputHandlers)
createInputHandlers();
if (qt_egl_device_integration()->usesDefaultScreen())
@@ -108,52 +142,283 @@ void QEglFSIntegration::destroy()
{
foreach (QWindow *w, qGuiApp->topLevelWindows())
w->destroy();
+
qt_egl_device_integration()->screenDestroy();
- if (display() != EGL_NO_DISPLAY)
- eglTerminate(display());
+
+ if (m_display != EGL_NO_DISPLAY)
+ eglTerminate(m_display);
+
qt_egl_device_integration()->platformDestroy();
}
-EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const
+QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const
{
- return qt_egl_device_integration()->platformDisplay();
+ return createUnixEventDispatcher();
+}
+
+QPlatformServices *QEglFSIntegration::services() const
+{
+ return m_services.data();
}
-QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const
+QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
{
- return new QEglFSWindow(window);
+ return m_fontDb.data();
}
-QEGLPlatformContext *QEglFSIntegration::createContext(const QSurfaceFormat &format,
- QPlatformOpenGLContext *shareContext,
- EGLDisplay display,
- QVariant *nativeHandle) const
+QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
{
+ QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window);
+ if (!window->handle())
+ window->create();
+ static_cast<QEglFSWindow *>(window->handle())->setBackingStore(bs);
+ return bs;
+}
+
+QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
+{
+ QWindowSystemInterface::flushWindowSystemEvents();
+ QEglFSWindow *w = new QEglFSWindow(window);
+ w->create();
+ if (window->type() != Qt::ToolTip)
+ w->requestActivateWindow();
+ return w;
+}
+
+QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ // If there is a "root" window into which raster and QOpenGLWidget content is
+ // composited, all other contexts must share with its context.
+ QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context();
+ EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display();
+ QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle();
+ QVariant nativeHandle = context->nativeHandle();
+
QEglFSContext *ctx;
- QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(format);
- if (!nativeHandle || nativeHandle->isNull()) {
- EGLConfig config = QEglFSIntegration::chooseConfig(display, adjustedFormat);
- ctx = new QEglFSContext(adjustedFormat, shareContext, display, &config, QVariant());
+ QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(context->format());
+ if (nativeHandle.isNull()) {
+ EGLConfig config = QEglFSIntegration::chooseConfig(dpy, adjustedFormat);
+ ctx = new QEglFSContext(adjustedFormat, share, dpy, &config, QVariant());
} else {
- ctx = new QEglFSContext(adjustedFormat, shareContext, display, 0, *nativeHandle);
+ ctx = new QEglFSContext(adjustedFormat, share, dpy, 0, nativeHandle);
}
- *nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), display));
+ nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), dpy));
+
+ context->setNativeHandle(nativeHandle);
return ctx;
}
-QPlatformOffscreenSurface *QEglFSIntegration::createOffscreenSurface(EGLDisplay display,
- const QSurfaceFormat &format,
- QOffscreenSurface *surface) const
+QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
- QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(format);
+ EGLDisplay dpy = surface->screen() ? static_cast<QEglFSScreen *>(surface->screen()->handle())->display() : display();
+ QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(surface->requestedFormat());
if (qt_egl_device_integration()->supportsPBuffers())
- return new QEGLPbuffer(display, fmt, surface);
+ return new QEGLPbuffer(dpy, fmt, surface);
else
- return new QEglFSOffscreenWindow(display, fmt, surface);
-
+ return new QEglFSOffscreenWindow(dpy, fmt, surface);
// Never return null. Multiple QWindows are not supported by this plugin.
}
+bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ // We assume that devices will have more and not less capabilities
+ if (qt_egl_device_integration()->hasCapability(cap))
+ return true;
+
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
+ case WindowManagement: return false;
+ case RasterGLSurface: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformNativeInterface *QEglFSIntegration::nativeInterface() const
+{
+ return const_cast<QEglFSIntegration *>(this);
+}
+
+enum ResourceType {
+ EglDisplay,
+ EglWindow,
+ EglContext,
+ EglConfig,
+ NativeDisplay,
+ XlibDisplay
+};
+
+static int resourceType(const QByteArray &key)
+{
+ static const QByteArray names[] = { // match ResourceType
+ QByteArrayLiteral("egldisplay"),
+ QByteArrayLiteral("eglwindow"),
+ QByteArrayLiteral("eglcontext"),
+ QByteArrayLiteral("eglconfig"),
+ QByteArrayLiteral("nativedisplay"),
+ QByteArrayLiteral("display")
+ };
+ const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
+ const QByteArray *result = std::find(names, end, key);
+ if (result == end)
+ result = std::find(names, end, key.toLower());
+ return int(result - names);
+}
+
+void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglDisplay:
+ result = display();
+ break;
+ case NativeDisplay:
+ result = reinterpret_cast<void*>(nativeDisplay());
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void *QEglFSIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case XlibDisplay:
+ // Play nice when using the x11 hooks: Be compatible with xcb that allows querying
+ // the X Display pointer, which is nothing but our native display.
+ result = reinterpret_cast<void*>(nativeDisplay());
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglDisplay:
+ if (window && window->handle())
+ result = static_cast<QEglFSScreen *>(window->handle()->screen())->display();
+ else
+ result = display();
+ break;
+ case EglWindow:
+ if (window && window->handle())
+ result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->eglWindow());
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglContext:
+ if (context->handle())
+ result = static_cast<QEglFSContext *>(context->handle())->eglContext();
+ break;
+ case EglConfig:
+ if (context->handle())
+ result = static_cast<QEglFSContext *>(context->handle())->eglConfig();
+ break;
+ case EglDisplay:
+ if (context->handle())
+ result = static_cast<QEglFSContext *>(context->handle())->eglDisplay();
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static void *eglContextForContext(QOpenGLContext *context)
+{
+ Q_ASSERT(context);
+
+ QEglFSContext *handle = static_cast<QEglFSContext *>(context->handle());
+ if (!handle)
+ return 0;
+
+ return handle->eglContext();
+}
+
+QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+ if (lowerCaseResource == "get_egl_context")
+ return NativeResourceForContextFunction(eglContextForContext);
+
+ return 0;
+}
+
+QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) const
+{
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+ if (function == QEglFSFunctions::loadKeymapTypeIdentifier())
+ return QFunctionPointer(loadKeymapStatic);
+#else
+ Q_UNUSED(function)
+#endif
+
+ return 0;
+}
+
+void QEglFSIntegration::loadKeymapStatic(const QString &filename)
+{
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+ QEglFSIntegration *self = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
+ if (self->m_kbdMgr)
+ self->m_kbdMgr->loadKeymap(filename);
+ else
+ qWarning("QEglFSIntegration: Cannot load keymap, no keyboard handler found");
+#else
+ Q_UNUSED(filename);
+#endif
+}
+
+void QEglFSIntegration::createInputHandlers()
+{
+#ifndef QT_NO_LIBINPUT
+ if (!qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT")) {
+ new QLibInputHandler(QLatin1String("libinput"), QString());
+ return;
+ }
+#endif
+
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+ m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
+ new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
+#ifndef QT_NO_TSLIB
+ const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB");
+ if (useTslib)
+ new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */);
+ else
+#endif // QT_NO_TSLIB
+ new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this);
+#endif
+}
+
+EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const
+{
+ return qt_egl_device_integration()->platformDisplay();
+}
+
EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
{
class Chooser : public QEglConfigChooser {
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index 11b643d540..98c7ee9f78 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -34,41 +34,72 @@
#ifndef QEGLFSINTEGRATION_H
#define QEGLFSINTEGRATION_H
-#include <QtPlatformSupport/private/qeglplatformintegration_p.h>
+#include <QtCore/QVariant>
+#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformscreen.h>
#include <EGL/egl.h>
#include "qeglfsglobal.h"
QT_BEGIN_NAMESPACE
-class Q_EGLFS_EXPORT QEglFSIntegration : public QEGLPlatformIntegration
+class QEglFSWindow;
+class QEglFSContext;
+class QFbVtHandler;
+class QEvdevKeyboardManager;
+
+class Q_EGLFS_EXPORT QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface
{
public:
QEglFSIntegration();
- void addScreen(QPlatformScreen *screen);
- void removeScreen(QPlatformScreen *screen);
-
void initialize() Q_DECL_OVERRIDE;
void destroy() Q_DECL_OVERRIDE;
+ EGLDisplay display() const { return m_display; }
+
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
+ QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
+ QPlatformServices *services() const Q_DECL_OVERRIDE;
+ QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; }
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
+
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
- static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format);
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
-protected:
- QEGLPlatformWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE;
- QEGLPlatformContext *createContext(const QSurfaceFormat &format,
- QPlatformOpenGLContext *shareContext,
- EGLDisplay display,
- QVariant *nativeHandle) const Q_DECL_OVERRIDE;
- QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display,
- const QSurfaceFormat &format,
- QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
- EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
+ // QPlatformNativeInterface
+ void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
+ void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE;
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
+ NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
+
+ QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
+
+ QFbVtHandler *vtHandler() { return m_vtHandler.data(); }
+
+ void addScreen(QPlatformScreen *screen);
+ void removeScreen(QPlatformScreen *screen);
+
+ static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format);
private:
- bool mDisableInputHandlers;
+ EGLNativeDisplayType nativeDisplay() const;
+ void createInputHandlers();
+ static void loadKeymapStatic(const QString &filename);
+
+ EGLDisplay m_display;
+ QPlatformInputContext *m_inputContext;
+ QScopedPointer<QPlatformFontDatabase> m_fontDb;
+ QScopedPointer<QPlatformServices> m_services;
+ QScopedPointer<QFbVtHandler> m_vtHandler;
+ QEvdevKeyboardManager *m_kbdMgr;
+ bool m_disableInputHandlers;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 1b6e2307f8..22ec424451 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -32,7 +32,10 @@
****************************************************************************/
#include <QtCore/qtextstream.h>
-#include <QtGui/qpa/qplatformcursor.h>
+#include <QtGui/qwindow.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformcursor.h>
+#include <QtPlatformSupport/private/qopenglcompositor_p.h>
#include "qeglfsscreen.h"
#include "qeglfswindow.h"
@@ -41,7 +44,8 @@
QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
- : QEGLPlatformScreen(dpy),
+ : m_dpy(dpy),
+ m_pointerWindow(0),
m_surface(EGL_NO_SURFACE),
m_cursor(0)
{
@@ -51,6 +55,7 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
QEglFSScreen::~QEglFSScreen()
{
delete m_cursor;
+ QOpenGLCompositor::destroy();
}
QRect QEglFSScreen::geometry() const
@@ -103,4 +108,89 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface)
m_surface = surface;
}
+void QEglFSScreen::handleCursorMove(const QPoint &pos)
+{
+ const QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
+ const QList<QOpenGLCompositorWindow *> windows = compositor->windows();
+
+ // Generate enter and leave events like a real windowing system would do.
+ if (windows.isEmpty())
+ return;
+
+ // First window is always fullscreen.
+ if (windows.count() == 1) {
+ QWindow *window = windows[0]->sourceWindow();
+ if (m_pointerWindow != window) {
+ m_pointerWindow = window;
+ QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos);
+ }
+ return;
+ }
+
+ QWindow *enter = 0, *leave = 0;
+ for (int i = windows.count() - 1; i >= 0; --i) {
+ QWindow *window = windows[i]->sourceWindow();
+ const QRect geom = window->geometry();
+ if (geom.contains(pos)) {
+ if (m_pointerWindow != window) {
+ leave = m_pointerWindow;
+ m_pointerWindow = window;
+ enter = window;
+ }
+ break;
+ }
+ }
+
+ if (enter && leave)
+ QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos);
+}
+
+QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) const
+{
+ QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
+ const QList<QOpenGLCompositorWindow *> windows = compositor->windows();
+ Q_ASSERT(!windows.isEmpty());
+
+ QImage img;
+
+ if (static_cast<QEglFSWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) {
+ // Request the compositor to render everything into an FBO and read it back. This
+ // is of course slow, but it's safe and reliable. It will not include the mouse
+ // cursor, which is a plus.
+ img = compositor->grab();
+ } else {
+ // Just a single OpenGL window without compositing. Do not support this case for now. Doing
+ // glReadPixels is not an option since it would read from the back buffer which may have
+ // undefined content when calling right after a swapBuffers (unless preserved swap is
+ // available and enabled, but we have no support for that).
+ qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead.");
+ return QPixmap();
+ }
+
+ if (!wid) {
+ const QSize screenSize = geometry().size();
+ if (width < 0)
+ width = screenSize.width() - x;
+ if (height < 0)
+ height = screenSize.height() - y;
+ return QPixmap::fromImage(img).copy(x, y, width, height);
+ }
+
+ foreach (QOpenGLCompositorWindow *w, windows) {
+ const QWindow *window = w->sourceWindow();
+ if (window->winId() == wid) {
+ const QRect geom = window->geometry();
+ if (width < 0)
+ width = geom.width() - x;
+ if (height < 0)
+ height = geom.height() - y;
+ QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height));
+ rect &= window->geometry();
+ return QPixmap::fromImage(img).copy(rect);
+ }
+ }
+
+ return QPixmap();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 07b6ff63ef..dc291285ad 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -35,7 +35,6 @@
#define QEGLFSSCREEN_H
#include "qeglfsglobal.h"
-#include <QtPlatformSupport/private/qeglplatformscreen_p.h>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@@ -43,7 +42,7 @@ QT_BEGIN_NAMESPACE
class QEglFSWindow;
class QOpenGLContext;
-class Q_EGLFS_EXPORT QEglFSScreen : public QEGLPlatformScreen
+class Q_EGLFS_EXPORT QEglFSScreen : public QPlatformScreen
{
public:
QEglFSScreen(EGLDisplay display);
@@ -62,16 +61,23 @@ public:
qreal refreshRate() const Q_DECL_OVERRIDE;
+ QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
+
EGLSurface primarySurface() const { return m_surface; }
-protected:
- void setPrimarySurface(EGLSurface surface);
+ EGLDisplay display() const { return m_dpy; }
+
+ void handleCursorMove(const QPoint &pos);
private:
- friend class QEglFSWindow;
+ void setPrimarySurface(EGLSurface surface);
+ EGLDisplay m_dpy;
+ QWindow *m_pointerWindow;
EGLSurface m_surface;
QPlatformCursor *m_cursor;
+
+ friend class QEglFSWindow;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index c0d51c94a5..c3b9dd6ef0 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -37,21 +37,23 @@
#include <private/qguiapplication_p.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/QOpenGLContext>
-#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h>
#include "qeglfswindow.h"
+#include "qeglfscursor.h"
#include "qeglfshooks.h"
-#include <QtDebug>
-
QT_BEGIN_NAMESPACE
QEglFSWindow::QEglFSWindow(QWindow *w)
- : QEGLPlatformWindow(w)
- , m_surface(0)
- , m_window(0)
- , m_flags(0)
+ : QPlatformWindow(w),
+ m_backingStore(0),
+ m_raster(false),
+ m_winId(0),
+ m_surface(0),
+ m_window(0),
+ m_flags(0)
{
}
@@ -60,12 +62,34 @@ QEglFSWindow::~QEglFSWindow()
destroy();
}
+static WId newWId()
+{
+ static WId id = 0;
+
+ if (id == std::numeric_limits<WId>::max())
+ qWarning("QEGLPlatformWindow: Out of window IDs");
+
+ return ++id;
+}
+
void QEglFSWindow::create()
{
if (m_flags.testFlag(Created))
return;
- QEGLPlatformWindow::create();
+ m_winId = newWId();
+
+ // Save the original surface type before changing to OpenGLSurface.
+ m_raster = (window()->surfaceType() == QSurface::RasterSurface);
+ if (m_raster) // change to OpenGL, but not for RasterGLSurface
+ window()->setSurfaceType(QSurface::OpenGLSurface);
+
+ if (window()->type() == Qt::Desktop) {
+ QRect fullscreenRect(QPoint(), screen()->availableGeometry().size());
+ QPlatformWindow::setGeometry(fullscreenRect);
+ QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
+ return;
+ }
m_flags = Created;
@@ -120,7 +144,7 @@ void QEglFSWindow::destroy()
{
QEglFSScreen *screen = this->screen();
if (m_flags.testFlag(HasNativeWindow)) {
- QEGLPlatformCursor *cursor = qobject_cast<QEGLPlatformCursor *>(screen->cursor());
+ QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(screen->cursor());
if (cursor)
cursor->resetResources();
@@ -265,4 +289,41 @@ QEglFSScreen *QEglFSWindow::screen() const
return static_cast<QEglFSScreen *>(QPlatformWindow::screen());
}
+bool QEglFSWindow::isRaster() const
+{
+ return m_raster || window()->surfaceType() == QSurface::RasterGLSurface;
+}
+
+QWindow *QEglFSWindow::sourceWindow() const
+{
+ return window();
+}
+
+const QPlatformTextureList *QEglFSWindow::textures() const
+{
+ if (m_backingStore)
+ return m_backingStore->textures();
+
+ return 0;
+}
+
+void QEglFSWindow::endCompositing()
+{
+ if (m_backingStore)
+ m_backingStore->notifyComposited();
+}
+
+WId QEglFSWindow::winId() const
+{
+ return m_winId;
+}
+
+void QEglFSWindow::setOpacity(qreal)
+{
+ if (!isRaster())
+ qWarning("QEglFSWindow: Cannot set opacity for non-raster windows");
+
+ // Nothing to do here. The opacity is stored in the QWindow.
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index f9d207c153..53b9e18dc1 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -37,17 +37,23 @@
#include "qeglfsintegration.h"
#include "qeglfsscreen.h"
#include "qeglfsglobal.h"
-#include <QtPlatformSupport/private/qeglplatformwindow_p.h>
+
+#include <qpa/qplatformwindow.h>
+#include <QtPlatformSupport/private/qopenglcompositor_p.h>
+#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
-class Q_EGLFS_EXPORT QEglFSWindow : public QEGLPlatformWindow
+class QOpenGLCompositorBackingStore;
+class QPlatformTextureList;
+
+class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow, public QOpenGLCompositorWindow
{
public:
QEglFSWindow(QWindow *w);
~QEglFSWindow();
- void create() Q_DECL_OVERRIDE;
+ void create();
void destroy();
void setGeometry(const QRect &) Q_DECL_OVERRIDE;
@@ -58,13 +64,15 @@ public:
void lower() Q_DECL_OVERRIDE;
void propagateSizeHints() Q_DECL_OVERRIDE { }
- void setOpacity(qreal) Q_DECL_OVERRIDE { }
void setMask(const QRegion &) Q_DECL_OVERRIDE { }
bool setKeyboardGrabEnabled(bool) Q_DECL_OVERRIDE { return false; }
bool setMouseGrabEnabled(bool) Q_DECL_OVERRIDE { return false; }
+ void setOpacity(qreal) Q_DECL_OVERRIDE;
+ WId winId() const Q_DECL_OVERRIDE;
QSurfaceFormat format() const Q_DECL_OVERRIDE;
- EGLNativeWindowType eglWindow() const Q_DECL_OVERRIDE;
+
+ EGLNativeWindowType eglWindow() const;
EGLSurface surface() const;
QEglFSScreen *screen() const;
@@ -73,11 +81,22 @@ public:
virtual void invalidateSurface() Q_DECL_OVERRIDE;
virtual void resetSurface();
-protected:
+ QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; }
+ void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; }
+ bool isRaster() const;
+
+ QWindow *sourceWindow() const Q_DECL_OVERRIDE;
+ const QPlatformTextureList *textures() const Q_DECL_OVERRIDE;
+ void endCompositing() Q_DECL_OVERRIDE;
+
+private:
+ QOpenGLCompositorBackingStore *m_backingStore;
+ bool m_raster;
+ WId m_winId;
+
EGLSurface m_surface;
EGLNativeWindowType m_window;
-private:
EGLConfig m_config;
QSurfaceFormat m_format;
diff --git a/src/plugins/platforms/haiku/qhaikuclipboard.cpp b/src/plugins/platforms/haiku/qhaikuclipboard.cpp
index f3aa9dc36e..a2d7e96d71 100644
--- a/src/plugins/platforms/haiku/qhaikuclipboard.cpp
+++ b/src/plugins/platforms/haiku/qhaikuclipboard.cpp
@@ -41,6 +41,8 @@
#include <Clipboard.h>
QHaikuClipboard::QHaikuClipboard()
+ : m_systemMimeData(Q_NULLPTR)
+ , m_userMimeData(Q_NULLPTR)
{
if (be_clipboard)
be_clipboard->StartWatching(BMessenger(this));
@@ -50,17 +52,26 @@ QHaikuClipboard::~QHaikuClipboard()
{
if (be_clipboard)
be_clipboard->StopWatching(BMessenger(this));
+
+ delete m_userMimeData;
+ delete m_systemMimeData;
}
QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode)
{
- QMimeData *mimeData = new QMimeData();
-
if (mode != QClipboard::Clipboard)
- return mimeData;
+ return 0;
+
+ if (m_userMimeData)
+ return m_userMimeData;
if (!be_clipboard->Lock())
- return mimeData;
+ return 0;
+
+ if (!m_systemMimeData)
+ m_systemMimeData = new QMimeData();
+ else
+ m_systemMimeData->clear();
const BMessage *clipboard = be_clipboard->Data();
if (clipboard) {
@@ -76,11 +87,11 @@ QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode)
if (dataLen && (status == B_OK)) {
const QString format = QString::fromLatin1(name);
if (format == QStringLiteral("text/plain")) {
- mimeData->setText(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
+ m_systemMimeData->setText(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
} else if (format == QStringLiteral("text/html")) {
- mimeData->setHtml(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
+ m_systemMimeData->setHtml(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
} else {
- mimeData->setData(format, QByteArray(reinterpret_cast<const char*>(data), dataLen));
+ m_systemMimeData->setData(format, QByteArray(reinterpret_cast<const char*>(data), dataLen));
}
}
}
@@ -88,7 +99,7 @@ QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode)
be_clipboard->Unlock();
- return mimeData;
+ return m_systemMimeData;
}
void QHaikuClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
@@ -96,6 +107,14 @@ void QHaikuClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
if (mode != QClipboard::Clipboard)
return;
+ if (mimeData) {
+ if (m_systemMimeData == mimeData)
+ return;
+
+ if (m_userMimeData == mimeData)
+ return;
+ }
+
if (!be_clipboard->Lock())
return;
@@ -115,6 +134,10 @@ void QHaikuClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
qWarning("Unable to store mime data on clipboard");
be_clipboard->Unlock();
+
+ m_userMimeData = mimeData;
+
+ emitChanged(QClipboard::Clipboard);
}
bool QHaikuClipboard::supportsMode(QClipboard::Mode mode) const
@@ -131,8 +154,12 @@ bool QHaikuClipboard::ownsMode(QClipboard::Mode mode) const
void QHaikuClipboard::MessageReceived(BMessage* message)
{
- if (message->what == B_CLIPBOARD_CHANGED)
+ if (message->what == B_CLIPBOARD_CHANGED) {
+ delete m_userMimeData;
+ m_userMimeData = Q_NULLPTR;
+
emitChanged(QClipboard::Clipboard);
+ }
BHandler::MessageReceived(message);
}
diff --git a/src/plugins/platforms/haiku/qhaikuclipboard.h b/src/plugins/platforms/haiku/qhaikuclipboard.h
index 0dc2bfdd3b..3c1f92c615 100644
--- a/src/plugins/platforms/haiku/qhaikuclipboard.h
+++ b/src/plugins/platforms/haiku/qhaikuclipboard.h
@@ -55,6 +55,10 @@ public:
// override from BHandler to catch change notifications from Haiku clipboard
void MessageReceived(BMessage* message) Q_DECL_OVERRIDE;
+
+private:
+ QMimeData *m_systemMimeData;
+ QMimeData *m_userMimeData;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/haiku/qhaikuwindow.cpp b/src/plugins/platforms/haiku/qhaikuwindow.cpp
index 5768e1cb40..9622d12111 100644
--- a/src/plugins/platforms/haiku/qhaikuwindow.cpp
+++ b/src/plugins/platforms/haiku/qhaikuwindow.cpp
@@ -130,6 +130,7 @@ QHaikuWindow::QHaikuWindow(QWindow *window)
if (!m_window)
qFatal("QHaikuWindow: failed to create window");
+ setGeometry(rect);
setWindowFlags(window->flags());
}
@@ -164,13 +165,13 @@ void QHaikuWindow::setVisible(bool visible)
{
if (visible) {
m_window->Show();
+
+ window()->requestActivate();
+
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), window()->geometry().size()));
} else {
m_window->Hide();
}
-
- window()->requestActivate();
-
- QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
}
bool QHaikuWindow::isExposed() const
@@ -306,10 +307,8 @@ void QHaikuWindow::haikuWindowMoved(const QPoint &pos)
const QRect newGeometry(pos, geometry().size());
QPlatformWindow::setGeometry(newGeometry);
- QWindowSystemInterface::setSynchronousWindowsSystemEvents(true);
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
- QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
- QWindowSystemInterface::setSynchronousWindowsSystemEvents(false);
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
}
void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress)
@@ -317,10 +316,8 @@ void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress)
const QRect newGeometry(geometry().topLeft(), size);
QPlatformWindow::setGeometry(newGeometry);
- QWindowSystemInterface::setSynchronousWindowsSystemEvents(true);
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
- QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
- QWindowSystemInterface::setSynchronousWindowsSystemEvents(false);
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
if ((m_windowState == Qt::WindowMaximized) && !zoomInProgress) {
// the user has resized the window while maximized -> reset maximized flag
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm
index 92799f80c1..7a37e213bd 100644
--- a/src/plugins/platforms/ios/qiosapplicationstate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationstate.mm
@@ -43,7 +43,7 @@
@implementation QIOSApplicationStateListener
-- (id) init
+- (id)init
{
self = [super init];
if (self) {
@@ -75,7 +75,7 @@
return self;
}
-- (void) dealloc
+- (void)dealloc
{
[[NSNotificationCenter defaultCenter]
removeObserver:self
@@ -92,12 +92,12 @@
[super dealloc];
}
-- (void) applicationDidBecomeActive
+- (void)applicationDidBecomeActive
{
[self handleApplicationStateChanged:UIApplicationStateActive];
}
-- (void) applicationWillResignActive
+- (void)applicationWillResignActive
{
// Note that UIApplication is still UIApplicationStateActive at this
// point, but since there is no separate notification for the inactive
@@ -105,12 +105,12 @@
[self handleApplicationStateChanged:UIApplicationStateInactive];
}
-- (void) applicationDidEnterBackground
+- (void)applicationDidEnterBackground
{
[self handleApplicationStateChanged:UIApplicationStateBackground];
}
-- (void) handleApplicationStateChanged:(UIApplicationState) uiApplicationState
+- (void)handleApplicationStateChanged:(UIApplicationState)uiApplicationState
{
// We may receive application state changes after QCoreApplication has
// gone down, as the block we schedule on the main queue keeps the
diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm
index 192ee67689..e0c6ec5d72 100644
--- a/src/plugins/platforms/ios/qiosclipboard.mm
+++ b/src/plugins/platforms/ios/qiosclipboard.mm
@@ -62,7 +62,7 @@
@implementation QUIClipboard
--(id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard
+- (id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard
{
self = [super init];
if (self) {
@@ -87,7 +87,7 @@
return self;
}
--(void)dealloc
+- (void)dealloc
{
[[NSNotificationCenter defaultCenter]
removeObserver:self
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index fc12e83a81..bd4b8778ed 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -198,7 +198,7 @@ namespace
bool debugStackUsage = false;
}
-extern "C" int __attribute__((weak)) main(int argc, char *argv[])
+extern "C" int qt_main_wrapper(int argc, char *argv[])
{
@autoreleasepool {
size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads
@@ -233,18 +233,7 @@ enum SetJumpResult
kJumpedFromUserMainTrampoline,
};
-// We define qtmn so that user_main_trampoline() will not cause
-// missing symbols in the case of hybrid applications that don't
-// use our main wrapper. Since the symbol is weak, it will not
-// get used or cause a clash in the normal Qt application usecase,
-// where we rename main to qtmn before linking.
-extern "C" int __attribute__((weak)) qtmn(int argc, char *argv[])
-{
- Q_UNUSED(argc);
- Q_UNUSED(argv);
-
- Q_UNREACHABLE();
-}
+extern "C" int main(int argc, char *argv[]);
static void __attribute__((noinline, noreturn)) user_main_trampoline()
{
@@ -263,7 +252,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline()
qFatal("Could not convert argv[%d] to C string", i);
}
- int exitCode = qtmn(argc, argv);
+ int exitCode = main(argc, argv);
delete[] argv;
qEventDispatcherDebug() << "Returned from main with exit code " << exitCode;
@@ -293,7 +282,7 @@ static bool rootLevelRunLoopIntegration()
@implementation QIOSApplicationStateTracker
-+ (void) load
++ (void)load
{
[[NSNotificationCenter defaultCenter]
addObserver:self
@@ -323,7 +312,7 @@ static bool rootLevelRunLoopIntegration()
# error "Unknown processor family"
#endif
-+ (void) applicationDidFinishLaunching
++ (void)applicationDidFinishLaunching
{
if (!isQtApplication())
return;
@@ -377,7 +366,7 @@ static bool rootLevelRunLoopIntegration()
// four bits of the exit code (exit(3) will only pass on the lower 8 bits).
static const char kApplicationWillTerminateExitCode = SIGTERM | 0x80;
-+ (void) applicationWillTerminate
++ (void)applicationWillTerminate
{
if (!isQtApplication())
return;
diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h
index 86b784618f..544f9e0a42 100644
--- a/src/plugins/platforms/ios/qiosglobal.h
+++ b/src/plugins/platforms/ios/qiosglobal.h
@@ -68,7 +68,7 @@ int infoPlistValue(NSString* key, int defaultValue);
QT_END_NAMESPACE
@interface UIResponder (QtFirstResponder)
-+(id)currentFirstResponder;
++ (id)currentFirstResponder;
@end
class FirstResponderCandidate : public QScopedValueRollback<UIResponder *>
diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm
index ef24abbfd9..f5b971391d 100644
--- a/src/plugins/platforms/ios/qiosglobal.mm
+++ b/src/plugins/platforms/ios/qiosglobal.mm
@@ -133,7 +133,7 @@ int infoPlistValue(NSString* key, int defaultValue)
@end
@implementation QtFirstResponderEvent
-- (void) dealloc
+- (void)dealloc
{
self.firstResponder = 0;
[super dealloc];
@@ -158,7 +158,7 @@ int infoPlistValue(NSString* key, int defaultValue)
@implementation UIResponder (QtFirstResponder)
-+(id)currentFirstResponder
++ (id)currentFirstResponder
{
QtFirstResponderEvent *event = [[[QtFirstResponderEvent alloc] init] autorelease];
[[UIApplication sharedApplication] sendAction:@selector(qt_findFirstResponder:event:) to:nil from:nil forEvent:event];
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 090df66e0d..d03c589b2a 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -579,7 +579,7 @@ void QIOSInputContext::focusWindowChanged(QWindow *focusWindow)
void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties)
{
// Mask for properties that we are interested in and see if any of them changed
- updatedProperties &= (Qt::ImEnabled | Qt::ImHints | Qt::ImQueryInput | Qt::ImPlatformData);
+ updatedProperties &= (Qt::ImEnabled | Qt::ImHints | Qt::ImQueryInput | Qt::ImEnterKeyType | Qt::ImPlatformData);
qImDebug() << "fw =" << qApp->focusWindow() << "fo =" << qApp->focusObject();
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 8395db81ff..eaff0daf19 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -219,6 +219,10 @@ QPlatformServices *QIOSIntegration::services() const
QVariant QIOSIntegration::styleHint(StyleHint hint) const
{
switch (hint) {
+ case PasswordMaskDelay:
+ // this number is based on timing the native delay
+ // since there is no API to get it
+ return 2000;
case ShowIsMaximized:
return true;
case SetFocusOnTouchRelease:
diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm
index 08fc8a5e9c..045d39e328 100644
--- a/src/plugins/platforms/ios/qiosmenu.mm
+++ b/src/plugins/platforms/ios/qiosmenu.mm
@@ -165,7 +165,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
[self reloadAllComponents];
}
--(void)listenForKeyboardWillHideNotification:(BOOL)listen
+- (void)listenForKeyboardWillHideNotification:(BOOL)listen
{
if (listen) {
[[NSNotificationCenter defaultCenter]
@@ -179,7 +179,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
}
}
--(void)dealloc
+- (void)dealloc
{
[self listenForKeyboardWillHideNotification:NO];
self.toolbar = 0;
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index 324133074b..3e16efcd22 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -104,12 +104,12 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
@public
QIOSScreen *m_screen;
}
-- (id) initWithQIOSScreen:(QIOSScreen *)screen;
+- (id)initWithQIOSScreen:(QIOSScreen *)screen;
@end
@implementation QIOSOrientationListener
-- (id) initWithQIOSScreen:(QIOSScreen *)screen
+- (id)initWithQIOSScreen:(QIOSScreen *)screen
{
self = [super init];
if (self) {
@@ -123,7 +123,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
return self;
}
-- (void) dealloc
+- (void)dealloc
{
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
@@ -132,7 +132,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
[super dealloc];
}
-- (void) orientationChanged:(NSNotification *)notification
+- (void)orientationChanged:(NSNotification *)notification
{
Q_UNUSED(notification);
m_screen->updateProperties();
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index be9c3b9e27..e4917593db 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -92,12 +92,12 @@
return [QUITextPosition positionWithIndex:(self.range.location + self.range.length)];
}
-- (NSRange) range
+- (NSRange)range
{
return _range;
}
--(BOOL)isEmpty
+- (BOOL)isEmpty
{
return (self.range.length == 0);
}
@@ -111,7 +111,7 @@
@implementation WrapperView
--(id)initWithView:(UIView *)view
+- (id)initWithView:(UIView *)view
{
if (self = [self init]) {
[self addSubview:view];
@@ -143,7 +143,7 @@
// retained, we ensure that all messages sent to the view during
// its lifetime in a window hierarcy will be able to traverse the
// responder chain.
--(void)willMoveToWindow:(UIWindow *)window
+- (void)willMoveToWindow:(UIWindow *)window
{
if (window)
[[self nextResponder] retain];
@@ -170,9 +170,31 @@
QVariantMap platformData = m_configuredImeState->value(Qt::ImPlatformData).toMap();
Qt::InputMethodHints hints = Qt::InputMethodHints(m_configuredImeState->value(Qt::ImHints).toUInt());
- self.returnKeyType = platformData.value(kImePlatformDataReturnKeyType).isValid() ?
- UIReturnKeyType(platformData.value(kImePlatformDataReturnKeyType).toInt()) :
- (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
+ Qt::EnterKeyType enterKeyType = Qt::EnterKeyType(m_configuredImeState->value(Qt::ImEnterKeyType).toUInt());
+
+ switch (enterKeyType) {
+ case Qt::EnterKeyReturn:
+ self.returnKeyType = UIReturnKeyDefault;
+ break;
+ case Qt::EnterKeyDone:
+ self.returnKeyType = UIReturnKeyDone;
+ break;
+ case Qt::EnterKeyGo:
+ self.returnKeyType = UIReturnKeyGo;
+ break;
+ case Qt::EnterKeySend:
+ self.returnKeyType = UIReturnKeySend;
+ break;
+ case Qt::EnterKeySearch:
+ self.returnKeyType = UIReturnKeySearch;
+ break;
+ case Qt::EnterKeyNext:
+ self.returnKeyType = UIReturnKeyNext;
+ break;
+ default:
+ self.returnKeyType = (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
+ break;
+ }
self.secureTextEntry = BOOL(hints & Qt::ImhHiddenText);
self.autocorrectionType = (hints & Qt::ImhNoPredictiveText) ?
@@ -235,7 +257,7 @@
}
// Based on what we set up in initWithInputContext above
- updatedProperties &= (Qt::ImHints | Qt::ImPlatformData);
+ updatedProperties &= (Qt::ImHints | Qt::ImEnterKeyType | Qt::ImPlatformData);
if (!updatedProperties)
return NO;
@@ -403,17 +425,17 @@
return m_inputContext->imeState().currentState.value(query);
}
--(id<UITextInputTokenizer>)tokenizer
+- (id<UITextInputTokenizer>)tokenizer
{
return [[[UITextInputStringTokenizer alloc] initWithTextInput:id<UITextInput>(self)] autorelease];
}
--(UITextPosition *)beginningOfDocument
+- (UITextPosition *)beginningOfDocument
{
return [QUITextPosition positionWithIndex:0];
}
--(UITextPosition *)endOfDocument
+- (UITextPosition *)endOfDocument
{
int endPosition = [self currentImeState:Qt::ImSurroundingText].toString().length();
return [QUITextPosition positionWithIndex:endPosition];
@@ -679,7 +701,7 @@
return [NSDictionary dictionaryWithObject:uifont forKey:UITextInputTextFontKey];
}
--(NSDictionary *)markedTextStyle
+- (NSDictionary *)markedTextStyle
{
return [NSDictionary dictionary];
}
@@ -698,7 +720,8 @@
if ([text isEqualToString:@"\n"]) {
[self sendKeyPressRelease:Qt::Key_Return modifiers:Qt::NoModifier];
- if (self.returnKeyType == UIReturnKeyDone)
+ if (self.returnKeyType == UIReturnKeyDone || self.returnKeyType == UIReturnKeyGo
+ || self.returnKeyType == UIReturnKeySend || self.returnKeyType == UIReturnKeySearch)
[self resignFirstResponder];
return;
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index a7068b9246..be89521c04 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -289,13 +289,13 @@
// -------------------------------------------------------------------------
--(BOOL)shouldAutorotate
+- (BOOL)shouldAutorotate
{
return m_screen && m_screen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation;
}
#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_6_0)
--(NSUInteger)supportedInterfaceOrientations
+- (NSUInteger)supportedInterfaceOrientations
{
// As documented by Apple in the iOS 6.0 release notes, setStatusBarOrientation:animated:
// only works if the supportedInterfaceOrientations of the view controller is 0, making
@@ -308,7 +308,7 @@
#endif
#if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_6_0)
--(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
Q_UNUSED(interfaceOrientation);
return [self shouldAutorotate];
diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.h b/src/plugins/platforms/ios/quiaccessibilityelement.h
index a690e12c7d..c76e3a6a1e 100644
--- a/src/plugins/platforms/ios/quiaccessibilityelement.h
+++ b/src/plugins/platforms/ios/quiaccessibilityelement.h
@@ -42,8 +42,8 @@
@property (readonly) QAccessible::Id axid;
-- (id) initWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view;
-+ (QMacAccessibilityElement *) elementWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view;
+- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view;
++ (QMacAccessibilityElement *)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view;
@end
diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm
index 2cecfc1126..3bac1ca88d 100644
--- a/src/plugins/platforms/ios/quiaccessibilityelement.mm
+++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm
@@ -37,7 +37,7 @@
@implementation QMacAccessibilityElement
-- (id) initWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view
+- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view
{
Q_ASSERT((int)anId < 0);
self = [super initWithAccessibilityContainer: view];
@@ -47,7 +47,7 @@
return self;
}
-+ (id) elementWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view
++ (id)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view
{
Q_ASSERT(anId);
if (!anId)
@@ -64,17 +64,17 @@
return element;
}
-- (void) invalidate
+- (void)invalidate
{
[self release];
}
-- (BOOL) isAccessibilityElement
+- (BOOL)isAccessibilityElement
{
return YES;
}
-- (NSString*) accessibilityLabel
+- (NSString*)accessibilityLabel
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (!iface) {
@@ -85,7 +85,7 @@
return iface->text(QAccessible::Name).toNSString();
}
-- (NSString*) accessibilityHint
+- (NSString*)accessibilityHint
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (!iface) {
@@ -95,7 +95,7 @@
return iface->text(QAccessible::Description).toNSString();
}
-- (NSString*) accessibilityValue
+- (NSString*)accessibilityValue
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (!iface) {
@@ -119,7 +119,7 @@
return [super accessibilityHint];
}
-- (CGRect) accessibilityFrame
+- (CGRect)accessibilityFrame
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (!iface) {
@@ -131,7 +131,7 @@
return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
}
-- (UIAccessibilityTraits) accessibilityTraits
+- (UIAccessibilityTraits)accessibilityTraits
{
UIAccessibilityTraits traits = UIAccessibilityTraitNone;
@@ -156,7 +156,7 @@
return traits;
}
-- (BOOL) accessibilityActivate
+- (BOOL)accessibilityActivate
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (QAccessibleActionInterface *action = iface->actionInterface()) {
@@ -171,21 +171,21 @@
return NO; // fall back to sending mouse clicks
}
-- (void) accessibilityIncrement
+- (void)accessibilityIncrement
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (QAccessibleActionInterface *action = iface->actionInterface())
action->doAction(QAccessibleActionInterface::increaseAction());
}
-- (void) accessibilityDecrement
+- (void)accessibilityDecrement
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (QAccessibleActionInterface *action = iface->actionInterface())
action->doAction(QAccessibleActionInterface::decreaseAction());
}
-- (BOOL) accessibilityScroll : (UIAccessibilityScrollDirection) direction
+- (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
QAccessibleActionInterface *action = iface->actionInterface();
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 87dc3b9dcb..c6ef843b9f 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -50,7 +50,7 @@
return [CAEAGLLayer class];
}
--(id)initWithQIOSWindow:(QIOSWindow *)window
+- (id)initWithQIOSWindow:(QIOSWindow *)window
{
if (self = [self initWithFrame:toCGRect(window->geometry())])
m_qioswindow = window;
@@ -316,7 +316,7 @@
}
}
-- (void) sendTouchEventWithTimestamp:(ulong)timeStamp
+- (void)sendTouchEventWithTimestamp:(ulong)timeStamp
{
// Send touch event synchronously
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
diff --git a/src/plugins/platforms/kms/kms.json b/src/plugins/platforms/kms/kms.json
deleted file mode 100644
index be662226ae..0000000000
--- a/src/plugins/platforms/kms/kms.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": [ "kms" ]
-}
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
deleted file mode 100644
index baa8778153..0000000000
--- a/src/plugins/platforms/kms/kms.pro
+++ /dev/null
@@ -1,37 +0,0 @@
-TARGET = qkms
-
-PLUGIN_TYPE = platforms
-PLUGIN_CLASS_NAME = QKmsIntegrationPlugin
-!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
-load(qt_plugin)
-
-QT += core-private gui-private platformsupport-private
-qtHaveModule(opengl):QT += opengl-private
-
-DEFINES += MESA_EGL_NO_X11_HEADERS __GBM__
-
-CONFIG += link_pkgconfig egl qpa/genericunixfontdatabase
-
-PKGCONFIG += libdrm libudev egl gbm glesv2
-
-SOURCES = main.cpp \
- qkmsintegration.cpp \
- qkmsscreen.cpp \
- qkmscontext.cpp \
- qkmswindow.cpp \
- qkmscursor.cpp \
- qkmsdevice.cpp \
- qkmsbackingstore.cpp \
- qkmsnativeinterface.cpp
-
-HEADERS = qkmsintegration.h \
- qkmsscreen.h \
- qkmscontext.h \
- qkmswindow.h \
- qkmscursor.h \
- qkmsdevice.h \
- qkmsbackingstore.h \
- qkmsnativeinterface.h
-
-OTHER_FILES += \
- kms.json
diff --git a/src/plugins/platforms/kms/main.cpp b/src/plugins/platforms/kms/main.cpp
deleted file mode 100644
index 565ac7a7d4..0000000000
--- a/src/plugins/platforms/kms/main.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qpa/qplatformintegrationplugin.h>
-#include "qkmsintegration.h"
-
-QT_BEGIN_NAMESPACE
-
-class QKmsIntegrationPlugin : public QPlatformIntegrationPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "kms.json")
-public:
- QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE;
-};
-
-QPlatformIntegration *QKmsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
-{
- Q_UNUSED(paramList);
- if (!system.compare(QLatin1String("kms"), Qt::CaseInsensitive))
- return new QKmsIntegration;
-
- return 0;
-}
-
-QT_END_NAMESPACE
-
-#include "main.moc"
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp
deleted file mode 100644
index 6e5a3f9192..0000000000
--- a/src/plugins/platforms/kms/qkmsbackingstore.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmsbackingstore.h"
-
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLShaderProgram>
-#include <QtGui/QScreen>
-
-QT_BEGIN_NAMESPACE
-
-QKmsBackingStore::QKmsBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
- , m_context(new QOpenGLContext)
- , m_texture(0)
- , m_program(0)
- , m_initialized(false)
-{
- m_context->setFormat(window->requestedFormat());
- m_context->setScreen(window->screen());
- m_context->create();
-}
-
-QKmsBackingStore::~QKmsBackingStore()
-{
- delete m_program;
- if (m_texture)
- glDeleteTextures(1, &m_texture);
-
- delete m_context;
-}
-
-QPaintDevice *QKmsBackingStore::paintDevice()
-{
- return &m_image;
-}
-
-void QKmsBackingStore::beginPaint(const QRegion &rgn)
-{
- m_dirty |= rgn;
-}
-
-void QKmsBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(region)
- Q_UNUSED(offset)
-
- m_context->makeCurrent(window);
-
- if (!m_initialized) {
- initializeOpenGLFunctions();
- m_initialized = true;
- }
-
- if (!m_program) {
- static const char *textureVertexProgram =
- "attribute highp vec2 vertexCoordEntry;\n"
- "attribute highp vec2 textureCoordEntry;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " textureCoord = textureCoordEntry;\n"
- " gl_Position = vec4(vertexCoordEntry, 0.0, 1.0);\n"
- "}\n";
-
- static const char *textureFragmentProgram =
- "uniform sampler2D texture;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
- "}\n";
-
- m_program = new QOpenGLShaderProgram;
-
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- m_program->bindAttributeLocation("vertexCoordEntry", 0);
- m_program->bindAttributeLocation("textureCoordEntry", 1);
- m_program->link();
- }
-
- m_program->bind();
-
- QRectF r = window->geometry();
- QRectF sr = window->screen()->geometry();
-
- GLfloat x1 = (r.left() / sr.width()) * 2 - 1;
- GLfloat x2 = (r.right() / sr.width()) * 2 - 1;
- GLfloat y1 = -1 * ((r.top() / sr.height()) * 2 - 1);
- GLfloat y2 = -1 * ((r.bottom() / sr.height()) * 2 - 1);
-
- const GLfloat vertexCoordinates[] = {
- x1, y1,
- x2, y1,
- x2, y2,
- x1, y2
- };
-
- const GLfloat textureCoordinates[] = {
- 0, 0,
- 1, 0,
- 1, 1,
- 0, 1
- };
-
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
-
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
-
- glBindTexture(GL_TEXTURE_2D, m_texture);
-
- if (!m_dirty.isNull()) {
- QRect imageRect = m_image.rect();
- QRegion fixed;
- Q_FOREACH (const QRect &rect, m_dirty.rects()) {
- // intersect with image rect to be sure
- QRect r = imageRect & rect;
- // if the rect is wide enough it's cheaper to just
- // extend it instead of doing an image copy
- if (r.width() >= imageRect.width() / 2) {
- r.setX(0);
- r.setWidth(imageRect.width());
- }
- fixed |= r;
- }
-
- Q_FOREACH (const QRect &rect, fixed.rects()) {
- // if the sub-rect is full-width we can pass the image data directly to
- // OpenGL instead of copying, since there's no gap between scanlines
- if (rect.width() == imageRect.width()) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(),
- rect.width(), rect.height(),
- GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.constScanLine(rect.y()));
- } else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(),
- rect.width(), rect.height(),
- GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.copy(rect).constBits());
- }
- }
-
- m_dirty = QRegion();
- }
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- m_program->release();
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
-
- m_context->swapBuffers(window);
-
- m_context->doneCurrent();
-}
-
-void QKmsBackingStore::resize(const QSize &size, const QRegion &staticContents)
-{
- Q_UNUSED(staticContents)
-
- m_image = QImage(size, QImage::Format_RGB32);
-
- m_context->makeCurrent(window());
-
- if (!m_initialized) {
- initializeOpenGLFunctions();
- m_initialized = true;
- }
-
- if (m_texture)
- glDeleteTextures(1, &m_texture);
-
- glGenTextures(1, &m_texture);
- glBindTexture(GL_TEXTURE_2D, m_texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(),
- 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.h b/src/plugins/platforms/kms/qkmsbackingstore.h
deleted file mode 100644
index a34b10d3d9..0000000000
--- a/src/plugins/platforms/kms/qkmsbackingstore.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBACKINGSTORE_KMS_H
-#define QBACKINGSTORE_KMS_H
-
-#include <qpa/qplatformbackingstore.h>
-#include <QtGui/QOpenGLFunctions>
-#include <QImage>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLContext;
-class QOpenGLShaderProgram;
-
-class QKmsBackingStore : public QPlatformBackingStore, public QOpenGLFunctions
-{
-public:
- QKmsBackingStore(QWindow *window);
- ~QKmsBackingStore();
-
- QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
-
- void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
-
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
- void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
-
- QImage toImage() const Q_DECL_OVERRIDE { return m_image; }
-
-private:
- QOpenGLContext *m_context;
- QImage m_image;
- uint m_texture;
- QOpenGLShaderProgram *m_program;
- QRegion m_dirty;
- bool m_initialized;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/kms/qkmscontext.cpp b/src/plugins/platforms/kms/qkmscontext.cpp
deleted file mode 100644
index e00835fbac..0000000000
--- a/src/plugins/platforms/kms/qkmscontext.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmsscreen.h"
-#include "qkmsdevice.h"
-#include "qkmscontext.h"
-#include "qkmswindow.h"
-#include "qkmsintegration.h"
-
-#include <QtGui/QOpenGLContext>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QKmsContext::QKmsContext(QOpenGLContext *context, QKmsDevice *device)
- : m_device(device)
-{
- EGLDisplay display = m_device->eglDisplay();
- EGLConfig config = q_configFromGLFormat(display, QKmsScreen::tweakFormat(context->format()));
- m_format = q_glFormatFromConfig(display, config);
-
- //Initialize EGLContext
- static EGLint contextAttribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, context->format().majorVersion(),
- EGL_NONE
- };
-
- eglBindAPI(EGL_OPENGL_ES_API);
-
- EGLContext share = EGL_NO_CONTEXT;
- if (context->shareContext())
- share = static_cast<QKmsContext *>(context->shareContext()->handle())->eglContext();
-
- m_eglContext = eglCreateContext(display, config, share, contextAttribs);
- if (m_eglContext == EGL_NO_CONTEXT) {
- qWarning("QKmsContext::QKmsContext(): eglError: %x, this: %p",
- eglGetError(), this);
- m_eglContext = 0;
- }
-}
-
-bool QKmsContext::isValid() const
-{
- return m_eglContext != EGL_NO_CONTEXT;
-}
-
-bool QKmsContext::makeCurrent(QPlatformSurface *surface)
-{
- Q_ASSERT(surface->surface()->supportsOpenGL());
-
- EGLDisplay display = m_device->eglDisplay();
- EGLSurface eglSurface;
-
- if (surface->surface()->surfaceClass() == QSurface::Window) {
- QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
- QKmsScreen *screen = static_cast<QKmsScreen *>(QPlatformScreen::platformScreenForWindow(window->window()));
- eglSurface = screen->eglSurface();
- screen->waitForPageFlipComplete();
- } else {
- eglSurface = static_cast<QKmsOffscreenWindow *>(surface)->surface();
- }
-
- bool ok = eglMakeCurrent(display, eglSurface, eglSurface, m_eglContext);
- if (!ok)
- qWarning("QKmsContext::makeCurrent(): eglError: %x, this: %p",
- eglGetError(), this);
-
- return true;
-}
-
-void QKmsContext::doneCurrent()
-{
- bool ok = eglMakeCurrent(m_device->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- if (!ok)
- qWarning("QKmsContext::doneCurrent(): eglError: %x, this: %p",
- eglGetError(), this);
-
-}
-
-void QKmsContext::swapBuffers(QPlatformSurface *surface)
-{
- //Cast context to a window surface and get the screen the context
- //is on and call swapBuffers on that screen.
- QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
- QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
- screen->swapBuffers();
-}
-
-void (*QKmsContext::getProcAddress(const QByteArray &procName)) ()
-{
- return eglGetProcAddress(procName.data());
-}
-
-
-EGLContext QKmsContext::eglContext() const
-{
- return m_eglContext;
-}
-
-QSurfaceFormat QKmsContext::format() const
-{
- return m_format;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscontext.h b/src/plugins/platforms/kms/qkmscontext.h
deleted file mode 100644
index 59cf9b1e34..0000000000
--- a/src/plugins/platforms/kms/qkmscontext.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSCONTEXT_H
-#define QKMSCONTEXT_H
-
-#include <qpa/qplatformopenglcontext.h>
-
-#define EGL_EGLEXT_PROTOTYPES 1
-#include <EGL/egl.h>
-
-QT_BEGIN_NAMESPACE
-
-class QKmsDevice;
-
-class QKmsContext : public QPlatformOpenGLContext
-{
-public:
- QKmsContext(QOpenGLContext *context, QKmsDevice *device);
-
- bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- void doneCurrent() Q_DECL_OVERRIDE;
- void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- void (*getProcAddress(const QByteArray &procName)) () Q_DECL_OVERRIDE;
-
- bool isValid() const Q_DECL_OVERRIDE;
-
- QSurfaceFormat format() const Q_DECL_OVERRIDE;
-
- EGLContext eglContext() const;
-
-private:
- EGLContext m_eglContext;
- QSurfaceFormat m_format;
-
- QKmsDevice *m_device;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSCONTEXT_H
diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp
deleted file mode 100644
index 44212cd3c8..0000000000
--- a/src/plugins/platforms/kms/qkmscursor.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-//#include <QDebug>
-#include "qkmscursor.h"
-#include "qkmsscreen.h"
-#include "qkmsdevice.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef DRM_CAP_CURSOR_WIDTH
-#define DRM_CAP_CURSOR_WIDTH 0x8
-#endif
-
-#ifndef DRM_CAP_CURSOR_HEIGHT
-#define DRM_CAP_CURSOR_HEIGHT 0x9
-#endif
-
-QKmsCursor::QKmsCursor(QKmsScreen *screen)
- : m_screen(screen),
- m_graphicsBufferManager(screen->device()->gbmDevice()),
- m_cursorImage(new QPlatformCursorImage(0, 0, 0, 0, 0, 0)),
- m_moved(false),
- m_cursorSize(64, 64)
-{
- uint64_t value = 0;
- if (!drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_WIDTH, &value))
- m_cursorSize.setWidth(value);
- if (!drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_HEIGHT, &value))
- m_cursorSize.setHeight(value);
-
- m_cursorBufferObject = gbm_bo_create(m_graphicsBufferManager, m_cursorSize.width(), m_cursorSize.height(),
- GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
-}
-
-QKmsCursor::~QKmsCursor()
-{
- drmModeSetCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0, 0);
- gbm_bo_destroy(m_cursorBufferObject);
-}
-
-void QKmsCursor::pointerEvent(const QMouseEvent &event)
-{
- m_moved = true;
- int status = drmModeMoveCursor(m_screen->device()->fd(),
- m_screen->crtcId(),
- event.globalX(),
- event.globalY());
- if (status) {
- qWarning("failed to move cursor: %d", status);
- }
-}
-
-void QKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window)
-{
- Q_UNUSED(window)
-
- if (!m_moved)
- drmModeMoveCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0);
-
- const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor;
- if (newShape != Qt::BitmapCursor) {
- m_cursorImage->set(newShape);
- } else {
- m_cursorImage->set(windowCursor->pixmap().toImage(),
- windowCursor->hotSpot().x(),
- windowCursor->hotSpot().y());
- }
-
- if (m_cursorImage->image()->width() > m_cursorSize.width() || m_cursorImage->image()->width() > m_cursorSize.height())
- qWarning("cursor larger than %dx%d, cursor truncated", m_cursorSize.width(), m_cursorSize.height());
-
- QImage cursorImage = m_cursorImage->image()->convertToFormat(QImage::Format_ARGB32)
- .copy(0, 0, m_cursorSize.width(), m_cursorSize.height());
- gbm_bo_write(m_cursorBufferObject, cursorImage.constBits(), cursorImage.byteCount());
-
- quint32 handle = gbm_bo_get_handle(m_cursorBufferObject).u32;
- int status = drmModeSetCursor(m_screen->device()->fd(),
- m_screen->crtcId(), handle,
- m_cursorSize.width(), m_cursorSize.height());
-
- if (status) {
- qWarning("failed to set cursor: %d", status);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscursor.h b/src/plugins/platforms/kms/qkmscursor.h
deleted file mode 100644
index 9aadf407c0..0000000000
--- a/src/plugins/platforms/kms/qkmscursor.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSCURSOR_H
-#define QKMSCURSOR_H
-
-#include <qpa/qplatformcursor.h>
-
-struct gbm_device;
-struct gbm_bo;
-
-QT_BEGIN_NAMESPACE
-
-class QKmsScreen;
-
-class QKmsCursor : public QPlatformCursor
-{
-public:
- QKmsCursor(QKmsScreen *screen);
- ~QKmsCursor();
-
- void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE;
- void changeCursor(QCursor *windowCursor, QWindow *window) Q_DECL_OVERRIDE;
-
-private:
- QKmsScreen *m_screen;
- gbm_device *m_graphicsBufferManager;
- gbm_bo *m_cursorBufferObject;
- QPlatformCursorImage *m_cursorImage;
- bool m_moved;
- QSize m_cursorSize;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSCURSOR_H
diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp
deleted file mode 100644
index 74fa59c16a..0000000000
--- a/src/plugins/platforms/kms/qkmsdevice.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-//#include <QDebug>
-#include "qkmsscreen.h"
-#include "qkmsdevice.h"
-
-#include "qkmsintegration.h"
-
-#include <QtCore/QSocketNotifier>
-#include <QtCore/private/qcore_unix_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QKmsDevice::QKmsDevice(const QString &path, QKmsIntegration *parent) :
- QObject(0), m_integration(parent)
-{
- m_fd = QT_OPEN(path.toLatin1().constData(), O_RDWR);
- if (m_fd < 0) {
- qWarning("Could not open %s.", path.toLatin1().constData());
- qFatal("No DRM display device");
- }
-
- m_graphicsBufferManager = gbm_create_device(m_fd);
- m_eglDisplay = eglGetDisplay(m_graphicsBufferManager);
-
- if (m_eglDisplay == EGL_NO_DISPLAY) {
- qWarning("Could not open EGL display");
- qFatal("EGL error");
- }
-
- EGLint major;
- EGLint minor;
- if (!eglInitialize(m_eglDisplay, &major, &minor)) {
- qWarning("Could not initialize EGL display");
- qFatal("EGL error");
- }
-
- createScreens();
-
-// QSocketNotifier *notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
-// connect(notifier, SIGNAL(activated(int)), this, SLOT(handlePageFlipCompleted()));
-}
-
-QKmsDevice::~QKmsDevice()
-{
-}
-
-void QKmsDevice::createScreens()
-{
- drmModeRes *resources = drmModeGetResources(m_fd);
- if (!resources)
- qFatal("drmModeGetResources failed");
-
- //Iterate connectors and create screens on each one active
- for (int i = 0; i < resources->count_connectors; i++) {
- drmModeConnector *connector = 0;
- connector = drmModeGetConnector(m_fd, resources->connectors[i]);
- if (connector && connector->connection == DRM_MODE_CONNECTED) {
- m_integration->addScreen(new QKmsScreen(this, resources, connector));
- }
- drmModeFreeConnector(connector);
- }
- drmModeFreeResources(resources);
-}
-
-void QKmsDevice::handlePageFlipCompleted()
-{
- drmEventContext eventContext;
-
- memset(&eventContext, 0, sizeof eventContext);
- eventContext.version = DRM_EVENT_CONTEXT_VERSION;
- eventContext.page_flip_handler = QKmsDevice::pageFlipHandler;
- drmHandleEvent(m_fd, &eventContext);
-
-}
-
-void QKmsDevice::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
-{
- Q_UNUSED(fd)
- Q_UNUSED(frame)
- Q_UNUSED(sec)
- Q_UNUSED(usec)
-
- QKmsScreen *screen = static_cast<QKmsScreen *>(data);
- screen->handlePageFlipped();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsdevice.h b/src/plugins/platforms/kms/qkmsdevice.h
deleted file mode 100644
index d5e33cb8c7..0000000000
--- a/src/plugins/platforms/kms/qkmsdevice.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSDEVICE_H
-#define QKMSDEVICE_H
-
-#include <stddef.h>
-
-extern "C" {
-#include <gbm.h>
-}
-#include <EGL/egl.h>
-
-#include <QObject>
-
-struct gbm_device;
-
-QT_BEGIN_NAMESPACE
-
-class QKmsIntegration;
-
-class QKmsDevice : public QObject
-{
- Q_OBJECT
-public:
- explicit QKmsDevice(const QString &path, QKmsIntegration *parent);
- ~QKmsDevice();
-
- EGLDisplay eglDisplay() { return m_eglDisplay; }
- gbm_device *gbmDevice() { return m_graphicsBufferManager; }
- int fd() const { return m_fd; }
-
- static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec,
- unsigned int usec, void *data);
-
-public slots:
- void handlePageFlipCompleted();
-private:
- void createScreens();
-
- QKmsIntegration *m_integration;
-
- EGLDisplay m_eglDisplay;
- EGLContext m_eglContext;
- gbm_device *m_graphicsBufferManager;
- int m_fd;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSDEVICE_H
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
deleted file mode 100644
index f48c868ae5..0000000000
--- a/src/plugins/platforms/kms/qkmsintegration.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmsintegration.h"
-#include "qkmsdevice.h"
-#include "qkmsscreen.h"
-#include "qkmswindow.h"
-#include "qkmsbackingstore.h"
-#include "qkmscontext.h"
-#include "qkmsnativeinterface.h"
-
-#if !defined(QT_NO_EVDEV)
-#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
-#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
-#include <QtPlatformSupport/private/qevdevtouch_p.h>
-#endif
-
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
-#include <QtPlatformSupport/private/qfbvthandler_p.h>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
-
-#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QScreen>
-#include <QtGui/QOffscreenSurface>
-#include <qpa/qplatformoffscreensurface.h>
-
-QT_BEGIN_NAMESPACE
-
-QKmsIntegration::QKmsIntegration()
- : QPlatformIntegration(),
- m_fontDatabase(new QGenericUnixFontDatabase()),
- m_nativeInterface(new QKmsNativeInterface),
- m_vtHandler(0),
- m_deviceDiscovery(0)
-{
-}
-
-QKmsIntegration::~QKmsIntegration()
-{
- delete m_deviceDiscovery;
- foreach (QKmsDevice *device, m_devices) {
- delete device;
- }
- foreach (QPlatformScreen *screen, m_screens) {
- destroyScreen(screen);
- }
- delete m_fontDatabase;
- delete m_vtHandler;
-}
-
-void QKmsIntegration::initialize()
-{
- qputenv("EGL_PLATFORM", "drm");
- m_vtHandler = new QFbVtHandler;
-
- m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_DRM | QDeviceDiscovery::Device_DRM_PrimaryGPU, 0);
- if (m_deviceDiscovery) {
- QStringList devices = m_deviceDiscovery->scanConnectedDevices();
- foreach (const QString &device, devices)
- addDevice(device);
-
- connect(m_deviceDiscovery, SIGNAL(deviceDetected(QString)), this, SLOT(addDevice(QString)));
- connect(m_deviceDiscovery, SIGNAL(deviceRemoved(QString)), this, SLOT(removeDevice(QString)));
- }
-
-#if !defined(QT_NO_EVDEV)
- new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
- new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
- new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
-#endif
-}
-
-void QKmsIntegration::addDevice(const QString &deviceNode)
-{
- m_devices.append(new QKmsDevice(deviceNode, this));
-}
-
-void QKmsIntegration::removeDevice(const QString &deviceNode)
-{
- // TODO: support hot-plugging some day?
- Q_UNUSED(deviceNode);
-}
-
-bool QKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
-{
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return true;
- case ThreadedOpenGL: return false;
- case RasterGLSurface: return true;
- default: return QPlatformIntegration::hasCapability(cap);
- }
-}
-
-QPlatformOpenGLContext *QKmsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
-{
- QKmsScreen *screen = static_cast<QKmsScreen *>(context->screen()->handle());
- return new QKmsContext(context, screen->device());
-}
-
-QPlatformWindow *QKmsIntegration::createPlatformWindow(QWindow *window) const
-{
- QKmsWindow *w = new QKmsWindow(window);
- w->requestActivateWindow();
- return w;
-}
-
-QPlatformBackingStore *QKmsIntegration::createPlatformBackingStore(QWindow *window) const
-{
- return new QKmsBackingStore(window);
-}
-
-// Neither a pbuffer nor a hidden QWindow is suitable. Just use an additional, small gbm surface.
-QKmsOffscreenWindow::QKmsOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface)
- : QPlatformOffscreenSurface(offscreenSurface)
- , m_format(format)
- , m_display(display)
- , m_surface(EGL_NO_SURFACE)
- , m_window(0)
-{
- QKmsScreen *screen = static_cast<QKmsScreen *>(offscreenSurface->screen()->handle());
- m_window = gbm_surface_create(screen->device()->gbmDevice(),
- 10, 10,
- GBM_FORMAT_XRGB8888,
- GBM_BO_USE_RENDERING);
- if (!m_window) {
- qWarning("QKmsOffscreenWindow: Failed to create native window");
- return;
- }
-
- EGLConfig config = q_configFromGLFormat(m_display, m_format);
- m_surface = eglCreateWindowSurface(m_display, config, m_window, 0);
- if (m_surface != EGL_NO_SURFACE)
- m_format = q_glFormatFromConfig(m_display, config);
-}
-
-QKmsOffscreenWindow::~QKmsOffscreenWindow()
-{
- if (m_surface != EGL_NO_SURFACE)
- eglDestroySurface(m_display, m_surface);
- if (m_window)
- gbm_surface_destroy((gbm_surface *) m_window);
-}
-
-QPlatformOffscreenSurface *QKmsIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
-{
- QKmsScreen *screen = static_cast<QKmsScreen *>(surface->screen()->handle());
- return new QKmsOffscreenWindow(screen->device()->eglDisplay(), QKmsScreen::tweakFormat(surface->format()), surface);
-}
-
-QPlatformFontDatabase *QKmsIntegration::fontDatabase() const
-{
- return m_fontDatabase;
-}
-
-void QKmsIntegration::addScreen(QKmsScreen *screen)
-{
- m_screens.append(screen);
- screenAdded(screen);
-}
-
-QAbstractEventDispatcher *QKmsIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-
-QPlatformNativeInterface *QKmsIntegration::nativeInterface() const
-{
- return m_nativeInterface;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
deleted file mode 100644
index bcf9ac7296..0000000000
--- a/src/plugins/platforms/kms/qkmsintegration.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPLATFORMINTEGRATION_KMS_H
-#define QPLATFORMINTEGRATION_KMS_H
-
-#include <qpa/qplatformintegration.h>
-#include <qpa/qplatformnativeinterface.h>
-#include <qpa/qplatformoffscreensurface.h>
-#include <QtPlatformSupport/private/qdevicediscovery_p.h>
-#include <EGL/egl.h>
-
-QT_BEGIN_NAMESPACE
-
-class QKmsScreen;
-class QKmsDevice;
-class QFbVtHandler;
-
-class QKmsOffscreenWindow : public QPlatformOffscreenSurface
-{
-public:
- QKmsOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface);
- ~QKmsOffscreenWindow();
-
- QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- bool isValid() const Q_DECL_OVERRIDE { return m_surface != EGL_NO_SURFACE; }
-
- EGLSurface surface() const { return m_surface; }
-
-private:
- QSurfaceFormat m_format;
- EGLDisplay m_display;
- EGLSurface m_surface;
- EGLNativeWindowType m_window;
-};
-
-class QKmsIntegration : public QObject, public QPlatformIntegration
-{
- Q_OBJECT
-
-public:
- QKmsIntegration();
- ~QKmsIntegration();
-
- void initialize() Q_DECL_OVERRIDE;
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
-
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
- QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
-
- QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
- QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
-
- QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
-
- void addScreen(QKmsScreen *screen);
- QObject *createDevice(const char *);
-
-private slots:
- void addDevice(const QString &deviceNode);
- void removeDevice(const QString &deviceNode);
-
-private:
- QStringList findDrmDevices();
-
- QList<QPlatformScreen *> m_screens;
- QList<QKmsDevice *> m_devices;
- QPlatformFontDatabase *m_fontDatabase;
- QPlatformNativeInterface *m_nativeInterface;
- QFbVtHandler *m_vtHandler;
- QDeviceDiscovery *m_deviceDiscovery;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/kms/qkmsnativeinterface.cpp b/src/plugins/platforms/kms/qkmsnativeinterface.cpp
deleted file mode 100644
index 1538a7f8c3..0000000000
--- a/src/plugins/platforms/kms/qkmsnativeinterface.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qguiapplication_p.h>
-#include "qkmsnativeinterface.h"
-#include "qkmsdevice.h"
-
-#include "qscreen.h"
-#include "qkmscontext.h"
-#include <QOpenGLContext>
-
-class QKmsResourceMap : public QMap<QByteArray, QKmsNativeInterface::ResourceType>
-{
-public:
- QKmsResourceMap()
- :QMap<QByteArray, QKmsNativeInterface::ResourceType>()
- {
- insert("egldisplay", QKmsNativeInterface::EglDisplay);
- insert("eglcontext", QKmsNativeInterface::EglContext);
- }
-};
-
-Q_GLOBAL_STATIC(QKmsResourceMap, qKmsResourceMap)
-
-void *QKmsNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
-{
- QByteArray lowerCaseResource = resourceString.toLower();
- ResourceType resource = qKmsResourceMap()->value(lowerCaseResource);
- void *result = 0;
- switch (resource) {
- case EglDisplay:
- result = eglDisplay();
- break;
- default:
- result = 0;
- }
- return result;
-
-}
-void *QKmsNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
-{
- QByteArray lowerCaseResource = resourceString.toLower();
- ResourceType resource = qKmsResourceMap()->value(lowerCaseResource);
- void *result = 0;
- switch (resource) {
- case EglDisplay:
- result = eglDisplayForWindow(window);
- break;
- case EglContext:
- result = eglContextForWindow(window);
- break;
- default:
- result = 0;
- }
- return result;
-}
-
-QPlatformNativeInterface::NativeResourceForContextFunction QKmsNativeInterface::nativeResourceFunctionForContext(const QByteArray &resource)
-{
- QByteArray lowerCaseResource = resource.toLower();
- if (lowerCaseResource == "get_egl_context") {
- return eglContextForContext;
- }
- return 0;
-}
-
-void *QKmsNativeInterface::eglDisplay()
-{
- //QKmsIntegration *integration = static_cast<QKmsIntegration *>(QGuiApplicationPrivate::platformIntegration());
- QKmsScreen *screen = static_cast<QKmsScreen *>(QGuiApplication::primaryScreen()->handle());
- if (!screen || !screen->device())
- return 0;
- return screen->device()->eglDisplay();
-}
-
-void *QKmsNativeInterface::eglDisplayForWindow(QWindow *window)
-{
- QKmsScreen *screen = qPlatformScreenForWindow(window);
- if (!screen)
- return 0;
- QKmsDevice *device = screen->device();
- if (!device)
- return 0;
- return device->eglDisplay();
-}
-
-void *QKmsNativeInterface::eglContextForWindow(QWindow *)
-{
- return 0;
-}
-
-QKmsScreen *QKmsNativeInterface::qPlatformScreenForWindow(QWindow *window)
-{
- QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
- return static_cast<QKmsScreen *>(screen->handle());
-}
-
-void *QKmsNativeInterface::eglContextForContext(QOpenGLContext *context)
-{
- Q_ASSERT(context);
-
- QKmsContext *eglPlatformContext = static_cast<QKmsContext *>(context->handle());
-
- return eglPlatformContext->eglContext();
-}
diff --git a/src/plugins/platforms/kms/qkmsnativeinterface.h b/src/plugins/platforms/kms/qkmsnativeinterface.h
deleted file mode 100644
index 56879d0a3a..0000000000
--- a/src/plugins/platforms/kms/qkmsnativeinterface.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSNATIVEINTERFACE_H
-#define QKMSNATIVEINTERFACE_H
-
-#include "qkmsscreen.h"
-
-#include <qpa/qplatformnativeinterface.h>
-
-class QKmsNativeInterface : public QPlatformNativeInterface
-{
-public:
- enum ResourceType {
- EglDisplay,
- EglContext
- };
-
- void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
- void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) Q_DECL_OVERRIDE;
-
- NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
-
- void *eglDisplay();
- void *eglDisplayForWindow(QWindow *window);
- void *eglContextForWindow(QWindow *window);
- static void *eglContextForContext(QOpenGLContext *context);
-
-private:
- static QKmsScreen *qPlatformScreenForWindow(QWindow *window);
-};
-
-
-#endif // QKMSNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp
deleted file mode 100644
index 6392b99cd5..0000000000
--- a/src/plugins/platforms/kms/qkmsscreen.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmsscreen.h"
-#include "qkmscursor.h"
-#include "qkmsdevice.h"
-#include "qkmscontext.h"
-
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
-
-#include <QCoreApplication>
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.kms.screen")
-
-//Fallback mode (taken from Wayland DRM demo compositor)
-static drmModeModeInfo builtin_1024x768 = {
- 63500, //clock
- 1024, 1072, 1176, 1328, 0,
- 768, 771, 775, 798, 0,
- 59920,
- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- 0,
- "1024x768"
-};
-
-QKmsScreen::QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector)
- : m_device(device),
- m_current_bo(0),
- m_next_bo(0),
- m_connectorId(connector->connector_id),
- m_depth(32),
- m_format(QImage::Format_Invalid),
- m_eglWindowSurface(EGL_NO_SURFACE),
- m_modeSet(false)
-{
- m_cursor = new QKmsCursor(this);
- initializeScreenMode(resources, connector);
-}
-
-QKmsScreen::~QKmsScreen()
-{
- delete m_cursor;
- drmModeSetCrtc(m_device->fd(), m_oldCrtc->crtc_id, m_oldCrtc->buffer_id,
- m_oldCrtc->x, m_oldCrtc->y,
- &m_connectorId, 1, &m_oldCrtc->mode);
- drmModeFreeCrtc(m_oldCrtc);
- if (m_eglWindowSurface != EGL_NO_SURFACE)
- eglDestroySurface(m_device->eglDisplay(), m_eglWindowSurface);
- gbm_surface_destroy(m_gbmSurface);
-}
-
-QRect QKmsScreen::geometry() const
-{
- return m_geometry;
-}
-
-int QKmsScreen::depth() const
-{
- return m_depth;
-}
-
-QImage::Format QKmsScreen::format() const
-{
- return m_format;
-}
-
-QSizeF QKmsScreen::physicalSize() const
-{
- return m_physicalSize;
-}
-
-QPlatformCursor *QKmsScreen::cursor() const
-{
- return m_cursor;
-}
-
-void QKmsScreen::initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector)
-{
- //Determine optimal mode for screen
- drmModeModeInfo *mode = 0;
- for (int i = 0; i < connector->count_modes; ++i) {
- if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
- mode = &connector->modes[i];
- break;
- }
- }
- if (!mode) {
- if (connector->count_modes > 0)
- mode = &connector->modes[0];
- else
- mode = &builtin_1024x768;
- }
-
- drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
- if (encoder == 0)
- qFatal("No encoder for connector.");
-
- int i;
- for (i = 0; i < resources->count_crtcs; i++) {
- if (encoder->possible_crtcs & (1 << i))
- break;
- }
- if (i == resources->count_crtcs)
- qFatal("No usable crtc for encoder.");
-
- m_oldCrtc = drmModeGetCrtc(m_device->fd(), encoder->crtc_id);
-
- m_crtcId = resources->crtcs[i];
- m_mode = *mode;
- m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay);
- qCDebug(lcQpaScreen) << "kms initialized with geometry" << m_geometry;
- m_depth = 32;
- m_format = QImage::Format_RGB32;
- m_physicalSize = QSizeF(connector->mmWidth, connector->mmHeight);
-
- m_gbmSurface = gbm_surface_create(m_device->gbmDevice(),
- m_mode.hdisplay, m_mode.vdisplay,
- GBM_BO_FORMAT_XRGB8888,
- GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
-
- qCDebug(lcQpaScreen) << "created gbm surface" << m_gbmSurface << m_mode.hdisplay << m_mode.vdisplay;
- //Cleanup
- drmModeFreeEncoder(encoder);
-}
-
-QSurfaceFormat QKmsScreen::tweakFormat(const QSurfaceFormat &format)
-{
- QSurfaceFormat fmt = format;
- fmt.setRedBufferSize(8);
- fmt.setGreenBufferSize(8);
- fmt.setBlueBufferSize(8);
- if (fmt.alphaBufferSize() != -1)
- fmt.setAlphaBufferSize(8);
- return fmt;
-}
-
-void QKmsScreen::initializeWithFormat(const QSurfaceFormat &format)
-{
- EGLDisplay display = m_device->eglDisplay();
- EGLConfig config = q_configFromGLFormat(display, tweakFormat(format));
-
- m_eglWindowSurface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_gbmSurface, NULL);
- qCDebug(lcQpaScreen) << "created window surface";
- m_surfaceFormat = q_glFormatFromConfig(display, config);
-}
-
-void QKmsScreen::swapBuffers()
-{
- eglSwapBuffers(m_device->eglDisplay(), m_eglWindowSurface);
-
- m_next_bo = gbm_surface_lock_front_buffer(m_gbmSurface);
- if (!m_next_bo)
- qFatal("kms: Failed to lock front buffer");
-
- performPageFlip();
-}
-
-void QKmsScreen::performPageFlip()
-{
- if (!m_next_bo)
- return;
-
- uint32_t width = gbm_bo_get_width(m_next_bo);
- uint32_t height = gbm_bo_get_height(m_next_bo);
- uint32_t stride = gbm_bo_get_stride(m_next_bo);
- uint32_t handle = gbm_bo_get_handle(m_next_bo).u32;
-
- uint32_t fb_id;
- int ret = drmModeAddFB(m_device->fd(), width, height, 24, 32,
- stride, handle, &fb_id);
- if (ret) {
- qFatal("kms: Failed to create fb: fd %d, w %d, h %d, stride %d, handle %d, ret %d",
- m_device->fd(), width, height, stride, handle, ret);
- }
-
- if (!m_modeSet) {
- //Set the Mode of the screen.
- int ret = drmModeSetCrtc(m_device->fd(), m_crtcId, fb_id,
- 0, 0, &m_connectorId, 1, &m_mode);
- if (ret)
- qFatal("failed to set mode");
- m_modeSet = true;
-
- // Initialize cursor
-
- static int hideCursor = qEnvironmentVariableIntValue("QT_QPA_KMS_HIDECURSOR");
- if (!hideCursor) {
- QCursor cursor(Qt::ArrowCursor);
- m_cursor->changeCursor(&cursor, 0);
- }
- }
-
- int pageFlipStatus = drmModePageFlip(m_device->fd(), m_crtcId,
- fb_id,
- DRM_MODE_PAGE_FLIP_EVENT, this);
- if (pageFlipStatus)
- {
- qWarning("Pageflip status: %d", pageFlipStatus);
- gbm_surface_release_buffer(m_gbmSurface, m_next_bo);
- m_next_bo = 0;
- }
-}
-
-void QKmsScreen::handlePageFlipped()
-{
- if (m_current_bo)
- gbm_surface_release_buffer(m_gbmSurface, m_current_bo);
-
- m_current_bo = m_next_bo;
- m_next_bo = 0;
-}
-
-QKmsDevice * QKmsScreen::device() const
-{
- return m_device;
-}
-
-void QKmsScreen::waitForPageFlipComplete()
-{
- while (m_next_bo) {
-#if 0
- //Check manually if there is something to be read on the device
- //as there are senarios where the signal is not received (starvation)
- fd_set fdSet;
- timeval timeValue;
- int returnValue;
-
- FD_ZERO(&fdSet);
- FD_SET(m_device->fd(), &fdSet);
- timeValue.tv_sec = 0;
- timeValue.tv_usec = 1000;
-
- returnValue = select(1, &fdSet, 0, 0, &timeValue);
- printf("select returns %d\n", returnValue);
-#endif
-
- m_device->handlePageFlipCompleted();
- }
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h
deleted file mode 100644
index c52d0211b3..0000000000
--- a/src/plugins/platforms/kms/qkmsscreen.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSSCREEN_H
-#define QKMSSCREEN_H
-
-#include <stddef.h>
-
-#define EGL_EGLEXT_PROTOTYPES 1
-#define GL_GLEXT_PROTOTYPES 1
-
-extern "C" {
-#include <gbm.h>
-#include <xf86drmMode.h>
-#include <xf86drm.h>
-}
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <QtGui/qopengl.h>
-#include <QtGui/qsurfaceformat.h>
-#include <QtCore/qloggingcategory.h>
-
-#include <qpa/qplatformscreen.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen)
-
-class QKmsCursor;
-class QKmsDevice;
-class QKmsContext;
-
-class QKmsScreen : public QPlatformScreen
-{
-public:
- QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector);
- ~QKmsScreen();
-
- QRect geometry() const Q_DECL_OVERRIDE;
- int depth() const Q_DECL_OVERRIDE;
- QImage::Format format() const Q_DECL_OVERRIDE;
- QSizeF physicalSize() const Q_DECL_OVERRIDE;
- QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
-
- quint32 crtcId() const { return m_crtcId; }
- QKmsDevice *device() const;
-
- void initializeWithFormat(const QSurfaceFormat &format);
-
- //Called by context for each screen
- void swapBuffers();
- void handlePageFlipped();
-
- EGLSurface eglSurface() const { return m_eglWindowSurface; }
-
- void waitForPageFlipComplete();
-
- static QSurfaceFormat tweakFormat(const QSurfaceFormat &format);
-
- QSurfaceFormat surfaceFormat() const { return m_surfaceFormat; }
-
-private:
- void performPageFlip();
- void initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector);
-
- QKmsDevice *m_device;
- gbm_bo *m_current_bo;
- gbm_bo *m_next_bo;
- quint32 m_connectorId;
-
- quint32 m_crtcId;
- drmModeModeInfo m_mode;
- QRect m_geometry;
- QSizeF m_physicalSize;
- int m_depth;
- QImage::Format m_format;
-
- drmModeCrtcPtr m_oldCrtc;
-
- QKmsCursor *m_cursor;
-
- gbm_surface *m_gbmSurface;
- EGLSurface m_eglWindowSurface;
-
- bool m_modeSet;
- QSurfaceFormat m_surfaceFormat;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSSCREEN_H
diff --git a/src/plugins/platforms/kms/qkmswindow.cpp b/src/plugins/platforms/kms/qkmswindow.cpp
deleted file mode 100644
index 3b01dfedca..0000000000
--- a/src/plugins/platforms/kms/qkmswindow.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmswindow.h"
-#include "qkmsscreen.h"
-
-#include <qpa/qwindowsysteminterface.h>
-#include <qpa/qplatformwindow_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QKmsWindow::QKmsWindow(QWindow *window)
- : QPlatformWindow(window)
-{
- Q_D(QPlatformWindow);
- m_screen = QPlatformScreen::platformScreenForWindow(window);
- static_cast<QKmsScreen *>(m_screen)->initializeWithFormat(window->requestedFormat());
- setGeometry(d->rect); // rect is set to window->geometry() in base ctor
-}
-
-void QKmsWindow::setGeometry(const QRect &rect)
-{
- // All windows must be fullscreen
- QRect fullscreenRect = m_screen->availableGeometry();
- if (rect != fullscreenRect)
- QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
-
- QPlatformWindow::setGeometry(fullscreenRect);
-}
-
-QSurfaceFormat QKmsWindow::format() const
-{
- return static_cast<QKmsScreen *>(m_screen)->surfaceFormat();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmswindow.h b/src/plugins/platforms/kms/qkmswindow.h
deleted file mode 100644
index aec6d55b5d..0000000000
--- a/src/plugins/platforms/kms/qkmswindow.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSWINDOW_H
-#define QKMSWINDOW_H
-
-#include <qpa/qplatformwindow.h>
-
-QT_BEGIN_NAMESPACE
-
-class QKmsWindow : public QPlatformWindow
-{
- Q_DECLARE_PRIVATE(QPlatformWindow)
-
-public:
- QKmsWindow(QWindow *window);
-
- void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
- QSurfaceFormat format() const Q_DECL_OVERRIDE;
-
-private:
- QPlatformScreen *m_screen;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSWINDOW_H
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index ccf86dafb2..8c8c8a15ea 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -46,6 +46,10 @@
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatforminputcontextfactory_p.h>
+#ifndef QT_NO_LIBINPUT
+#include <QtPlatformSupport/private/qlibinputhandler_p.h>
+#endif
+
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
@@ -130,6 +134,13 @@ QPlatformServices *QLinuxFbIntegration::services() const
void QLinuxFbIntegration::createInputHandlers()
{
+#ifndef QT_NO_LIBINPUT
+ if (!qEnvironmentVariableIntValue("QT_QPA_FB_NO_LIBINPUT")) {
+ new QLibInputHandler(QLatin1String("libinput"), QString());
+ return;
+ }
+#endif
+
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this);
diff --git a/src/plugins/platforms/mirclient/mirclient.json b/src/plugins/platforms/mirclient/mirclient.json
new file mode 100644
index 0000000000..c31558a2f1
--- /dev/null
+++ b/src/plugins/platforms/mirclient/mirclient.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "mirclient" ]
+}
diff --git a/src/plugins/platforms/mirclient/mirclient.pro b/src/plugins/platforms/mirclient/mirclient.pro
new file mode 100644
index 0000000000..033ce579b9
--- /dev/null
+++ b/src/plugins/platforms/mirclient/mirclient.pro
@@ -0,0 +1,47 @@
+TARGET = mirclient
+TEMPLATE = lib
+
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = MirServerIntegrationPlugin
+!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
+load(qt_plugin)
+
+QT += core-private gui-private platformsupport-private dbus
+
+CONFIG += qpa/genericunixfontdatabase
+
+DEFINES += MESA_EGL_NO_X11_HEADERS
+# CONFIG += c++11 # only enables C++0x
+QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -std=c++11 -Werror -Wall
+QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined
+
+CONFIG += link_pkgconfig
+PKGCONFIG += egl mirclient ubuntu-platform-api
+
+SOURCES = \
+ qmirclientbackingstore.cpp \
+ qmirclientclipboard.cpp \
+ qmirclientglcontext.cpp \
+ qmirclientinput.cpp \
+ qmirclientintegration.cpp \
+ qmirclientnativeinterface.cpp \
+ qmirclientplatformservices.cpp \
+ qmirclientplugin.cpp \
+ qmirclientscreen.cpp \
+ qmirclienttheme.cpp \
+ qmirclientwindow.cpp
+
+HEADERS = \
+ qmirclientbackingstore.h \
+ qmirclientclipboard.h \
+ qmirclientglcontext.h \
+ qmirclientinput.h \
+ qmirclientintegration.h \
+ qmirclientlogging.h \
+ qmirclientnativeinterface.h \
+ qmirclientorientationchangeevent_p.h \
+ qmirclientplatformservices.h \
+ qmirclientplugin.h \
+ qmirclientscreen.h \
+ qmirclienttheme.h \
+ qmirclientwindow.h
diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
new file mode 100644
index 0000000000..daa0b229ec
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientbackingstore.h"
+#include "qmirclientlogging.h"
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLTexture>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/qopenglfunctions.h>
+
+QMirClientBackingStore::QMirClientBackingStore(QWindow* window)
+ : QPlatformBackingStore(window)
+ , mContext(new QOpenGLContext)
+ , mTexture(new QOpenGLTexture(QOpenGLTexture::Target2D))
+ , mBlitter(new QOpenGLTextureBlitter)
+{
+ mContext->setFormat(window->requestedFormat());
+ mContext->setScreen(window->screen());
+ mContext->create();
+
+ window->setSurfaceType(QSurface::OpenGLSurface);
+}
+
+QMirClientBackingStore::~QMirClientBackingStore()
+{
+}
+
+void QMirClientBackingStore::flush(QWindow* window, const QRegion& region, const QPoint& offset)
+{
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+ mContext->makeCurrent(window);
+ glViewport(0, 0, window->width(), window->height());
+
+ updateTexture();
+
+ if (!mBlitter->isCreated())
+ mBlitter->create();
+
+ mBlitter->bind();
+ mBlitter->setSwizzleRB(true);
+ mBlitter->blit(mTexture->textureId(), QMatrix4x4(), QOpenGLTextureBlitter::OriginTopLeft);
+ mBlitter->release();
+
+ mContext->swapBuffers(window);
+}
+
+void QMirClientBackingStore::updateTexture()
+{
+ if (mDirty.isNull())
+ return;
+
+ if (!mTexture->isCreated()) {
+ mTexture->setMinificationFilter(QOpenGLTexture::Nearest);
+ mTexture->setMagnificationFilter(QOpenGLTexture::Nearest);
+ mTexture->setWrapMode(QOpenGLTexture::ClampToEdge);
+ mTexture->setData(mImage, QOpenGLTexture::DontGenerateMipMaps);
+ mTexture->create();
+ }
+ mTexture->bind();
+
+ QRegion fixed;
+ QRect imageRect = mImage.rect();
+
+ Q_FOREACH (const QRect &rect, mDirty.rects()) {
+ // intersect with image rect to be sure
+ QRect r = imageRect & rect;
+
+ // if the rect is wide enough it is cheaper to just extend it instead of doing an image copy
+ if (r.width() >= imageRect.width() / 2) {
+ r.setX(0);
+ r.setWidth(imageRect.width());
+ }
+
+ fixed |= r;
+ }
+
+ Q_FOREACH (const QRect &rect, fixed.rects()) {
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there is no gap between scanlines
+ if (rect.width() == imageRect.width()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ mImage.constScanLine(rect.y()));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ mImage.copy(rect).constBits());
+ }
+ }
+ /* End of code taken from QEGLPlatformBackingStore */
+
+ mDirty = QRegion();
+}
+
+
+void QMirClientBackingStore::beginPaint(const QRegion& region)
+{
+ mDirty |= region;
+}
+
+void QMirClientBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/)
+{
+ mImage = QImage(size, QImage::Format_RGB32);
+
+ if (mTexture->isCreated())
+ mTexture->destroy();
+}
+
+QPaintDevice* QMirClientBackingStore::paintDevice()
+{
+ return &mImage;
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.h b/src/plugins/platforms/mirclient/qmirclientbackingstore.h
new file mode 100644
index 0000000000..22b8bf9bc5
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientbackingstore.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTBACKINGSTORE_H
+#define QMIRCLIENTBACKINGSTORE_H
+
+#include <qpa/qplatformbackingstore.h>
+
+class QOpenGLContext;
+class QOpenGLTexture;
+class QOpenGLTextureBlitter;
+
+class QMirClientBackingStore : public QPlatformBackingStore
+{
+public:
+ QMirClientBackingStore(QWindow* window);
+ virtual ~QMirClientBackingStore();
+
+ // QPlatformBackingStore methods.
+ void beginPaint(const QRegion&) override;
+ void flush(QWindow* window, const QRegion& region, const QPoint& offset) override;
+ void resize(const QSize& size, const QRegion& staticContents) override;
+ QPaintDevice* paintDevice() override;
+
+protected:
+ void updateTexture();
+
+private:
+ QScopedPointer<QOpenGLContext> mContext;
+ QScopedPointer<QOpenGLTexture> mTexture;
+ QScopedPointer<QOpenGLTextureBlitter> mBlitter;
+ QImage mImage;
+ QRegion mDirty;
+};
+
+#endif // QMIRCLIENTBACKINGSTORE_H
diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
new file mode 100644
index 0000000000..aa2ddf2103
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientclipboard.h"
+
+#include <QtCore/QMimeData>
+#include <QtCore/QStringList>
+#include <QDBusInterface>
+#include <QDBusPendingCallWatcher>
+#include <QDBusPendingReply>
+
+// FIXME(loicm) The clipboard data format is not defined by Ubuntu Platform API
+// which makes it impossible to have non-Qt applications communicate with Qt
+// applications through the clipboard API. The solution would be to have
+// Ubuntu Platform define the data format or propose an API that supports
+// embedding different mime types in the clipboard.
+
+// Data format:
+// number of mime types (sizeof(int))
+// data layout ((4 * sizeof(int)) * number of mime types)
+// mime type string offset (sizeof(int))
+// mime type string size (sizeof(int))
+// data offset (sizeof(int))
+// data size (sizeof(int))
+// data (n bytes)
+
+namespace {
+
+const int maxFormatsCount = 16;
+const int maxBufferSize = 4 * 1024 * 1024; // 4 Mb
+
+}
+
+QMirClientClipboard::QMirClientClipboard()
+ : mMimeData(new QMimeData)
+ , mIsOutdated(true)
+ , mUpdatesDisabled(false)
+ , mDBusSetupDone(false)
+{
+}
+
+QMirClientClipboard::~QMirClientClipboard()
+{
+ delete mMimeData;
+}
+
+void QMirClientClipboard::requestDBusClipboardContents()
+{
+ if (!mDBusSetupDone) {
+ setupDBus();
+ }
+
+ if (!mPendingGetContentsCall.isNull())
+ return;
+
+ QDBusPendingCall pendingCall = mDBusClipboard->asyncCall("GetContents");
+
+ mPendingGetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
+
+ QObject::connect(mPendingGetContentsCall.data(), SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher*)));
+}
+
+void QMirClientClipboard::onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher* call)
+{
+ Q_ASSERT(call == mPendingGetContentsCall.data());
+
+ QDBusPendingReply<QByteArray> reply = *call;
+ if (reply.isError()) {
+ qCritical("QMirClientClipboard - Failed to get system clipboard contents via D-Bus. %s, %s",
+ qPrintable(reply.error().name()), qPrintable(reply.error().message()));
+ // TODO: Might try again later a number of times...
+ } else {
+ QByteArray serializedMimeData = reply.argumentAt<0>();
+ updateMimeData(serializedMimeData);
+ }
+ call->deleteLater();
+}
+
+void QMirClientClipboard::onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher *call)
+{
+ QDBusPendingReply<void> reply = *call;
+ if (reply.isError()) {
+ qCritical("QMirClientClipboard - Failed to set the system clipboard contents via D-Bus. %s, %s",
+ qPrintable(reply.error().name()), qPrintable(reply.error().message()));
+ // TODO: Might try again later a number of times...
+ }
+ call->deleteLater();
+}
+
+void QMirClientClipboard::updateMimeData(const QByteArray &serializedMimeData)
+{
+ if (mUpdatesDisabled)
+ return;
+
+ QMimeData *newMimeData = deserializeMimeData(serializedMimeData);
+ if (newMimeData) {
+ delete mMimeData;
+ mMimeData = newMimeData;
+ mIsOutdated = false;
+ emitChanged(QClipboard::Clipboard);
+ } else {
+ qWarning("QMirClientClipboard - Got invalid serialized mime data. Ignoring it.");
+ }
+}
+
+void QMirClientClipboard::setupDBus()
+{
+ QDBusConnection dbusConnection = QDBusConnection::sessionBus();
+
+ bool ok = dbusConnection.connect(
+ "com.canonical.QtMir",
+ "/com/canonical/QtMir/Clipboard",
+ "com.canonical.QtMir.Clipboard",
+ "ContentsChanged",
+ this, SLOT(updateMimeData(QByteArray)));
+ if (!ok) {
+ qCritical("QMirClientClipboard - Failed to connect to ContentsChanged signal form the D-Bus system clipboard.");
+ }
+
+ mDBusClipboard = new QDBusInterface("com.canonical.QtMir",
+ "/com/canonical/QtMir/Clipboard",
+ "com.canonical.QtMir.Clipboard",
+ dbusConnection);
+
+ mDBusSetupDone = true;
+}
+
+QByteArray QMirClientClipboard::serializeMimeData(QMimeData *mimeData) const
+{
+ const QStringList formats = mimeData->formats();
+ const int formatCount = qMin(formats.size(), maxFormatsCount);
+ const int headerSize = sizeof(int) + (formatCount * 4 * sizeof(int));
+ int bufferSize = headerSize;
+
+ for (int i = 0; i < formatCount; i++)
+ bufferSize += formats[i].size() + mimeData->data(formats[i]).size();
+
+ QByteArray serializedMimeData;
+ if (bufferSize <= maxBufferSize) {
+ // Serialize data.
+ serializedMimeData.resize(bufferSize);
+ {
+ char *buffer = serializedMimeData.data();
+ int* header = reinterpret_cast<int*>(serializedMimeData.data());
+ int offset = headerSize;
+ header[0] = formatCount;
+ for (int i = 0; i < formatCount; i++) {
+ const int formatOffset = offset;
+ const int formatSize = formats[i].size();
+ const int dataOffset = offset + formatSize;
+ const int dataSize = mimeData->data(formats[i]).size();
+ memcpy(&buffer[formatOffset], formats[i].toLatin1().data(), formatSize);
+ memcpy(&buffer[dataOffset], mimeData->data(formats[i]).data(), dataSize);
+ header[i*4+1] = formatOffset;
+ header[i*4+2] = formatSize;
+ header[i*4+3] = dataOffset;
+ header[i*4+4] = dataSize;
+ offset += formatSize + dataSize;
+ }
+ }
+ } else {
+ qWarning("QMirClientClipboard: Not sending contents (%d bytes) to the global clipboard as it's"
+ " bigger than the maximum allowed size of %d bytes", bufferSize, maxBufferSize);
+ }
+
+ return serializedMimeData;
+}
+
+QMimeData *QMirClientClipboard::deserializeMimeData(const QByteArray &serializedMimeData) const
+{
+ if (static_cast<std::size_t>(serializedMimeData.size()) < sizeof(int)) {
+ // Data is invalid
+ return nullptr;
+ }
+
+ QMimeData *mimeData = new QMimeData;
+
+ const char* const buffer = serializedMimeData.constData();
+ const int* const header = reinterpret_cast<const int*>(serializedMimeData.constData());
+
+ const int count = qMin(header[0], maxFormatsCount);
+
+ for (int i = 0; i < count; i++) {
+ const int formatOffset = header[i*4+1];
+ const int formatSize = header[i*4+2];
+ const int dataOffset = header[i*4+3];
+ const int dataSize = header[i*4+4];
+
+ if (formatOffset + formatSize <= serializedMimeData.size()
+ && dataOffset + dataSize <= serializedMimeData.size()) {
+
+ QString mimeType = QString::fromLatin1(&buffer[formatOffset], formatSize);
+ QByteArray mimeDataBytes(&buffer[dataOffset], dataSize);
+
+ mimeData->setData(mimeType, mimeDataBytes);
+ }
+ }
+
+ return mimeData;
+}
+
+QMimeData* QMirClientClipboard::mimeData(QClipboard::Mode mode)
+{
+ if (mode != QClipboard::Clipboard)
+ return nullptr;
+
+ if (mIsOutdated && mPendingGetContentsCall.isNull()) {
+ requestDBusClipboardContents();
+ }
+
+ // Return whatever we have at the moment instead of blocking until we have something.
+ //
+ // This might be called during app startup just for the sake of checking if some
+ // "Paste" UI control should be enabled or not.
+ // We will emit QClipboard::changed() once we finally have something.
+ return mMimeData;
+}
+
+void QMirClientClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
+{
+ if (mode != QClipboard::Clipboard)
+ return;
+
+ if (!mPendingGetContentsCall.isNull()) {
+ // Ignore whatever comes from the system clipboard as we are going to change it anyway
+ QObject::disconnect(mPendingGetContentsCall.data(), 0, this, 0);
+ mUpdatesDisabled = true;
+ mPendingGetContentsCall->waitForFinished();
+ mUpdatesDisabled = false;
+ delete mPendingGetContentsCall.data();
+ }
+
+ QByteArray serializedMimeData = serializeMimeData(mimeData);
+ if (!serializedMimeData.isEmpty()) {
+ setDBusClipboardContents(serializedMimeData);
+ }
+
+ mMimeData = mimeData;
+ emitChanged(QClipboard::Clipboard);
+}
+
+bool QMirClientClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ return mode == QClipboard::Clipboard;
+}
+
+bool QMirClientClipboard::ownsMode(QClipboard::Mode mode) const
+{
+ Q_UNUSED(mode);
+ return false;
+}
+
+void QMirClientClipboard::setDBusClipboardContents(const QByteArray &clipboardContents)
+{
+ if (!mPendingSetContentsCall.isNull()) {
+ // Ignore any previous set call as we are going to overwrite it anyway
+ QObject::disconnect(mPendingSetContentsCall.data(), 0, this, 0);
+ mUpdatesDisabled = true;
+ mPendingSetContentsCall->waitForFinished();
+ mUpdatesDisabled = false;
+ delete mPendingSetContentsCall.data();
+ }
+
+ QDBusPendingCall pendingCall = mDBusClipboard->asyncCall("SetContents", clipboardContents);
+
+ mPendingSetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
+
+ QObject::connect(mPendingSetContentsCall.data(), SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher*)));
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.h b/src/plugins/platforms/mirclient/qmirclientclipboard.h
new file mode 100644
index 0000000000..d3d3d400d2
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientclipboard.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTCLIPBOARD_H
+#define QMIRCLIENTCLIPBOARD_H
+
+#include <qpa/qplatformclipboard.h>
+
+#include <QMimeData>
+#include <QPointer>
+class QDBusInterface;
+class QDBusPendingCallWatcher;
+
+class QMirClientClipboard : public QObject, public QPlatformClipboard
+{
+ Q_OBJECT
+public:
+ QMirClientClipboard();
+ virtual ~QMirClientClipboard();
+
+ // QPlatformClipboard methods.
+ QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override;
+ void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override;
+ bool supportsMode(QClipboard::Mode mode) const override;
+ bool ownsMode(QClipboard::Mode mode) const override;
+
+ void requestDBusClipboardContents();
+
+private Q_SLOTS:
+ void onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher*);
+ void onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher*);
+ void updateMimeData(const QByteArray &serializedMimeData);
+
+private:
+ void setupDBus();
+
+ QByteArray serializeMimeData(QMimeData *mimeData) const;
+ QMimeData *deserializeMimeData(const QByteArray &serializedMimeData) const;
+
+ void setDBusClipboardContents(const QByteArray &clipboardContents);
+
+ QMimeData *mMimeData;
+ bool mIsOutdated;
+
+ QPointer<QDBusInterface> mDBusClipboard;
+
+ QPointer<QDBusPendingCallWatcher> mPendingGetContentsCall;
+ QPointer<QDBusPendingCallWatcher> mPendingSetContentsCall;
+
+ bool mUpdatesDisabled;
+ bool mDBusSetupDone;
+};
+
+#endif // QMIRCLIENTCLIPBOARD_H
diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
new file mode 100644
index 0000000000..bfba5051e5
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientglcontext.h"
+#include "qmirclientwindow.h"
+#include "qmirclientlogging.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+
+#if !defined(QT_NO_DEBUG)
+static void printOpenGLESConfig() {
+ static bool once = true;
+ if (once) {
+ const char* string = (const char*) glGetString(GL_VENDOR);
+ LOG("OpenGL ES vendor: %s", string);
+ string = (const char*) glGetString(GL_RENDERER);
+ LOG("OpenGL ES renderer: %s", string);
+ string = (const char*) glGetString(GL_VERSION);
+ LOG("OpenGL ES version: %s", string);
+ string = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
+ LOG("OpenGL ES Shading Language version: %s", string);
+ string = (const char*) glGetString(GL_EXTENSIONS);
+ LOG("OpenGL ES extensions: %s", string);
+ once = false;
+ }
+}
+#endif
+
+static EGLenum api_in_use()
+{
+#ifdef QTUBUNTU_USE_OPENGL
+ return EGL_OPENGL_API;
+#else
+ return EGL_OPENGL_ES_API;
+#endif
+}
+
+QMirClientOpenGLContext::QMirClientOpenGLContext(QMirClientScreen* screen, QMirClientOpenGLContext* share)
+{
+ ASSERT(screen != NULL);
+ mEglDisplay = screen->eglDisplay();
+ mScreen = screen;
+
+ // Create an OpenGL ES 2 context.
+ QVector<EGLint> attribs;
+ attribs.append(EGL_CONTEXT_CLIENT_VERSION);
+ attribs.append(2);
+ attribs.append(EGL_NONE);
+ ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
+
+ mEglContext = eglCreateContext(mEglDisplay, screen->eglConfig(), share ? share->eglContext() : EGL_NO_CONTEXT,
+ attribs.constData());
+ DASSERT(mEglContext != EGL_NO_CONTEXT);
+}
+
+QMirClientOpenGLContext::~QMirClientOpenGLContext()
+{
+ ASSERT(eglDestroyContext(mEglDisplay, mEglContext) == EGL_TRUE);
+}
+
+bool QMirClientOpenGLContext::makeCurrent(QPlatformSurface* surface)
+{
+ DASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ EGLSurface eglSurface = static_cast<QMirClientWindow*>(surface)->eglSurface();
+#if defined(QT_NO_DEBUG)
+ eglBindAPI(api_in_use());
+ eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
+#else
+ ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
+ ASSERT(eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext) == EGL_TRUE);
+ printOpenGLESConfig();
+#endif
+ return true;
+}
+
+void QMirClientOpenGLContext::doneCurrent()
+{
+#if defined(QT_NO_DEBUG)
+ eglBindAPI(api_in_use());
+ eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+#else
+ ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
+ ASSERT(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_TRUE);
+#endif
+}
+
+void QMirClientOpenGLContext::swapBuffers(QPlatformSurface* surface)
+{
+ QMirClientWindow *ubuntuWindow = static_cast<QMirClientWindow*>(surface);
+
+ EGLSurface eglSurface = ubuntuWindow->eglSurface();
+#if defined(QT_NO_DEBUG)
+ eglBindAPI(api_in_use());
+ eglSwapBuffers(mEglDisplay, eglSurface);
+#else
+ ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
+ ASSERT(eglSwapBuffers(mEglDisplay, eglSurface) == EGL_TRUE);
+#endif
+
+ // "Technique" copied from mir, in examples/eglapp.c around line 96
+ EGLint newBufferWidth = -1;
+ EGLint newBufferHeight = -1;
+ /*
+ * Querying the surface (actually the current buffer) dimensions here is
+ * the only truly safe way to be sure that the dimensions we think we
+ * have are those of the buffer being rendered to. But this should be
+ * improved in future; https://bugs.launchpad.net/mir/+bug/1194384
+ */
+ eglQuerySurface(mEglDisplay, eglSurface, EGL_WIDTH, &newBufferWidth);
+ eglQuerySurface(mEglDisplay, eglSurface, EGL_HEIGHT, &newBufferHeight);
+
+ ubuntuWindow->onBuffersSwapped_threadSafe(newBufferWidth, newBufferHeight);
+}
+
+void (*QMirClientOpenGLContext::getProcAddress(const QByteArray& procName)) ()
+{
+#if defined(QT_NO_DEBUG)
+ eglBindAPI(api_in_use());
+#else
+ ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
+#endif
+ return eglGetProcAddress(procName.constData());
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.h b/src/plugins/platforms/mirclient/qmirclientglcontext.h
new file mode 100644
index 0000000000..cc40298259
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientglcontext.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTGLCONTEXT_H
+#define QMIRCLIENTGLCONTEXT_H
+
+#include <qpa/qplatformopenglcontext.h>
+#include "qmirclientscreen.h"
+
+class QMirClientOpenGLContext : public QPlatformOpenGLContext
+{
+public:
+ QMirClientOpenGLContext(QMirClientScreen* screen, QMirClientOpenGLContext* share);
+ virtual ~QMirClientOpenGLContext();
+
+ // QPlatformOpenGLContext methods.
+ QSurfaceFormat format() const override { return mScreen->surfaceFormat(); }
+ void swapBuffers(QPlatformSurface* surface) override;
+ bool makeCurrent(QPlatformSurface* surface) override;
+ void doneCurrent() override;
+ bool isValid() const override { return mEglContext != EGL_NO_CONTEXT; }
+ void (*getProcAddress(const QByteArray& procName)) ();
+
+ EGLContext eglContext() const { return mEglContext; }
+
+private:
+ QMirClientScreen* mScreen;
+ EGLContext mEglContext;
+ EGLDisplay mEglDisplay;
+};
+
+#endif // QMIRCLIENTGLCONTEXT_H
diff --git a/src/plugins/platforms/mirclient/qmirclientinput.cpp b/src/plugins/platforms/mirclient/qmirclientinput.cpp
new file mode 100644
index 0000000000..56bc21f420
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientinput.cpp
@@ -0,0 +1,520 @@
+/****************************************************************************
+**
+** Copyright (C) 2014-2015 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// Local
+#include "qmirclientinput.h"
+#include "qmirclientintegration.h"
+#include "qmirclientnativeinterface.h"
+#include "qmirclientscreen.h"
+#include "qmirclientwindow.h"
+#include "qmirclientlogging.h"
+#include "qmirclientorientationchangeevent_p.h"
+
+// Qt
+#if !defined(QT_NO_DEBUG)
+#include <QtCore/QThread>
+#endif
+#include <QtCore/qglobal.h>
+#include <QtCore/QCoreApplication>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatforminputcontext.h>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-keysyms.h>
+
+#include <mir_toolkit/mir_client_library.h>
+
+#define LOG_EVENTS 0
+
+// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
+static const uint32_t KeyTable[] = {
+ XKB_KEY_Escape, Qt::Key_Escape,
+ XKB_KEY_Tab, Qt::Key_Tab,
+ XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab,
+ XKB_KEY_BackSpace, Qt::Key_Backspace,
+ XKB_KEY_Return, Qt::Key_Return,
+ XKB_KEY_Insert, Qt::Key_Insert,
+ XKB_KEY_Delete, Qt::Key_Delete,
+ XKB_KEY_Clear, Qt::Key_Delete,
+ XKB_KEY_Pause, Qt::Key_Pause,
+ XKB_KEY_Print, Qt::Key_Print,
+
+ XKB_KEY_Home, Qt::Key_Home,
+ XKB_KEY_End, Qt::Key_End,
+ XKB_KEY_Left, Qt::Key_Left,
+ XKB_KEY_Up, Qt::Key_Up,
+ XKB_KEY_Right, Qt::Key_Right,
+ XKB_KEY_Down, Qt::Key_Down,
+ XKB_KEY_Prior, Qt::Key_PageUp,
+ XKB_KEY_Next, Qt::Key_PageDown,
+
+ XKB_KEY_Shift_L, Qt::Key_Shift,
+ XKB_KEY_Shift_R, Qt::Key_Shift,
+ XKB_KEY_Shift_Lock, Qt::Key_Shift,
+ XKB_KEY_Control_L, Qt::Key_Control,
+ XKB_KEY_Control_R, Qt::Key_Control,
+ XKB_KEY_Meta_L, Qt::Key_Meta,
+ XKB_KEY_Meta_R, Qt::Key_Meta,
+ XKB_KEY_Alt_L, Qt::Key_Alt,
+ XKB_KEY_Alt_R, Qt::Key_Alt,
+ XKB_KEY_Caps_Lock, Qt::Key_CapsLock,
+ XKB_KEY_Num_Lock, Qt::Key_NumLock,
+ XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock,
+ XKB_KEY_Super_L, Qt::Key_Super_L,
+ XKB_KEY_Super_R, Qt::Key_Super_R,
+ XKB_KEY_Menu, Qt::Key_Menu,
+ XKB_KEY_Hyper_L, Qt::Key_Hyper_L,
+ XKB_KEY_Hyper_R, Qt::Key_Hyper_R,
+ XKB_KEY_Help, Qt::Key_Help,
+
+ XKB_KEY_KP_Space, Qt::Key_Space,
+ XKB_KEY_KP_Tab, Qt::Key_Tab,
+ XKB_KEY_KP_Enter, Qt::Key_Enter,
+ XKB_KEY_KP_Home, Qt::Key_Home,
+ XKB_KEY_KP_Left, Qt::Key_Left,
+ XKB_KEY_KP_Up, Qt::Key_Up,
+ XKB_KEY_KP_Right, Qt::Key_Right,
+ XKB_KEY_KP_Down, Qt::Key_Down,
+ XKB_KEY_KP_Prior, Qt::Key_PageUp,
+ XKB_KEY_KP_Next, Qt::Key_PageDown,
+ XKB_KEY_KP_End, Qt::Key_End,
+ XKB_KEY_KP_Begin, Qt::Key_Clear,
+ XKB_KEY_KP_Insert, Qt::Key_Insert,
+ XKB_KEY_KP_Delete, Qt::Key_Delete,
+ XKB_KEY_KP_Equal, Qt::Key_Equal,
+ XKB_KEY_KP_Multiply, Qt::Key_Asterisk,
+ XKB_KEY_KP_Add, Qt::Key_Plus,
+ XKB_KEY_KP_Separator, Qt::Key_Comma,
+ XKB_KEY_KP_Subtract, Qt::Key_Minus,
+ XKB_KEY_KP_Decimal, Qt::Key_Period,
+ XKB_KEY_KP_Divide, Qt::Key_Slash,
+
+ XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr,
+ XKB_KEY_Multi_key, Qt::Key_Multi_key,
+ XKB_KEY_Codeinput, Qt::Key_Codeinput,
+ XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate,
+ XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate,
+ XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate,
+
+ XKB_KEY_Mode_switch, Qt::Key_Mode_switch,
+ XKB_KEY_script_switch, Qt::Key_Mode_switch,
+ XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp,
+ XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown,
+ XKB_KEY_XF86PowerOff, Qt::Key_PowerOff,
+ XKB_KEY_XF86PowerDown, Qt::Key_PowerDown,
+
+ 0, 0
+};
+
+class QMirClientEvent : public QEvent
+{
+public:
+ QMirClientEvent(QMirClientWindow* window, const MirEvent *event, QEvent::Type type)
+ : QEvent(type), window(window) {
+ nativeEvent = mir_event_ref(event);
+ }
+ ~QMirClientEvent()
+ {
+ mir_event_unref(nativeEvent);
+ }
+
+ QPointer<QMirClientWindow> window;
+ const MirEvent *nativeEvent;
+};
+
+QMirClientInput::QMirClientInput(QMirClientClientIntegration* integration)
+ : QObject(nullptr)
+ , mIntegration(integration)
+ , mEventFilterType(static_cast<QMirClientNativeInterface*>(
+ integration->nativeInterface())->genericEventFilterType())
+ , mEventType(static_cast<QEvent::Type>(QEvent::registerEventType()))
+{
+ // Initialize touch device.
+ mTouchDevice = new QTouchDevice;
+ mTouchDevice->setType(QTouchDevice::TouchScreen);
+ mTouchDevice->setCapabilities(
+ QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure |
+ QTouchDevice::NormalizedPosition);
+ QWindowSystemInterface::registerTouchDevice(mTouchDevice);
+}
+
+QMirClientInput::~QMirClientInput()
+{
+ // Qt will take care of deleting mTouchDevice.
+}
+
+#if (LOG_EVENTS != 0)
+static const char* nativeEventTypeToStr(MirEventType t)
+{
+ switch (t)
+ {
+ case mir_event_type_key:
+ return "mir_event_type_key";
+ case mir_event_type_motion:
+ return "mir_event_type_motion";
+ case mir_event_type_surface:
+ return "mir_event_type_surface";
+ case mir_event_type_resize:
+ return "mir_event_type_resize";
+ case mir_event_type_prompt_session_state_change:
+ return "mir_event_type_prompt_session_state_change";
+ case mir_event_type_orientation:
+ return "mir_event_type_orientation";
+ case mir_event_type_close_surface:
+ return "mir_event_type_close_surface";
+ case mir_event_type_input:
+ return "mir_event_type_input";
+ default:
+ DLOG("Invalid event type %d", t);
+ return "invalid";
+ }
+}
+#endif // LOG_EVENTS != 0
+
+void QMirClientInput::customEvent(QEvent* event)
+{
+ DASSERT(QThread::currentThread() == thread());
+ QMirClientEvent* ubuntuEvent = static_cast<QMirClientEvent*>(event);
+ const MirEvent *nativeEvent = ubuntuEvent->nativeEvent;
+
+ if ((ubuntuEvent->window == nullptr) || (ubuntuEvent->window->window() == nullptr)) {
+ qWarning() << "Attempted to deliver an event to a non-existent window, ignoring.";
+ return;
+ }
+
+ // Event filtering.
+ long result;
+ if (QWindowSystemInterface::handleNativeEvent(
+ ubuntuEvent->window->window(), mEventFilterType,
+ const_cast<void *>(static_cast<const void *>(nativeEvent)), &result) == true) {
+ DLOG("event filtered out by native interface");
+ return;
+ }
+
+ #if (LOG_EVENTS != 0)
+ LOG("QMirClientInput::customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent)));
+ #endif
+
+ // Event dispatching.
+ switch (mir_event_get_type(nativeEvent))
+ {
+ case mir_event_type_input:
+ dispatchInputEvent(ubuntuEvent->window->window(), mir_event_get_input_event(nativeEvent));
+ break;
+ case mir_event_type_resize:
+ {
+ Q_ASSERT(ubuntuEvent->window->screen() == mIntegration->screen());
+
+ auto resizeEvent = mir_event_get_resize_event(nativeEvent);
+
+ mIntegration->screen()->handleWindowSurfaceResize(
+ mir_resize_event_get_width(resizeEvent),
+ mir_resize_event_get_height(resizeEvent));
+
+ ubuntuEvent->window->handleSurfaceResize(mir_resize_event_get_width(resizeEvent),
+ mir_resize_event_get_height(resizeEvent));
+ break;
+ }
+ case mir_event_type_surface:
+ {
+ auto surfaceEvent = mir_event_get_surface_event(nativeEvent);
+ if (mir_surface_event_get_attribute(surfaceEvent) == mir_surface_attrib_focus) {
+ ubuntuEvent->window->handleSurfaceFocusChange(mir_surface_event_get_attribute_value(surfaceEvent) ==
+ mir_surface_focused);
+ }
+ break;
+ }
+ case mir_event_type_orientation:
+ dispatchOrientationEvent(ubuntuEvent->window->window(), mir_event_get_orientation_event(nativeEvent));
+ break;
+ case mir_event_type_close_surface:
+ QWindowSystemInterface::handleCloseEvent(ubuntuEvent->window->window());
+ break;
+ default:
+ DLOG("unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent)));
+ }
+}
+
+void QMirClientInput::postEvent(QMirClientWindow *platformWindow, const MirEvent *event)
+{
+ QWindow *window = platformWindow->window();
+
+ QCoreApplication::postEvent(this, new QMirClientEvent(
+ platformWindow, event, mEventType));
+
+ if ((window->flags().testFlag(Qt::WindowTransparentForInput)) && window->parent()) {
+ QCoreApplication::postEvent(this, new QMirClientEvent(
+ static_cast<QMirClientWindow*>(platformWindow->QPlatformWindow::parent()),
+ event, mEventType));
+ }
+}
+
+void QMirClientInput::dispatchInputEvent(QWindow *window, const MirInputEvent *ev)
+{
+ switch (mir_input_event_get_type(ev))
+ {
+ case mir_input_event_type_key:
+ dispatchKeyEvent(window, ev);
+ break;
+ case mir_input_event_type_touch:
+ dispatchTouchEvent(window, ev);
+ break;
+ case mir_input_event_type_pointer:
+ dispatchPointerEvent(window, ev);
+ break;
+ default:
+ break;
+ }
+}
+
+void QMirClientInput::dispatchTouchEvent(QWindow *window, const MirInputEvent *ev)
+{
+ const MirTouchEvent *tev = mir_input_event_get_touch_event(ev);
+
+ // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
+ // needs to be fixed as soon as the compat input lib adds query support.
+ const float kMaxPressure = 1.28;
+ const QRect kWindowGeometry = window->geometry();
+ QList<QWindowSystemInterface::TouchPoint> touchPoints;
+
+
+ // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
+ // as Qt::TouchPointMoved
+ const unsigned int kPointerCount = mir_touch_event_point_count(tev);
+ for (unsigned int i = 0; i < kPointerCount; ++i) {
+ QWindowSystemInterface::TouchPoint touchPoint;
+
+ const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) + kWindowGeometry.x();
+ const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere
+ const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major);
+ const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor);
+ const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure);
+ touchPoint.id = mir_touch_event_id(tev, i);
+ touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
+ touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH);
+ touchPoint.pressure = kP / kMaxPressure;
+
+ MirTouchAction touch_action = mir_touch_event_action(tev, i);
+ switch (touch_action)
+ {
+ case mir_touch_action_down:
+ touchPoint.state = Qt::TouchPointPressed;
+ break;
+ case mir_touch_action_up:
+ touchPoint.state = Qt::TouchPointReleased;
+ break;
+ case mir_touch_action_change:
+ default:
+ touchPoint.state = Qt::TouchPointMoved;
+ }
+
+ touchPoints.append(touchPoint);
+ }
+
+ ulong timestamp = mir_input_event_get_event_time(ev) / 1000000;
+ QWindowSystemInterface::handleTouchEvent(window, timestamp,
+ mTouchDevice, touchPoints);
+}
+
+static uint32_t translateKeysym(uint32_t sym, char *string, size_t size)
+{
+ Q_UNUSED(size);
+ string[0] = '\0';
+
+ if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35)
+ return Qt::Key_F1 + (int(sym) - XKB_KEY_F1);
+
+ for (int i = 0; KeyTable[i]; i += 2) {
+ if (sym == KeyTable[i])
+ return KeyTable[i + 1];
+ }
+
+ string[0] = sym;
+ string[1] = '\0';
+ return toupper(sym);
+}
+
+namespace
+{
+Qt::KeyboardModifiers qt_modifiers_from_mir(MirInputEventModifiers modifiers)
+{
+ Qt::KeyboardModifiers q_modifiers = Qt::NoModifier;
+ if (modifiers & mir_input_event_modifier_shift) {
+ q_modifiers |= Qt::ShiftModifier;
+ }
+ if (modifiers & mir_input_event_modifier_ctrl) {
+ q_modifiers |= Qt::ControlModifier;
+ }
+ if (modifiers & mir_input_event_modifier_alt) {
+ q_modifiers |= Qt::AltModifier;
+ }
+ if (modifiers & mir_input_event_modifier_meta) {
+ q_modifiers |= Qt::MetaModifier;
+ }
+ return q_modifiers;
+}
+}
+
+void QMirClientInput::dispatchKeyEvent(QWindow *window, const MirInputEvent *event)
+{
+ const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event);
+
+ ulong timestamp = mir_input_event_get_event_time(event) / 1000000;
+ xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event);
+
+ // Key modifier and unicode index mapping.
+ auto modifiers = qt_modifiers_from_mir(mir_keyboard_event_modifiers(key_event));
+
+ MirKeyboardAction action = mir_keyboard_event_action(key_event);
+ QEvent::Type keyType = action == mir_keyboard_action_up
+ ? QEvent::KeyRelease : QEvent::KeyPress;
+
+ char s[2];
+ int sym = translateKeysym(xk_sym, s, sizeof(s));
+ QString text = QString::fromLatin1(s);
+
+ bool is_auto_rep = action == mir_keyboard_action_repeat;
+
+ QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ if (context) {
+ QKeyEvent qKeyEvent(keyType, sym, modifiers, text, is_auto_rep);
+ qKeyEvent.setTimestamp(timestamp);
+ if (context->filterEvent(&qKeyEvent)) {
+ DLOG("key event filtered out by input context");
+ return;
+ }
+ }
+
+ QWindowSystemInterface::handleKeyEvent(window, timestamp, keyType, sym, modifiers, text, is_auto_rep);
+}
+
+namespace
+{
+Qt::MouseButtons extract_buttons(const MirPointerEvent *pev)
+{
+ Qt::MouseButtons buttons = Qt::NoButton;
+ if (mir_pointer_event_button_state(pev, mir_pointer_button_primary))
+ buttons |= Qt::LeftButton;
+ if (mir_pointer_event_button_state(pev, mir_pointer_button_secondary))
+ buttons |= Qt::RightButton;
+ if (mir_pointer_event_button_state(pev, mir_pointer_button_tertiary))
+ buttons |= Qt::MidButton;
+
+ // TODO: Should mir back and forward buttons exist?
+ // should they be Qt::X button 1 and 2?
+ return buttons;
+}
+}
+
+void QMirClientInput::dispatchPointerEvent(QWindow *window, const MirInputEvent *ev)
+{
+ auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
+
+ auto pev = mir_input_event_get_pointer_event(ev);
+ auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev));
+ auto buttons = extract_buttons(pev);
+
+ auto local_point = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x),
+ mir_pointer_event_axis_value(pev, mir_pointer_axis_y));
+
+ QWindowSystemInterface::handleMouseEvent(window, timestamp, local_point, local_point /* Should we omit global point instead? */,
+ buttons, modifiers);
+}
+
+#if (LOG_EVENTS != 0)
+static const char* nativeOrientationDirectionToStr(MirOrientation orientation)
+{
+ switch (orientation) {
+ case mir_orientation_normal:
+ return "Normal";
+ break;
+ case mir_orientation_left:
+ return "Left";
+ break;
+ case mir_orientation_inverted:
+ return "Inverted";
+ break;
+ case mir_orientation_right:
+ return "Right";
+ break;
+ default:
+ return "INVALID!";
+ }
+}
+#endif
+
+void QMirClientInput::dispatchOrientationEvent(QWindow *window, const MirOrientationEvent *event)
+{
+ MirOrientation mir_orientation = mir_orientation_event_get_direction(event);
+ #if (LOG_EVENTS != 0)
+ // Orientation event logging.
+ LOG("ORIENTATION direction: %s", nativeOrientationDirectionToStr(mir_orientation));
+ #endif
+
+ if (!window->screen()) {
+ DLOG("Window has no associated screen, dropping orientation event");
+ return;
+ }
+
+ OrientationChangeEvent::Orientation orientation;
+ switch (mir_orientation) {
+ case mir_orientation_normal:
+ orientation = OrientationChangeEvent::TopUp;
+ break;
+ case mir_orientation_left:
+ orientation = OrientationChangeEvent::LeftUp;
+ break;
+ case mir_orientation_inverted:
+ orientation = OrientationChangeEvent::TopDown;
+ break;
+ case mir_orientation_right:
+ orientation = OrientationChangeEvent::RightUp;
+ break;
+ default:
+ DLOG("No such orientation %d", mir_orientation);
+ return;
+ }
+
+ // Dispatch orientation event to [Platform]Screen, as that is where Qt reads it. Screen will handle
+ // notifying Qt of the actual orientation change - done to prevent multiple Windows each creating
+ // an identical orientation change event and passing it directly to Qt.
+ // [Platform]Screen can also factor in the native orientation.
+ QCoreApplication::postEvent(static_cast<QMirClientScreen*>(window->screen()->handle()),
+ new OrientationChangeEvent(OrientationChangeEvent::mType, orientation));
+}
+
diff --git a/src/plugins/platforms/mirclient/qmirclientinput.h b/src/plugins/platforms/mirclient/qmirclientinput.h
new file mode 100644
index 0000000000..c987d18c12
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientinput.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014-2015 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTINPUT_H
+#define QMIRCLIENTINPUT_H
+
+// Qt
+#include <qpa/qwindowsysteminterface.h>
+
+#include <mir_toolkit/mir_client_library.h>
+
+class QMirClientClientIntegration;
+class QMirClientWindow;
+
+class QMirClientInput : public QObject
+{
+ Q_OBJECT
+
+public:
+ QMirClientInput(QMirClientClientIntegration* integration);
+ virtual ~QMirClientInput();
+
+ // QObject methods.
+ void customEvent(QEvent* event) override;
+
+ void postEvent(QMirClientWindow* window, const MirEvent *event);
+ QMirClientClientIntegration* integration() const { return mIntegration; }
+
+protected:
+ void dispatchKeyEvent(QWindow *window, const MirInputEvent *event);
+ void dispatchPointerEvent(QWindow *window, const MirInputEvent *event);
+ void dispatchTouchEvent(QWindow *window, const MirInputEvent *event);
+ void dispatchInputEvent(QWindow *window, const MirInputEvent *event);
+
+ void dispatchOrientationEvent(QWindow* window, const MirOrientationEvent *event);
+
+private:
+ QMirClientClientIntegration* mIntegration;
+ QTouchDevice* mTouchDevice;
+ const QByteArray mEventFilterType;
+ const QEvent::Type mEventType;
+};
+
+#endif // QMIRCLIENTINPUT_H
diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.cpp b/src/plugins/platforms/mirclient/qmirclientintegration.cpp
new file mode 100644
index 0000000000..a234f4eac6
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientintegration.cpp
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2014-2015 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// Qt
+#include <QGuiApplication>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformnativeinterface.h>
+#include <qpa/qplatforminputcontextfactory_p.h>
+#include <qpa/qplatforminputcontext.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QOpenGLContext>
+
+// Local
+#include "qmirclientbackingstore.h"
+#include "qmirclientclipboard.h"
+#include "qmirclientglcontext.h"
+#include "qmirclientinput.h"
+#include "qmirclientintegration.h"
+#include "qmirclientlogging.h"
+#include "qmirclientnativeinterface.h"
+#include "qmirclientscreen.h"
+#include "qmirclienttheme.h"
+#include "qmirclientwindow.h"
+
+// platform-api
+#include <ubuntu/application/lifecycle_delegate.h>
+#include <ubuntu/application/id.h>
+#include <ubuntu/application/options.h>
+
+static void resumedCallback(const UApplicationOptions *options, void* context)
+{
+ Q_UNUSED(options)
+ Q_UNUSED(context)
+ DASSERT(context != NULL);
+ QCoreApplication::postEvent(QCoreApplication::instance(),
+ new QEvent(QEvent::ApplicationActivate));
+}
+
+static void aboutToStopCallback(UApplicationArchive *archive, void* context)
+{
+ Q_UNUSED(archive)
+ DASSERT(context != NULL);
+ QMirClientClientIntegration* integration = static_cast<QMirClientClientIntegration*>(context);
+ integration->inputContext()->hideInputPanel();
+ QCoreApplication::postEvent(QCoreApplication::instance(),
+ new QEvent(QEvent::ApplicationDeactivate));
+}
+
+QMirClientClientIntegration::QMirClientClientIntegration()
+ : QPlatformIntegration()
+ , mNativeInterface(new QMirClientNativeInterface)
+ , mFontDb(new QGenericUnixFontDatabase)
+ , mServices(new QMirClientPlatformServices)
+ , mClipboard(new QMirClientClipboard)
+ , mScaleFactor(1.0)
+{
+ setupOptions();
+ setupDescription();
+
+ // Create new application instance
+ mInstance = u_application_instance_new_from_description_with_options(mDesc, mOptions);
+
+ if (mInstance == nullptr)
+ qFatal("QMirClientClientIntegration: connection to Mir server failed. Check that a Mir server is\n"
+ "running, and the correct socket is being used and is accessible. The shell may have\n"
+ "rejected the incoming connection, so check its log file");
+
+ // Create default screen.
+ mScreen = new QMirClientScreen(u_application_instance_get_mir_connection(mInstance));
+ screenAdded(mScreen);
+
+ // Initialize input.
+ if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_INPUT")) {
+ mInput = new QMirClientInput(this);
+ mInputContext = QPlatformInputContextFactory::create();
+ } else {
+ mInput = nullptr;
+ mInputContext = nullptr;
+ }
+
+ // compute the scale factor
+ const int defaultGridUnit = 8;
+ int gridUnit = defaultGridUnit;
+ QByteArray gridUnitString = qgetenv("GRID_UNIT_PX");
+ if (!gridUnitString.isEmpty()) {
+ bool ok;
+ gridUnit = gridUnitString.toInt(&ok);
+ if (!ok) {
+ gridUnit = defaultGridUnit;
+ }
+ }
+ mScaleFactor = static_cast<qreal>(gridUnit) / defaultGridUnit;
+}
+
+QMirClientClientIntegration::~QMirClientClientIntegration()
+{
+ delete mInput;
+ delete mInputContext;
+ delete mScreen;
+ delete mServices;
+}
+
+QPlatformServices *QMirClientClientIntegration::services() const
+{
+ return mServices;
+}
+
+void QMirClientClientIntegration::setupOptions()
+{
+ QStringList args = QCoreApplication::arguments();
+ int argc = args.size() + 1;
+ char **argv = new char*[argc];
+ for (int i = 0; i < argc - 1; i++)
+ argv[i] = qstrdup(args.at(i).toLocal8Bit());
+ argv[argc - 1] = nullptr;
+
+ mOptions = u_application_options_new_from_cmd_line(argc - 1, argv);
+
+ for (int i = 0; i < argc; i++)
+ delete [] argv[i];
+ delete [] argv;
+}
+
+void QMirClientClientIntegration::setupDescription()
+{
+ mDesc = u_application_description_new();
+ UApplicationId* id = u_application_id_new_from_stringn("QtUbuntu", 8);
+ u_application_description_set_application_id(mDesc, id);
+
+ UApplicationLifecycleDelegate* delegate = u_application_lifecycle_delegate_new();
+ u_application_lifecycle_delegate_set_application_resumed_cb(delegate, &resumedCallback);
+ u_application_lifecycle_delegate_set_application_about_to_stop_cb(delegate, &aboutToStopCallback);
+ u_application_lifecycle_delegate_set_context(delegate, this);
+ u_application_description_set_application_lifecycle_delegate(mDesc, delegate);
+}
+
+QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const
+{
+ return const_cast<QMirClientClientIntegration*>(this)->createPlatformWindow(window);
+}
+
+QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window)
+{
+ QPlatformWindow* platformWindow = new QMirClientWindow(
+ window, mClipboard, static_cast<QMirClientScreen*>(mScreen), mInput, u_application_instance_get_mir_connection(mInstance));
+ platformWindow->requestActivateWindow();
+ return platformWindow;
+}
+
+bool QMirClientClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps:
+ return true;
+ break;
+
+ case OpenGL:
+ return true;
+ break;
+
+ case ThreadedOpenGL:
+ if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) {
+ return true;
+ } else {
+ DLOG("ubuntumirclient: disabled threaded OpenGL");
+ return false;
+ }
+ break;
+
+ default:
+ return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QAbstractEventDispatcher *QMirClientClientIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
+QPlatformBackingStore* QMirClientClientIntegration::createPlatformBackingStore(QWindow* window) const
+{
+ return new QMirClientBackingStore(window);
+}
+
+QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext(
+ QOpenGLContext* context) const
+{
+ return const_cast<QMirClientClientIntegration*>(this)->createPlatformOpenGLContext(context);
+}
+
+QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext(
+ QOpenGLContext* context)
+{
+ return new QMirClientOpenGLContext(static_cast<QMirClientScreen*>(context->screen()->handle()),
+ static_cast<QMirClientOpenGLContext*>(context->shareHandle()));
+}
+
+QStringList QMirClientClientIntegration::themeNames() const
+{
+ return QStringList(QMirClientTheme::name);
+}
+
+QPlatformTheme* QMirClientClientIntegration::createPlatformTheme(const QString& name) const
+{
+ Q_UNUSED(name);
+ return new QMirClientTheme;
+}
+
+QVariant QMirClientClientIntegration::styleHint(StyleHint hint) const
+{
+ switch (hint) {
+ case QPlatformIntegration::StartDragDistance: {
+ // default is 10 pixels (see QPlatformTheme::defaultThemeHint)
+ return 10.0 * mScaleFactor;
+ }
+ case QPlatformIntegration::PasswordMaskDelay: {
+ // return time in milliseconds - 1 second
+ return QVariant(1000);
+ }
+ default:
+ break;
+ }
+ return QPlatformIntegration::styleHint(hint);
+}
+
+QPlatformClipboard* QMirClientClientIntegration::clipboard() const
+{
+ return mClipboard.data();
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.h b/src/plugins/platforms/mirclient/qmirclientintegration.h
new file mode 100644
index 0000000000..2960209691
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientintegration.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTINTEGRATION_H
+#define QMIRCLIENTINTEGRATION_H
+
+#include <qpa/qplatformintegration.h>
+#include <QSharedPointer>
+
+#include "qmirclientplatformservices.h"
+
+// platform-api
+#include <ubuntu/application/description.h>
+#include <ubuntu/application/instance.h>
+
+class QMirClientClipboard;
+class QMirClientInput;
+class QMirClientScreen;
+
+class QMirClientClientIntegration : public QPlatformIntegration {
+public:
+ QMirClientClientIntegration();
+ virtual ~QMirClientClientIntegration();
+
+ // QPlatformIntegration methods.
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
+ QAbstractEventDispatcher *createEventDispatcher() const override;
+ QPlatformNativeInterface* nativeInterface() const override { return mNativeInterface; }
+ QPlatformBackingStore* createPlatformBackingStore(QWindow* window) const override;
+ QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context) const override;
+ QPlatformFontDatabase* fontDatabase() const override { return mFontDb; }
+ QStringList themeNames() const override;
+ QPlatformTheme* createPlatformTheme(const QString& name) const override;
+ QVariant styleHint(StyleHint hint) const override;
+ QPlatformServices *services() const override;
+ QPlatformWindow* createPlatformWindow(QWindow* window) const override;
+ QPlatformInputContext* inputContext() const override { return mInputContext; }
+ QPlatformClipboard* clipboard() const override;
+
+ QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context);
+ QPlatformWindow* createPlatformWindow(QWindow* window);
+ QMirClientScreen* screen() const { return mScreen; }
+
+private:
+ void setupOptions();
+ void setupDescription();
+
+ QPlatformNativeInterface* mNativeInterface;
+ QPlatformFontDatabase* mFontDb;
+
+ QMirClientPlatformServices* mServices;
+
+ QMirClientScreen* mScreen;
+ QMirClientInput* mInput;
+ QPlatformInputContext* mInputContext;
+ QSharedPointer<QMirClientClipboard> mClipboard;
+ qreal mScaleFactor;
+
+ // Platform API stuff
+ UApplicationOptions* mOptions;
+ UApplicationDescription* mDesc;
+ UApplicationInstance* mInstance;
+};
+
+#endif // QMIRCLIENTINTEGRATION_H
diff --git a/src/plugins/platforms/mirclient/qmirclientlogging.h b/src/plugins/platforms/mirclient/qmirclientlogging.h
new file mode 100644
index 0000000000..80914d28b9
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientlogging.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTLOGGING_H
+#define QMIRCLIENTLOGGING_H
+
+// Logging and assertion macros.
+#define LOG(...) qDebug(__VA_ARGS__)
+#define LOG_IF(cond,...) do { if (cond) qDebug(__VA_ARGS__); } while (0)
+#define ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
+#define NOT_REACHED() qt_assert("Not reached!",__FILE__,__LINE__)
+
+// Logging and assertion macros are compiled out for release builds.
+#if !defined(QT_NO_DEBUG)
+#define DLOG(...) LOG(__VA_ARGS__)
+#define DLOG_IF(cond,...) LOG_IF((cond), __VA_ARGS__)
+#define DASSERT(cond) ASSERT((cond))
+#define DNOT_REACHED() NOT_REACHED()
+#else
+#define DLOG(...) qt_noop()
+#define DLOG_IF(cond,...) qt_noop()
+#define DASSERT(cond) qt_noop()
+#define DNOT_REACHED() qt_noop()
+#endif
+
+#endif // QMIRCLIENTLOGGING_H
diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp b/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
new file mode 100644
index 0000000000..a0bb932df3
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// Qt
+#include <private/qguiapplication_p.h>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qscreen.h>
+#include <QtCore/QMap>
+
+// Local
+#include "qmirclientnativeinterface.h"
+#include "qmirclientscreen.h"
+#include "qmirclientglcontext.h"
+
+class QMirClientResourceMap : public QMap<QByteArray, QMirClientNativeInterface::ResourceType>
+{
+public:
+ QMirClientResourceMap()
+ : QMap<QByteArray, QMirClientNativeInterface::ResourceType>() {
+ insert("egldisplay", QMirClientNativeInterface::EglDisplay);
+ insert("eglcontext", QMirClientNativeInterface::EglContext);
+ insert("nativeorientation", QMirClientNativeInterface::NativeOrientation);
+ insert("display", QMirClientNativeInterface::Display);
+ }
+};
+
+Q_GLOBAL_STATIC(QMirClientResourceMap, ubuntuResourceMap)
+
+QMirClientNativeInterface::QMirClientNativeInterface()
+ : mGenericEventFilterType(QByteArrayLiteral("Event"))
+ , mNativeOrientation(nullptr)
+{
+}
+
+QMirClientNativeInterface::~QMirClientNativeInterface()
+{
+ delete mNativeOrientation;
+ mNativeOrientation = nullptr;
+}
+
+void* QMirClientNativeInterface::nativeResourceForContext(
+ const QByteArray& resourceString, QOpenGLContext* context)
+{
+ if (!context)
+ return nullptr;
+
+ const QByteArray kLowerCaseResource = resourceString.toLower();
+
+ if (!ubuntuResourceMap()->contains(kLowerCaseResource))
+ return nullptr;
+
+ const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
+
+ if (kResourceType == QMirClientNativeInterface::EglContext)
+ return static_cast<QMirClientOpenGLContext*>(context->handle())->eglContext();
+ else
+ return nullptr;
+}
+
+void* QMirClientNativeInterface::nativeResourceForWindow(const QByteArray& resourceString, QWindow* window)
+{
+ const QByteArray kLowerCaseResource = resourceString.toLower();
+ if (!ubuntuResourceMap()->contains(kLowerCaseResource))
+ return NULL;
+ const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
+ if (kResourceType == QMirClientNativeInterface::EglDisplay) {
+ if (window) {
+ return static_cast<QMirClientScreen*>(window->screen()->handle())->eglDisplay();
+ } else {
+ return static_cast<QMirClientScreen*>(
+ QGuiApplication::primaryScreen()->handle())->eglDisplay();
+ }
+ } else if (kResourceType == QMirClientNativeInterface::NativeOrientation) {
+ // Return the device's native screen orientation.
+ if (window) {
+ QMirClientScreen *ubuntuScreen = static_cast<QMirClientScreen*>(window->screen()->handle());
+ mNativeOrientation = new Qt::ScreenOrientation(ubuntuScreen->nativeOrientation());
+ } else {
+ QPlatformScreen *platformScreen = QGuiApplication::primaryScreen()->handle();
+ mNativeOrientation = new Qt::ScreenOrientation(platformScreen->nativeOrientation());
+ }
+ return mNativeOrientation;
+ } else {
+ return NULL;
+ }
+}
+
+void* QMirClientNativeInterface::nativeResourceForScreen(const QByteArray& resourceString, QScreen* screen)
+{
+ const QByteArray kLowerCaseResource = resourceString.toLower();
+ if (!ubuntuResourceMap()->contains(kLowerCaseResource))
+ return NULL;
+ const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
+ if (kResourceType == QMirClientNativeInterface::Display) {
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ return static_cast<QMirClientScreen*>(screen->handle())->eglNativeDisplay();
+ } else
+ return NULL;
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h b/src/plugins/platforms/mirclient/qmirclientnativeinterface.h
new file mode 100644
index 0000000000..84f03bb915
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientnativeinterface.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTNATIVEINTERFACE_H
+#define QMIRCLIENTNATIVEINTERFACE_H
+
+#include <qpa/qplatformnativeinterface.h>
+
+class QMirClientNativeInterface : public QPlatformNativeInterface {
+public:
+ enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display };
+
+ QMirClientNativeInterface();
+ ~QMirClientNativeInterface();
+
+ // QPlatformNativeInterface methods.
+ void* nativeResourceForContext(const QByteArray& resourceString,
+ QOpenGLContext* context) override;
+ void* nativeResourceForWindow(const QByteArray& resourceString,
+ QWindow* window) override;
+ void* nativeResourceForScreen(const QByteArray& resourceString,
+ QScreen* screen) override;
+
+ // New methods.
+ const QByteArray& genericEventFilterType() const { return mGenericEventFilterType; }
+
+private:
+ const QByteArray mGenericEventFilterType;
+ Qt::ScreenOrientation* mNativeOrientation;
+};
+
+#endif // QMIRCLIENTNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h b/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h
new file mode 100644
index 0000000000..24d7307faa
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
+#define QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
+
+#include <QEvent>
+#include "qmirclientlogging.h"
+
+class OrientationChangeEvent : public QEvent {
+public:
+ enum Orientation {
+ Undefined = 0,
+ TopUp,
+ TopDown,
+ LeftUp,
+ RightUp,
+ FaceUp,
+ FaceDown
+ };
+
+ OrientationChangeEvent(QEvent::Type type, Orientation orientation)
+ : QEvent(type)
+ , mOrientation(orientation)
+ {
+ }
+
+ static const QEvent::Type mType;
+ Orientation mOrientation;
+};
+
+#endif // QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
diff --git a/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp b/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp
new file mode 100644
index 0000000000..d0260c79d3
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientplatformservices.h"
+
+#include <QUrl>
+
+#include <ubuntu/application/url_dispatcher/service.h>
+#include <ubuntu/application/url_dispatcher/session.h>
+
+bool QMirClientPlatformServices::openUrl(const QUrl &url)
+{
+ return callDispatcher(url);
+}
+
+bool QMirClientPlatformServices::openDocument(const QUrl &url)
+{
+ return callDispatcher(url);
+}
+
+bool QMirClientPlatformServices::callDispatcher(const QUrl &url)
+{
+ UAUrlDispatcherSession* session = ua_url_dispatcher_session();
+ if (!session)
+ return false;
+
+ ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL);
+
+ free(session);
+
+ // We are returning true here because the other option
+ // is spawning a nested event loop and wait for the
+ // callback. But there is no guarantee on how fast
+ // the callback is going to be so we prefer to avoid the
+ // nested event loop. Long term plan is improve Qt API
+ // to support an async openUrl
+ return true;
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientplatformservices.h b/src/plugins/platforms/mirclient/qmirclientplatformservices.h
new file mode 100644
index 0000000000..64a0432d06
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientplatformservices.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTPLATFORMSERVICES_H
+#define QMIRCLIENTPLATFORMSERVICES_H
+
+#include <qpa/qplatformservices.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+
+class QMirClientPlatformServices : public QPlatformServices {
+public:
+ bool openUrl(const QUrl &url) override;
+ bool openDocument(const QUrl &url) override;
+
+private:
+ bool callDispatcher(const QUrl &url);
+};
+
+#endif // QMIRCLIENTPLATFORMSERVICES_H
diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.cpp b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
new file mode 100644
index 0000000000..43d913f8d2
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientplugin.h"
+#include "qmirclientintegration.h"
+
+QStringList QMirClientIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "mirclient";
+ return list;
+}
+
+QPlatformIntegration* QMirClientIntegrationPlugin::create(const QString &system,
+ const QStringList &)
+{
+ if (system.toLower() == "mirclient") {
+#ifdef PLATFORM_API_TOUCH
+ setenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient", 1);
+#else
+ setenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient", 1);
+#endif
+ return new QMirClientClientIntegration;
+ } else {
+ return 0;
+ }
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.h b/src/plugins/platforms/mirclient/qmirclientplugin.h
new file mode 100644
index 0000000000..a6f1a1081a
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientplugin.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTPLUGIN_H
+#define QMIRCLIENTPLUGIN_H
+
+#include <qpa/qplatformintegrationplugin.h>
+
+class QMirClientIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "mirclient.json")
+
+public:
+ QStringList keys() const;
+ QPlatformIntegration* create(const QString&, const QStringList&);
+};
+
+#endif // QMIRCLIENTPLUGIN_H
diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.cpp b/src/plugins/platforms/mirclient/qmirclientscreen.cpp
new file mode 100644
index 0000000000..5c4b1cd0d6
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientscreen.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <mir_toolkit/mir_client_library.h>
+
+// Qt
+#include <QCoreApplication>
+#include <QtCore/qmath.h>
+#include <QScreen>
+#include <QThread>
+#include <qpa/qwindowsysteminterface.h>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+
+// local
+#include "qmirclientscreen.h"
+#include "qmirclientlogging.h"
+#include "qmirclientorientationchangeevent_p.h"
+
+#include "memory"
+
+static const int kSwapInterval = 1;
+
+#if !defined(QT_NO_DEBUG)
+
+static const char *orientationToStr(Qt::ScreenOrientation orientation) {
+ switch (orientation) {
+ case Qt::PrimaryOrientation:
+ return "primary";
+ case Qt::PortraitOrientation:
+ return "portrait";
+ case Qt::LandscapeOrientation:
+ return "landscape";
+ case Qt::InvertedPortraitOrientation:
+ return "inverted portrait";
+ case Qt::InvertedLandscapeOrientation:
+ return "inverted landscape";
+ default:
+ return "INVALID!";
+ }
+}
+
+static void printEglConfig(EGLDisplay display, EGLConfig config) {
+ DASSERT(display != EGL_NO_DISPLAY);
+ DASSERT(config != nullptr);
+ static const struct { const EGLint attrib; const char* name; } kAttribs[] = {
+ { EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
+ { EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
+ { EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
+ { EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
+ { EGL_RED_SIZE, "EGL_RED_SIZE" },
+ { EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
+ { EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
+ { EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
+ { EGL_CONFIG_ID, "EGL_CONFIG_ID" },
+ { EGL_LEVEL, "EGL_LEVEL" },
+ { EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
+ { EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
+ { EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
+ { EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
+ { EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
+ { EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
+ { EGL_SAMPLES, "EGL_SAMPLES" },
+ { EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
+ { EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
+ { EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
+ { EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
+ { EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
+ { EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
+ { EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
+ { EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
+ { EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
+ { EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
+ { -1, NULL }
+ };
+ const char* string = eglQueryString(display, EGL_VENDOR);
+ LOG("EGL vendor: %s", string);
+ string = eglQueryString(display, EGL_VERSION);
+ LOG("EGL version: %s", string);
+ string = eglQueryString(display, EGL_EXTENSIONS);
+ LOG("EGL extensions: %s", string);
+ LOG("EGL configuration attibutes:");
+ for (int index = 0; kAttribs[index].attrib != -1; index++) {
+ EGLint value;
+ if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
+ LOG(" %s: %d", kAttribs[index].name, static_cast<int>(value));
+ }
+}
+#endif
+
+
+const QEvent::Type OrientationChangeEvent::mType =
+ static_cast<QEvent::Type>(QEvent::registerEventType());
+
+static const MirDisplayOutput *find_active_output(
+ const MirDisplayConfiguration *conf)
+{
+ const MirDisplayOutput *output = NULL;
+ for (uint32_t d = 0; d < conf->num_outputs; d++)
+ {
+ const MirDisplayOutput *out = conf->outputs + d;
+
+ if (out->used &&
+ out->connected &&
+ out->num_modes &&
+ out->current_mode < out->num_modes)
+ {
+ output = out;
+ break;
+ }
+ }
+
+ return output;
+}
+
+QMirClientScreen::QMirClientScreen(MirConnection *connection)
+ : mFormat(QImage::Format_RGB32)
+ , mDepth(32)
+ , mSurfaceFormat()
+ , mEglDisplay(EGL_NO_DISPLAY)
+ , mEglConfig(nullptr)
+{
+ // Initialize EGL.
+ ASSERT(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
+
+ mEglNativeDisplay = mir_connection_get_egl_native_display(connection);
+ ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
+ ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
+
+ // Configure EGL buffers format.
+ mSurfaceFormat.setRedBufferSize(8);
+ mSurfaceFormat.setGreenBufferSize(8);
+ mSurfaceFormat.setBlueBufferSize(8);
+ mSurfaceFormat.setAlphaBufferSize(8);
+ mSurfaceFormat.setDepthBufferSize(24);
+ mSurfaceFormat.setStencilBufferSize(8);
+ if (!qEnvironmentVariableIsEmpty("QTUBUNTU_MULTISAMPLE")) {
+ mSurfaceFormat.setSamples(4);
+ DLOG("ubuntumirclient: setting MSAA to 4 samples");
+ }
+#ifdef QTUBUNTU_USE_OPENGL
+ mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
+#else
+ mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
+#endif
+ mEglConfig = q_configFromGLFormat(mEglDisplay, mSurfaceFormat, true);
+
+ #if !defined(QT_NO_DEBUG)
+ printEglConfig(mEglDisplay, mEglConfig);
+ #endif
+
+ // Set vblank swap interval.
+ int swapInterval = kSwapInterval;
+ QByteArray swapIntervalString = qgetenv("QTUBUNTU_SWAPINTERVAL");
+ if (!swapIntervalString.isEmpty()) {
+ bool ok;
+ swapInterval = swapIntervalString.toInt(&ok);
+ if (!ok)
+ swapInterval = kSwapInterval;
+ }
+ DLOG("ubuntumirclient: setting swap interval to %d", swapInterval);
+ eglSwapInterval(mEglDisplay, swapInterval);
+
+ // Get screen resolution.
+ auto configDeleter = [](MirDisplayConfiguration *config) { mir_display_config_destroy(config); };
+ using configUp = std::unique_ptr<MirDisplayConfiguration, decltype(configDeleter)>;
+ configUp displayConfig(mir_connection_create_display_config(connection), configDeleter);
+ ASSERT(displayConfig != nullptr);
+
+ auto const displayOutput = find_active_output(displayConfig.get());
+ ASSERT(displayOutput != nullptr);
+
+ const MirDisplayMode *mode = &displayOutput->modes[displayOutput->current_mode];
+ const int kScreenWidth = mode->horizontal_resolution;
+ const int kScreenHeight = mode->vertical_resolution;
+ DASSERT(kScreenWidth > 0 && kScreenHeight > 0);
+
+ DLOG("ubuntumirclient: screen resolution: %dx%d", kScreenWidth, kScreenHeight);
+
+ mGeometry = QRect(0, 0, kScreenWidth, kScreenHeight);
+
+ DLOG("QQMirClientScreen::QQMirClientScreen (this=%p)", this);
+
+ // Set the default orientation based on the initial screen dimmensions.
+ mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+
+ // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait
+ mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+}
+
+QMirClientScreen::~QMirClientScreen()
+{
+ eglTerminate(mEglDisplay);
+}
+
+void QMirClientScreen::customEvent(QEvent* event) {
+ DASSERT(QThread::currentThread() == thread());
+
+ OrientationChangeEvent* oReadingEvent = static_cast<OrientationChangeEvent*>(event);
+ switch (oReadingEvent->mOrientation) {
+ case OrientationChangeEvent::LeftUp: {
+ mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
+ Qt::InvertedPortraitOrientation : Qt::LandscapeOrientation;
+ break;
+ }
+ case OrientationChangeEvent::TopUp: {
+ mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
+ Qt::LandscapeOrientation : Qt::PortraitOrientation;
+ break;
+ }
+ case OrientationChangeEvent::RightUp: {
+ mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
+ Qt::PortraitOrientation : Qt::InvertedLandscapeOrientation;
+ break;
+ }
+ case OrientationChangeEvent::TopDown: {
+ mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
+ Qt::InvertedLandscapeOrientation : Qt::InvertedPortraitOrientation;
+ break;
+ }
+ default: {
+ DLOG("QMirClientScreen::customEvent - Unknown orientation.");
+ return;
+ }
+ }
+
+ // Raise the event signal so that client apps know the orientation changed
+ DLOG("QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
+ QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
+}
+
+void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeight)
+{
+ if ((windowWidth > windowHeight && mGeometry.width() < mGeometry.height())
+ || (windowWidth < windowHeight && mGeometry.width() > mGeometry.height())) {
+
+ // The window aspect ratio differ's from the screen one. This means that
+ // unity8 has rotated the window in its scene.
+ // As there's no way to express window rotation in Qt's API, we have
+ // Flip QScreen's dimensions so that orientation properties match
+ // (primaryOrientation particularly).
+ // FIXME: This assumes a phone scenario. Won't work, or make sense,
+ // on the desktop
+
+ QRect currGeometry = mGeometry;
+ mGeometry.setWidth(currGeometry.height());
+ mGeometry.setHeight(currGeometry.width());
+
+ DLOG("QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
+ mGeometry.width(), mGeometry.height());
+ QWindowSystemInterface::handleScreenGeometryChange(screen(),
+ mGeometry /* newGeometry */,
+ mGeometry /* newAvailableGeometry */);
+
+ if (mGeometry.width() < mGeometry.height()) {
+ mCurrentOrientation = Qt::PortraitOrientation;
+ } else {
+ mCurrentOrientation = Qt::LandscapeOrientation;
+ }
+ DLOG("QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
+ QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
+ }
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.h b/src/plugins/platforms/mirclient/qmirclientscreen.h
new file mode 100644
index 0000000000..5d9325354f
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientscreen.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTSCREEN_H
+#define QMIRCLIENTSCREEN_H
+
+#include <qpa/qplatformscreen.h>
+#include <QSurfaceFormat>
+#include <EGL/egl.h>
+
+struct MirConnection;
+
+class QMirClientScreen : public QObject, public QPlatformScreen
+{
+ Q_OBJECT
+public:
+ QMirClientScreen(MirConnection *connection);
+ virtual ~QMirClientScreen();
+
+ // QPlatformScreen methods.
+ QImage::Format format() const override { return mFormat; }
+ int depth() const override { return mDepth; }
+ QRect geometry() const override { return mGeometry; }
+ QRect availableGeometry() const override { return mGeometry; }
+ Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; }
+ Qt::ScreenOrientation orientation() const override { return mNativeOrientation; }
+
+ // New methods.
+ QSurfaceFormat surfaceFormat() const { return mSurfaceFormat; }
+ EGLDisplay eglDisplay() const { return mEglDisplay; }
+ EGLConfig eglConfig() const { return mEglConfig; }
+ EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }
+ void handleWindowSurfaceResize(int width, int height);
+
+ // QObject methods.
+ void customEvent(QEvent* event);
+
+private:
+ QRect mGeometry;
+ Qt::ScreenOrientation mNativeOrientation;
+ Qt::ScreenOrientation mCurrentOrientation;
+ QImage::Format mFormat;
+ int mDepth;
+ QSurfaceFormat mSurfaceFormat;
+ EGLDisplay mEglDisplay;
+ EGLConfig mEglConfig;
+ EGLNativeDisplayType mEglNativeDisplay;
+};
+
+#endif // QMIRCLIENTSCREEN_H
diff --git a/src/plugins/platforms/mirclient/qmirclienttheme.cpp b/src/plugins/platforms/mirclient/qmirclienttheme.cpp
new file mode 100644
index 0000000000..c15da23945
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclienttheme.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclienttheme.h"
+
+#include <QtCore/QVariant>
+
+const char *QMirClientTheme::name = "ubuntu";
+
+QMirClientTheme::QMirClientTheme()
+{
+}
+
+QMirClientTheme::~QMirClientTheme()
+{
+}
+
+QVariant QMirClientTheme::themeHint(ThemeHint hint) const
+{
+ if (hint == QPlatformTheme::SystemIconThemeName) {
+ QByteArray iconTheme = qgetenv("QTUBUNTU_ICON_THEME");
+ if (iconTheme.isEmpty()) {
+ return QVariant(QStringLiteral("ubuntu-mobile"));
+ } else {
+ return QVariant(QString(iconTheme));
+ }
+ } else {
+ return QGenericUnixTheme::themeHint(hint);
+ }
+}
diff --git a/src/plugins/platforms/mirclient/qmirclienttheme.h b/src/plugins/platforms/mirclient/qmirclienttheme.h
new file mode 100644
index 0000000000..8f330395a0
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclienttheme.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTTHEME_H
+#define QMIRCLIENTTHEME_H
+
+#include <QtPlatformSupport/private/qgenericunixthemes_p.h>
+
+class QMirClientTheme : public QGenericUnixTheme
+{
+public:
+ static const char* name;
+ QMirClientTheme();
+ virtual ~QMirClientTheme();
+
+ // From QPlatformTheme
+ QVariant themeHint(ThemeHint hint) const override;
+};
+
+#endif // QMIRCLIENTTHEME_H
diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.cpp b/src/plugins/platforms/mirclient/qmirclientwindow.cpp
new file mode 100644
index 0000000000..f3fd1e756d
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientwindow.cpp
@@ -0,0 +1,452 @@
+/****************************************************************************
+**
+** Copyright (C) 2014-2015 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// Local
+#include "qmirclientclipboard.h"
+#include "qmirclientinput.h"
+#include "qmirclientwindow.h"
+#include "qmirclientscreen.h"
+#include "qmirclientlogging.h"
+
+// Qt
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <QMutex>
+#include <QMutexLocker>
+#include <QSize>
+#include <QtMath>
+
+// Platform API
+#include <ubuntu/application/instance.h>
+
+#include <EGL/egl.h>
+
+#define IS_OPAQUE_FLAG 1
+
+namespace
+{
+MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)
+{
+ switch (state) {
+ case Qt::WindowNoState:
+ return mir_surface_state_restored;
+
+ case Qt::WindowFullScreen:
+ return mir_surface_state_fullscreen;
+
+ case Qt::WindowMaximized:
+ return mir_surface_state_maximized;
+
+ case Qt::WindowMinimized:
+ return mir_surface_state_minimized;
+
+ default:
+ LOG("Unexpected Qt::WindowState: %d", state);
+ return mir_surface_state_restored;
+ }
+}
+
+#if !defined(QT_NO_DEBUG)
+const char *qtWindowStateToStr(Qt::WindowState state)
+{
+ switch (state) {
+ case Qt::WindowNoState:
+ return "NoState";
+
+ case Qt::WindowFullScreen:
+ return "FullScreen";
+
+ case Qt::WindowMaximized:
+ return "Maximized";
+
+ case Qt::WindowMinimized:
+ return "Minimized";
+
+ default:
+ return "!?";
+ }
+}
+#endif
+
+} // anonymous namespace
+
+class QMirClientWindowPrivate
+{
+public:
+ void createEGLSurface(EGLNativeWindowType nativeWindow);
+ void destroyEGLSurface();
+ int panelHeight();
+
+ QMirClientScreen* screen;
+ EGLSurface eglSurface;
+ WId id;
+ QMirClientInput* input;
+ Qt::WindowState state;
+ MirConnection *connection;
+ MirSurface* surface;
+ QSize bufferSize;
+ QMutex mutex;
+ QSharedPointer<QMirClientClipboard> clipboard;
+};
+
+static void eventCallback(MirSurface* surface, const MirEvent *event, void* context)
+{
+ (void) surface;
+ DASSERT(context != NULL);
+ QMirClientWindow* platformWindow = static_cast<QMirClientWindow*>(context);
+ platformWindow->priv()->input->postEvent(platformWindow, event);
+}
+
+static void surfaceCreateCallback(MirSurface* surface, void* context)
+{
+ DASSERT(context != NULL);
+ QMirClientWindow* platformWindow = static_cast<QMirClientWindow*>(context);
+ platformWindow->priv()->surface = surface;
+
+ mir_surface_set_event_handler(surface, eventCallback, context);
+}
+
+QMirClientWindow::QMirClientWindow(QWindow* w, QSharedPointer<QMirClientClipboard> clipboard, QMirClientScreen* screen,
+ QMirClientInput* input, MirConnection* connection)
+ : QObject(nullptr), QPlatformWindow(w)
+{
+ DASSERT(screen != NULL);
+
+ d = new QMirClientWindowPrivate;
+ d->screen = screen;
+ d->eglSurface = EGL_NO_SURFACE;
+ d->input = input;
+ d->state = window()->windowState();
+ d->connection = connection;
+ d->clipboard = clipboard;
+
+ static int id = 1;
+ d->id = id++;
+
+ // Use client geometry if set explicitly, use available screen geometry otherwise.
+ QPlatformWindow::setGeometry(window()->geometry() != screen->geometry() ?
+ window()->geometry() : screen->availableGeometry());
+ createWindow();
+ DLOG("QMirClientWindow::QMirClientWindow (this=%p, w=%p, screen=%p, input=%p)", this, w, screen, input);
+}
+
+QMirClientWindow::~QMirClientWindow()
+{
+ DLOG("QMirClientWindow::~QMirClientWindow");
+ d->destroyEGLSurface();
+
+ mir_surface_release_sync(d->surface);
+
+ delete d;
+}
+
+void QMirClientWindowPrivate::createEGLSurface(EGLNativeWindowType nativeWindow)
+{
+ DLOG("QMirClientWindowPrivate::createEGLSurface (this=%p, nativeWindow=%p)",
+ this, reinterpret_cast<void*>(nativeWindow));
+
+ eglSurface = eglCreateWindowSurface(screen->eglDisplay(), screen->eglConfig(),
+ nativeWindow, nullptr);
+
+ DASSERT(eglSurface != EGL_NO_SURFACE);
+}
+
+void QMirClientWindowPrivate::destroyEGLSurface()
+{
+ DLOG("QMirClientWindowPrivate::destroyEGLSurface (this=%p)", this);
+ if (eglSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(screen->eglDisplay(), eglSurface);
+ eglSurface = EGL_NO_SURFACE;
+ }
+}
+
+// FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633
+// we need to guess the panel height (3GU + 2DP)
+int QMirClientWindowPrivate::panelHeight()
+{
+ const int defaultGridUnit = 8;
+ int gridUnit = defaultGridUnit;
+ QByteArray gridUnitString = qgetenv("GRID_UNIT_PX");
+ if (!gridUnitString.isEmpty()) {
+ bool ok;
+ gridUnit = gridUnitString.toInt(&ok);
+ if (!ok) {
+ gridUnit = defaultGridUnit;
+ }
+ }
+ qreal densityPixelRatio = static_cast<qreal>(gridUnit) / defaultGridUnit;
+ return gridUnit * 3 + qFloor(densityPixelRatio) * 2;
+}
+
+namespace
+{
+static MirPixelFormat
+mir_choose_default_pixel_format(MirConnection *connection)
+{
+ MirPixelFormat format[mir_pixel_formats];
+ unsigned int nformats;
+
+ mir_connection_get_available_surface_formats(connection,
+ format, mir_pixel_formats, &nformats);
+
+ return format[0];
+}
+}
+
+void QMirClientWindow::createWindow()
+{
+ DLOG("QMirClientWindow::createWindow (this=%p)", this);
+
+ // FIXME: remove this remnant of an old platform-api enum - needs ubuntu-keyboard update
+ const int SCREEN_KEYBOARD_ROLE = 7;
+ // Get surface role and flags.
+ QVariant roleVariant = window()->property("role");
+ int role = roleVariant.isValid() ? roleVariant.toUInt() : 1; // 1 is the default role for apps.
+ QVariant opaqueVariant = window()->property("opaque");
+ uint flags = opaqueVariant.isValid() ?
+ opaqueVariant.toUInt() ? static_cast<uint>(IS_OPAQUE_FLAG) : 0 : 0;
+
+ // FIXME(loicm) Opaque flag is forced for now for non-system sessions (applications) for
+ // performance reasons.
+ flags |= static_cast<uint>(IS_OPAQUE_FLAG);
+
+ const QByteArray title = (!window()->title().isNull()) ? window()->title().toUtf8() : "Window 1"; // legacy title
+ const int panelHeight = d->panelHeight();
+
+#if !defined(QT_NO_DEBUG)
+ LOG("panelHeight: '%d'", panelHeight);
+ LOG("role: '%d'", role);
+ LOG("flags: '%s'", (flags & static_cast<uint>(1)) ? "Opaque" : "NotOpaque");
+ LOG("title: '%s'", title.constData());
+#endif
+
+ // Get surface geometry.
+ QRect geometry;
+ if (d->state == Qt::WindowFullScreen) {
+ printf("QMirClientWindow - fullscreen geometry\n");
+ geometry = screen()->geometry();
+ } else if (d->state == Qt::WindowMaximized) {
+ printf("QMirClientWindow - maximized geometry\n");
+ geometry = screen()->availableGeometry();
+ /*
+ * FIXME: Autopilot relies on being able to convert coordinates relative of the window
+ * into absolute screen coordinates. Mir does not allow this, see bug lp:1346633
+ * Until there's a correct way to perform this transformation agreed, this horrible hack
+ * guesses the transformation heuristically.
+ *
+ * Assumption: this method only used on phone devices!
+ */
+ geometry.setY(panelHeight);
+ } else {
+ printf("QMirClientWindow - regular geometry\n");
+ geometry = this->geometry();
+ geometry.setY(panelHeight);
+ }
+
+ DLOG("[ubuntumirclient QPA] creating surface at (%d, %d) with size (%d, %d) with title '%s'\n",
+ geometry.x(), geometry.y(), geometry.width(), geometry.height(), title.data());
+
+ MirSurfaceSpec *spec;
+ if (role == SCREEN_KEYBOARD_ROLE)
+ {
+ spec = mir_connection_create_spec_for_input_method(d->connection, geometry.width(),
+ geometry.height(), mir_choose_default_pixel_format(d->connection));
+ }
+ else
+ {
+ spec = mir_connection_create_spec_for_normal_surface(d->connection, geometry.width(),
+ geometry.height(), mir_choose_default_pixel_format(d->connection));
+ }
+ mir_surface_spec_set_name(spec, title.data());
+
+ // Create platform window
+ mir_wait_for(mir_surface_create(spec, surfaceCreateCallback, this));
+ mir_surface_spec_release(spec);
+
+ DASSERT(d->surface != NULL);
+ d->createEGLSurface((EGLNativeWindowType)mir_buffer_stream_get_egl_native_window(mir_surface_get_buffer_stream(d->surface)));
+
+ if (d->state == Qt::WindowFullScreen) {
+ // TODO: We could set this on creation once surface spec supports it (mps already up)
+ mir_wait_for(mir_surface_set_state(d->surface, mir_surface_state_fullscreen));
+ }
+
+ // Window manager can give us a final size different from what we asked for
+ // so let's check what we ended up getting
+ {
+ MirSurfaceParameters parameters;
+ mir_surface_get_parameters(d->surface, &parameters);
+
+ geometry.setWidth(parameters.width);
+ geometry.setHeight(parameters.height);
+ }
+
+ DLOG("[ubuntumirclient QPA] created surface has size (%d, %d)",
+ geometry.width(), geometry.height());
+
+ // Assume that the buffer size matches the surface size at creation time
+ d->bufferSize = geometry.size();
+
+ // Tell Qt about the geometry.
+ QWindowSystemInterface::handleGeometryChange(window(), geometry);
+ QPlatformWindow::setGeometry(geometry);
+}
+
+void QMirClientWindow::moveResize(const QRect& rect)
+{
+ (void) rect;
+ // TODO: Not yet supported by mir.
+}
+
+void QMirClientWindow::handleSurfaceResize(int width, int height)
+{
+ QMutexLocker(&d->mutex);
+ LOG("QMirClientWindow::handleSurfaceResize(width=%d, height=%d)", width, height);
+
+ // The current buffer size hasn't actually changed. so just render on it and swap
+ // buffers in the hope that the next buffer will match the surface size advertised
+ // in this event.
+ // But since this event is processed by a thread different from the one that swaps
+ // buffers, you can never know if this information is already outdated as there's
+ // no synchronicity whatsoever between the processing of resize events and the
+ // consumption of buffers.
+ if (d->bufferSize.width() != width || d->bufferSize.height() != height) {
+ QWindowSystemInterface::handleExposeEvent(window(), geometry());
+ QWindowSystemInterface::flushWindowSystemEvents();
+ }
+}
+
+void QMirClientWindow::handleSurfaceFocusChange(bool focused)
+{
+ LOG("QMirClientWindow::handleSurfaceFocusChange(focused=%s)", focused ? "true" : "false");
+ QWindow *activatedWindow = focused ? window() : nullptr;
+
+ // System clipboard contents might have changed while this window was unfocused and wihtout
+ // this process getting notified about it because it might have been suspended (due to
+ // application lifecycle policies), thus unable to listen to any changes notified through
+ // D-Bus.
+ // Therefore let's ensure we are up to date with the system clipboard now that we are getting
+ // focused again.
+ if (focused) {
+ d->clipboard->requestDBusClipboardContents();
+ }
+
+ QWindowSystemInterface::handleWindowActivated(activatedWindow, Qt::ActiveWindowFocusReason);
+}
+
+void QMirClientWindow::setWindowState(Qt::WindowState state)
+{
+ QMutexLocker(&d->mutex);
+ DLOG("QMirClientWindow::setWindowState (this=%p, %s)", this, qtWindowStateToStr(state));
+
+ if (state == d->state)
+ return;
+
+ // TODO: Perhaps we should check if the states are applied?
+ mir_wait_for(mir_surface_set_state(d->surface, qtWindowStateToMirSurfaceState(state)));
+ d->state = state;
+}
+
+void QMirClientWindow::setGeometry(const QRect& rect)
+{
+ DLOG("QMirClientWindow::setGeometry (this=%p)", this);
+
+ bool doMoveResize;
+
+ {
+ QMutexLocker(&d->mutex);
+ QPlatformWindow::setGeometry(rect);
+ doMoveResize = d->state != Qt::WindowFullScreen && d->state != Qt::WindowMaximized;
+ }
+
+ if (doMoveResize) {
+ moveResize(rect);
+ }
+}
+
+void QMirClientWindow::setVisible(bool visible)
+{
+ QMutexLocker(&d->mutex);
+ DLOG("QMirClientWindow::setVisible (this=%p, visible=%s)", this, visible ? "true" : "false");
+
+ if (visible) {
+ mir_wait_for(mir_surface_set_state(d->surface, qtWindowStateToMirSurfaceState(d->state)));
+
+ QWindowSystemInterface::handleExposeEvent(window(), QRect());
+ QWindowSystemInterface::flushWindowSystemEvents();
+ } else {
+ // TODO: Use the new mir_surface_state_hidden state instead of mir_surface_state_minimized.
+ // Will have to change qtmir and unity8 for that.
+ mir_wait_for(mir_surface_set_state(d->surface, mir_surface_state_minimized));
+ }
+}
+
+void* QMirClientWindow::eglSurface() const
+{
+ return d->eglSurface;
+}
+
+WId QMirClientWindow::winId() const
+{
+ return d->id;
+}
+
+void QMirClientWindow::onBuffersSwapped_threadSafe(int newBufferWidth, int newBufferHeight)
+{
+ QMutexLocker(&d->mutex);
+
+ bool sizeKnown = newBufferWidth > 0 && newBufferHeight > 0;
+
+ if (sizeKnown && (d->bufferSize.width() != newBufferWidth ||
+ d->bufferSize.height() != newBufferHeight)) {
+
+ DLOG("QMirClientWindow::onBuffersSwapped_threadSafe - buffer size changed from (%d,%d) to (%d,%d)",
+ d->bufferSize.width(), d->bufferSize.height(), newBufferWidth, newBufferHeight);
+
+ d->bufferSize.rwidth() = newBufferWidth;
+ d->bufferSize.rheight() = newBufferHeight;
+
+ QRect newGeometry;
+
+ newGeometry = geometry();
+ newGeometry.setWidth(d->bufferSize.width());
+ newGeometry.setHeight(d->bufferSize.height());
+
+ QPlatformWindow::setGeometry(newGeometry);
+ QWindowSystemInterface::handleGeometryChange(window(), newGeometry, QRect());
+ }
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.h b/src/plugins/platforms/mirclient/qmirclientwindow.h
new file mode 100644
index 0000000000..f342669544
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientwindow.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014-2015 Canonical, Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTWINDOW_H
+#define QMIRCLIENTWINDOW_H
+
+#include <qpa/qplatformwindow.h>
+#include <QSharedPointer>
+
+#include <mir_toolkit/mir_client_library.h>
+
+class QMirClientClipboard;
+class QMirClientInput;
+class QMirClientScreen;
+class QMirClientWindowPrivate;
+
+class QMirClientWindow : public QObject, public QPlatformWindow
+{
+ Q_OBJECT
+public:
+ QMirClientWindow(QWindow *w, QSharedPointer<QMirClientClipboard> clipboard, QMirClientScreen *screen,
+ QMirClientInput *input, MirConnection *mir_connection);
+ virtual ~QMirClientWindow();
+
+ // QPlatformWindow methods.
+ WId winId() const override;
+ void setGeometry(const QRect&) override;
+ void setWindowState(Qt::WindowState state) override;
+ void setVisible(bool visible) override;
+
+ // New methods.
+ void* eglSurface() const;
+ void handleSurfaceResize(int width, int height);
+ void handleSurfaceFocusChange(bool focused);
+ void onBuffersSwapped_threadSafe(int newBufferWidth, int newBufferHeight);
+
+ QMirClientWindowPrivate* priv() { return d; }
+
+private:
+ void createWindow();
+ void moveResize(const QRect& rect);
+
+ QMirClientWindowPrivate *d;
+};
+
+#endif // QMIRCLIENTWINDOW_H
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 22d443733e..43bb04e318 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -40,3 +40,5 @@ contains(QT_CONFIG, linuxfb): SUBDIRS += linuxfb
haiku {
SUBDIRS += haiku
}
+
+contains(QT_CONFIG, mirclient): SUBDIRS += mirclient
diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
index e5c853dad8..04e264860e 100644
--- a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
+++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
@@ -124,4 +124,25 @@ void QQnxAbstractVirtualKeyboard::setLocale(const QLocale &locale)
emit localeChanged(locale);
}
+QQnxAbstractVirtualKeyboard::EnterKeyType
+ QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(Qt::EnterKeyType type)
+{
+ switch (type) {
+ case Qt::EnterKeyDone:
+ return Done;
+ case Qt::EnterKeyGo:
+ return Go;
+ case Qt::EnterKeyNext:
+ return Next;
+ case Qt::EnterKeySearch:
+ return Search;
+ case Qt::EnterKeySend:
+ return Send;
+ case Qt::EnterKeyDefault:
+ case Qt::EnterKeyReturn:
+ case Qt::EnterKeyPrevious: // unsupported
+ return DefaultReturn;
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
index 8bf8313000..2fa2ed7291 100644
--- a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
+++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
@@ -74,6 +74,8 @@ public:
KeyboardMode keyboardMode() const { return m_keyboardMode; }
EnterKeyType enterKeyType() const { return m_enterKeyType; }
+ static EnterKeyType qtEnterKeyTypeToQnx(Qt::EnterKeyType type);
+
Q_SIGNALS:
void heightChanged(int height);
void visibilityChanged(bool visible);
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
index 3506de4bc0..ed0db82685 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
@@ -1384,13 +1384,17 @@ void QQnxInputContext::setFocusObject(QObject *object)
if (hasSession())
dispatchFocusLossEvent();
} else {
- QInputMethodQueryEvent query(Qt::ImHints);
+ QInputMethodQueryEvent query(Qt::ImHints | Qt::ImEnterKeyType);
QCoreApplication::sendEvent(object, &query);
int inputHints = query.value(Qt::ImHints).toInt();
+ Qt::EnterKeyType qtEnterKeyType = Qt::EnterKeyType(query.value(Qt::ImEnterKeyType).toInt());
dispatchFocusGainEvent(inputHints);
m_virtualKeyboard.setInputHints(inputHints);
+ m_virtualKeyboard.setEnterKeyType(
+ QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(qtEnterKeyType)
+ );
if (!m_inputPanelVisible)
showInputPanel();
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
index 91ecffa2aa..3860cdf0db 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
@@ -172,11 +172,15 @@ void QQnxInputContext::setFocusObject(QObject *object)
if (m_inputPanelVisible)
hideInputPanel();
} else {
- QInputMethodQueryEvent query(Qt::ImHints);
+ QInputMethodQueryEvent query(Qt::ImHints | Qt::ImEnterKeyType);
QCoreApplication::sendEvent(object, &query);
int inputHints = query.value(Qt::ImHints).toInt();
+ Qt::EnterKeyType qtEnterKeyType = Qt::EnterKeyType(query.value(Qt::ImEnterKeyType).toInt());
m_virtualKeyboard.setInputHints(inputHints);
+ m_virtualKeyboard.setEnterKeyType(
+ QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(qtEnterKeyType)
+ );
if (!m_inputPanelVisible)
showInputPanel();
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 071bab7920..1c825dbbdd 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -95,7 +95,6 @@
#include <private/qsimpledrag_p.h>
#include <QtCore/QDebug>
-#include <QtCore/QHash>
#include <errno.h>
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index 23607523bd..b00c9df408 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -17,6 +17,31 @@
"features": [
"disable_desktopgl"
]
- }
+ },
+ {
+ "id": 2,
+ "description": "Intel Q965/Q963 - GMA 3000 has insufficient support of opengl and directx",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x2992" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl",
+ "disable_angle"
+ ]
+ },
+ {
+ "id": 3,
+ "description": "No OpenGL on Intel G33/G31 (QTBUG-47522)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x29C2" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl"
+ ]
+ }
]
}
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 16c278d9df..3f19e4401a 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -35,10 +35,10 @@
#include "qwindowswindow.h"
#include "qwindowsnativeimage.h"
#include "qwindowscontext.h"
-#include "qwindowsscaling.h"
#include <QtGui/QWindow>
#include <QtGui/QPainter>
+#include <private/qhighdpiscaling_p.h>
#include <QtCore/QDebug>
@@ -68,10 +68,12 @@ QPaintDevice *QWindowsBackingStore::paintDevice()
return &m_image->image();
}
-void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoint &offset)
+void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
+ const QPoint &offset)
{
Q_ASSERT(window);
+ const QRect br = region.boundingRect();
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << offset << br;
QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window);
@@ -81,9 +83,8 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin
const Qt::WindowFlags flags = window->flags();
if ((flags & Qt::FramelessWindowHint) && QWindowsWindow::setWindowLayered(rw->handle(), flags, hasAlpha, rw->opacity()) && hasAlpha) {
// Windows with alpha: Use blend function to update.
- const QMargins marginsDP = rw->frameMarginsDp();
- const QRect r = rw->geometryDp() + marginsDP;
- const QPoint frameOffset(marginsDP.left(), marginsDP.top());
+ QRect r = QHighDpi::toNativePixels(window->frameGeometry(), window);
+ QPoint frameOffset(QHighDpi::toNativePixels(QPoint(window->frameMargins().left(), window->frameMargins().top()), window));
QRect dirtyRect = br.translated(offset + frameOffset);
SIZE size = {r.width(), r.height()};
@@ -127,15 +128,14 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin
}
}
-void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion &regionDip)
+void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
{
- const QSize size = sizeDip * QWindowsScaling::factor();
if (m_image.isNull() || m_image->image().size() != size) {
#ifndef QT_NO_DEBUG_OUTPUT
if (QWindowsContext::verbose && lcQpaBackingStore().isDebugEnabled()) {
qCDebug(lcQpaBackingStore)
- << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << sizeDip << ' '
- << regionDip << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
+ << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << region
+ << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
}
#endif
const QImage::Format format = window()->format().hasAlpha() ?
@@ -144,10 +144,10 @@ void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion &regionDip
QWindowsNativeImage *oldwni = m_image.data();
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);
- if (oldwni && !regionDip.isEmpty()) {
+ if (oldwni && !region.isEmpty()) {
const QImage &oldimg(oldwni->image());
QImage &newimg(newwni->image());
- QRegion staticRegion = QWindowsScaling::mapToNative(regionDip);
+ QRegion staticRegion(region);
staticRegion &= QRect(0, 0, oldimg.width(), oldimg.height());
staticRegion &= QRect(0, 0, newimg.width(), newimg.height());
QPainter painter(&newimg);
@@ -156,38 +156,36 @@ void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion &regionDip
painter.drawImage(rect, oldimg, rect);
}
- if (QWindowsScaling::isActive())
- newwni->setDevicePixelRatio(QWindowsScaling::factor());
m_image.reset(newwni);
}
}
Q_GUI_EXPORT void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-bool QWindowsBackingStore::scroll(const QRegion &areaDip, int dxDip, int dyDip)
+bool QWindowsBackingStore::scroll(const QRegion &area, int dx, int dy)
{
if (m_image.isNull() || m_image->image().isNull())
return false;
- const QPoint dp = QPoint(dxDip, dyDip) * QWindowsScaling::factor();
- const QVector<QRect> rects = areaDip.rects();
+ const QVector<QRect> rects = area.rects();
+ const QPoint offset(dx, dy);
for (int i = 0; i < rects.size(); ++i)
- qt_scrollRectInImage(m_image->image(), QWindowsScaling::mapToNative(rects.at(i)), dp);
+ qt_scrollRectInImage(m_image->image(), rects.at(i), offset);
return true;
}
-void QWindowsBackingStore::beginPaint(const QRegion &regionDip)
+void QWindowsBackingStore::beginPaint(const QRegion &region)
{
if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaBackingStore) <<__FUNCTION__ << regionDip;
+ qCDebug(lcQpaBackingStore) <<__FUNCTION__ << region;
if (m_image->image().hasAlphaChannel()) {
QPainter p(&m_image->image());
p.setCompositionMode(QPainter::CompositionMode_Source);
const QColor blank = Qt::transparent;
- foreach (const QRect &r, regionDip.rects())
- p.fillRect(QWindowsScaling::mapToNative(r), blank);
+ foreach (const QRect &r, region.rects())
+ p.fillRect(r, blank);
}
}
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
index 41ad29babc..4badcf1b09 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.h
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -35,7 +35,6 @@
#define QWINDOWSBACKINGSTORE_H
#include "qtwindows_additional.h"
-#include "qwindowsscaling.h"
#include <qpa/qplatformbackingstore.h>
#include <QtCore/QScopedPointer>
@@ -53,12 +52,7 @@ public:
~QWindowsBackingStore();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE
- {
- flushDp(window, QWindowsScaling::mapToNative(region.boundingRect()),
- offset * QWindowsScaling::factor());
- }
- void flushDp(QWindow *window, const QRect &boundingRect, const QPoint &offset);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
void resize(const QSize &size, const QRegion &r) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 3f355db607..717adcc47f 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -51,7 +51,6 @@
#endif
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
-#include "qwindowsscaling.h"
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
@@ -1232,9 +1231,7 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg)
}
}
- QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered,
- pos / QWindowsScaling::factor(),
- globalPos / QWindowsScaling::factor(),
+ QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
QWindowsKeyMapper::queryKeyboardModifiers());
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 5f443f2675..1fbef61029 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -36,7 +36,6 @@
#include "qwindowscontext.h"
#include "qwindowswindow.h"
#include "qwindowsscreen.h"
-#include "qwindowsscaling.h"
#include <QtGui/QBitmap>
#include <QtGui/QImage>
@@ -646,13 +645,12 @@ QWindowsCursor::CursorState QWindowsCursor::cursorState()
QPoint QWindowsCursor::pos() const
{
- return mousePosition() / QWindowsScaling::factor();
+ return mousePosition();
}
void QWindowsCursor::setPos(const QPoint &pos)
{
- const QPoint posDp = pos * QWindowsScaling::factor();
- SetCursorPos(posDp.x() , posDp.y());
+ SetCursorPos(pos.x() , pos.y());
}
/*!
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 03438e3ee2..d24cba3c68 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -33,7 +33,7 @@
#include "qwindowsdrag.h"
#include "qwindowscontext.h"
-#include "qwindowsscaling.h"
+#include "qwindowsscreen.h"
#ifndef QT_NO_CLIPBOARD
# include "qwindowsclipboard.h"
#endif
@@ -43,7 +43,6 @@
#include "qwindowswindow.h"
#include "qwindowsmousehandler.h"
#include "qwindowscursor.h"
-#include "qwindowsscaling.h"
#include <QtGui/QMouseEvent>
#include <QtGui/QPixmap>
@@ -52,6 +51,7 @@
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface_p.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/QDebug>
#include <QtCore/QBuffer>
@@ -280,6 +280,13 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
}
#endif // !QT_NO_DEBUG_OUTPUT
+static qreal dragScaleFactor()
+{
+ const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
+ const QWindowsScreen *screen = screenManager.screenAtDp(QWindowsCursor::mousePosition());
+ return screen ? QHighDpiScaling::factor(screen) : qreal(1);
+}
+
/*!
\brief Blend custom pixmap with cursors.
*/
@@ -289,19 +296,22 @@ void QWindowsOleDropSource::createCursors()
const QDrag *drag = m_drag->currentDrag();
const QPixmap pixmap = drag->pixmap();
const bool hasPixmap = !pixmap.isNull();
- const int scaleFactor = QWindowsScaling::factor();
- const QSize pixmapSizeDp = pixmap.size() * scaleFactor;
+
+ const qreal scaleFactor = dragScaleFactor();
const bool scalePixmap = hasPixmap
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
- const QPixmap drawPixmap = scalePixmap
- ? pixmap.scaled(pixmapSizeDp, Qt::KeepAspectRatio, Qt::SmoothTransformation) : pixmap;
-
+ const QPixmap scaledPixmap = scalePixmap
+ ? pixmap.scaled((QSizeF(pixmap.size()) * scaleFactor).toSize(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation)
+ : pixmap;
Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
int actionCount = int(sizeof(actions) / sizeof(actions[0]));
if (!hasPixmap)
--actionCount; // No Qt::IgnoreAction unless pixmap
- const QPoint hotSpot = drag->hotSpot() * scaleFactor;
+ const QPoint hotSpot = scalePixmap
+ ? (QPointF(drag->hotSpot()) * scaleFactor).toPoint()
+ : drag->hotSpot();
for (int cnum = 0; cnum < actionCount; ++cnum) {
const Qt::DropAction action = actions[cnum];
QPixmap cursorPixmap = drag->dragCursor(action);
@@ -321,14 +331,14 @@ void QWindowsOleDropSource::createCursors()
if (hasPixmap) {
const int x1 = qMin(-hotSpot.x(), 0);
- const int x2 = qMax(pixmapSizeDp.width() - hotSpot.x(), cursorPixmap.width());
+ const int x2 = qMax(scaledPixmap.width() - hotSpot.x(), cursorPixmap.width());
const int y1 = qMin(-hotSpot.y(), 0);
- const int y2 = qMax(pixmapSizeDp.height() - hotSpot.y(), cursorPixmap.height());
+ const int y2 = qMax(scaledPixmap.height() - hotSpot.y(), cursorPixmap.height());
QPixmap newCursor(x2 - x1 + 1, y2 - y1 + 1);
newCursor.fill(Qt::transparent);
QPainter p(&newCursor);
const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
- p.drawPixmap(pmDest, drawPixmap);
+ p.drawPixmap(pmDest, scaledPixmap);
p.drawPixmap(qMax(0, hotSpot.x()),qMax(0, hotSpot.y()), cursorPixmap);
newPixmap = newCursor;
newHotSpot = QPoint(qMax(0, hotSpot.x()), qMax(0, hotSpot.y()));
@@ -454,7 +464,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
if (!m_touchDragWindow)
m_touchDragWindow = new QWindowsDragCursorWindow;
m_touchDragWindow->setPixmap(e.pixmap);
- m_touchDragWindow->setFramePosition((QWindowsCursor::mousePosition() - e.hotSpot) / QWindowsScaling::factor());
+ m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot);
if (!m_touchDragWindow->isVisible())
m_touchDragWindow->show();
break;
@@ -530,9 +540,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
const QPlatformDragQtResponse response =
- QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(),
- m_lastPoint / QWindowsScaling::factor(),
- actions);
+ QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions);
m_answerRect = response.answerRect();
const Qt::DropAction action = response.acceptedAction();
@@ -625,9 +633,8 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
const QPlatformDropQtResponse response =
QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(),
- m_lastPoint / QWindowsScaling::factor(),
+ m_lastPoint,
translateToQDragDropActions(*pdwEffect));
-
if (response.isAccepted()) {
const Qt::DropAction action = response.acceptedAction();
if (action == Qt::MoveAction || action == Qt::TargetMoveAction) {
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 68e38dc4a6..554a6c8b4c 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -36,7 +36,6 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowsmousehandler.h"
-#include "qwindowsscaling.h"
#include <QtCore/QDebug>
#include <QtCore/QObject>
@@ -254,10 +253,9 @@ void QWindowsInputContext::cursorRectChanged()
if (!m_compositionContext.hwnd)
return;
const QInputMethod *inputMethod = QGuiApplication::inputMethod();
- const QRect cursorRectangleDip = inputMethod->cursorRectangle().toRect();
- if (!cursorRectangleDip.isValid())
+ const QRect cursorRectangle = inputMethod->cursorRectangle().toRect();
+ if (!cursorRectangle.isValid())
return;
- const QRect cursorRectangle = QWindowsScaling::mapToNative(cursorRectangleDip);
qCDebug(lcQpaInputMethods) << __FUNCTION__<< cursorRectangle;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 79df6ce720..bbb1f68a52 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -33,7 +33,6 @@
****************************************************************************/
#include "qwindowsintegration.h"
-#include "qwindowsscaling.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#include "qwindowsopenglcontext.h"
@@ -64,6 +63,7 @@
# include "qwindowssessionmanager.h"
#endif
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/qpa/qplatforminputcontextfactory_p.h>
#include <QtCore/private/qeventdispatcher_win_p.h>
@@ -223,12 +223,8 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
m_context.setProcessDpiAwareness(dpiAwareness);
dpiAwarenessSet = true;
}
- // Determine suitable scale factor, don't mix Windows and Qt scaling
- if (dpiAwareness != QtWindows::ProcessDpiUnaware)
- QWindowsScaling::setFactor(QWindowsScaling::determineUiScaleFactor());
qCDebug(lcQpaWindows)
- << __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling="
- << QWindowsScaling::factor();
+ << __FUNCTION__ << "DpiAwareness=" << dpiAwareness;
QTouchDevice *touchDevice = m_context.touchDevice();
if (touchDevice) {
@@ -268,10 +264,9 @@ QWindowsIntegration::~QWindowsIntegration()
void QWindowsIntegration::initialize()
{
- if (QPlatformInputContext *pluginContext = QPlatformInputContextFactory::create())
- d->m_inputContext.reset(pluginContext);
- else
- d->m_inputContext.reset(new QWindowsInputContext);
+ QString icStr = QPlatformInputContextFactory::requested();
+ icStr.isNull() ? d->m_inputContext.reset(new QWindowsInputContext)
+ : d->m_inputContext.reset(QPlatformInputContextFactory::create(icStr));
}
bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -307,7 +302,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
{
QWindowsWindowData requested;
requested.flags = window->flags();
- requested.geometry = QWindowsScaling::mapToNative(window->geometry());
+ requested.geometry = QHighDpi::toNativePixels(window->geometry(), window);
// Apply custom margins (see QWindowsWindow::setCustomMargins())).
const QVariant customMarginsV = window->property("_q_windowsCustomMargins");
if (customMarginsV.isValid())
@@ -327,7 +322,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
window->setFlags(obtained.flags);
// Trigger geometry change signals of QWindow.
if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry)
- QWindowSystemInterface::handleGeometryChange(window, QWindowsScaling::mapFromNative(obtained.geometry));
+ QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
}
return obtained;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index d47c7df9e0..3636bb7893 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -35,12 +35,12 @@
#include "qwindowscontext.h"
#include "qwindowswindow.h"
#include "qwindowsguieventdispatcher.h"
-#include "qwindowsscaling.h"
#include "qwindowsinputcontext.h"
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <QtGui/QKeyEvent>
#if defined(WM_APPCOMMAND)
@@ -792,10 +792,12 @@ static void showSystemMenu(QWindow* w)
#undef enabled
#undef disabled
#endif // !Q_OS_WINCE
- const QPoint topLeft = topLevel->geometry().topLeft() * QWindowsScaling::factor();
+ const QPoint pos = QHighDpi::toNativePixels(topLevel->geometry().topLeft(), topLevel);
const int ret = TrackPopupMenuEx(menu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
- topLeft.x(), topLeft.y(), topLevelHwnd, 0);
+ pos.x(), pos.y(),
+ topLevelHwnd,
+ 0);
if (ret)
qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, ret, 0);
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index e6b80f2b93..200eb11855 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -211,10 +211,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
const QPoint globalPosition = winEventPosition;
const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition);
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
- QWindowSystemInterface::handleFrameStrutMouseEvent(window,
- clientPosition / QWindowsScaling::factor(),
- globalPosition / QWindowsScaling::factor(),
- buttons,
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
+ globalPosition, buttons,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
return false; // Allow further event processing (dragging of windows).
@@ -279,7 +277,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
// ChildWindowFromPointEx() may not find the Qt window (failing with ERROR_ACCESS_DENIED)
if (!currentWindowUnderMouse) {
const QRect clientRect(QPoint(0, 0), window->size());
- if (clientRect.contains(winEventPosition / QWindowsScaling::factor()))
+ if (clientRect.contains(winEventPosition))
currentWindowUnderMouse = window;
}
@@ -366,10 +364,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
m_windowUnderMouse = currentWindowUnderMouse;
}
- QWindowSystemInterface::handleMouseEvent(window,
- winEventPosition / QWindowsScaling::factor(),
- globalPosition / QWindowsScaling::factor(),
- buttons,
+ QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
m_previousCaptureWindow = hasCapture ? window : 0;
@@ -404,11 +399,9 @@ static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int del
}
if (handleEvent) {
- const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor();
QWindowSystemInterface::handleWheelEvent(receiver,
- posDip, globalPos / QWindowsScaling::factor(),
- delta / QWindowsScaling::factor(),
- orientation, mods);
+ QWindowsGeometryHint::mapFromGlobal(receiver, globalPos),
+ globalPos, delta, orientation, mods);
}
}
@@ -494,7 +487,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo);
QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
- const qreal screenPosFactor = 0.01 / qreal(QWindowsScaling::factor());
for (int i = 0; i < winTouchPointCount; ++i) {
const TOUCHINPUT &winTouchInput = winTouchInputs[i];
int id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1);
@@ -508,9 +500,9 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
if (m_lastTouchPositions.contains(id))
touchPoint.normalPosition = m_lastTouchPositions.value(id);
- const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) * screenPosFactor;
+ const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) / qreal(100.);
if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
- touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) * screenPosFactor);
+ touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) / qreal(100.));
touchPoint.area.moveCenter(screenPos);
QPointF normalPosition = QPointF(screenPos.x() / screenGeometry.width(),
screenPos.y() / screenGeometry.height());
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.h b/src/plugins/platforms/windows/qwindowsnativeimage.h
index 6f9ce93ef0..80a1de1ea5 100644
--- a/src/plugins/platforms/windows/qwindowsnativeimage.h
+++ b/src/plugins/platforms/windows/qwindowsnativeimage.h
@@ -57,8 +57,6 @@ public:
HDC hdc() const { return m_hdc; }
- void setDevicePixelRatio(qreal scaleFactor) { m_image.setDevicePixelRatio(scaleFactor); }
-
static QImage::Format systemFormat();
private:
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index 810fddbca7..52e83395d1 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -224,7 +224,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c
#elif defined(Q_OS_WINCE)
return QWindowsOpenGLTester::Gles;
#else
- QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion);
+ QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion, gpu.description);
SupportedRenderersCache *srCache = supportedRenderersCache();
SupportedRenderersCache::const_iterator it = srCache->find(qgpu);
if (it != srCache->cend())
@@ -250,19 +250,19 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c
qCDebug(lcQpaGl) << "GPU features:" << features;
if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific
- qCWarning(lcQpaGl) << "Disabling Desktop GL: " << gpu;
+ qCDebug(lcQpaGl) << "Disabling Desktop GL: " << gpu;
result &= ~QWindowsOpenGLTester::DesktopGl;
}
if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword
- qCWarning(lcQpaGl) << "Disabling ANGLE: " << gpu;
+ qCDebug(lcQpaGl) << "Disabling ANGLE: " << gpu;
result &= ~QWindowsOpenGLTester::GlesMask;
} else {
if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword
- qCWarning(lcQpaGl) << "Disabling D3D11: " << gpu;
+ qCDebug(lcQpaGl) << "Disabling D3D11: " << gpu;
result &= ~QWindowsOpenGLTester::AngleRendererD3d11;
}
if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific
- qCWarning(lcQpaGl) << "Disabling D3D9: " << gpu;
+ qCDebug(lcQpaGl) << "Disabling D3D9: " << gpu;
result &= ~QWindowsOpenGLTester::AngleRendererD3d9;
}
}
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index 748885542d..3cd8bf4d4b 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -36,7 +36,7 @@
#include <QtCore/QByteArray>
#include <QtCore/QFlags>
-#include <private/qversionnumber_p.h>
+#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscaling.cpp b/src/plugins/platforms/windows/qwindowsscaling.cpp
deleted file mode 100644
index 6ab7f254fd..0000000000
--- a/src/plugins/platforms/windows/qwindowsscaling.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsscaling.h"
-#include "qwindowsscreen.h"
-
-#include <QtCore/QDebug>
-#include <QtCore/QCoreApplication>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWindowsScaling
- \brief Windows scaling utilities
-
- \internal
- \ingroup qt-lighthouse-win
-*/
-
-int QWindowsScaling::m_factor = 1;
-
-static const char devicePixelRatioEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
-
-// Suggest a scale factor by checking monitor sizes.
-int QWindowsScaling::determineUiScaleFactor()
-{
- if (!qEnvironmentVariableIsSet(devicePixelRatioEnvVar))
- return 1;
- const QByteArray envDevicePixelRatioEnv = qgetenv(devicePixelRatioEnvVar);
- // Auto: Suggest a scale factor by checking monitor resolution.
- if (envDevicePixelRatioEnv == "auto") {
- const int maxResolution = QWindowsScreen::maxMonitorHorizResolution();
- return maxResolution > 180 ? maxResolution / 96 : 1;
- }
- // Get factor from environment
- bool ok = false;
- const int envFactor = envDevicePixelRatioEnv.toInt(&ok);
- return ok && envFactor > 0 ? envFactor : 1;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscaling.h b/src/plugins/platforms/windows/qwindowsscaling.h
deleted file mode 100644
index 39e554bbe2..0000000000
--- a/src/plugins/platforms/windows/qwindowsscaling.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSSCALING_H
-#define QWINDOWSSCALING_H
-
-#include <QtGui/QRegion>
-#include <QtCore/QVector>
-#include <QtCore/QRect>
-
-QT_BEGIN_NAMESPACE
-
-enum
-#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC)
- : int
-#endif
-{ QWINDOWSIZE_MAX = 16777215 };
-
-class QWindowsScaling {
-public:
- static bool isActive() { return m_factor > 1; }
- static int factor() { return m_factor; }
- static void setFactor(int factor) { m_factor = factor; }
- static int determineUiScaleFactor();
-
- // Scaling helpers for size constraints.
- static int mapToNativeConstrained(int qt)
- { return m_factor != 1 && qt > 0 && qt < QWINDOWSIZE_MAX ? qt * m_factor : qt; }
-
- static int mapFromNativeConstrained(int dp)
- { return m_factor != 1 && dp > 0 && dp < QWINDOWSIZE_MAX ? dp / m_factor : dp; }
-
- static QSize mapToNativeConstrained(const QSize &qt)
- { return QSize(mapToNativeConstrained(qt.width()), mapToNativeConstrained(qt.height())); }
-
- static QRect mapToNative(const QRect &qRect)
- {
- return QRect(qRect.x() * m_factor, qRect.y() * m_factor, qRect.width() * m_factor, qRect.height() * m_factor);
- }
-
- static QRect mapFromNative(const QRect &dp)
- {
- return isActive() ?
- QRect(dp.x() / m_factor, dp.y() / m_factor, (dp.width() + 1) / m_factor, (dp.height() + 1) / m_factor) :
- dp;
- }
-
- static QRegion mapToNative(const QRegion &regionQt)
- {
- if (!QWindowsScaling::isActive() || regionQt.isEmpty())
- return regionQt;
-
- QRegion result;
- foreach (const QRect &rectQt, regionQt.rects())
- result += QWindowsScaling::mapToNative(rectQt);
- return result;
- }
-
- static QRegion mapFromNative(const QRegion &regionDp)
- {
- if (!QWindowsScaling::isActive() || regionDp.isEmpty())
- return regionDp;
-
- QRegion result;
- foreach (const QRect &rectDp, regionDp.rects())
- result += QWindowsScaling::mapFromNative(rectDp);
- return result;
- }
-
-private:
- static int m_factor;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSSCALING_H
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 7756c77001..391735a035 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -43,6 +43,7 @@
#include <QtGui/QPixmap>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
#include <QtGui/QScreen>
#include <QtCore/QDebug>
@@ -218,36 +219,14 @@ QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
{
}
-BOOL QT_WIN_CALLBACK monitorResolutionEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p)
-{
- QWindowsScreenData data;
- if (monitorData(hMonitor, &data)) {
- int *maxHorizResolution = reinterpret_cast<int *>(p);
- const int horizResolution = qRound(data.dpi.first);
- if (horizResolution > *maxHorizResolution)
- *maxHorizResolution = horizResolution;
- }
- return TRUE;
-}
-
-int QWindowsScreen::maxMonitorHorizResolution()
-{
- int result = 0;
- EnumDisplayMonitors(0, 0, monitorResolutionEnumCallback, (LPARAM)&result);
- return result;
-}
-
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
-QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const
+QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
RECT r;
HWND hwnd = window ? (HWND)window : GetDesktopWindow();
GetClientRect(hwnd, &r);
- const int x = qX * QWindowsScaling::factor();
- const int y = qY * QWindowsScaling::factor();
- int width = qWidth * QWindowsScaling::factor();
- int height = qHeight * QWindowsScaling::factor();
+
if (width < 0) width = r.right - r.left;
if (height < 0) height = r.bottom - r.top;
@@ -271,10 +250,6 @@ QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int q
DeleteObject(bitmap);
ReleaseDC(0, display_dc);
- if (QWindowsScaling::isActive()) {
- const qreal factor = 1.0 / qreal(QWindowsScaling::factor());
- return pixmap.transformed(QTransform::fromScale(factor, factor));
- }
return pixmap;
}
@@ -285,7 +260,7 @@ QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int q
QWindow *QWindowsScreen::topLevelAt(const QPoint &point) const
{
QWindow *result = 0;
- if (QWindow *child = QWindowsScreen::windowAt(point * QWindowsScaling::factor(), CWP_SKIPINVISIBLE))
+ if (QWindow *child = QWindowsScreen::windowAt(point, CWP_SKIPINVISIBLE))
result = QWindowsWindow::topLevelOf(child);
qCDebug(lcQpaWindows) <<__FUNCTION__ << point << result;
return result;
@@ -313,6 +288,12 @@ QWindowsScreen *QWindowsScreen::screenOf(const QWindow *w)
return 0;
}
+qreal QWindowsScreen::pixelDensity() const
+{
+ const qreal physicalDpi = m_data.geometry.width() / m_data.physicalSizeMM.width() * qreal(25.4);
+ return qRound(physicalDpi / 96);
+}
+
/*!
\brief Determine siblings in a virtual desktop system.
@@ -542,7 +523,7 @@ void QWindowsScreenManager::clearScreens()
const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
{
foreach (QWindowsScreen *scr, m_screens) {
- if (scr->geometryDp().contains(p))
+ if (scr->geometry().contains(p))
return scr;
}
return Q_NULLPTR;
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 7352c45777..67e7ff644b 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -34,7 +34,6 @@
#ifndef QWINDOWSSCREEN_H
#define QWINDOWSSCREEN_H
-#include "qwindowsscaling.h"
#include "qtwindowsglobal.h"
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
@@ -82,16 +81,14 @@ public:
static QWindowsScreen *screenOf(const QWindow *w = 0);
- QRect geometryDp() const { return m_data.geometry; }
- QRect geometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(geometryDp()); }
- QRect availableGeometryDp() const { return m_data.availableGeometry; }
- QRect availableGeometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(availableGeometryDp()); }
+ QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
+ QRect availableGeometry() const Q_DECL_OVERRIDE { return m_data.availableGeometry; }
int depth() const Q_DECL_OVERRIDE { return m_data.depth; }
QImage::Format format() const Q_DECL_OVERRIDE { return m_data.format; }
QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_data.physicalSizeMM; }
- QDpi logicalDpi() const Q_DECL_OVERRIDE
- { return QDpi(m_data.dpi.first / QWindowsScaling::factor(), m_data.dpi.second / QWindowsScaling::factor()); }
- qreal devicePixelRatio() const Q_DECL_OVERRIDE { return QWindowsScaling::factor(); }
+ QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_data.dpi; }
+ qreal pixelDensity() const Q_DECL_OVERRIDE;
+ qreal devicePixelRatio() const Q_DECL_OVERRIDE { return 1.0; }
qreal refreshRate() const Q_DECL_OVERRIDE { return m_data.refreshRateHz; }
QString name() const Q_DECL_OVERRIDE { return m_data.name; }
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_data.orientation; }
@@ -112,7 +109,6 @@ public:
#endif // !QT_NO_CURSOR
const QWindowsScreenData &data() const { return m_data; }
- static int maxMonitorHorizResolution();
private:
QWindowsScreenData m_data;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 7b871be015..3951401273 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qwindowstabletsupport.h"
-#include "qwindowsscaling.h"
#ifndef QT_NO_TABLETEVENT
@@ -55,7 +54,7 @@
#include <QtCore/private/qsystemlibrary_p.h>
// Note: The definition of the PACKET structure in pktdef.h depends on this define.
-#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z)
+#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z | PK_TIME)
#include <pktdef.h>
QT_BEGIN_NAMESPACE
@@ -343,17 +342,18 @@ QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(const quint64 uniqueI
bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, LPARAM lParam)
{
+ PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
+ const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
+ if (!totalPacks)
+ return false;
if (!LOWORD(lParam)) {
qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice;
- QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime,
+ m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
m_devices.at(m_currentDevice).uniqueId);
return true;
}
- PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
- const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
- if (!totalPacks)
- return false;
const UINT currentCursor = proximityBuffer[0].pkCursor;
UINT physicalCursorId;
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
@@ -371,7 +371,8 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
qCDebug(lcQpaTablet) << "enter proximity for device #"
<< m_currentDevice << m_devices.at(m_currentDevice);
- QWindowSystemInterface::handleTabletEnterProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ QWindowSystemInterface::handleTabletEnterProximityEvent(proximityBuffer[0].pkTime,
+ m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
m_devices.at(m_currentDevice).uniqueId);
return true;
@@ -399,8 +400,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
// in which case we snap the position to the mouse position.
// It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext
// area is always the virtual desktop.
- const QRect virtualDesktopArea
- = QWindowsScaling::mapToNative(QGuiApplication::primaryScreen()->virtualGeometry());
+ const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
qCDebug(lcQpaTablet) << __FUNCTION__ << "processing " << packetCount
<< "target:" << QGuiApplicationPrivate::tabletPressTarget;
@@ -420,7 +420,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
QPoint globalPos = globalPosF.toPoint();
// Get Mouse Position and compare to tablet info
- QPoint mouseLocation = QWindowsCursor::mousePosition();
+ const QPoint mouseLocation = QWindowsCursor::mousePosition();
// Positions should be almost the same if we are in absolute
// mode. If they are not, use the mouse location.
@@ -475,9 +475,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
<< tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
}
- const QPointF localPosDip = QPointF(localPos / QWindowsScaling::factor());
- const QPointF globalPosDip = globalPosF / qreal(QWindowsScaling::factor());
- QWindowSystemInterface::handleTabletEvent(target, localPosDip, globalPosDip,
+ QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF,
currentDevice, currentPointer,
static_cast<Qt::MouseButtons>(packet.pkButtons),
pressureNew, tiltX, tiltY,
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index d3f67e9eaa..33c7ccfdce 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -43,7 +43,6 @@
#include "qwindowsintegration.h"
#include "qt_windows.h"
#include "qwindowsfontdatabase.h"
-#include "qwindowsscaling.h"
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
# include "winuser.h"
@@ -68,6 +67,7 @@
#include <QtGui/QPainter>
#include <QtGui/QPixmapCache>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
#include <private/qsystemlibrary_p.h>
#include <algorithm>
@@ -495,7 +495,8 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
{
- const int scaleFactor = QWindowsScaling::factor();
+ const QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ const int scaleFactor = primaryScreen ? qRound(QHighDpiScaling::factor(primaryScreen)) : 1;
const QSizeF pixmapSize = size * scaleFactor;
int resourceId = -1;
LPCTSTR iconName = 0;
@@ -632,7 +633,7 @@ public:
static FakePointer *create(T thing)
{
- return reinterpret_cast<FakePointer *>(thing);
+ return reinterpret_cast<FakePointer *>(qintptr(thing));
}
T operator * () const
@@ -720,6 +721,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
iconSize|SHGFI_SYSICONINDEX;
#endif // Q_OS_WINCE
unsigned long val = 0;
+#if !defined(QT_NO_WINCE_SHELLSDK)
if (cacheableDirIcon && useDefaultFolderIcon) {
flags |= SHGFI_USEFILEATTRIBUTES;
val = SHGetFileInfo(L"dummy",
@@ -729,6 +731,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
val = SHGetFileInfo(reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
&info, sizeof(SHFILEINFO), flags);
}
+#endif // !QT_NO_WINCE_SHELLSDK
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
if (val && info.hIcon) {
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 288f73cb8f..f9b34334df 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -36,7 +36,6 @@
#include "qwindowscontext.h"
#include "qwindowsdrag.h"
#include "qwindowsscreen.h"
-#include "qwindowsscaling.h"
#include "qwindowsintegration.h"
#include "qwindowsopenglcontext.h"
#ifdef QT_NO_CURSOR
@@ -49,8 +48,9 @@
#include <QtGui/QRegion>
#include <QtGui/QOpenGLContext>
#include <private/qsystemlibrary_p.h>
-#include <private/qwindow_p.h>
+#include <private/qwindow_p.h> // QWINDOWSIZE_MAX
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/QDebug>
@@ -169,7 +169,7 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point)
const QWindowsScreen *screen = screenManager.screens().size() == 1
? screenManager.screens().first() : screenManager.screenAtDp(point);
if (screen)
- return screen->availableGeometryDp().topLeft() - screen->geometryDp().topLeft();
+ return screen->availableGeometry().topLeft() - screen->geometry().topLeft();
#else
Q_UNUSED(hwnd)
Q_UNUSED(point)
@@ -608,9 +608,7 @@ QWindowsWindowData
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);
- const QRect geometryDip = QWindowsScaling::mapFromNative(data.geometry);
- QRect fixedGeometryDip = QPlatformWindow::initialGeometry(w, geometryDip, defaultWindowWidth, defaultWindowHeight);
- const QRect rect = fixedGeometryDip != geometryDip ? QWindowsScaling::mapToNative(fixedGeometryDip) : data.geometry;
+ const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, defaultWindowWidth, defaultWindowHeight);
if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
title = topLevel ? qAppName() : w->objectName();
@@ -706,6 +704,20 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang
}
}
+
+// Scaling helpers for size constraints.
+static QSize toNativeSizeConstrained(QSize dip, const QWindow *w)
+{
+ if (QHighDpiScaling::isActive()) {
+ const qreal factor = QHighDpiScaling::factor(w);
+ if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
+ dip.rwidth() *= factor;
+ if (dip.height() > 0 && dip.height() < QWINDOWSIZE_MAX)
+ dip.rheight() *= factor;
+ }
+ return dip;
+}
+
/*!
\class QWindowsGeometryHint
\brief Stores geometry constraints and provides utility functions.
@@ -718,8 +730,8 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang
*/
QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w, const QMargins &cm) :
- minimumSize(QWindowsScaling::mapToNativeConstrained(w->minimumSize())),
- maximumSize(QWindowsScaling::mapToNativeConstrained(w->maximumSize())),
+ minimumSize(toNativeSizeConstrained(w->minimumSize(), w)),
+ maximumSize(toNativeSizeConstrained(w->maximumSize(), w)),
customMargins(cm)
{
}
@@ -953,8 +965,7 @@ void QWindowsWindow::fireExpose(const QRegion &region, bool force)
clearFlag(Exposed);
else
setFlag(Exposed);
- QWindowSystemInterface::handleExposeEvent(window(),
- QWindowsScaling::mapFromNative(region));
+ QWindowSystemInterface::handleExposeEvent(window(), region);
}
static inline QWindow *findTransientChild(const QWindow *parent)
@@ -1134,7 +1145,7 @@ bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const
return m_data.embedded;
}
-QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const
+QPoint QWindowsWindow::mapToGlobal(const QPoint &pos) const
{
if (m_data.hwnd)
return QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos);
@@ -1142,7 +1153,7 @@ QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const
return pos;
}
-QPoint QWindowsWindow::mapFromGlobalDp(const QPoint &pos) const
+QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const
{
if (m_data.hwnd)
return QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos);
@@ -1323,22 +1334,22 @@ static QRect normalFrameGeometry(HWND hwnd)
return QRect();
}
-QRect QWindowsWindow::normalGeometryDp() const
+QRect QWindowsWindow::normalGeometry() const
{
// Check for fake 'fullscreen' mode.
const bool fakeFullScreen = m_savedFrameGeometry.isValid() && window()->windowState() == Qt::WindowFullScreen;
const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
- const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMarginsDp();
+ const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMargins();
return frame.isValid() ? frame.marginsRemoved(margins) : frame;
}
-void QWindowsWindow::setGeometryDp(const QRect &rectIn)
+void QWindowsWindow::setGeometry(const QRect &rectIn)
{
QRect rect = rectIn;
// This means it is a call from QWindow::setFramePosition() and
// the coordinates include the frame (size is still the contents rectangle).
if (QWindowsGeometryHint::positionIncludesFrame(window())) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top()));
}
if (m_windowState == Qt::WindowMinimized)
@@ -1407,9 +1418,8 @@ void QWindowsWindow::handleGeometryChange()
return;
const QRect previousGeometry = m_data.geometry;
m_data.geometry = geometry_sys();
- const QRect geometryDip = QWindowsScaling::mapFromNative(m_data.geometry);
- QPlatformWindow::setGeometry(geometryDip);
- QWindowSystemInterface::handleGeometryChange(window(), geometryDip);
+ QPlatformWindow::setGeometry(m_data.geometry);
+ QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
// expose events when shrinking, synthesize.
if (!testFlag(OpenGL_ES2) && isExposed()
@@ -1417,7 +1427,7 @@ void QWindowsWindow::handleGeometryChange()
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
}
if (previousGeometry.topLeft() != m_data.geometry.topLeft()) {
- QPlatformScreen *newScreen = screenForGeometry(geometryDip);
+ QPlatformScreen *newScreen = screenForGeometry(m_data.geometry);
if (newScreen != screen())
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
}
@@ -1429,7 +1439,7 @@ void QWindowsWindow::handleGeometryChange()
void QWindowsWindow::setGeometry_sys(const QRect &rect) const
{
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
const QRect frameGeometry = rect + margins;
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window()
@@ -1468,7 +1478,7 @@ QRect QWindowsWindow::frameGeometry_sys() const
QRect QWindowsWindow::geometry_sys() const
{
- return frameGeometry_sys().marginsRemoved(frameMarginsDp());
+ return frameGeometry_sys().marginsRemoved(frameMargins());
}
/*!
@@ -1540,7 +1550,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
{
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: "
<< m_data.flags << "\n to: " << flags;
- const QRect oldGeometry = geometryDp();
+ const QRect oldGeometry = geometry();
if (m_data.flags != flags) {
m_data.flags = flags;
if (m_data.hwnd) {
@@ -1626,8 +1636,9 @@ void QWindowsWindow::setWindowState(Qt::WindowState state)
bool QWindowsWindow::isFullScreen_sys() const
{
- return window()->isTopLevel()
- && geometry_sys() == QWindowsScaling::mapToNative(window()->screen()->geometry());
+ const QWindow *w = window();
+ return w->isTopLevel()
+ && geometry_sys() == QHighDpi::toNativePixels(w->screen()->geometry(), w);
}
/*!
@@ -1697,15 +1708,14 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
// Use geometry of QWindow::screen() within creation or the virtual screen the
// window is in (QTBUG-31166, QTBUG-30724).
const QScreen *screen = window()->screen();
- const QRect rDip = screen->geometry();
- const QRect r = QWindowsScaling::mapToNative(rDip);
+ const QRect r = QHighDpi::toNativePixels(screen->geometry(), window());
const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
setFlag(SynchronousGeometryChangeEvent);
SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
if (!wasSync)
clearFlag(SynchronousGeometryChangeEvent);
- QWindowSystemInterface::handleGeometryChange(window(), rDip);
+ QWindowSystemInterface::handleGeometryChange(window(), r);
QWindowSystemInterface::flushWindowSystemEvents();
} else if (newState != Qt::WindowMinimized) {
// Restore saved state.
@@ -1804,7 +1814,7 @@ void QWindowsWindow::propagateSizeHints()
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
}
-bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp)
+bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &margins)
{
#ifndef Q_OS_WINCE
if (!qWindow->isTopLevel()) // Implement hasHeightForWidth().
@@ -1812,26 +1822,19 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam);
if ((windowPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE)))
return false;
- const QRect suggestedFrameGeometryDp(windowPos->x, windowPos->y,
- windowPos->cx, windowPos->cy);
- const qreal factor = QWindowsScaling::factor();
- const QRect suggestedGeometryDp = suggestedFrameGeometryDp - marginsDp;
- const QRectF suggestedGeometry = QRectF(QPointF(suggestedGeometryDp.topLeft()) / factor,
- QSizeF(suggestedGeometryDp.size()) / factor);
- const QRectF correctedGeometryF =
- qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(suggestedGeometry);
+ const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
+ windowPos->cx, windowPos->cy);
+ const QRect suggestedGeometry = suggestedFrameGeometry - margins;
+ const QRectF correctedGeometryF = qWindow->handle()->windowClosestAcceptableGeometry(suggestedGeometry);
if (!correctedGeometryF.isValid())
return false;
- const QRect correctedFrameGeometryDp
- = QRectF(correctedGeometryF.topLeft() * factor,
- correctedGeometryF.size() * factor).toRect()
- + marginsDp;
- if (correctedFrameGeometryDp == suggestedFrameGeometryDp)
+ const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
+ if (correctedFrameGeometry == suggestedFrameGeometry)
return false;
- windowPos->x = correctedFrameGeometryDp.left();
- windowPos->y = correctedFrameGeometryDp.top();
- windowPos->cx = correctedFrameGeometryDp.width();
- windowPos->cy = correctedFrameGeometryDp.height();
+ windowPos->x = correctedFrameGeometry.left();
+ windowPos->y = correctedFrameGeometry.top();
+ windowPos->cx = correctedFrameGeometry.width();
+ windowPos->cy = correctedFrameGeometry.height();
return true;
#else // !Q_OS_WINCE
Q_UNUSED(message)
@@ -1841,11 +1844,11 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
bool QWindowsWindow::handleGeometryChanging(MSG *message) const
{
- const QMargins marginsDp = window()->isTopLevel() ? frameMarginsDp() : QMargins();
- return QWindowsWindow::handleGeometryChangingMessage(message, window(), marginsDp);
+ const QMargins margins = window()->isTopLevel() ? frameMargins() : QMargins();
+ return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
}
-QMargins QWindowsWindow::frameMarginsDp() const
+QMargins QWindowsWindow::frameMargins() const
{
// Frames are invalidated by style changes (window state, flags).
// As they are also required for geometry calculations in resize
@@ -1892,17 +1895,17 @@ static inline void addRectToWinRegion(const QRect &rect, HRGN *winRegion)
}
}
-static HRGN qRegionToWinRegion(const QRegion &regionDip)
+static HRGN qRegionToWinRegion(const QRegion &region)
{
- const QVector<QRect> rects = regionDip.rects();
+ const QVector<QRect> rects = region.rects();
if (rects.isEmpty())
return NULL;
const int rectCount = rects.size();
if (rectCount == 1)
- return createRectRegion(QWindowsScaling::mapToNative(regionDip.boundingRect()));
- HRGN hRegion = createRectRegion(QWindowsScaling::mapToNative(rects.front()));
+ return createRectRegion(region.boundingRect());
+ HRGN hRegion = createRectRegion(rects.front());
for (int i = 1; i < rectCount; ++i)
- addRectToWinRegion(QWindowsScaling::mapToNative(rects.at(i)), &hRegion);
+ addRectToWinRegion(rects.at(i), &hRegion);
return hRegion;
}
@@ -1916,7 +1919,7 @@ void QWindowsWindow::setMask(const QRegion &region)
// Mask is in client area coordinates, so offset it in case we have a frame
if (window()->isTopLevel()) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
OffsetRgn(winRegion, margins.left(), margins.top());
}
@@ -2053,23 +2056,23 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
|| (m_data.flags & Qt::FramelessWindowHint)) {
return false;
}
- const QSize minimumSize = QWindowsScaling::mapToNativeConstrained(w->minimumSize());
+ const QSize minimumSize = w->minimumSize();
if (minimumSize.isEmpty())
return false;
- const QSize maximumSize = QWindowsScaling::mapToNativeConstrained(w->maximumSize());
+ const QSize maximumSize = w->maximumSize();
const bool fixedWidth = minimumSize.width() == maximumSize.width();
const bool fixedHeight = minimumSize.height() == maximumSize.height();
if (!fixedWidth && !fixedHeight)
return false;
- const QPoint localPos = mapFromGlobalDp(globalPos);
- const QSize size = w->size() * QWindowsScaling::factor();
+ const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
+ const QSize size = w->size();
if (fixedHeight) {
if (localPos.y() >= size.height()) {
*result = HTBORDER; // Unspecified border, no resize cursor.
return true;
}
if (localPos.y() < 0) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
const int topResizeBarPos = margins.left() - margins.top();
if (localPos.y() < topResizeBarPos) {
*result = HTCAPTION; // Extend caption over top resize bar, let's user move the window.
@@ -2245,10 +2248,6 @@ void QWindowsWindow::setWindowIcon(const QIcon &icon)
The property can be set using QPlatformNativeInterface::setWindowProperty() or,
before platform window creation, by setting a dynamic property
on the QWindow (see QWindowsIntegration::createPlatformWindow()).
-
- Note: The function uses (unscaled) device pixels since the QWizard also
- uses AdjustWindowRect() and using device independent pixels would introduce
- rounding errors.
*/
void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index fff90b4b11..d96022e3a5 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -38,7 +38,6 @@
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
#endif
-#include "qwindowsscaling.h"
#include "qwindowscursor.h"
#include <qpa/qplatformwindow.h>
@@ -145,28 +144,18 @@ public:
~QWindowsWindow();
QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- void setGeometryDp(const QRect &rectIn);
- void setGeometry(const QRect &rect) Q_DECL_OVERRIDE
- { setGeometryDp(QWindowsScaling::mapToNative(rect)); }
- QRect geometryDp() const { return m_data.geometry; }
- QRect geometry() const Q_DECL_OVERRIDE
- { return QWindowsScaling::mapFromNative(geometryDp()); }
- QRect normalGeometryDp() const;
- QRect normalGeometry() const Q_DECL_OVERRIDE
- { return QWindowsScaling::mapFromNative(normalGeometryDp()); }
- qreal devicePixelRatio() const Q_DECL_OVERRIDE
- { return qreal(QWindowsScaling::factor()); }
+ void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
+ QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
+ QRect normalGeometry() const Q_DECL_OVERRIDE;
+
void setVisible(bool visible) Q_DECL_OVERRIDE;
bool isVisible() const;
bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); }
bool isActive() const Q_DECL_OVERRIDE;
bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE;
- QPoint mapToGlobalDp(const QPoint &pos) const;
- QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE
- { return mapToGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); }
- QPoint mapFromGlobalDp(const QPoint &pos) const;
- QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE
- { return mapFromGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); }
+ QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
+ QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
+
void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE;
void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE;
@@ -184,8 +173,7 @@ public:
void propagateSizeHints() Q_DECL_OVERRIDE;
static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp);
bool handleGeometryChanging(MSG *message) const;
- QMargins frameMarginsDp() const;
- QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); }
+ QMargins frameMargins() const Q_DECL_OVERRIDE;
void setOpacity(qreal level) Q_DECL_OVERRIDE;
void setMask(const QRegion &region) Q_DECL_OVERRIDE;
@@ -196,7 +184,7 @@ public:
bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; }
- bool startSystemResize(const QPoint &, Qt::Corner corner) Q_DECL_OVERRIDE;
+ bool startSystemResize(const QPoint &pos, Qt::Corner corner) Q_DECL_OVERRIDE;
void setFrameStrutEventsEnabled(bool enabled);
bool frameStrutEventsEnabled() const { return testFlag(FrameStrutEventsEnabled); }
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index de901aaeb1..6e5789a86e 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -40,7 +40,6 @@ SOURCES += \
$$PWD/qwindowsservices.cpp \
$$PWD/qwindowsnativeimage.cpp \
$$PWD/qwindowsnativeinterface.cpp \
- $$PWD/qwindowsscaling.cpp \
$$PWD/qwindowsopengltester.cpp
HEADERS += \
@@ -67,7 +66,6 @@ HEADERS += \
$$PWD/qplatformfunctions_wince.h \
$$PWD/qwindowsnativeimage.h \
$$PWD/qwindowsnativeinterface.h \
- $$PWD/qwindowsscaling.h \
$$PWD/qwindowsopengltester.h
INCLUDEPATH += $$PWD
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
index 94ce23bd2c..707f3bf0ba 100644
--- a/src/plugins/platforms/winrt/qwinrtcursor.cpp
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -36,11 +36,13 @@
#include "qwinrtcursor.h"
#include "qwinrtscreen.h"
+#include <private/qeventdispatcher_winrt_p.h>
#include <QtCore/qfunctions_winrt.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
+#include <functional>
#include <wrl.h>
#include <windows.ui.core.h>
#include <windows.foundation.h>
@@ -77,12 +79,17 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window)
{
Q_D(QWinRTCursor);
+ HRESULT hr;
ICoreWindow *coreWindow = static_cast<QWinRTScreen *>(window->screen()->handle())->coreWindow();
CoreCursorType type;
switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) {
case Qt::BlankCursor:
- coreWindow->put_PointerCursor(Q_NULLPTR);
+ hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow]() {
+ coreWindow->put_PointerCursor(Q_NULLPTR);
+ return S_OK;
+ });
+ RETURN_VOID_IF_FAILED("Failed to set blank native cursor");
return;
default:
case Qt::OpenHandCursor:
@@ -142,11 +149,13 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window)
}
ComPtr<ICoreCursor> cursor;
- HRESULT hr = d->cursorFactory->CreateCursor(type, 0, &cursor);
+ hr = d->cursorFactory->CreateCursor(type, 0, &cursor);
RETURN_VOID_IF_FAILED("Failed to create native cursor.");
- hr = coreWindow->put_PointerCursor(cursor.Get());
- RETURN_VOID_IF_FAILED("Failed to set native cursor.");
+ hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, &cursor]() {
+ return coreWindow->put_PointerCursor(cursor.Get());
+ });
+ RETURN_VOID_IF_FAILED("Failed to set native cursor");
}
#endif // QT_NO_CURSOR
@@ -154,8 +163,12 @@ QPoint QWinRTCursor::pos() const
{
ICoreWindow *coreWindow =
static_cast<QWinRTScreen *>(QGuiApplication::primaryScreen()->handle())->coreWindow();
+ HRESULT hr;
Point point;
- coreWindow->get_PointerPosition(&point);
+ hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, &point]() {
+ return coreWindow->get_PointerPosition(&point);
+ });
+ RETURN_IF_FAILED("Failed to get native cursor position", QPoint());
return QPoint(point.X, point.Y);
}
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
index 42ffe8f716..44aab266ca 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -35,38 +35,131 @@
****************************************************************************/
#include "qwinrteglcontext.h"
+#include "qwinrtwindow.h"
+#include <private/qeventdispatcher_winrt_p.h>
+#include <functional>
+
+#include <EGL/egl.h>
#define EGL_EGLEXT_PROTOTYPES
-#include "EGL/eglext.h"
+#include <EGL/eglext.h>
+
+#include <QOpenGLContext>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
QT_BEGIN_NAMESPACE
-QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config)
- : QEGLPlatformContext(format, share, display, &config), m_eglSurface(surface)
+class QWinRTEGLContextPrivate
+{
+public:
+ QSurfaceFormat format;
+ EGLDisplay eglDisplay;
+ EGLConfig eglConfig;
+ EGLContext eglContext;
+ QHash<QPlatformSurface *, EGLSurface> surfaceForWindow;
+};
+
+QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context)
+ : d_ptr(new QWinRTEGLContextPrivate)
+{
+ Q_D(QWinRTEGLContext);
+ d->format = context->format();
+ d->format.setRenderableType(QSurfaceFormat::OpenGLES);
+}
+
+QWinRTEGLContext::~QWinRTEGLContext()
{
+ Q_D(QWinRTEGLContext);
+ foreach (const EGLSurface &surface, d->surfaceForWindow)
+ eglDestroySurface(d->eglDisplay, surface);
+ if (d->eglContext != EGL_NO_CONTEXT)
+ eglDestroyContext(d->eglDisplay, d->eglContext);
+ if (d->eglDisplay != EGL_NO_DISPLAY)
+ eglTerminate(d->eglDisplay);
}
-void QWinRTEGLContext::swapBuffers(QPlatformSurface *surface)
+void QWinRTEGLContext::initialize()
{
-#ifdef Q_OS_WINPHONE
- const QSize size = surface->surface()->size();
- eglPostSubBufferNV(eglDisplay(), eglSurfaceForPlatformSurface(surface),
- 0, 0, size.width(), size.height());
-#else
- eglSwapBuffers(eglDisplay(), eglSurfaceForPlatformSurface(surface));
-#endif
+ Q_D(QWinRTEGLContext);
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (d->eglDisplay == EGL_NO_DISPLAY)
+ qCritical("Failed to initialize EGL display: 0x%x", eglGetError());
+
+ if (!eglInitialize(d->eglDisplay, nullptr, nullptr))
+ qCritical("Failed to initialize EGL: 0x%x", eglGetError());
+
+ d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->format);
+
+ const EGLint flags = d->format.testOption(QSurfaceFormat::DebugContext)
+ ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0;
+ const EGLint attributes[] = {
+ EGL_CONTEXT_CLIENT_VERSION, d->format.majorVersion(),
+ EGL_CONTEXT_MINOR_VERSION_KHR, d->format.minorVersion(),
+ EGL_CONTEXT_FLAGS_KHR, flags,
+ EGL_NONE
+ };
+ d->eglContext = eglCreateContext(d->eglDisplay, d->eglConfig, nullptr, attributes);
+ if (d->eglContext == EGL_NO_CONTEXT) {
+ qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError());
+ return;
+ }
}
-EGLSurface QWinRTEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface)
{
- if (surface->surface()->surfaceClass() == QSurface::Window) {
- // All windows use the same surface
- return m_eglSurface;
- } else {
- // TODO: return EGL surfaces for offscreen surfaces
- qWarning("This plugin does not support offscreen surfaces.");
- return EGL_NO_SURFACE;
+ Q_D(QWinRTEGLContext);
+ Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface);
+
+ EGLSurface surface = d->surfaceForWindow.value(windowSurface);
+ if (surface == EGL_NO_SURFACE) {
+ QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d, window, &surface]() {
+ surface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig,
+ reinterpret_cast<EGLNativeWindowType>(window->winId()),
+ nullptr);
+ if (surface == EGL_NO_SURFACE) {
+ qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
+ return E_FAIL;
+ }
+ return S_OK;
+ });
+ if (FAILED(hr))
+ return false;
+ d->surfaceForWindow.insert(windowSurface, surface);
}
+
+ const bool ok = eglMakeCurrent(d->eglDisplay, surface, surface, d->eglContext);
+ if (!ok) {
+ qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError());
+ return false;
+ }
+
+ eglSwapInterval(d->eglDisplay, d->format.swapInterval());
+ return true;
+}
+
+void QWinRTEGLContext::doneCurrent()
+{
+ Q_D(const QWinRTEGLContext);
+ const bool ok = eglMakeCurrent(d->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (!ok)
+ qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError());
+}
+
+void QWinRTEGLContext::swapBuffers(QPlatformSurface *windowSurface)
+{
+ Q_D(QWinRTEGLContext);
+ Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface);
+
+ eglSwapBuffers(d->eglDisplay, d->surfaceForWindow.value(windowSurface));
+}
+
+QSurfaceFormat QWinRTEGLContext::format() const
+{
+ Q_D(const QWinRTEGLContext);
+ return d->format;
}
QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
@@ -221,7 +314,7 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
if (i != standardFuncs.end())
return i.value();
- return QEGLPlatformContext::getProcAddress(procName);
+ return eglGetProcAddress(procName.constData());
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h
index 958d623c4c..31a2124b03 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.h
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.h
@@ -37,23 +37,29 @@
#ifndef QWINDOWSEGLCONTEXT_H
#define QWINDOWSEGLCONTEXT_H
-#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+#include <qpa/qplatformopenglcontext.h>
QT_BEGIN_NAMESPACE
-class QWinRTEGLContext : public QEGLPlatformContext
+class QWinRTEGLContextPrivate;
+class QWinRTEGLContext : public QPlatformOpenGLContext
{
public:
- explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config);
+ explicit QWinRTEGLContext(QOpenGLContext *context);
+ ~QWinRTEGLContext();
- void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
+ void initialize() Q_DECL_OVERRIDE;
+
+ bool makeCurrent(QPlatformSurface *windowSurface) Q_DECL_OVERRIDE;
+ void doneCurrent() Q_DECL_OVERRIDE;
+ void swapBuffers(QPlatformSurface *windowSurface) Q_DECL_OVERRIDE;
-protected:
- EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
+ QSurfaceFormat format() const Q_DECL_OVERRIDE;
+ QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
private:
- EGLSurface m_eglSurface;
+ QScopedPointer<QWinRTEGLContextPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTEGLContext)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
index 09edea52e7..c348faf015 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -39,13 +39,11 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
-#ifdef QT_WINRT_USE_DWRITE
#include <QtCore/QUuid>
#include <QtGui/private/qfontengine_ft_p.h>
#include <dwrite_1.h>
#include <wrl.h>
using namespace Microsoft::WRL;
-#endif // QT_WINRT_USE_DWRITE
QT_BEGIN_NAMESPACE
@@ -122,9 +120,7 @@ QString QWinRTFontDatabase::fontDir() const
const QString applicationDirPath = QCoreApplication::applicationDirPath();
fontDirectory = applicationDirPath + QLatin1String("/fonts");
if (!QFile::exists(fontDirectory)) {
-#ifdef QT_WINRT_USE_DWRITE
if (m_fontFamilies.isEmpty())
-#endif
qWarning("No fonts directory found in application package.");
fontDirectory = applicationDirPath;
}
@@ -132,8 +128,6 @@ QString QWinRTFontDatabase::fontDir() const
return fontDirectory;
}
-#ifdef QT_WINRT_USE_DWRITE
-
QWinRTFontDatabase::~QWinRTFontDatabase()
{
foreach (IDWriteFontFile *fontFile, m_fonts.keys())
@@ -449,13 +443,4 @@ void QWinRTFontDatabase::releaseHandle(void *handle)
QBasicFontDatabase::releaseHandle(handle);
}
-#else // QT_WINRT_USE_DWRITE
-
-QFont QWinRTFontDatabase::defaultFont() const
-{
- return QFont(QFontDatabase().families().value(0));
-}
-
-#endif // !QT_WINRT_USE_DWRITE
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
index 7b3f402c13..a88092e432 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -39,26 +39,21 @@
#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
-#ifdef QT_WINRT_USE_DWRITE
struct IDWriteFontFile;
struct IDWriteFontFamily;
-#endif
QT_BEGIN_NAMESPACE
-#ifdef QT_WINRT_USE_DWRITE
struct FontDescription
{
quint32 index;
QByteArray uuid;
};
-#endif
class QWinRTFontDatabase : public QBasicFontDatabase
{
public:
QString fontDir() const;
-#ifdef QT_WINRT_USE_DWRITE
~QWinRTFontDatabase();
QFont defaultFont() const Q_DECL_OVERRIDE;
bool fontsAlwaysScalable() const Q_DECL_OVERRIDE;
@@ -69,7 +64,6 @@ public:
private:
QHash<IDWriteFontFile *, FontDescription> m_fonts;
QHash<QString, IDWriteFontFamily *> m_fontFamilies;
-#endif // QT_WINRT_USE_DWRITE
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
index c94b53ef1c..f3b390b4d6 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -37,7 +37,9 @@
#include "qwinrtinputcontext.h"
#include "qwinrtscreen.h"
#include <QtGui/QWindow>
+#include <private/qeventdispatcher_winrt_p.h>
+#include <functional>
#include <wrl.h>
#include <roapi.h>
#include <windows.ui.viewmanagement.h>
@@ -163,10 +165,14 @@ void QWinRTInputContext::showInputPanel()
if (FAILED(hr))
return;
- boolean success;
- hr = inputPane->TryShow(&success);
- if (FAILED(hr))
- qErrnoWarning(hr, "Failed to show input panel.");
+ QEventDispatcherWinRT::runOnXamlThread([&inputPane]() {
+ HRESULT hr;
+ boolean success;
+ hr = inputPane->TryShow(&success);
+ if (FAILED(hr) || !success)
+ qErrnoWarning(hr, "Failed to show input panel.");
+ return hr;
+ });
}
void QWinRTInputContext::hideInputPanel()
@@ -176,141 +182,16 @@ void QWinRTInputContext::hideInputPanel()
if (FAILED(hr))
return;
- boolean success;
- hr = inputPane->TryHide(&success);
- if (FAILED(hr))
- qErrnoWarning(hr, "Failed to hide input panel.");
-}
-
-#else // Q_OS_WINPHONE
-
-// IRawElementProviderSimple
-HRESULT QWinRTInputContext::get_ProviderOptions(ProviderOptions *retVal)
-{
- *retVal = ProviderOptions_ServerSideProvider|ProviderOptions_UseComThreading;
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::GetPatternProvider(PATTERNID id, IUnknown **retVal)
-{
- switch (id) {
- case 10002: //UIA_ValuePatternId
- return QueryInterface(__uuidof(IValueProvider), (void**)retVal);
- break;
- case 10014: //UIA_TextPatternId:
- return QueryInterface(__uuidof(ITextProvider), (void**)retVal);
- case 10029: //UIA_TextChildPatternId:
- *retVal = nullptr;
- break;
- default:
- qWarning("Unhandled pattern ID: %d", id);
- break;
- }
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::GetPropertyValue(PROPERTYID idProp, VARIANT *retVal)
-{
- switch (idProp) {
- case 30003: //UIA_ControlTypePropertyId
- retVal->vt = VT_I4;
- retVal->lVal = 50025; //UIA_CustomControlTypeId
- break;
- case 30008: //UIA_IsKeyboardFocusablePropertyId
- case 30009: //UIA_HasKeyboardFocusPropertyId
- // These are probably never actually called
- case 30016: //UIA_IsControlElementPropertyId
- case 30017: //UIA_IsContentElementPropertyId
- retVal->vt = VT_BOOL;
- retVal->boolVal = VARIANT_TRUE;
- break;
- case 30019: //UIA_IsPasswordPropertyId
- retVal->vt = VT_BOOL;
- retVal->boolVal = VARIANT_FALSE;
- break;
- case 30020: //UIA_NativeWindowHandlePropertyId
- retVal->vt = VT_PTR;
- retVal->punkVal = m_screen->coreWindow();
- break;
- }
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::get_HostRawElementProvider(IRawElementProviderSimple **retVal)
-{
- // Return the window's element provider
- IInspectable *hostProvider;
- HRESULT hr = m_screen->coreWindow()->get_AutomationHostProvider(&hostProvider);
- if (SUCCEEDED(hr)) {
- hr = hostProvider->QueryInterface(IID_PPV_ARGS(retVal));
- hostProvider->Release();
- }
- return hr;
-}
-
-// ITextProvider
-HRESULT QWinRTInputContext::GetSelection(SAFEARRAY **)
-{
- // To be useful, requires listening to the focus object for a selection change and raising an event
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::GetVisibleRanges(SAFEARRAY **)
-{
- // To be useful, requires listening to the focus object for a selection change and raising an event
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::RangeFromChild(IRawElementProviderSimple *,ITextRangeProvider **)
-{
- // To be useful, requires listening to the focus object for a selection change and raising an event
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::RangeFromPoint(UiaPoint, ITextRangeProvider **)
-{
- // To be useful, requires listening to the focus object for a selection change and raising an event
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::get_DocumentRange(ITextRangeProvider **)
-{
- // To be useful, requires listening to the focus object for a selection change and raising an event
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::get_SupportedTextSelection(SupportedTextSelection *)
-{
- // To be useful, requires listening to the focus object for a selection change and raising an event
- return S_OK;
-}
-
-// IValueProvider
-HRESULT QWinRTInputContext::SetValue(LPCWSTR)
-{
- // To be useful, requires listening to the focus object for a value change and raising an event
- // May be useful for inputPanel autocomplete, etc.
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::get_Value(BSTR *)
-{
- // To be useful, requires listening to the focus object for a value change and raising an event
- // May be useful for inputPanel autocomplete, etc.
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::get_IsReadOnly(BOOL *isReadOnly)
-{
- // isReadOnly dictates keyboard opening behavior when view is tapped.
- // We need to decide if the user tapped within a control which is about to receive focus...
- // Since this isn't possible (this function gets called before we receive the touch event),
- // the most platform-aligned option is to show the keyboard if an editable item has focus,
- // and close the keyboard if it is already open.
- *isReadOnly = m_isInputPanelVisible || !inputMethodAccepted();
- return S_OK;
+ QEventDispatcherWinRT::runOnXamlThread([&inputPane]() {
+ HRESULT hr;
+ boolean success;
+ hr = inputPane->TryHide(&success);
+ if (FAILED(hr) || !success)
+ qErrnoWarning(hr, "Failed to hide input panel.");
+ return hr;
+ });
}
-#endif // !Q_OS_WINPHONE
+#endif // Q_OS_WINPHONE
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h
index ce7fbabf49..cc3bce435f 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.h
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h
@@ -41,9 +41,6 @@
#include <QtCore/QRectF>
#include <wrl.h>
-#ifndef Q_OS_WINPHONE
-# include <UIAutomationCore.h>
-#endif
namespace ABI {
namespace Windows {
@@ -63,11 +60,6 @@ QT_BEGIN_NAMESPACE
class QWinRTScreen;
class QWinRTInputContext : public QPlatformInputContext
-#ifndef Q_OS_WINPHONE
- , public Microsoft::WRL::RuntimeClass<
- Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
- IRawElementProviderSimple, ITextProvider, IValueProvider>
-#endif // !Q_OS_WINPHONE
{
public:
explicit QWinRTInputContext(QWinRTScreen *);
@@ -79,26 +71,7 @@ public:
#ifdef Q_OS_WINPHONE
void showInputPanel();
void hideInputPanel();
-#else // Q_OS_WINPHONE
- // IRawElementProviderSimple
- HRESULT __stdcall get_ProviderOptions(ProviderOptions *retVal);
- HRESULT __stdcall GetPatternProvider(PATTERNID, IUnknown **);
- HRESULT __stdcall GetPropertyValue(PROPERTYID idProp, VARIANT *retVal);
- HRESULT __stdcall get_HostRawElementProvider(IRawElementProviderSimple **retVal);
-
- // ITextProvider
- HRESULT __stdcall GetSelection(SAFEARRAY **);
- HRESULT __stdcall GetVisibleRanges(SAFEARRAY **);
- HRESULT __stdcall RangeFromChild(IRawElementProviderSimple *,ITextRangeProvider **);
- HRESULT __stdcall RangeFromPoint(UiaPoint, ITextRangeProvider **);
- HRESULT __stdcall get_DocumentRange(ITextRangeProvider **);
- HRESULT __stdcall get_SupportedTextSelection(SupportedTextSelection *);
-
- // IValueProvider
- HRESULT __stdcall SetValue(LPCWSTR);
- HRESULT __stdcall get_Value(BSTR *);
- HRESULT __stdcall get_IsReadOnly(BOOL *);
-#endif // !Q_OS_WINPHONE
+#endif
private:
HRESULT onShowing(ABI::Windows::UI::ViewManagement::IInputPane *,
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index 70ee6dbe6a..7079d46523 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -45,37 +45,138 @@
#include "qwinrtfontdatabase.h"
#include "qwinrttheme.h"
+#include <QtCore/QCoreApplication>
+#include <QtGui/QSurface>
#include <QtGui/QOpenGLContext>
+#include <qfunctions_winrt.h>
+#include <functional>
#include <wrl.h>
+#include <windows.ui.xaml.h>
+#include <windows.applicationmodel.h>
+#include <windows.applicationmodel.core.h>
#include <windows.ui.core.h>
#include <windows.ui.viewmanagement.h>
-#include <Windows.ApplicationModel.core.h>
+#include <windows.graphics.display.h>
+#ifdef Q_OS_WINPHONE
+# include <windows.phone.ui.input.h>
+#endif
using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::ApplicationModel;
+using namespace ABI::Windows::ApplicationModel::Core;
+using namespace ABI::Windows::UI;
using namespace ABI::Windows::UI::Core;
using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::Graphics::Display;
using namespace ABI::Windows::ApplicationModel::Core;
+#ifdef Q_OS_WINPHONE
+using namespace ABI::Windows::Phone::UI::Input;
+#endif
+
+typedef IEventHandler<IInspectable *> ResumeHandler;
+typedef IEventHandler<SuspendingEventArgs *> SuspendHandler;
+#ifdef Q_OS_WINPHONE
+typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
+#endif
QT_BEGIN_NAMESPACE
-QWinRTIntegration::QWinRTIntegration()
- : m_success(false)
- , m_fontDatabase(new QWinRTFontDatabase)
- , m_services(new QWinRTServices)
+typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken);
+uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
+#ifdef Q_OS_WINPHONE
+typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
+uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
+#endif
+
+class QWinRTIntegrationPrivate
+{
+public:
+ QPlatformFontDatabase *fontDatabase;
+ QPlatformServices *platformServices;
+ QWinRTScreen *mainScreen;
+ QScopedPointer<QWinRTInputContext> inputContext;
+
+ ComPtr<ICoreApplication> application;
+ QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
+#ifdef Q_OS_WINPHONE
+ ComPtr<IHardwareButtonsStatics> hardwareButtons;
+ QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
+#endif
+};
+
+QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
{
- m_screen = new QWinRTScreen;
- screenAdded(m_screen);
+ Q_D(QWinRTIntegration);
+
+ d->fontDatabase = new QWinRTFontDatabase;
+
+ HRESULT hr;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&d->application));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTIntegration::onSuspended).Get(),
+ &d->applicationTokens[&ICoreApplication::remove_Resuming]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTIntegration::onResume).Get(),
+ &d->applicationTokens[&ICoreApplication::remove_Resuming]);
+ Q_ASSERT_SUCCEEDED(hr);
- m_success = true;
+#ifdef Q_OS_WINPHONE
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(),
+ IID_PPV_ARGS(&d->hardwareButtons));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTIntegration::onBackButtonPressed).Get(),
+ &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]);
+ Q_ASSERT_SUCCEEDED(hr);
+#endif // Q_OS_WINPHONE
+
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr;
+ ComPtr<Xaml::IWindowStatics> windowStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(),
+ IID_PPV_ARGS(&windowStatics));
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IWindow> window;
+ hr = windowStatics->get_Current(&window);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = window->Activate();
+ Q_ASSERT_SUCCEEDED(hr);
+
+ d->mainScreen = new QWinRTScreen(window.Get());
+ d->inputContext.reset(new QWinRTInputContext(d->mainScreen));
+ screenAdded(d->mainScreen);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
}
QWinRTIntegration::~QWinRTIntegration()
{
+ Q_D(QWinRTIntegration);
+ HRESULT hr;
+#ifdef Q_OS_WINPHONE
+ for (QHash<HardwareButtonsCallbackRemover, EventRegistrationToken>::const_iterator i = d->buttonsTokens.begin(); i != d->buttonsTokens.end(); ++i) {
+ hr = (d->hardwareButtons.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+#endif
+ for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) {
+ hr = (d->application.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ destroyScreen(d->mainScreen);
Windows::Foundation::Uninitialize();
}
+bool QWinRTIntegration::succeeded() const
+{
+ Q_D(const QWinRTIntegration);
+ return d->mainScreen;
+}
+
QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const
{
return new QWinRTEventDispatcher;
@@ -112,28 +213,31 @@ QPlatformBackingStore *QWinRTIntegration::createPlatformBackingStore(QWindow *wi
QPlatformOpenGLContext *QWinRTIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- QWinRTScreen *screen = static_cast<QWinRTScreen *>(context->screen()->handle());
- return new QWinRTEGLContext(context->format(), context->handle(), screen->eglDisplay(), screen->eglSurface(), screen->eglConfig());
+ return new QWinRTEGLContext(context);
}
QPlatformFontDatabase *QWinRTIntegration::fontDatabase() const
{
- return m_fontDatabase;
+ Q_D(const QWinRTIntegration);
+ return d->fontDatabase;
}
QPlatformInputContext *QWinRTIntegration::inputContext() const
{
- return m_screen->inputContext();
+ Q_D(const QWinRTIntegration);
+ return d->inputContext.data();
}
QPlatformServices *QWinRTIntegration::services() const
{
- return m_services;
+ Q_D(const QWinRTIntegration);
+ return d->platformServices;
}
Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
{
- return m_screen->keyboardModifiers();
+ Q_D(const QWinRTIntegration);
+ return d->mainScreen->keyboardModifiers();
}
QStringList QWinRTIntegration::themeNames() const
@@ -149,4 +253,45 @@ name) const
return 0;
}
+
+// System-level integration points
+
+#ifdef Q_OS_WINPHONE
+HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
+{
+ Q_D(QWinRTIntegration);
+
+ QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
+ QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
+ backPress.setAccepted(false);
+ backRelease.setAccepted(false);
+
+ QWindow *window = d->mainScreen->topWindow();
+ QObject *receiver = window ? static_cast<QObject *>(window)
+ : static_cast<QObject *>(QCoreApplication::instance());
+
+ // If the event is ignored, the app go to the background
+ QCoreApplication::sendEvent(receiver, &backPress);
+ QCoreApplication::sendEvent(receiver, &backRelease);
+ args->put_Handled(backPress.isAccepted() || backRelease.isAccepted());
+
+ return S_OK;
+}
+#endif // Q_OS_WINPHONE
+
+HRESULT QWinRTIntegration::onSuspended(IInspectable *, ISuspendingEventArgs *)
+{
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
+ QWindowSystemInterface::flushWindowSystemEvents();
+ return S_OK;
+}
+
+HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *)
+{
+ // First the system invokes onResume and then changes
+ // the visibility of the screen to be active.
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
+ return S_OK;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h
index bbd6c1e41b..0115e034b5 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.h
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -39,11 +39,33 @@
#include <qpa/qplatformintegration.h>
+namespace ABI {
+ namespace Windows {
+ namespace ApplicationModel {
+ struct ISuspendingEventArgs;
+ }
+ namespace Foundation {
+ struct IAsyncAction;
+ }
+#ifdef Q_OS_WINPHONE
+ namespace Phone {
+ namespace UI {
+ namespace Input {
+ struct IBackPressedEventArgs;
+ }
+ }
+ }
+#endif
+ }
+}
+struct IAsyncInfo;
+struct IInspectable;
+
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
-class QWinRTScreen;
+class QWinRTIntegrationPrivate;
class QWinRTIntegration : public QPlatformIntegration
{
private:
@@ -53,10 +75,12 @@ public:
static QWinRTIntegration *create()
{
- QWinRTIntegration *integration = new QWinRTIntegration;
- return integration->m_success ? integration : 0;
+ QScopedPointer<QWinRTIntegration> integration(new QWinRTIntegration);
+ return integration->succeeded() ? integration.take() : nullptr;
}
+ bool succeeded() const;
+
bool hasCapability(QPlatformIntegration::Capability cap) const;
QVariant styleHint(StyleHint hint) const;
@@ -71,11 +95,16 @@ public:
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
+
private:
- bool m_success;
- QWinRTScreen *m_screen;
- QPlatformFontDatabase *m_fontDatabase;
- QPlatformServices *m_services;
+#ifdef Q_OS_WINPHONE
+ HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
+#endif
+ HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
+ HRESULT onResume(IInspectable *, IInspectable *);
+
+ QScopedPointer<QWinRTIntegrationPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTIntegration)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 1d36bb31f6..2a7cbaa159 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -36,26 +36,18 @@
#include "qwinrtscreen.h"
-#define EGL_EGLEXT_PROTOTYPES
-#include <EGL/eglext.h>
-#include <d3d11.h>
-#include <dxgi1_2.h>
-#ifndef Q_OS_WINPHONE
-#include <dxgi1_3.h>
-#endif
-
#include "qwinrtbackingstore.h"
#include "qwinrtinputcontext.h"
#include "qwinrtcursor.h"
-#include "qwinrteglcontext.h"
+#include <private/qeventdispatcher_winrt_p.h>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QGuiApplication>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/qt_windows.h>
#include <QtCore/qfunctions_winrt.h>
+#include <functional>
#include <wrl.h>
#include <windows.system.h>
#include <Windows.Applicationmodel.h>
@@ -64,12 +56,10 @@
#include <windows.ui.h>
#include <windows.ui.core.h>
#include <windows.ui.input.h>
+#include <windows.ui.xaml.h>
#include <windows.ui.viewmanagement.h>
#include <windows.graphics.display.h>
#include <windows.foundation.h>
-#ifdef Q_OS_WINPHONE
-#include <windows.phone.ui.input.h>
-#endif
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@@ -77,17 +67,13 @@ using namespace ABI::Windows::ApplicationModel;
using namespace ABI::Windows::ApplicationModel::Core;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::System;
+using namespace ABI::Windows::UI;
using namespace ABI::Windows::UI::Core;
using namespace ABI::Windows::UI::Input;
using namespace ABI::Windows::UI::ViewManagement;
using namespace ABI::Windows::Devices::Input;
using namespace ABI::Windows::Graphics::Display;
-#ifdef Q_OS_WINPHONE
-using namespace ABI::Windows::Phone::UI::Input;
-#endif
-typedef IEventHandler<IInspectable*> ResumeHandler;
-typedef IEventHandler<SuspendingEventArgs*> SuspendHandler;
typedef ITypedEventHandler<CoreWindow*, WindowActivatedEventArgs*> ActivatedHandler;
typedef ITypedEventHandler<CoreWindow*, CoreWindowEventArgs*> ClosedHandler;
typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterReceivedHandler;
@@ -96,11 +82,7 @@ typedef ITypedEventHandler<CoreWindow*, KeyEventArgs*> KeyHandler;
typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
-typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler;
typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
-#ifdef Q_OS_WINPHONE
-typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
-#endif
QT_BEGIN_NAMESPACE
@@ -419,33 +401,26 @@ static inline Qt::Key qKeyFromCode(quint32 code, int mods)
return static_cast<Qt::Key>(code & 0xff);
}
-typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken);
-uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistrationToken);
uint qHash(CoreWindowCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRegistrationToken);
uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
-#ifdef Q_OS_WINPHONE
-typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
-uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
-#endif
class QWinRTScreenPrivate
{
public:
- ComPtr<ICoreApplication> application;
+ QTouchDevice *touchDevice;
ComPtr<ICoreWindow> coreWindow;
+ ComPtr<Xaml::IDependencyObject> canvas;
+ ComPtr<IApplicationView> view;
ComPtr<IDisplayInformation> displayInformation;
#ifdef Q_OS_WINPHONE
- ComPtr<IHardwareButtonsStatics> hardwareButtons;
-#endif
+ ComPtr<IStatusBar> statusBar;
+#endif // Q_OS_WINPHONE
QScopedPointer<QWinRTCursor> cursor;
-#ifdef Q_OS_WINPHONE
- QScopedPointer<QWinRTInputContext> inputContext;
-#else
- ComPtr<QWinRTInputContext> inputContext;
-#endif
+
+ QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
QSizeF logicalSize;
QSurfaceFormat surfaceFormat;
@@ -458,68 +433,30 @@ public:
#ifndef Q_OS_WINPHONE
QHash<quint32, QPair<Qt::Key, QString>> activeKeys;
#endif
- QTouchDevice *touchDevice;
- QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
- EGLDisplay eglDisplay;
- EGLSurface eglSurface;
- EGLConfig eglConfig;
-
- QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens;
-#ifdef Q_OS_WINPHONE
- QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
-#endif
};
-QWinRTScreen::QWinRTScreen()
+// To be called from the XAML thread
+QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
: d_ptr(new QWinRTScreenPrivate)
{
Q_D(QWinRTScreen);
d->orientation = Qt::PrimaryOrientation;
d->touchDevice = Q_NULLPTR;
- d->eglDisplay = EGL_NO_DISPLAY;
- // Obtain the WinRT Application, view, and window
HRESULT hr;
- hr = RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
- IID_PPV_ARGS(&d->application));
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &d->applicationTokens[&ICoreApplication::remove_Resuming]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &d->applicationTokens[&ICoreApplication::remove_Resuming]);
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<ICoreApplicationView> view;
- hr = d->application->GetCurrentView(&view);
- Q_ASSERT_SUCCEEDED(hr);
- hr = view->get_CoreWindow(&d->coreWindow);
+ hr = xamlWindow->get_CoreWindow(&d->coreWindow);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->Activate();
Q_ASSERT_SUCCEEDED(hr);
-#ifdef Q_OS_WINPHONE
- d->inputContext.reset(new QWinRTInputContext(this));
-#else
- d->inputContext = Make<QWinRTInputContext>(this);
-#endif
-
Rect rect;
hr = d->coreWindow->get_Bounds(&rect);
Q_ASSERT_SUCCEEDED(hr);
d->logicalSize = QSizeF(rect.Width, rect.Height);
- d->surfaceFormat.setAlphaBufferSize(0);
- d->surfaceFormat.setRedBufferSize(8);
- d->surfaceFormat.setGreenBufferSize(8);
- d->surfaceFormat.setBlueBufferSize(8);
- d->surfaceFormat.setDepthBufferSize(24);
- d->surfaceFormat.setStencilBufferSize(8);
- d->surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
- d->surfaceFormat.setSamples(1);
- d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
-
hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]);
@@ -538,24 +475,14 @@ QWinRTScreen::QWinRTScreen()
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
Q_ASSERT_SUCCEEDED(hr);
-#ifndef Q_OS_WINPHONE
hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
Q_ASSERT_SUCCEEDED(hr);
-#endif
hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]);
Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &d->windowTokens[&ICoreWindow::remove_AutomationProviderRequested]);
- Q_ASSERT_SUCCEEDED(hr);
-#ifdef Q_OS_WINPHONE
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), IID_PPV_ARGS(&d->hardwareButtons));
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]);
- Q_ASSERT_SUCCEEDED(hr);
-#endif // Q_OS_WINPHONE
// Orientation handling
ComPtr<IDisplayInformationStatics> displayInformationStatics;
@@ -583,45 +510,43 @@ QWinRTScreen::QWinRTScreen()
d->orientation = d->nativeOrientation;
onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
- d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (d->eglDisplay == EGL_NO_DISPLAY)
- qCritical("Failed to initialize EGL display: 0x%x", eglGetError());
-
- if (!eglInitialize(d->eglDisplay, NULL, NULL))
- qCritical("Failed to initialize EGL: 0x%x", eglGetError());
-
- // Check that the device properly supports depth/stencil rendering, and disable them if not
- ComPtr<ID3D11Device> d3dDevice;
- const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf());
- if (ok && d3dDevice) {
- ComPtr<IDXGIDevice> dxgiDevice;
- hr = d3dDevice.As(&dxgiDevice);
- if (SUCCEEDED(hr)) {
- ComPtr<IDXGIAdapter> dxgiAdapter;
- hr = dxgiDevice->GetAdapter(&dxgiAdapter);
- if (SUCCEEDED(hr)) {
- ComPtr<IDXGIAdapter2> dxgiAdapter2;
- hr = dxgiAdapter.As(&dxgiAdapter2);
- if (SUCCEEDED(hr)) {
- DXGI_ADAPTER_DESC2 desc;
- hr = dxgiAdapter2->GetDesc2(&desc);
- if (SUCCEEDED(hr)) {
- // The following GPUs do not render properly with depth/stencil
- if ((desc.VendorId == 0x4d4f4351 && desc.DeviceId == 0x32303032)) { // Qualcomm Adreno 225
- d->surfaceFormat.setDepthBufferSize(-1);
- d->surfaceFormat.setStencilBufferSize(-1);
- }
- }
- }
- }
- }
- }
+ ComPtr<IApplicationViewStatics2> applicationViewStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
+ IID_PPV_ARGS(&applicationViewStatics));
+ RETURN_VOID_IF_FAILED("Could not get ApplicationViewStatics");
+
+ hr = applicationViewStatics->GetForCurrentView(&d->view);
+ RETURN_VOID_IF_FAILED("Could not access currentView");
+
+ // Create a canvas and set it as the window content. Eventually, this should have its own method so multiple "screens" can be added
+ ComPtr<Xaml::Controls::ICanvas> canvas;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(), &canvas);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IFrameworkElement> frameworkElement;
+ hr = canvas.As(&frameworkElement);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = frameworkElement->put_Width(d->logicalSize.width());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = frameworkElement->put_Height(d->logicalSize.height());
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IUIElement> uiElement;
+ hr = canvas.As(&uiElement);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = xamlWindow->put_Content(uiElement.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = canvas.As(&d->canvas);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ d->cursor.reset(new QWinRTCursor);
- d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->surfaceFormat);
- d->surfaceFormat = q_glFormatFromConfig(d->eglDisplay, d->eglConfig, d->surfaceFormat);
- d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), NULL);
- if (d->eglSurface == EGL_NO_SURFACE)
- qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
+#ifdef Q_OS_WINPHONE
+ ComPtr<IStatusBarStatics> statusBarStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_StatusBar).Get(),
+ IID_PPV_ARGS(&statusBarStatics));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = statusBarStatics->GetForCurrentView(&d->statusBar);
+ Q_ASSERT_SUCCEEDED(hr);
+#endif // Q_OS_WINPHONE
}
QWinRTScreen::~QWinRTScreen()
@@ -629,16 +554,20 @@ QWinRTScreen::~QWinRTScreen()
Q_D(QWinRTScreen);
// Unregister callbacks
- for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i)
- (d->application.Get()->*i.key())(i.value());
- for (QHash<CoreWindowCallbackRemover, EventRegistrationToken>::const_iterator i = d->windowTokens.begin(); i != d->windowTokens.end(); ++i)
- (d->coreWindow.Get()->*i.key())(i.value());
- for (QHash<DisplayCallbackRemover, EventRegistrationToken>::const_iterator i = d->displayTokens.begin(); i != d->displayTokens.end(); ++i)
- (d->displayInformation.Get()->*i.key())(i.value());
-#ifdef Q_OS_WINPHONE
- for (QHash<HardwareButtonsCallbackRemover, EventRegistrationToken>::const_iterator i = d->buttonsTokens.begin(); i != d->buttonsTokens.end(); ++i)
- (d->hardwareButtons.Get()->*i.key())(i.value());
-#endif
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr;
+ for (QHash<CoreWindowCallbackRemover, EventRegistrationToken>::const_iterator i = d->windowTokens.begin(); i != d->windowTokens.end(); ++i) {
+ hr = (d->coreWindow.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ for (QHash<DisplayCallbackRemover, EventRegistrationToken>::const_iterator i = d->displayTokens.begin(); i != d->displayTokens.end(); ++i) {
+ hr = (d->displayInformation.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ return hr;
+ });
+ RETURN_VOID_IF_FAILED("Failed to unregister screen event callbacks");
}
QRect QWinRTScreen::geometry() const
@@ -657,12 +586,6 @@ QImage::Format QWinRTScreen::format() const
return QImage::Format_ARGB32_Premultiplied;
}
-QSurfaceFormat QWinRTScreen::surfaceFormat() const
-{
- Q_D(const QWinRTScreen);
- return d->surfaceFormat;
-}
-
QSizeF QWinRTScreen::physicalSize() const
{
Q_D(const QWinRTScreen);
@@ -682,21 +605,9 @@ qreal QWinRTScreen::scaleFactor() const
return d->scaleFactor;
}
-QWinRTInputContext *QWinRTScreen::inputContext() const
-{
- Q_D(const QWinRTScreen);
-#ifdef Q_OS_WINPHONE
- return d->inputContext.data();
-#else
- return d->inputContext.Get();
-#endif
-}
-
QPlatformCursor *QWinRTScreen::cursor() const
{
Q_D(const QWinRTScreen);
- if (!d->cursor)
- const_cast<QWinRTScreenPrivate *>(d)->cursor.reset(new QWinRTCursor);
return d->cursor.data();
}
@@ -744,22 +655,10 @@ ICoreWindow *QWinRTScreen::coreWindow() const
return d->coreWindow.Get();
}
-EGLDisplay QWinRTScreen::eglDisplay() const
+Xaml::IDependencyObject *QWinRTScreen::canvas() const
{
Q_D(const QWinRTScreen);
- return d->eglDisplay;
-}
-
-EGLSurface QWinRTScreen::eglSurface() const
-{
- Q_D(const QWinRTScreen);
- return d->eglSurface;
-}
-
-EGLConfig QWinRTScreen::eglConfig() const
-{
- Q_D(const QWinRTScreen);
- return d->eglConfig;
+ return d->canvas.Get();
}
QWindow *QWinRTScreen::topWindow() const
@@ -773,6 +672,19 @@ void QWinRTScreen::addWindow(QWindow *window)
Q_D(QWinRTScreen);
if (window == topWindow())
return;
+
+#ifdef Q_OS_WINPHONE
+ if (d->statusBar && (window->flags() & Qt::WindowType_Mask) == Qt::Window) {
+ QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr;
+ ComPtr<IAsyncAction> op;
+ hr = d->statusBar->HideAsync(&op);
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ }
+#endif // Q_OS_WINPHONE
+
d->visibleWindows.prepend(window);
QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
handleExpose();
@@ -809,6 +721,20 @@ void QWinRTScreen::lower(QWindow *window)
handleExpose();
}
+void QWinRTScreen::updateWindowTitle()
+{
+ Q_D(QWinRTScreen);
+
+ QWindow *window = topWindow();
+ if (!window)
+ return;
+
+ const QString title = window->title();
+ HStringReference titleRef(reinterpret_cast<LPCWSTR>(title.utf16()), title.length());
+ HRESULT hr = d->view->put_Title(titleRef.Get());
+ RETURN_VOID_IF_FAILED("Unable to set window title");
+}
+
void QWinRTScreen::handleExpose()
{
Q_D(QWinRTScreen);
@@ -1055,17 +981,6 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
return S_OK;
}
-HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args)
-{
-#ifndef Q_OS_WINPHONE
- Q_D(const QWinRTScreen);
- args->put_AutomationProvider(d->inputContext.Get());
-#else
- Q_UNUSED(args)
-#endif
- return S_OK;
-}
-
HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *)
{
Q_D(QWinRTScreen);
@@ -1075,18 +990,14 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
hr = d->coreWindow->get_Bounds(&size);
RETURN_OK_IF_FAILED("Failed to get window bounds");
QSizeF logicalSize = QSizeF(size.Width, size.Height);
-#ifndef Q_OS_WINPHONE // This handler is called from orientation changed, in which case we should always update the size
if (d->logicalSize == logicalSize)
return S_OK;
-#endif
d->logicalSize = logicalSize;
- if (d->eglDisplay) {
- const QRect newGeometry = geometry();
- QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
- QPlatformScreen::resizeMaximizedWindows();
- handleExpose();
- }
+ const QRect newGeometry = geometry();
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
+ QPlatformScreen::resizeMaximizedWindows();
+ handleExpose();
return S_OK;
}
@@ -1110,31 +1021,6 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args
return S_OK;
}
-HRESULT QWinRTScreen::onSuspended(IInspectable *, ISuspendingEventArgs *)
-{
-#ifndef Q_OS_WINPHONE
- Q_D(QWinRTScreen);
- ComPtr<ID3D11Device> d3dDevice;
- const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf());
- if (ok && d3dDevice) {
- ComPtr<IDXGIDevice3> dxgiDevice;
- if (SUCCEEDED(d3dDevice.As(&dxgiDevice)))
- dxgiDevice->Trim();
- }
-#endif
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
- QWindowSystemInterface::flushWindowSystemEvents();
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onResume(IInspectable *, IInspectable *)
-{
- // First the system invokes onResume and then changes
- // the visibility of the screen to be active.
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
- return S_OK;
-}
-
HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
{
foreach (QWindow *w, QGuiApplication::topLevelWindows())
@@ -1165,10 +1051,6 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
d->orientation = newOrientation;
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
}
-
-#ifdef Q_OS_WINPHONE // The size changed handler is ignored in favor of this callback
- onSizeChanged(Q_NULLPTR, Q_NULLPTR);
-#endif
return S_OK;
}
@@ -1205,27 +1087,4 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
return S_OK;
}
-#ifdef Q_OS_WINPHONE
-HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
-{
- Q_D(QWinRTScreen);
-
- QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
- QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
- backPress.setAccepted(false);
- backRelease.setAccepted(false);
-
- QObject *receiver = d->visibleWindows.isEmpty()
- ? static_cast<QObject *>(QGuiApplication::instance())
- : static_cast<QObject *>(d->visibleWindows.first());
-
- // If the event is ignored, the app will suspend
- QGuiApplication::sendEvent(receiver, &backPress);
- QGuiApplication::sendEvent(receiver, &backRelease);
- args->put_Handled(backPress.isAccepted() || backRelease.isAccepted());
-
- return S_OK;
-}
-#endif // Q_OS_WINPHONE
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index d34ce75748..796e6abb80 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -40,8 +40,6 @@
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
-#include <EGL/egl.h>
-
namespace ABI {
namespace Windows {
namespace ApplicationModel {
@@ -59,21 +57,16 @@ namespace ABI {
struct IWindowActivatedEventArgs;
struct IWindowSizeChangedEventArgs;
}
+ namespace Xaml {
+ struct IDependencyObject;
+ struct IWindow;
+ }
}
namespace Graphics {
namespace Display {
struct IDisplayInformation;
}
}
-#ifdef Q_OS_WINPHONE
- namespace Phone {
- namespace UI {
- namespace Input {
- struct IBackPressedEventArgs;
- }
- }
- }
-#endif
}
}
struct IInspectable;
@@ -81,23 +74,20 @@ struct IInspectable;
QT_BEGIN_NAMESPACE
class QTouchDevice;
-class QWinRTEGLContext;
class QWinRTCursor;
class QWinRTInputContext;
class QWinRTScreenPrivate;
class QWinRTScreen : public QPlatformScreen
{
public:
- explicit QWinRTScreen();
+ explicit QWinRTScreen(ABI::Windows::UI::Xaml::IWindow *xamlWindow);
~QWinRTScreen();
QRect geometry() const;
int depth() const;
QImage::Format format() const;
- QSurfaceFormat surfaceFormat() const;
QSizeF physicalSize() const Q_DECL_OVERRIDE;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
qreal scaleFactor() const;
- QWinRTInputContext *inputContext() const;
QPlatformCursor *cursor() const;
Qt::KeyboardModifiers keyboardModifiers() const;
@@ -110,10 +100,10 @@ public:
void raise(QWindow *window);
void lower(QWindow *window);
+ void updateWindowTitle();
+
ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
- EGLDisplay eglDisplay() const; // To opengl context
- EGLSurface eglSurface() const; // To window
- EGLConfig eglConfig() const;
+ ABI::Windows::UI::Xaml::IDependencyObject *canvas() const;
private:
void handleExpose();
@@ -127,20 +117,13 @@ private:
HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *);
- HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
- HRESULT onResume(IInspectable *, IInspectable *);
HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *);
HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *);
- HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *);
HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-#ifdef Q_OS_WINPHONE
- HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
-#endif
-
QScopedPointer<QWinRTScreenPrivate> d_ptr;
Q_DECLARE_PRIVATE(QWinRTScreen)
};
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index adc5dfb776..634d62ef24 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -36,47 +36,138 @@
#include "qwinrtwindow.h"
#include "qwinrtscreen.h"
+#include <private/qeventdispatcher_winrt_p.h>
-#include <qpa/qwindowsysteminterface.h>
+#include <EGL/egl.h>
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/eglext.h>
+
+#include <qfunctions_winrt.h>
#include <qpa/qplatformscreen.h>
+#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QGuiApplication>
-#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QWindow>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
-#include <qfunctions_winrt.h>
-#include <windows.ui.viewmanagement.h>
+#include <functional>
#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#include <windows.ui.xaml.h>
+#include <windows.ui.xaml.controls.h>
+#include <windows.ui.viewmanagement.h>
using namespace ABI::Windows::UI::ViewManagement;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::UI;
QT_BEGIN_NAMESPACE
+class QWinRTWindowPrivate
+{
+public:
+ QWinRTScreen *screen;
+
+ QSurfaceFormat surfaceFormat;
+ QString windowTitle;
+
+ ComPtr<Xaml::Controls::ISwapChainPanel> swapChainPanel;
+};
+
QWinRTWindow::QWinRTWindow(QWindow *window)
: QPlatformWindow(window)
- , m_screen(static_cast<QWinRTScreen*>(screen()))
+ , d_ptr(new QWinRTWindowPrivate)
{
+ Q_D(QWinRTWindow);
+
+ d->screen = static_cast<QWinRTScreen *>(screen());
setWindowFlags(window->flags());
setWindowState(window->windowState());
setWindowTitle(window->title());
handleContentOrientationChange(window->contentOrientation());
+
+ d->surfaceFormat.setAlphaBufferSize(0);
+ d->surfaceFormat.setRedBufferSize(8);
+ d->surfaceFormat.setGreenBufferSize(8);
+ d->surfaceFormat.setBlueBufferSize(8);
+ d->surfaceFormat.setDepthBufferSize(24);
+ d->surfaceFormat.setStencilBufferSize(8);
+ d->surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
+ d->surfaceFormat.setSamples(1);
+ d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ // Create a new swapchain and place it inside the canvas
+ HRESULT hr;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_SwapChainPanel).Get(),
+ &d->swapChainPanel);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IUIElement> uiElement;
+ hr = d->swapChainPanel.As(&uiElement);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<Xaml::IDependencyObject> canvas = d->screen->canvas();
+ ComPtr<Xaml::Controls::IPanel> panel;
+ hr = canvas.As(&panel);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVector<Xaml::UIElement *>> children;
+ hr = panel->get_Children(&children);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = children->Append(uiElement.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+
setGeometry(window->geometry());
}
QWinRTWindow::~QWinRTWindow()
{
- m_screen->removeWindow(window());
+ Q_D(QWinRTWindow);
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
+ HRESULT hr;
+ ComPtr<Xaml::IDependencyObject> canvas = d->screen->canvas();
+ ComPtr<Xaml::Controls::IPanel> panel;
+ hr = canvas.As(&panel);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVector<Xaml::UIElement *>> children;
+ hr = panel->get_Children(&children);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<Xaml::IUIElement> uiElement;
+ hr = d->swapChainPanel.As(&uiElement);
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 index;
+ boolean found;
+ hr = children->IndexOf(uiElement.Get(), &index, &found);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (found) {
+ hr = children->RemoveAt(index);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ return S_OK;
+ });
+ RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down");
}
QSurfaceFormat QWinRTWindow::format() const
{
- return m_screen->surfaceFormat();
+ Q_D(const QWinRTWindow);
+ return d->surfaceFormat;
}
bool QWinRTWindow::isActive() const
{
- return m_screen->topWindow() == window();
+ Q_D(const QWinRTWindow);
+ return d->screen->topWindow() == window();
}
bool QWinRTWindow::isExposed() const
@@ -87,55 +178,70 @@ bool QWinRTWindow::isExposed() const
void QWinRTWindow::setGeometry(const QRect &rect)
{
+ Q_D(QWinRTWindow);
+
if (window()->isTopLevel()) {
- QPlatformWindow::setGeometry(m_screen->geometry());
+ QPlatformWindow::setGeometry(d->screen->geometry());
QWindowSystemInterface::handleGeometryChange(window(), geometry());
} else {
QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(window(), rect);
}
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr;
+ ComPtr<Xaml::IFrameworkElement> frameworkElement;
+ hr = d->swapChainPanel.As(&frameworkElement);
+ Q_ASSERT_SUCCEEDED(hr);
+ const QSizeF size = QSizeF(geometry().size()) / d->screen->scaleFactor();
+ hr = frameworkElement->put_Width(size.width());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = frameworkElement->put_Height(size.height());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
}
void QWinRTWindow::setVisible(bool visible)
{
+ Q_D(QWinRTWindow);
if (!window()->isTopLevel())
return;
if (visible)
- m_screen->addWindow(window());
+ d->screen->addWindow(window());
else
- m_screen->removeWindow(window());
+ d->screen->removeWindow(window());
}
void QWinRTWindow::setWindowTitle(const QString &title)
{
- ComPtr<IApplicationViewStatics2> statics;
- HRESULT hr;
-
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
- IID_PPV_ARGS(&statics));
- RETURN_VOID_IF_FAILED("Could not get ApplicationViewStatics");
-
- ComPtr<IApplicationView> view;
- hr = statics->GetForCurrentView(&view);
- RETURN_VOID_IF_FAILED("Could not access currentView");
-
- HStringReference str(reinterpret_cast<LPCWSTR>(title.utf16()), title.length());
- hr = view->put_Title(str.Get());
- RETURN_VOID_IF_FAILED("Unable to set window title");
+ Q_D(QWinRTWindow);
+ d->windowTitle = title;
+ d->screen->updateWindowTitle();
}
void QWinRTWindow::raise()
{
+ Q_D(QWinRTWindow);
if (!window()->isTopLevel())
return;
- m_screen->raise(window());
+ d->screen->raise(window());
}
void QWinRTWindow::lower()
{
+ Q_D(QWinRTWindow);
if (!window()->isTopLevel())
return;
- m_screen->lower(window());
+ d->screen->lower(window());
+}
+
+WId QWinRTWindow::winId() const
+{
+ Q_D(const QWinRTWindow);
+ return WId(d->swapChainPanel.Get());
}
qreal QWinRTWindow::devicePixelRatio() const
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 3cfe346ab2..88c149b080 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -42,8 +42,7 @@
QT_BEGIN_NAMESPACE
-class QWinRTScreen;
-
+class QWinRTWindowPrivate;
class QWinRTWindow : public QPlatformWindow
{
public:
@@ -59,10 +58,13 @@ public:
void raise();
void lower();
+ WId winId() const Q_DECL_OVERRIDE;
+
qreal devicePixelRatio() const Q_DECL_OVERRIDE;
private:
- QWinRTScreen *m_screen;
+ QScopedPointer<QWinRTWindowPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTWindow)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index 80429daeed..2718ea62bb 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -1,14 +1,6 @@
TARGET = qwinrt
CONFIG -= precompile_header
-# For Windows Phone 8 we have to deploy fonts together with the application as DirectWrite
-# is not supported here.
-winphone:equals(WINSDK_VER, 8.0): {
- fonts.path = $$[QT_INSTALL_LIBS]/fonts
- fonts.files = $$QT_SOURCE_TREE/lib/fonts/DejaVu*.ttf
- INSTALLS += fonts
-}
-
PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin
!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
@@ -18,13 +10,8 @@ QT += core-private gui-private platformsupport-private
DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES
-LIBS += $$QMAKE_LIBS_CORE
-
-!if(winphone:equals(WINSDK_VER, 8.0)) {
- LIBS += -ldwrite
- INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include
- DEFINES += QT_WINRT_USE_DWRITE
-}
+LIBS += $$QMAKE_LIBS_CORE -ldwrite
+INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include
SOURCES = \
main.cpp \
@@ -60,9 +47,4 @@ HEADERS = \
qwinrttheme.h \
qwinrtwindow.h
-winphone:equals(WINSDK_VER, 8.0): {
- SOURCES -= qwinrtplatformmessagedialoghelper.cpp
- HEADERS -= qwinrtplatformmessagedialoghelper.h
-}
-
OTHER_FILES += winrt.json
diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp
index 10411e72e2..508f5e82e6 100644
--- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp
@@ -78,6 +78,7 @@ QStringList QXcbGlIntegrationFactory::keys(const QString &pluginPath)
list.append(loader()->keyMap().values());
return list;
#else
+ Q_UNUSED(pluginPath);
return QStringList();
#endif
}
@@ -93,6 +94,9 @@ QXcbGlIntegration *QXcbGlIntegrationFactory::create(const QString &platform, con
}
if (QXcbGlIntegration *ret = loadIntegration(loader(), platform))
return ret;
+#else
+ Q_UNUSED(platform);
+ Q_UNUSED(pluginPath);
#endif
return Q_NULLPTR;
}
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 8b14fc7d70..37f01d4eed 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -188,16 +188,18 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
Window window = 0; // Temporary window used to query OpenGL context
if (config) {
+ const QByteArrayList glxExt = QByteArray(glXQueryExtensionsString(m_display, screen->screenNumber())).split(' ');
+
// Resolve entry point for glXCreateContextAttribsARB
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
- glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
+ if (glxExt.contains("GLX_ARB_create_context"))
+ glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
- QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(m_display, screen->screenNumber())).split(' ');
- bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile");
+ const bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile");
// Use glXCreateContextAttribsARB if available
// Also, GL ES context creation requires GLX_EXT_create_context_es2_profile
- if (glxExt.contains("GLX_ARB_create_context") && glXCreateContextAttribsARB != 0
+ if (glXCreateContextAttribsARB != 0
&& (m_format.renderableType() != QSurfaceFormat::OpenGLES || (supportsProfiles && glxExt.contains("GLX_EXT_create_context_es2_profile")))) {
// Try to create an OpenGL context for each known OpenGL version in descending
// order from the requested version.
@@ -561,10 +563,12 @@ void (*QGLXContext::getProcAddress(const QByteArray &procName)) ()
if (!glXGetProcAddressARB)
#endif
{
+#ifndef QT_NO_LIBRARY
extern const QString qt_gl_library_name();
// QLibrary lib(qt_gl_library_name());
QLibrary lib(QLatin1String("GL"));
glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
+#endif
}
}
resolved = true;
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index c0f5477f82..e62d515b62 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -49,6 +49,7 @@
#include <qdebug.h>
#include <qpainter.h>
#include <qscreen.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <qpa/qplatformgraphicsbuffer.h>
#include <algorithm>
@@ -313,14 +314,7 @@ void QXcbBackingStore::beginPaint(const QRegion &region)
if (!m_image)
return;
- int dpr = int(m_image->image()->devicePixelRatio());
- const int windowDpr = int(window()->devicePixelRatio());
- if (windowDpr != dpr) {
- resize(window()->size(), QRegion());
- dpr = int(m_image->image()->devicePixelRatio());
- }
-
- m_paintRegion = dpr == 1 ? region : QTransform::fromScale(dpr,dpr).map(region);
+ m_paintRegion = region;
m_image->preparePaint(m_paintRegion);
if (m_image->image()->hasAlphaChannel()) {
@@ -369,18 +363,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
if (!m_image || m_image->size().isEmpty())
return;
- const int dpr = int(window->devicePixelRatio());
-
-#ifndef QT_NO_DEBUG
- const int imageDpr = int(m_image->image()->devicePixelRatio());
- if (dpr != imageDpr)
- qWarning() << "QXcbBackingStore::flush() wrong devicePixelRatio for backingstore image" << dpr << imageDpr;
-#endif
-
- QSize imageSize = m_image->size() / dpr; //because we multiply with the DPR later
+ QSize imageSize = m_image->size();
QRegion clipped = region;
- clipped &= QRect(0, 0, window->width(), window->height());
+ clipped &= QRect(QPoint(), QHighDpi::toNativePixels(window->size(), window));
clipped &= QRect(0, 0, imageSize.width(), imageSize.height()).translated(-offset);
QRect bounds = clipped.boundingRect();
@@ -398,8 +384,8 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
QVector<QRect> rects = clipped.rects();
for (int i = 0; i < rects.size(); ++i) {
- QRect rect = QRect(rects.at(i).topLeft() * dpr, rects.at(i).size() * dpr);
- m_image->put(platformWindow->xcb_window(), rect.topLeft(), rect.translated(offset * dpr));
+ QRect rect = QRect(rects.at(i).topLeft(), rects.at(i).size());
+ m_image->put(platformWindow->xcb_window(), rect.topLeft(), rect.translated(offset));
}
Q_XCB_NOOP(connection());
@@ -430,9 +416,7 @@ void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion &region, c
void QXcbBackingStore::resize(const QSize &size, const QRegion &)
{
- const int dpr = int(window()->devicePixelRatio());
- const QSize xSize = size * dpr;
- if (m_image && xSize == m_image->size() && dpr == m_image->image()->devicePixelRatio())
+ if (m_image && size == m_image->size())
return;
Q_XCB_NOOP(connection());
@@ -445,13 +429,11 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &)
QXcbWindow* win = static_cast<QXcbWindow *>(pw);
delete m_image;
- m_image = new QXcbShmImage(screen, xSize, win->depth(), win->imageFormat());
- m_image->image()->setDevicePixelRatio(dpr);
+ m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat());
// Slow path for bgr888 VNC: Create an additional image, paint into that and
// swap R and B while copying to m_image after each paint.
if (win->imageNeedsRgbSwap()) {
- m_rgbImage = QImage(xSize, win->imageFormat());
- m_rgbImage.setDevicePixelRatio(dpr);
+ m_rgbImage = QImage(size, win->imageFormat());
}
Q_XCB_NOOP(connection());
}
@@ -463,14 +445,12 @@ bool QXcbBackingStore::scroll(const QRegion &area, int dx, int dy)
if (!m_image || m_image->image()->isNull())
return false;
- const int dpr = int(m_image->image()->devicePixelRatio());
- QRegion xArea = dpr == 1 ? area : QTransform::fromScale(dpr,dpr).map(area);
m_image->preparePaint(area);
- QPoint delta(dx * dpr, dy * dpr);
- const QVector<QRect> xRects = xArea.rects();
- for (int i = 0; i < xRects.size(); ++i)
- qt_scrollRectInImage(*m_image->image(), xRects.at(i), delta);
+ QPoint delta(dx, dy);
+ const QVector<QRect> rects = area.rects();
+ for (int i = 0; i < rects.size(); ++i)
+ qt_scrollRectInImage(*m_image->image(), rects.at(i), delta);
return true;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index d2e08aecee..e612cff9a3 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -590,9 +590,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
qCDebug(QT_XCB_GLINTEGRATION) << "Failed to create xcb gl-integration";
sync();
-
- if (qEnvironmentVariableIsEmpty("QT_IM_MODULE"))
- qputenv("QT_IM_MODULE", QByteArray("compose"));
}
QXcbConnection::~QXcbConnection()
@@ -2074,10 +2071,11 @@ bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCo
}
#endif // defined(XCB_USE_XINPUT2)
-QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker()
+QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const
{
if (!m_systemTrayTracker) {
- if ( (m_systemTrayTracker = QXcbSystemTrayTracker::create(this)) ) {
+ QXcbConnection *self = const_cast<QXcbConnection *>(this);
+ if ((self->m_systemTrayTracker = QXcbSystemTrayTracker::create(self))) {
connect(m_systemTrayTracker, SIGNAL(systemTrayWindowChanged(QScreen*)),
QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)));
}
@@ -2085,6 +2083,22 @@ QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker()
return m_systemTrayTracker;
}
+bool QXcbConnection::xEmbedSystemTrayAvailable()
+{
+ if (!QGuiApplicationPrivate::platformIntegration())
+ return false;
+ QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection();
+ return connection->systemTrayTracker();
+}
+
+bool QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel()
+{
+ if (!QGuiApplicationPrivate::platformIntegration())
+ return false;
+ QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection();
+ return connection->systemTrayTracker() && connection->systemTrayTracker()->visualHasAlphaChannel();
+}
+
bool QXcbConnection::event(QEvent *e)
{
if (e->type() == QEvent::User + 1) {
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index a183a72353..4a0348aa0c 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -474,7 +474,9 @@ public:
QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; }
- QXcbSystemTrayTracker *systemTrayTracker();
+ QXcbSystemTrayTracker *systemTrayTracker() const;
+ static bool xEmbedSystemTrayAvailable();
+ static bool xEmbedSystemTrayVisualHasAlphaChannel();
#ifdef XCB_USE_XINPUT2
void handleEnterEvent(const xcb_enter_notify_event_t *);
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index d7688be0ff..7a5480a8a5 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -562,10 +562,8 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
}
QWindowSystemInterface::TouchPoint &touchPoint = dev->touchPoints[xiDeviceEvent->detail];
QXcbScreen* screen = platformWindow->xcbScreen();
- QPointF pos = screen->mapFromNative(QPointF(fixed1616ToReal(xiDeviceEvent->root_x),
- fixed1616ToReal(xiDeviceEvent->root_y)));
- qreal x = pos.x();
- qreal y = pos.y();
+ qreal x = fixed1616ToReal(xiDeviceEvent->root_x);
+ qreal y = fixed1616ToReal(xiDeviceEvent->root_y);
qreal nx = -1.0, ny = -1.0, d = 0.0;
for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) {
XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i];
@@ -872,9 +870,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
}
}
if (!angleDelta.isNull()) {
- const int dpr = int(platformWindow->devicePixelRatio());
- QPoint local(fixed1616ToReal(xiDeviceEvent->event_x)/dpr, fixed1616ToReal(xiDeviceEvent->event_y)/dpr);
- QPoint global(fixed1616ToReal(xiDeviceEvent->root_x)/dpr, fixed1616ToReal(xiDeviceEvent->root_y)/dpr);
+ QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y));
+ QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y));
Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
if (modifiers & Qt::AltModifier) {
std::swap(angleDelta.rx(), angleDelta.ry());
@@ -900,9 +897,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
angleDelta.setX(-120);
}
if (!angleDelta.isNull()) {
- const int dpr = int(platformWindow->devicePixelRatio());
- QPoint local(fixed1616ToReal(xiDeviceEvent->event_x)/dpr, fixed1616ToReal(xiDeviceEvent->event_y)/dpr);
- QPoint global(fixed1616ToReal(xiDeviceEvent->root_x)/dpr, fixed1616ToReal(xiDeviceEvent->root_y)/dpr);
+ QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y));
+ QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y));
Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
if (modifiers & Qt::AltModifier)
std::swap(angleDelta.rx(), angleDelta.ry());
@@ -1024,9 +1020,8 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
tabletData->inProximity = true;
tabletData->tool = toolIdToTabletDevice(tool);
tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_TOOL_SERIAL]);
- QWindowSystemInterface::handleTabletEnterProximityEvent(tabletData->tool,
- tabletData->pointerType,
- tabletData->serialId);
+ QWindowSystemInterface::handleTabletEnterProximityEvent(ev->time,
+ tabletData->tool, tabletData->pointerType, tabletData->serialId);
} else {
tabletData->inProximity = false;
tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_ID]);
@@ -1035,9 +1030,8 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
if (!tabletData->tool)
tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_SERIAL]);
tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_LAST_TOOL_SERIAL]);
- QWindowSystemInterface::handleTabletLeaveProximityEvent(tabletData->tool,
- tabletData->pointerType,
- tabletData->serialId);
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(ev->time,
+ tabletData->tool, tabletData->pointerType, tabletData->serialId);
}
// TODO maybe have a hash of tabletData->deviceId to device data so we can
// look up the tablet name here, and distinguish multiple tablets
@@ -1115,13 +1109,14 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event)
}
if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled()))
- qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf",
- tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail,
+ qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d seq %d detail %d time %d "
+ "pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf",
+ tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, ev->time,
fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y),
fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y),
(int)tabletData.buttons, pressure, xTilt, yTilt, rotation);
- QWindowSystemInterface::handleTabletEvent(window, local, global,
+ QWindowSystemInterface::handleTabletEvent(window, ev->time, local, global,
tabletData.tool, tabletData.pointerType,
tabletData.buttons, pressure,
xTilt, yTilt, tangentialPressure,
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index bd880698e6..0cd9159052 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -52,7 +52,7 @@ typedef char *(*PtrXcursorLibraryGetTheme)(void *);
typedef int (*PtrXcursorLibrarySetTheme)(void *, const char *);
typedef int (*PtrXcursorLibraryGetDefaultSize)(void *);
-#ifdef XCB_USE_XLIB
+#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY)
#include <X11/Xlib.h>
enum {
XCursorShape = CursorShape
@@ -300,7 +300,7 @@ QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen)
const char *cursorStr = "cursor";
xcb_open_font(xcb_connection(), cursorFont, strlen(cursorStr), cursorStr);
-#ifdef XCB_USE_XLIB
+#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY)
static bool function_ptrs_not_initialized = true;
if (function_ptrs_not_initialized) {
QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
@@ -491,7 +491,7 @@ xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
return cursor;
}
-#ifdef XCB_USE_XLIB
+#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY)
bool updateCursorTheme(void *dpy, const QByteArray &theme) {
if (!ptrXcursorLibraryGetTheme
|| !ptrXcursorLibrarySetTheme)
@@ -535,7 +535,7 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape)
}
return cursor;
}
-#endif //XCB_USE_XLIB
+#endif //XCB_USE_XLIB / QT_NO_LIBRARY
xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
{
@@ -544,7 +544,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
xcb_cursor_t cursor = XCB_NONE;
// Try Xcursor first
-#ifdef XCB_USE_XLIB
+#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY)
if (cshape >= 0 && cshape <= Qt::LastCursor) {
void *dpy = connection()->xlib_display();
// special case for non-standard dnd-* cursors
@@ -637,15 +637,14 @@ QPoint QXcbCursor::pos() const
{
QPoint p;
queryPointer(connection(), 0, &p);
- return m_screen->mapFromNative(p);
+ return p;
}
void QXcbCursor::setPos(const QPoint &pos)
{
- const QPoint xPos = m_screen->mapToNative(pos);
xcb_window_t root = 0;
queryPointer(connection(), &root, 0);
- xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, xPos.x(), xPos.y());
+ xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y());
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h
index 7e5cdc6870..f4f6e61706 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.h
+++ b/src/plugins/platforms/xcb/qxcbcursor.h
@@ -90,7 +90,7 @@ private:
#ifndef QT_NO_CURSOR
CursorHash m_cursorHash;
#endif
-#ifdef XCB_USE_XLIB
+#if defined(XCB_USE_XLIB) && !defined(QT_NO_LIBRARY)
static void cursorThemePropertyChanged(QXcbVirtualDesktop *screen,
const QByteArray &name,
const QVariant &property,
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 1d13adf851..a3e646ed7a 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -51,6 +51,7 @@
#include <private/qshapedpixmapdndwindow_p.h>
#include <private/qsimpledrag_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -71,12 +72,16 @@ QT_BEGIN_NAMESPACE
const int xdnd_version = 5;
+static inline xcb_window_t xcb_window(QPlatformWindow *w)
+{
+ return static_cast<QXcbWindow *>(w)->xcb_window();
+}
+
static inline xcb_window_t xcb_window(QWindow *w)
{
return static_cast<QXcbWindow *>(w->handle())->xcb_window();
}
-
static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w)
{
xcb_window_t proxy = XCB_NONE;
@@ -297,15 +302,8 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
return 0;
}
-void QXcbDrag::move(const QMouseEvent *me)
+void QXcbDrag::move(const QPoint &globalPos)
{
- // The mouse event is in the coordinate system of the window that started the drag.
- // We do not know which window that was at this point, so we just use the device pixel ratio
- // of the QGuiApplication. This will break once we support screens with different DPR. Fixing
- // this properly requires some redesign of the drag and drop architecture.
- static const int dpr = int(qApp->devicePixelRatio());
- QBasicDrag::move(me);
- QPoint globalPos = me->globalPos();
if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
return;
@@ -318,6 +316,9 @@ void QXcbDrag::move(const QMouseEvent *me)
break;
}
}
+
+ QBasicDrag::moveShapedPixmapWindow(QHighDpiScaling::mapPositionFromNative(globalPos, screen));
+
if (screen != current_screen) {
// ### need to recreate the shaped pixmap window?
// int screen = QCursor::x11Screen();
@@ -340,7 +341,7 @@ void QXcbDrag::move(const QMouseEvent *me)
// qt_xdnd_current_screen = screen;
xcb_window_t rootwin = current_screen->root();
xcb_translate_coordinates_reply_t *translate =
- ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x() * dpr, globalPos.y() * dpr);
+ ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y());
if (!translate)
return;
@@ -443,7 +444,7 @@ void QXcbDrag::move(const QMouseEvent *me)
DEBUG() << "sending Xdnd enter source=" << enter.data.data32[0];
if (w)
- handleEnter(w->window(), &enter);
+ handleEnter(w, &enter);
else if (target)
xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&enter);
waiting_for_status = false;
@@ -463,7 +464,7 @@ void QXcbDrag::move(const QMouseEvent *me)
move.type = atom(QXcbAtom::XdndPosition);
move.data.data32[0] = connection()->clipboard()->owner();
move.data.data32[1] = 0; // flags
- move.data.data32[2] = (globalPos.x() * dpr << 16) + globalPos.y() * dpr;
+ move.data.data32[2] = (globalPos.x() << 16) + globalPos.y();
move.data.data32[3] = connection()->time();
move.data.data32[4] = toXdndAction(defaultAction(currentDrag()->supportedActions(), QGuiApplication::keyboardModifiers()));
DEBUG() << "sending Xdnd position source=" << move.data.data32[0] << "target=" << move.window;
@@ -471,15 +472,15 @@ void QXcbDrag::move(const QMouseEvent *me)
source_time = connection()->time();
if (w)
- handle_xdnd_position(w->window(), &move);
+ handle_xdnd_position(w, &move);
else
xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&move);
}
}
-void QXcbDrag::drop(const QMouseEvent *event)
+void QXcbDrag::drop(const QPoint &globalPos)
{
- QBasicDrag::drop(event);
+ QBasicDrag::drop(globalPos);
if (!current_target)
return;
@@ -505,7 +506,7 @@ void QXcbDrag::drop(const QMouseEvent *event)
connection()->time(),
current_target,
current_proxy_target,
- (w ? w->window() : 0),
+ w,
// current_embeddig_widget,
currentDrag(),
QTime::currentTime()
@@ -518,7 +519,7 @@ void QXcbDrag::drop(const QMouseEvent *event)
}
if (w) {
- handleDrop(w->window(), &drop);
+ handleDrop(w, &drop);
} else {
xcb_send_event(xcb_connection(), false, current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&drop);
}
@@ -664,7 +665,7 @@ static bool checkEmbedded(QWidget* w, const XEvent* xe)
#endif
-void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *event)
+void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event)
{
Q_UNUSED(window);
DEBUG() << "handleEnter" << window;
@@ -689,6 +690,7 @@ void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *ev
length = xdnd_max_type;
xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
+ xdnd_types.reserve(length);
for (int i = 0; i < length; ++i)
xdnd_types.append(atoms[i]);
}
@@ -704,17 +706,14 @@ void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *ev
DEBUG() << " " << connection()->atomName(xdnd_types.at(i));
}
-void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *e)
+void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *e)
{
QPoint p((e->data.data32[2] & 0xffff0000) >> 16, e->data.data32[2] & 0x0000ffff);
Q_ASSERT(w);
QRect geometry = w->geometry();
- const int dpr = int(w->handle()->devicePixelRatio());
-
- p /= dpr;
p -= geometry.topLeft();
- if (!w || (w->type() == Qt::Desktop))
+ if (!w || !w->window() || (w->window()->type() == Qt::Desktop))
return;
if (e->data.data32[0] != xdnd_dragsource) {
@@ -723,7 +722,7 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
}
currentPosition = p;
- currentWindow = w;
+ currentWindow = w->window();
// timestamp from the source
if (e->data.data32[3] != XCB_NONE) {
@@ -740,7 +739,7 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
supported_actions = Qt::DropActions(toDropAction(e->data.data32[4]));
}
- QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(w,dropData,p,supported_actions);
+ QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(w->window(),dropData,p,supported_actions);
QRect answerRect(p + geometry.topLeft(), QSize(1,1));
answerRect = qt_response.answerRect().translated(geometry.topLeft()).intersected(geometry);
@@ -796,7 +795,7 @@ namespace
};
}
-void QXcbDrag::handlePosition(QWindow * w, const xcb_client_message_event_t *event)
+void QXcbDrag::handlePosition(QPlatformWindow * w, const xcb_client_message_event_t *event)
{
xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
xcb_generic_event_t *nextEvent;
@@ -830,12 +829,10 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event)
updateCursor(Qt::IgnoreAction);
}
- static const int dpr = int(qApp->devicePixelRatio());
-
if ((event->data.data32[1] & 2) == 0) {
QPoint p((event->data.data32[2] & 0xffff0000) >> 16, event->data.data32[2] & 0x0000ffff);
QSize s((event->data.data32[3] & 0xffff0000) >> 16, event->data.data32[3] & 0x0000ffff);
- source_sameanswer = QRect(p / dpr, s / dpr);
+ source_sameanswer = QRect(p, s);
} else {
source_sameanswer = QRect();
}
@@ -861,10 +858,10 @@ void QXcbDrag::handleStatus(const xcb_client_message_event_t *event)
DEBUG("xdndHandleStatus end");
}
-void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event)
+void QXcbDrag::handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event)
{
DEBUG("xdnd leave");
- if (!currentWindow || w != currentWindow.data())
+ if (!currentWindow || w != currentWindow.data()->handle())
return; // sanity
// ###
@@ -879,7 +876,7 @@ void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event)
DEBUG("xdnd drag leave from unexpected source (%x not %x", event->data.data32[0], xdnd_dragsource);
}
- QWindowSystemInterface::handleDrag(w,0,QPoint(),Qt::IgnoreAction);
+ QWindowSystemInterface::handleDrag(w->window(),0,QPoint(),Qt::IgnoreAction);
xdnd_dragsource = 0;
xdnd_types.clear();
@@ -909,7 +906,7 @@ void QXcbDrag::send_leave()
w = 0;
if (w)
- handleLeave(w->window(), (const xcb_client_message_event_t *)&leave);
+ handleLeave(w, (const xcb_client_message_event_t *)&leave);
else
xcb_send_event(xcb_connection(), false,current_proxy_target,
XCB_EVENT_MASK_NO_EVENT, (const char *)&leave);
@@ -920,7 +917,7 @@ void QXcbDrag::send_leave()
waiting_for_status = false;
}
-void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event)
+void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event)
{
DEBUG("xdndHandleDrop");
if (!currentWindow) {
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 95da76b732..699d402ea6 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -53,8 +53,8 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DRAGANDDROP
-class QMouseEvent;
class QWindow;
+class QPlatformWindow;
class QXcbConnection;
class QXcbWindow;
class QXcbDropData;
@@ -72,14 +72,14 @@ public:
void startDrag() Q_DECL_OVERRIDE;
void cancel() Q_DECL_OVERRIDE;
- void move(const QMouseEvent *me) Q_DECL_OVERRIDE;
- void drop(const QMouseEvent *me) Q_DECL_OVERRIDE;
+ void move(const QPoint &globalPos) Q_DECL_OVERRIDE;
+ void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
void endDrag() Q_DECL_OVERRIDE;
- void handleEnter(QWindow *window, const xcb_client_message_event_t *event);
- void handlePosition(QWindow *w, const xcb_client_message_event_t *event);
- void handleLeave(QWindow *w, const xcb_client_message_event_t *event);
- void handleDrop(QWindow *, const xcb_client_message_event_t *event);
+ void handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event);
+ void handlePosition(QPlatformWindow *w, const xcb_client_message_event_t *event);
+ void handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event);
+ void handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event);
void handleStatus(const xcb_client_message_event_t *event);
void handleSelectionRequest(const xcb_selection_request_event_t *event);
@@ -99,7 +99,7 @@ private:
void init();
- void handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *event);
+ void handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *event);
void handle_xdnd_status(const xcb_client_message_event_t *event);
void send_leave();
@@ -146,7 +146,7 @@ private:
xcb_timestamp_t timestamp;
xcb_window_t target;
xcb_window_t proxy_target;
- QWindow *targetWindow;
+ QPlatformWindow *targetWindow;
// QWidget *embedding_widget;
QPointer<QDrag> drag;
QTime time;
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index fc06f1a7b0..9cedfa77ad 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -268,7 +268,10 @@ void QXcbIntegration::initialize()
{
// Perform everything that may potentially need the event dispatcher (timers, socket
// notifiers) here instead of the constructor.
- m_inputContext.reset(QPlatformInputContextFactory::create());
+ QString icStr = QPlatformInputContextFactory::requested();
+ if (icStr.isNull())
+ icStr = QLatin1String("compose");
+ m_inputContext.reset(QPlatformInputContextFactory::create(icStr));
}
void QXcbIntegration::moveToScreen(QWindow *window, int screen)
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index ea541e4556..2e088d3ca5 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -1545,11 +1545,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
{
- QByteArray chars;
- chars.resize(1 + xkb_state_key_get_utf8(state, code, 0, 0));
- // equivalent of XLookupString
- xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
- return QString::fromUtf8(chars);
+ QVarLengthArray<char, 32> chars(32);
+ const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
+ if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
+ chars.resize(size + 1);
+ xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
+ }
+ return QString::fromUtf8(chars.constData(), size);
}
void QXcbKeyboard::handleKeyPressEvent(const xcb_key_press_event_t *event)
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 8bf9003af7..dfb0a125e2 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -47,6 +47,7 @@
#include <QtGui/qscreen.h>
#include <QtPlatformHeaders/qxcbwindowfunctions.h>
+#include <QtPlatformHeaders/qxcbintegrationfunctions.h>
#ifndef QT_NO_DBUS
#include "QtPlatformSupport/private/qdbusmenuconnection_p.h"
@@ -76,7 +77,8 @@ static int resourceType(const QByteArray &key)
QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen"),
QByteArrayLiteral("rootwindow"),
QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingEnabled"),
- QByteArrayLiteral("nofonthinting")
+ QByteArrayLiteral("nofonthinting"),
+ QByteArrayLiteral("atspibus")
};
const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
const QByteArray *result = std::find(names, end, key);
@@ -85,8 +87,7 @@ static int resourceType(const QByteArray &key)
QXcbNativeInterface::QXcbNativeInterface() :
m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t")),
- m_sysTraySelectionAtom(XCB_ATOM_NONE),
- m_systrayVisualId(XCB_NONE)
+ m_sysTraySelectionAtom(XCB_ATOM_NONE)
{
}
@@ -117,22 +118,12 @@ bool QXcbNativeInterface::systemTrayAvailable(const QScreen *screen) const
bool QXcbNativeInterface::requestSystemTrayWindowDock(const QWindow *window)
{
- const QPlatformWindow *platformWindow = window->handle();
- if (!platformWindow)
- return false;
- QXcbSystemTrayTracker *trayTracker = systemTrayTracker(window->screen());
- if (!trayTracker)
- return false;
- trayTracker->requestSystemTrayWindowDock(static_cast<const QXcbWindow *>(platformWindow)->xcb_window());
- return true;
+ return QXcbWindow::requestSystemTrayWindowDockStatic(window);
}
QRect QXcbNativeInterface::systemTrayWindowGlobalGeometry(const QWindow *window)
{
- if (const QPlatformWindow *platformWindow = window->handle())
- if (const QXcbSystemTrayTracker *trayTracker = systemTrayTracker(window->screen()))
- return trayTracker->systemTrayWindowGlobalGeometry(static_cast<const QXcbWindow *>(platformWindow)->xcb_window());
- return QRect();
+ return QXcbWindow::systemTrayWindowGlobalGeometryStatic(window);
}
xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const QXcbScreen *screen)
@@ -163,54 +154,14 @@ xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const
return selection_window;
}
-bool QXcbNativeInterface::systrayVisualHasAlphaChannel() {
- const QXcbScreen *screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle());
-
- if (m_systrayVisualId == XCB_NONE) {
- xcb_connection_t *xcb_conn = screen->xcb_connection();
- xcb_atom_t tray_atom = screen->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL);
-
- xcb_window_t systray_window = locateSystemTray(xcb_conn, screen);
- if (systray_window == XCB_WINDOW_NONE)
- return false;
-
- // Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom
- xcb_get_property_cookie_t systray_atom_cookie;
- xcb_get_property_reply_t *systray_atom_reply;
-
- systray_atom_cookie = xcb_get_property_unchecked(xcb_conn, false, systray_window,
- tray_atom, XCB_ATOM_VISUALID, 0, 1);
- systray_atom_reply = xcb_get_property_reply(xcb_conn, systray_atom_cookie, 0);
-
- if (!systray_atom_reply)
- return false;
-
- if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply) > 0) {
- xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply);
- m_systrayVisualId = vids[0];
- }
-
- free(systray_atom_reply);
- }
-
- if (m_systrayVisualId != XCB_NONE) {
- quint8 depth = screen->depthOfVisual(m_systrayVisualId);
- return depth == 32;
- } else {
- return false;
- }
+bool QXcbNativeInterface::systrayVisualHasAlphaChannel()
+{
+ return QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel();
}
-void QXcbNativeInterface::setParentRelativeBackPixmap(const QWindow *qwindow)
+void QXcbNativeInterface::setParentRelativeBackPixmap(QWindow *window)
{
- if (const QPlatformWindow *platformWindow = qwindow->handle()) {
- const QXcbWindow *qxwindow = static_cast<const QXcbWindow *>(platformWindow);
- xcb_connection_t *xcb_conn = qxwindow->xcb_connection();
-
- const quint32 mask = XCB_CW_BACK_PIXMAP;
- const quint32 values[] = { XCB_BACK_PIXMAP_PARENT_RELATIVE };
- Q_XCB_CALL(xcb_change_window_attributes(xcb_conn, qxwindow->xcb_window(), mask, values));
- }
+ QXcbWindow::setParentRelativeBackPixmapStatic(window);
}
void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
@@ -233,6 +184,9 @@ void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resour
case Display:
result = display();
break;
+ case AtspiBus:
+ result = atspiBus();
+ break;
case Connection:
result = connection();
break;
@@ -294,6 +248,9 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resourceStr
case NoFontHinting:
result = xcbScreen->noFontHinting() ? this : 0; //qboolptr...
break;
+ case RootWindow:
+ result = reinterpret_cast<void *>(xcbScreen->root());
+ break;
default:
break;
}
@@ -389,9 +346,24 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio
return func;
//case sensitive
- if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) {
- return QFunctionPointer(QXcbWindow::setWmWindowTypeStatic);
- }
+ if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier())
+ return QFunctionPointer(QXcbWindowFunctions::SetWmWindowType(QXcbWindow::setWmWindowTypeStatic));
+
+ if (function == QXcbWindowFunctions::setWmWindowIconTextIdentifier())
+ return QFunctionPointer(QXcbWindowFunctions::SetWmWindowIconText(QXcbWindow::setWindowIconTextStatic));
+
+ if (function == QXcbWindowFunctions::setParentRelativeBackPixmapIdentifier())
+ return QFunctionPointer(QXcbWindowFunctions::SetParentRelativeBackPixmap(QXcbWindow::setParentRelativeBackPixmapStatic));
+
+ if (function == QXcbWindowFunctions::requestSystemTrayWindowDockIdentifier())
+ return QFunctionPointer(QXcbWindowFunctions::RequestSystemTrayWindowDock(QXcbWindow::requestSystemTrayWindowDockStatic));
+
+ if (function == QXcbWindowFunctions::systemTrayWindowGlobalGeometryIdentifier())
+ return QFunctionPointer(QXcbWindowFunctions::SystemTrayWindowGlobalGeometry(QXcbWindow::systemTrayWindowGlobalGeometryStatic));
+
+ if (function == QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannelIdentifier())
+ return QFunctionPointer(QXcbIntegrationFunctions::XEmbedSystemTrayVisualHasAlphaChannel(QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel));
+
if (function == QXcbWindowFunctions::visualIdIdentifier()) {
return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic));
}
@@ -466,6 +438,27 @@ void *QXcbNativeInterface::connection()
return integration->defaultConnection()->xcb_connection();
}
+void *QXcbNativeInterface::atspiBus()
+{
+ QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
+ QXcbConnection *defaultConnection = integration->defaultConnection();
+ if (defaultConnection) {
+ xcb_atom_t atspiBusAtom = defaultConnection->internAtom("AT_SPI_BUS");
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(defaultConnection->xcb_connection(), false,
+ defaultConnection->rootWindow(),
+ atspiBusAtom,
+ XCB_ATOM_STRING, 0, 128));
+ xcb_get_property_reply_t *reply = Q_XCB_CALL(xcb_get_property_reply(defaultConnection->xcb_connection(), cookie, 0));
+ Q_ASSERT(!reply->bytes_after);
+ char *data = (char *)xcb_get_property_value(reply);
+ int length = xcb_get_property_value_length(reply);
+ QByteArray *busAddress = new QByteArray(data, length);
+ free(reply);
+ return busAddress;
+ }
+ return 0;
+}
+
void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time)
{
if (screen) {
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 721c6f4b1d..f88b710864 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -67,7 +67,8 @@ public:
RootWindow,
ScreenSubpixelType,
ScreenAntialiasingEnabled,
- NoFontHinting
+ NoFontHinting,
+ AtspiBus
};
QXcbNativeInterface();
@@ -98,6 +99,7 @@ public:
void *x11Screen();
void *rootWindow();
void *display();
+ void *atspiBus();
void *connection();
static void setStartupId(const char *);
static void setAppTime(QScreen *screen, xcb_timestamp_t time);
@@ -105,7 +107,7 @@ public:
Q_INVOKABLE void beep();
Q_INVOKABLE bool systemTrayAvailable(const QScreen *screen) const;
- Q_INVOKABLE void setParentRelativeBackPixmap(const QWindow *window);
+ Q_INVOKABLE void setParentRelativeBackPixmap(QWindow *window);
Q_INVOKABLE bool systrayVisualHasAlphaChannel();
Q_INVOKABLE bool requestSystemTrayWindowDock(const QWindow *window);
Q_INVOKABLE QRect systemTrayWindowGlobalGeometry(const QWindow *window);
@@ -121,7 +123,6 @@ private:
const QByteArray m_genericEventFilterType;
xcb_atom_t m_sysTraySelectionAtom;
- xcb_visualid_t m_systrayVisualId;
static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 3dcd6a713a..c6e48dc8c4 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -44,6 +44,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <private/qmath_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -86,7 +87,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
, m_orientation(Qt::PrimaryOrientation)
, m_refreshRate(60)
, m_forcedDpi(-1)
- , m_devicePixelRatio(1)
+ , m_pixelDensity(1)
, m_hintStyle(QFontEngine::HintStyle(-1))
, m_noFontHinting(false)
, m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1))
@@ -107,9 +108,8 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
updateGeometry(output ? output->timestamp : 0);
}
- const int dpr = int(devicePixelRatio());
if (m_geometry.isEmpty()) {
- m_geometry = QRect(QPoint(), m_virtualSize/dpr);
+ m_geometry = QRect(QPoint(), m_virtualSize);
m_nativeGeometry = QRect(QPoint(), m_virtualSize);
}
if (m_availableGeometry.isEmpty())
@@ -117,12 +117,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
readXResources();
- // disable font hinting when we do UI scaling
- static bool dpr_scaling_enabled = (qgetenv("QT_DEVICE_PIXEL_RATIO").toInt() > 1
- || qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto");
- if (dpr_scaling_enabled)
- m_noFontHinting = true;
-
QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs(
xcb_get_window_attributes_reply(xcb_connection(),
xcb_get_window_attributes_unchecked(xcb_connection(), screen()->root), NULL));
@@ -201,9 +195,8 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
{
xcb_window_t root = screen()->root;
- int dpr = int(devicePixelRatio());
- int x = p.x() / dpr;
- int y = p.y() / dpr;
+ int x = p.x();
+ int y = p.y();
xcb_window_t parent = root;
xcb_window_t child = root;
@@ -237,43 +230,6 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
return 0;
}
-
-QPoint QXcbScreen::mapToNative(const QPoint &pos) const
-{
- const int dpr = int(devicePixelRatio());
- return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft();
-}
-
-QPoint QXcbScreen::mapFromNative(const QPoint &pos) const
-{
- const int dpr = int(devicePixelRatio());
- return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft();
-}
-
-QPointF QXcbScreen::mapToNative(const QPointF &pos) const
-{
- const int dpr = int(devicePixelRatio());
- return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft();
-}
-
-QPointF QXcbScreen::mapFromNative(const QPointF &pos) const
-{
- const int dpr = int(devicePixelRatio());
- return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft();
-}
-
-QRect QXcbScreen::mapToNative(const QRect &rect) const
-{
- const int dpr = int(devicePixelRatio());
- return QRect(mapToNative(rect.topLeft()), rect.size() * dpr);
-}
-
-QRect QXcbScreen::mapFromNative(const QRect &rect) const
-{
- const int dpr = int(devicePixelRatio());
- return QRect(mapFromNative(rect.topLeft()), rect.size() / dpr);
-}
-
void QXcbScreen::windowShown(QXcbWindow *window)
{
// Freedesktop.org Startup Notification
@@ -335,29 +291,22 @@ QDpi QXcbScreen::virtualDpi() const
Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height());
}
+
QDpi QXcbScreen::logicalDpi() const
{
static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
if (overrideDpi)
return QDpi(overrideDpi, overrideDpi);
- int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio());
- if (m_forcedDpi > 0)
- return QDpi(m_forcedDpi/primaryDpr, m_forcedDpi/primaryDpr);
- QDpi vDpi = virtualDpi();
- return QDpi(vDpi.first/primaryDpr, vDpi.second/primaryDpr);
+ if (m_forcedDpi > 0) {
+ return QDpi(m_forcedDpi, m_forcedDpi);
+ }
+ return virtualDpi();
}
-
-qreal QXcbScreen::devicePixelRatio() const
+qreal QXcbScreen::pixelDensity() const
{
- static int override_dpr = qEnvironmentVariableIntValue("QT_DEVICE_PIXEL_RATIO");
- static bool auto_dpr = qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto";
- if (override_dpr > 0)
- return override_dpr;
- if (auto_dpr)
- return m_devicePixelRatio;
- return 1.0;
+ return m_pixelDensity;
}
QPlatformCursor *QXcbScreen::cursor() const
@@ -516,11 +465,10 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation)
free(workArea);
qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4);
- m_devicePixelRatio = qRound(dpi/96);
- const int dpr = int(devicePixelRatio()); // we may override m_devicePixelRatio
- m_geometry = QRect(xGeometry.topLeft(), xGeometry.size()/dpr);
+ m_pixelDensity = qRound(dpi/96);
+ m_geometry = QRect(xGeometry.topLeft(), xGeometry.size());
m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size());
- m_availableGeometry = QRect(mapFromNative(xAvailableGeometry.topLeft()), xAvailableGeometry.size()/dpr);
+ m_availableGeometry = QRect(xAvailableGeometry.topLeft(), xAvailableGeometry.size());
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index ccc30c0b84..cbb6307d6e 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -96,7 +96,7 @@ public:
QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; }
QDpi virtualDpi() const;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
- qreal devicePixelRatio() const Q_DECL_OVERRIDE;
+ qreal pixelDensity() const Q_DECL_OVERRIDE;
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
qreal refreshRate() const Q_DECL_OVERRIDE { return m_refreshRate; }
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_orientation; }
@@ -139,13 +139,6 @@ public:
QXcbXSettings *xSettings() const;
- QPoint mapToNative(const QPoint &pos) const;
- QPoint mapFromNative(const QPoint &pos) const;
- QPointF mapToNative(const QPointF &pos) const;
- QPointF mapFromNative(const QPointF &pos) const;
- QRect mapToNative(const QRect &rect) const;
- QRect mapFromNative(const QRect &rect) const;
-
private:
static bool xResource(const QByteArray &identifier,
const QByteArray &expectedIdentifier,
@@ -176,7 +169,7 @@ private:
QXcbCursor *m_cursor;
int m_refreshRate;
int m_forcedDpi;
- int m_devicePixelRatio;
+ int m_pixelDensity;
QFontEngine::HintStyle m_hintStyle;
bool m_noFontHinting;
QFontEngine::SubpixelAntialiasingType m_subpixelType;
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index 328b72234a..c2101a71c1 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -134,6 +134,7 @@ static void sm_setProperty(const QString &name, const QStringList &value)
SmPropValue *prop = new SmPropValue[value.count()];
int count = 0;
QList<QByteArray> vl;
+ vl.reserve(value.size());
for (QStringList::ConstIterator it = value.begin(); it != value.end(); ++it) {
prop[count].length = (*it).length();
vl.append((*it).toUtf8());
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
index a4fdd70b79..1f217e8de7 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -63,14 +63,14 @@ QXcbSystemTrayTracker *QXcbSystemTrayTracker::create(QXcbConnection *connection)
const xcb_atom_t selection = connection->internAtom(netSysTray.constData());
if (!selection)
return 0;
- return new QXcbSystemTrayTracker(connection, trayAtom, selection, connection);
+
+ return new QXcbSystemTrayTracker(connection, trayAtom, selection);
}
QXcbSystemTrayTracker::QXcbSystemTrayTracker(QXcbConnection *connection,
xcb_atom_t trayAtom,
- xcb_atom_t selection,
- QObject *parent)
- : QObject(parent)
+ xcb_atom_t selection)
+ : QObject(connection)
, m_selection(selection)
, m_trayAtom(trayAtom)
, m_connection(connection)
@@ -125,6 +125,7 @@ xcb_window_t QXcbSystemTrayTracker::trayWindow()
// does not work for the QWindow parented on the tray.
QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) const
{
+
xcb_connection_t *conn = m_connection->xcb_connection();
xcb_get_geometry_reply_t *geomReply =
xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), 0);
@@ -161,9 +162,43 @@ void QXcbSystemTrayTracker::handleDestroyNotifyEvent(const xcb_destroy_notify_ev
{
if (event->window == m_trayWindow) {
m_connection->removeWindowEventListener(m_trayWindow);
- m_trayWindow = 0;
+ m_trayWindow = XCB_WINDOW_NONE;
emitSystemTrayWindowChanged();
}
}
+bool QXcbSystemTrayTracker::visualHasAlphaChannel()
+{
+ if (m_trayWindow == XCB_WINDOW_NONE)
+ return false;
+
+ xcb_atom_t tray_atom = m_connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL);
+
+ // Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom
+ xcb_get_property_cookie_t systray_atom_cookie;
+ xcb_get_property_reply_t *systray_atom_reply;
+
+ systray_atom_cookie = xcb_get_property_unchecked(m_connection->xcb_connection(), false, m_trayWindow,
+ tray_atom, XCB_ATOM_VISUALID, 0, 1);
+ systray_atom_reply = xcb_get_property_reply(m_connection->xcb_connection(), systray_atom_cookie, 0);
+
+ if (!systray_atom_reply)
+ return false;
+
+ xcb_visualid_t systrayVisualId = XCB_NONE;
+ if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply) > 0) {
+ xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply);
+ systrayVisualId = vids[0];
+ }
+
+ free(systray_atom_reply);
+
+ if (systrayVisualId != XCB_NONE) {
+ quint8 depth = m_connection->primaryScreen()->depthOfVisual(systrayVisualId);
+ return depth == 32;
+ }
+
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
index 9c20f1729a..b619afb9c4 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
@@ -57,14 +57,14 @@ public:
void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *) Q_DECL_OVERRIDE;
+ bool visualHasAlphaChannel();
signals:
void systemTrayWindowChanged(QScreen *screen);
private:
explicit QXcbSystemTrayTracker(QXcbConnection *connection,
xcb_atom_t trayAtom,
- xcb_atom_t selection,
- QObject *parent = 0);
+ xcb_atom_t selection);
static xcb_window_t locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection);
void emitSystemTrayWindowChanged();
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 4fdebe1ebb..1ff052f2c0 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -37,6 +37,7 @@
#include <QScreen>
#include <QtGui/QIcon>
#include <QtGui/QRegion>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include "qxcbintegration.h"
#include "qxcbconnection.h"
@@ -46,6 +47,7 @@
#include "qxcbwmsupport.h"
#include "qxcbimage.h"
#include "qxcbnativeinterface.h"
+#include "qxcbsystemtraytracker.h"
#include <qpa/qplatformintegration.h>
@@ -139,73 +141,11 @@ enum QX11EmbedMessageType {
const quint32 XEMBED_VERSION = 0;
-static inline QRect mapLocalGeometryToNative(const QRect &qtRect, int dpr)
-{
- return QRect(qtRect.x() * dpr, qtRect.y() * dpr, qtRect.width() * dpr, qtRect.height() * dpr);
-}
-
-// When mapping expose events to Qt rects: round top/left towards the origin and
-// bottom/right away from the origin, making sure that we cover the whole widget
-
-static inline QPoint dpr_floor(const QPoint &p, int dpr)
-{
- return QPoint(p.x()/dpr, p.y()/dpr);
-}
-
-static inline QPoint dpr_ceil(const QPoint &p, int dpr)
-{
- return QPoint((p.x() + dpr - 1) / dpr, (p.y() + dpr - 1) / dpr);
-}
-
-static inline QSize dpr_ceil(const QSize &s, int dpr)
-{
- return QSize((s.width() + dpr - 1) / dpr, (s.height() + dpr - 1) / dpr);
-}
-
-static inline QRect mapExposeFromNative(const QRect &xRect, int dpr)
-{
- return QRect(dpr_floor(xRect.topLeft(), dpr), dpr_ceil(xRect.bottomRight(), dpr));
-}
-
-static inline QRect mapLocalGeometryFromNative(const QRect &xRect, int dpr)
-{
- return QRect(xRect.topLeft() / dpr, dpr_ceil(xRect.size(), dpr));
-}
-
QXcbScreen *QXcbWindow::parentScreen()
{
return parent() ? static_cast<QXcbWindow*>(parent())->parentScreen() : m_xcbScreen;
}
-QPoint QXcbWindow::mapToNative(const QPoint &pos, const QXcbScreen *screen) const
-{
- if (parent())
- return pos * int(screen->devicePixelRatio());
- else
- return screen->mapToNative(pos);
-}
-QPoint QXcbWindow::mapFromNative(const QPoint &pos, const QXcbScreen *screen) const
-{
- if (parent())
- return pos / int(screen->devicePixelRatio());
- else
- return screen->mapFromNative(pos);
-}
-QRect QXcbWindow::mapToNative(const QRect &rect, const QXcbScreen *screen) const
-{
- if (parent())
- return mapLocalGeometryToNative(rect, int(screen->devicePixelRatio()));
- else
- return screen->mapToNative(rect);
-}
-QRect QXcbWindow::mapFromNative(const QRect &rect, const QXcbScreen *screen) const
-{
- if (parent())
- return mapLocalGeometryFromNative(rect, int(screen->devicePixelRatio()));
- else
- return screen->mapFromNative(rect);
-}
-
// Returns \c true if we should set WM_TRANSIENT_FOR on \a w
static inline bool isTransient(const QWindow *w)
{
@@ -381,7 +321,7 @@ void QXcbWindow::create()
Qt::WindowType type = window()->type();
QXcbScreen *currentScreen = xcbScreen();
- QRect rect = window()->geometry();
+ QRect rect = windowGeometry();
QXcbScreen *platformScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect));
m_xcbScreen = platformScreen;
@@ -424,17 +364,15 @@ void QXcbWindow::create()
if (platformScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
- const int dpr = int(devicePixelRatio());
-
- QSize minimumSize = window()->minimumSize();
+ const QSize minimumSize = windowMinimumSize();
if (rect.width() > 0 || rect.height() > 0) {
- rect.setWidth(qBound(1, rect.width(), XCOORD_MAX/dpr));
- rect.setHeight(qBound(1, rect.height(), XCOORD_MAX/dpr));
+ rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
+ rect.setHeight(qBound(1, rect.height(), XCOORD_MAX));
} else if (minimumSize.width() > 0 || minimumSize.height() > 0) {
rect.setSize(minimumSize);
} else {
- rect.setWidth(defaultWindowWidth);
- rect.setHeight(defaultWindowHeight);
+ rect.setWidth(QHighDpi::toNativePixels(int(defaultWindowWidth), platformScreen->QPlatformScreen::screen()));
+ rect.setHeight(QHighDpi::toNativePixels(int(defaultWindowHeight), platformScreen->QPlatformScreen::screen()));
}
xcb_window_t xcb_parent_id = platformScreen->root();
@@ -478,9 +416,7 @@ void QXcbWindow::create()
m_visualId = visualInfo->visualid;
- const QRect xRect = mapToNative(rect, platformScreen);
-
- m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, xRect.x(), xRect.y(), xRect.width(), xRect.height(),
+ m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWBackPixel|CWBorderPixel|CWColormap, &a);
@@ -536,16 +472,14 @@ void QXcbWindow::create()
}
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
- const QRect xRect = mapToNative(rect, platformScreen);
-
Q_XCB_CALL(xcb_create_window(xcb_connection(),
m_depth,
m_window, // window id
xcb_parent_id, // parent window id
- xRect.x(),
- xRect.y(),
- xRect.width(),
- xRect.height(),
+ rect.x(),
+ rect.y(),
+ rect.width(),
+ rect.height(),
0, // border width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
m_visualId, // visual
@@ -708,15 +642,14 @@ void QXcbWindow::setGeometry(const QRect &rect)
propagateSizeHints();
- QXcbScreen *currentScreen = xcbScreen();
+ QXcbScreen *currentScreen = m_xcbScreen;
QXcbScreen *newScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect));
if (!newScreen)
- newScreen = currentScreen;
+ newScreen = xcbScreen();
m_xcbScreen = newScreen;
- const QRect xRect = mapToNative(rect, newScreen);
- const QRect wmGeometry = windowToWmGeometry(xRect);
+ const QRect wmGeometry = windowToWmGeometry(rect);
if (newScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
@@ -1328,7 +1261,7 @@ void QXcbWindow::updateMotifWmHintsBeforeMap()
mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
}
- if (window()->minimumSize() == window()->maximumSize()) {
+ if (windowMinimumSize() == windowMaximumSize()) {
// fixed size, remove the resize handle (since mwm/dtwm
// isn't smart enough to do it itself)
mwmhints.flags |= MWM_HINTS_FUNCTIONS;
@@ -1522,10 +1455,22 @@ void QXcbWindow::setWindowTitle(const QString &title)
xcb_flush(xcb_connection());
}
+void QXcbWindow::setWindowIconText(const QString &title)
+{
+ const QByteArray ba = title.toUtf8();
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_NET_WM_ICON_NAME),
+ atom(QXcbAtom::UTF8_STRING),
+ 8,
+ ba.length(),
+ ba.constData()));
+}
+
void QXcbWindow::setWindowIcon(const QIcon &icon)
{
QVector<quint32> icon_data;
-
if (!icon.isNull()) {
QList<QSize> availableSizes = icon.availableSizes();
if (availableSizes.isEmpty()) {
@@ -1602,8 +1547,7 @@ void QXcbWindow::propagateSizeHints()
xcb_size_hints_t hints;
memset(&hints, 0, sizeof(hints));
- const int dpr = int(devicePixelRatio());
- const QRect xRect = windowToWmGeometry(mapToNative(geometry(), xcbScreen()));
+ const QRect xRect = windowToWmGeometry(geometry());
QWindow *win = window();
@@ -1613,10 +1557,10 @@ void QXcbWindow::propagateSizeHints()
xcb_size_hints_set_size(&hints, true, xRect.width(), xRect.height());
xcb_size_hints_set_win_gravity(&hints, m_gravity);
- QSize minimumSize = win->minimumSize() * dpr;
- QSize maximumSize = win->maximumSize() * dpr;
- QSize baseSize = win->baseSize() * dpr;
- QSize sizeIncrement = win->sizeIncrement() * dpr;
+ QSize minimumSize = windowMinimumSize();
+ QSize maximumSize = windowMaximumSize();
+ QSize baseSize = windowBaseSize();
+ QSize sizeIncrement = windowSizeIncrement();
if (minimumSize.width() > 0 || minimumSize.height() > 0)
xcb_size_hints_set_min_size(&hints,
@@ -1690,6 +1634,12 @@ void QXcbWindow::setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmW
static_cast<QXcbWindow *>(window->handle())->setWmWindowType(windowTypes, window->flags());
}
+void QXcbWindow::setWindowIconTextStatic(QWindow *window, const QString &text)
+{
+ if (window->handle())
+ static_cast<QXcbWindow *>(window->handle())->setWindowIconText(text);
+}
+
uint QXcbWindow::visualIdStatic(QWindow *window)
{
if (window && window->handle())
@@ -1855,13 +1805,54 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W
xcb_flush(xcb_connection());
}
+void QXcbWindow::setParentRelativeBackPixmapStatic(QWindow *window)
+{
+ if (window->handle())
+ static_cast<QXcbWindow *>(window->handle())->setParentRelativeBackPixmap();
+}
+
+void QXcbWindow::setParentRelativeBackPixmap()
+{
+ const quint32 mask = XCB_CW_BACK_PIXMAP;
+ const quint32 values[] = { XCB_BACK_PIXMAP_PARENT_RELATIVE };
+ Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
+}
+
+bool QXcbWindow::requestSystemTrayWindowDockStatic(const QWindow *window)
+{
+ if (window->handle())
+ return static_cast<QXcbWindow *>(window->handle())->requestSystemTrayWindowDock();
+ return false;
+}
+
+bool QXcbWindow::requestSystemTrayWindowDock() const
+{
+ if (!connection()->systemTrayTracker())
+ return false;
+ connection()->systemTrayTracker()->requestSystemTrayWindowDock(m_window);
+ return true;
+}
+
+QRect QXcbWindow::systemTrayWindowGlobalGeometryStatic(const QWindow *window)
+{
+ if (window->handle())
+ return static_cast<QXcbWindow *>(window->handle())->systemTrayWindowGlobalGeometry();
+ return QRect();
+}
+
+QRect QXcbWindow::systemTrayWindowGlobalGeometry() const
+{
+ if (!connection()->systemTrayTracker())
+ return QRect();
+ return connection()->systemTrayTracker()->systemTrayWindowGlobalGeometry(m_window);
+}
+
class ExposeCompressor
{
public:
- ExposeCompressor(xcb_window_t window, QRegion *region, int devicePixelRatio)
+ ExposeCompressor(xcb_window_t window, QRegion *region)
: m_window(window)
, m_region(region)
- , m_dpr(devicePixelRatio)
, m_pending(true)
{
}
@@ -1877,7 +1868,7 @@ public:
return false;
if (expose->count == 0)
m_pending = false;
- *m_region |= mapExposeFromNative(QRect(expose->x, expose->y, expose->width, expose->height), m_dpr);
+ *m_region |= QRect(expose->x, expose->y, expose->width, expose->height);
return true;
}
@@ -1889,7 +1880,6 @@ public:
private:
xcb_window_t m_window;
QRegion *m_region;
- int m_dpr;
bool m_pending;
};
@@ -1903,16 +1893,14 @@ bool QXcbWindow::handleGenericEvent(xcb_generic_event_t *event, long *result)
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
- const int dpr = int(devicePixelRatio());
- QRect x_rect(event->x, event->y, event->width, event->height);
- QRect rect = mapExposeFromNative(x_rect, dpr);
+ QRect rect(event->x, event->y, event->width, event->height);
if (m_exposeRegion.isEmpty())
m_exposeRegion = rect;
else
m_exposeRegion |= rect;
- ExposeCompressor compressor(m_window, &m_exposeRegion, dpr);
+ ExposeCompressor compressor(m_window, &m_exposeRegion);
xcb_generic_event_t *filter = 0;
do {
filter = connection()->checkEvent(compressor);
@@ -1964,13 +1952,13 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
}
#ifndef QT_NO_DRAGANDDROP
} else if (event->type == atom(QXcbAtom::XdndEnter)) {
- connection()->drag()->handleEnter(window(), event);
+ connection()->drag()->handleEnter(this, event);
} else if (event->type == atom(QXcbAtom::XdndPosition)) {
- connection()->drag()->handlePosition(window(), event);
+ connection()->drag()->handlePosition(this, event);
} else if (event->type == atom(QXcbAtom::XdndLeave)) {
- connection()->drag()->handleLeave(window(), event);
+ connection()->drag()->handleLeave(this, event);
} else if (event->type == atom(QXcbAtom::XdndDrop)) {
- connection()->drag()->handleDrop(window(), event);
+ connection()->drag()->handleDrop(this, event);
#endif
} else if (event->type == atom(QXcbAtom::_XEMBED)) {
handleXEmbedMessage(event);
@@ -1990,26 +1978,6 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
}
}
-// Temporary workaround for bug in QPlatformScreen::screenForGeometry
-// we need the native geometries to detect our screen, but that's not
-// available in cross-platform code. Will be fixed properly when highDPI
-// support is refactored to expose the native coordinate system.
-
-QXcbScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const
-{
- QXcbScreen *currentScreen = xcbScreen();
- if (!currentScreen && QGuiApplication::primaryScreen())
- currentScreen = static_cast<QXcbScreen*>(QGuiApplication::primaryScreen()->handle());
- if (currentScreen && !parent() && !currentScreen->nativeGeometry().intersects(newGeometry)) {
- Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
- QXcbScreen *xcbScreen = static_cast<QXcbScreen*>(screen);
- if (xcbScreen->nativeGeometry().intersects(newGeometry))
- return xcbScreen;
- }
- }
- return currentScreen;
-}
-
void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
{
bool fromSendEvent = (event->response_type & 0x80);
@@ -2026,19 +1994,18 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
}
}
- const QRect nativeRect = QRect(pos, QSize(event->width, event->height));
- QXcbScreen *newScreen = parent() ? parentScreen() : screenForNativeGeometry(nativeRect);
+ const QRect rect = QRect(pos, QSize(event->width, event->height));
+ QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(rect);
QXcbScreen *currentScreen = m_xcbScreen;
- m_xcbScreen = newScreen;
+ m_xcbScreen = static_cast<QXcbScreen*>(newScreen);
if (!newScreen)
return;
- const QRect rect = mapFromNative(nativeRect, newScreen);
QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(window(), rect);
if (newScreen != currentScreen)
- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
+ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
m_configureNotifyPending = false;
@@ -2071,11 +2038,10 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
if (!m_embedded)
return pos;
- const int dpr = int(devicePixelRatio());
QPoint ret;
xcb_translate_coordinates_cookie_t cookie =
xcb_translate_coordinates(xcb_connection(), xcb_window(), xcbScreen()->root(),
- pos.x() * dpr, pos.y() * dpr);
+ pos.x(), pos.y());
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) {
@@ -2084,7 +2050,7 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
free(reply);
}
- return mapFromNative(ret, xcbScreen());
+ return ret;
}
QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const
@@ -2092,17 +2058,15 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const
if (!m_embedded)
return pos;
- const int dpr = int(devicePixelRatio());
QPoint ret;
- QPoint xPos = mapToNative(pos, xcbScreen());
xcb_translate_coordinates_cookie_t cookie =
xcb_translate_coordinates(xcb_connection(), xcbScreen()->root(), xcb_window(),
- xPos.x(), xPos.y());
+ pos.x(), pos.y());
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) {
- ret.setX(reply->dst_x / dpr);
- ret.setY(reply->dst_y / dpr);
+ ret.setX(reply->dst_x);
+ ret.setY(reply->dst_y);
free(reply);
}
@@ -2118,7 +2082,7 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
if (m_configureNotifyPending)
m_deferredExpose = true;
else
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size() * int(devicePixelRatio())));
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}
@@ -2150,9 +2114,8 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
sendXEmbedMessage(container->xcb_window(), XEMBED_REQUEST_FOCUS);
}
}
- const int dpr = int(devicePixelRatio());
- QPoint local(event_x / dpr, event_y / dpr);
- QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y));
+ QPoint local(event_x, event_y);
+ QPoint global(root_x, root_y);
if (isWheel) {
if (!connection()->isAtLeastXI21()) {
@@ -2174,9 +2137,8 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y,
int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
{
- const int dpr = int(devicePixelRatio());
- QPoint local(event_x / dpr, event_y / dpr);
- QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y));
+ QPoint local(event_x, event_y);
+ QPoint global(root_x, root_y);
if (detail >= 4 && detail <= 7) {
// mouse wheel, handled in handleButtonPressEvent()
@@ -2189,11 +2151,8 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x,
void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
{
- if (!xcbScreen())
- return;
- const int dpr = int(devicePixelRatio());
- QPoint local(event_x / dpr, event_y / dpr);
- QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y));
+ QPoint local(event_x, event_y);
+ QPoint global(root_x, root_y);
handleMouseEvent(timestamp, local, global, modifiers);
}
@@ -2321,11 +2280,10 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
if (ignoreEnterEvent(event))
return;
- const int dpr = int(devicePixelRatio());
- const QPoint local(event->event_x/dpr, event->event_y/dpr);
+ const QPoint local(event->event_x, event->event_y);
if (!xcbScreen())
return;
- QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
+ QPoint global = QPoint(event->root_x, event->root_y);
QWindowSystemInterface::handleEnterEvent(window(), local, global);
}
@@ -2341,11 +2299,10 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0;
if (enterWindow) {
- const int dpr = int(devicePixelRatio());
- QPoint local(enter->event_x/dpr, enter->event_y/dpr);
+ QPoint local(enter->event_x, enter->event_y);
if (!xcbScreen())
return;
- QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
+ QPoint global = QPoint(event->root_x, event->root_y);
QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global);
} else {
@@ -2524,7 +2481,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
xev.type = moveResize;
xev.window = xcb_window();
xev.format = 32;
- const QPoint globalPos = mapToNative(window()->mapToGlobal(pos), xcbScreen());
+ const QPoint globalPos = window()->mapToGlobal(pos);
xev.data.data32[0] = globalPos.x();
xev.data.data32[1] = globalPos.y();
const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner;
@@ -2650,10 +2607,11 @@ void QXcbWindow::setMask(const QRegion &region)
xcb_shape_mask(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_BOUNDING, xcb_window(), 0, 0, XCB_NONE);
} else {
- const int dpr = devicePixelRatio();
QVector<xcb_rectangle_t> rects;
- foreach (const QRect &r, region.rects())
- rects.push_back(qRectToXCBRectangle(mapLocalGeometryToNative(r, dpr)));
+ const QVector<QRect> regionRects = region.rects();
+ rects.reserve(regionRects.count());
+ foreach (const QRect &r, regionRects)
+ rects.push_back(qRectToXCBRectangle(r));
xcb_shape_rectangles(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
xcb_window(), 0, 0, rects.size(), &rects[0]);
@@ -2691,11 +2649,6 @@ void QXcbWindow::postSyncWindowRequest()
}
}
-qreal QXcbWindow::devicePixelRatio() const
-{
- return xcbScreen() ? xcbScreen()->devicePixelRatio() : 1.0;
-}
-
QXcbScreen *QXcbWindow::xcbScreen() const
{
return static_cast<QXcbScreen *>(screen());
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index a379a6f9db..8968664bad 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -86,6 +86,7 @@ public:
QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
void setWindowTitle(const QString &title) Q_DECL_OVERRIDE;
+ void setWindowIconText(const QString &title);
void setWindowIcon(const QIcon &icon) Q_DECL_OVERRIDE;
void raise() Q_DECL_OVERRIDE;
void lower() Q_DECL_OVERRIDE;
@@ -145,6 +146,16 @@ public:
QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const;
void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags);
+ static void setWindowIconTextStatic(QWindow *window, const QString &text);
+
+ static void setParentRelativeBackPixmapStatic(QWindow *window);
+ void setParentRelativeBackPixmap();
+
+ static bool requestSystemTrayWindowDockStatic(const QWindow *window);
+ bool requestSystemTrayWindowDock() const;
+
+ static QRect systemTrayWindowGlobalGeometryStatic(const QWindow *window);
+ QRect systemTrayWindowGlobalGeometry() const;
uint visualId() const;
bool needsSync() const;
@@ -152,8 +163,6 @@ public:
void postSyncWindowRequest();
void clearSyncWindowRequest() { m_pendingSyncRequest = 0; }
- qreal devicePixelRatio() const Q_DECL_OVERRIDE;
-
QXcbScreen *xcbScreen() const;
virtual void create();
@@ -169,10 +178,6 @@ protected:
virtual void *createVisual() { return Q_NULLPTR; }
virtual bool supportsSyncProtocol() { return !window()->supportsOpenGL(); }
- QPoint mapToNative(const QPoint &pos, const QXcbScreen *screen) const;
- QPoint mapFromNative(const QPoint &pos, const QXcbScreen *screen) const;
- QRect mapToNative(const QRect &rect, const QXcbScreen *screen) const;
- QRect mapFromNative(const QRect &rect, const QXcbScreen *screen) const;
QXcbScreen *parentScreen();
void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
diff --git a/src/plugins/platforms/xcb/qxlibconvenience.cpp b/src/plugins/platforms/xcb/qxlibconvenience.cpp
deleted file mode 100644
index f3c7d2b24e..0000000000
--- a/src/plugins/platforms/xcb/qxlibconvenience.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifdef XCB_USE_XLIB
-
-#include "qxlibconvenience.h"
-
-// Some Xlib headers are heavy macro namespace polluters and conflict with Qt types.
-// This unit makes it easier to deal with them by encapsulating these includes in this .cpp.
-#include <X11/Xutil.h>
-
-QT_BEGIN_NAMESPACE
-
-xcb_keysym_t q_XLookupString(void *display, xcb_window_t window, xcb_window_t root, uint state, xcb_keycode_t code, int type, QByteArray *chars)
-{
- KeySym sym = 0;
- chars->resize(512);
- XKeyEvent event;
- memset(&event, 0, sizeof(event));
- event.type = type;
- event.display = static_cast<Display*>(display);
- event.window = window;
- event.root = root;
- event.state = state;
- event.keycode = code;
- int count = XLookupString(&event, chars->data(), chars->size(), &sym, 0);
- chars->resize(count);
- return sym;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/xcb/qxlibconvenience.h b/src/plugins/platforms/xcb/qxlibconvenience.h
deleted file mode 100644
index 0e6e1c37ec..0000000000
--- a/src/plugins/platforms/xcb/qxlibconvenience.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef XLIBUTILS_H
-#define XLIBUTILS_H
-
-#ifdef XCB_USE_XLIB
-
-#include <xcb/xcb_keysyms.h>
-#include <QByteArray>
-
-QT_BEGIN_NAMESPACE
-
-xcb_keysym_t q_XLookupString(void *display, xcb_window_t window, xcb_window_t root, uint state, xcb_keycode_t code, int type, QByteArray *chars);
-
-QT_END_NAMESPACE
-
-#endif // XCB_USE_XLIB
-#endif
diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
index 2ac31bf715..141056637e 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
+++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
@@ -34,7 +34,11 @@
#ifndef QGTK2DIALOGHELPERS_P_H
#define QGTK2DIALOGHELPERS_P_H
+#include <QtCore/qhash.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qurl.h>
#include <QtCore/qscopedpointer.h>
+#include <QtCore/qstring.h>
#include <qpa/qplatformdialoghelper.h>
typedef struct _GtkDialog GtkDialog;
@@ -43,6 +47,7 @@ typedef struct _GtkFileFilter GtkFileFilter;
QT_BEGIN_NAMESPACE
class QGtk2Dialog;
+class QColor;
class QGtk2ColorDialogHelper : public QPlatformColorDialogHelper
{
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index af4f6fc8fe..dd5345e67e 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -1,8 +1,15 @@
TEMPLATE = subdirs
+load(qfeatures)
SUBDIRS *= sqldrivers
-!winrt:qtHaveModule(network): SUBDIRS += bearer
-qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts platformthemes generic
+!winrt:qtHaveModule(network):!contains(QT_DISABLED_FEATURES, bearermanagement): SUBDIRS += bearer
+qtHaveModule(gui) {
+ SUBDIRS *= platforms platforminputcontexts platformthemes
+ !contains(QT_DISABLED_FEATURES, imageformatplugin): SUBDIRS *= imageformats
+ !contains(QT_DISABLED_FEATURES, library): SUBDIRS *= generic
+}
qtHaveModule(widgets): SUBDIRS *= styles
-!winrt:!wince:qtHaveModule(widgets): SUBDIRS += printsupport
+!winrt:!wince*:qtHaveModule(widgets):!contains(QT_DISABLED_FEATURES, printer) {
+ SUBDIRS += printsupport
+}
diff --git a/src/plugins/printsupport/cocoa/main.cpp b/src/plugins/printsupport/cocoa/main.cpp
index 2037724719..3db7b49ba4 100644
--- a/src/plugins/printsupport/cocoa/main.cpp
+++ b/src/plugins/printsupport/cocoa/main.cpp
@@ -38,8 +38,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_PRINTER
-
class QCocoaPrinterSupportPlugin : public QPlatformPrinterSupportPlugin
{
Q_OBJECT
@@ -67,8 +65,6 @@ QPlatformPrinterSupport *QCocoaPrinterSupportPlugin::create(const QString &key)
return platformPrinterSupport;
}
-#endif
-
QT_END_NAMESPACE
#include "main.moc"
diff --git a/src/plugins/printsupport/cups/main.cpp b/src/plugins/printsupport/cups/main.cpp
index 82485114ab..abd24d411a 100644
--- a/src/plugins/printsupport/cups/main.cpp
+++ b/src/plugins/printsupport/cups/main.cpp
@@ -37,8 +37,6 @@
#include <qpa/qplatformprintplugin.h>
#include <QtCore/QStringList>
-#ifndef QT_NO_PRINTER
-
QT_BEGIN_NAMESPACE
class QCupsPrinterSupportPlugin : public QPlatformPrinterSupportPlugin
@@ -65,6 +63,4 @@ QPlatformPrinterSupport *QCupsPrinterSupportPlugin::create(const QString &key)
QT_END_NAMESPACE
-#endif // QT_NO_PRINTER
-
#include "main.moc"
diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp
index c00d7f302c..7ca81986b4 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp
@@ -33,8 +33,6 @@
#include "qcupsprintengine_p.h"
-#ifndef QT_NO_PRINTER
-
#include <qpa/qplatformprintplugin.h>
#include <qpa/qplatformprintersupport.h>
@@ -226,7 +224,9 @@ void QCupsPrintEnginePrivate::closePrintDevice()
it += 2;
}
- for (int c = 0; c < options.size(); ++c) {
+ const int numOptions = options.size();
+ cupsOptStruct.reserve(numOptions);
+ for (int c = 0; c < numOptions; ++c) {
cups_option_t opt;
opt.name = options[c].first.data();
opt.value = options[c].second.data();
@@ -315,5 +315,3 @@ void QCupsPrintEnginePrivate::setPageSize(const QPageSize &pageSize)
}
QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h
index b589d40b6c..a611740e09 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h
@@ -47,8 +47,6 @@
#include "QtPrintSupport/qprintengine.h"
-#ifndef QT_NO_PRINTER
-
#include <QtCore/qstring.h>
#include <QtGui/qpaintengine.h>
@@ -100,6 +98,4 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_PRINTER
-
#endif // QCUPSPRINTENGINE_P_H
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
index ea7c116e3c..b257918acf 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
@@ -34,8 +34,6 @@
#include "qcupsprintersupport_p.h"
-#ifndef QT_NO_PRINTER
-
#include "qcupsprintengine_p.h"
#include "qppdprintdevice.h"
#include <private/qprinterinfo_p.h>
@@ -80,6 +78,7 @@ QStringList QCupsPrinterSupport::availablePrintDeviceIds() const
QStringList list;
cups_dest_t *dests;
int count = cupsGetDests(&dests);
+ list.reserve(count);
for (int i = 0; i < count; ++i) {
QString printerId = QString::fromLocal8Bit(dests[i].name);
if (dests[i].instance)
@@ -109,5 +108,3 @@ QString QCupsPrinterSupport::defaultPrintDeviceId() const
}
QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
index ea913deeaa..6dcaa4e893 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
@@ -48,8 +48,6 @@
#include <qpa/qplatformprintersupport.h>
-#ifndef QT_NO_PRINTER
-
#include <QtCore/qstringlist.h>
QT_BEGIN_NAMESPACE
@@ -73,5 +71,4 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_PRINTER
#endif // QCUPSPRINTERSUPPORT_H
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp
index 808424b1ed..1b9ff98fca 100644
--- a/src/plugins/printsupport/cups/qppdprintdevice.cpp
+++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp
@@ -42,8 +42,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_PRINTER
-
QPpdPrintDevice::QPpdPrintDevice()
: QPlatformPrintDevice(),
m_cupsDest(0),
@@ -269,6 +267,7 @@ void QPpdPrintDevice::loadInputSlots() const
if (m_ppd) {
ppd_option_t *inputSlots = ppdFindOption(m_ppd, "InputSlot");
if (inputSlots) {
+ m_inputSlots.reserve(inputSlots->num_choices);
for (int i = 0; i < inputSlots->num_choices; ++i)
m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i]));
}
@@ -309,6 +308,7 @@ void QPpdPrintDevice::loadOutputBins() const
if (m_ppd) {
ppd_option_t *outputBins = ppdFindOption(m_ppd, "OutputBin");
if (outputBins) {
+ m_outputBins.reserve(outputBins->num_choices);
for (int i = 0; i < outputBins->num_choices; ++i)
m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i]));
}
@@ -350,6 +350,7 @@ void QPpdPrintDevice::loadDuplexModes() const
if (m_ppd) {
ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex");
if (duplexModes) {
+ m_duplexModes.reserve(duplexModes->num_choices);
for (int i = 0; i < duplexModes->num_choices; ++i)
m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice));
}
@@ -472,6 +473,4 @@ cups_ptype_e QPpdPrintDevice::printerTypeFlags() const
return static_cast<cups_ptype_e>(printerOption("printer-type").toUInt());
}
-#endif // QT_NO_PRINTER
-
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h
index 5ebcf39566..a28348eb60 100644
--- a/src/plugins/printsupport/cups/qppdprintdevice.h
+++ b/src/plugins/printsupport/cups/qppdprintdevice.h
@@ -47,7 +47,9 @@
#include <qpa/qplatformprintdevice.h>
-#ifndef QT_NO_PRINTER
+#include <QtCore/qbytearray.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qmargins.h>
#include <cups/cups.h>
#include <cups/ppd.h>
@@ -107,5 +109,4 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_PRINTER
#endif // QPPDPRINTDEVICE_H
diff --git a/src/plugins/printsupport/printsupport.pro b/src/plugins/printsupport/printsupport.pro
index ed201f0744..bd6681f53c 100644
--- a/src/plugins/printsupport/printsupport.pro
+++ b/src/plugins/printsupport/printsupport.pro
@@ -2,4 +2,7 @@ TEMPLATE = subdirs
osx: SUBDIRS += cocoa
win32: SUBDIRS += windows
-unix:!mac:contains(QT_CONFIG, cups): SUBDIRS += cups
+unix:!mac:contains(QT_CONFIG, cups) {
+ load(qfeatures)
+ !contains(QT_DISABLED_FEATURES, cups): SUBDIRS += cups
+}
diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
index 505f3138ca..d378ff3130 100644
--- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
+++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
@@ -41,8 +41,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_PRINTER
-
QT_WARNING_DISABLE_GCC("-Wsign-compare")
extern qreal qt_pointMultiplier(QPageLayout::Unit unit);
@@ -471,6 +469,4 @@ QString QWindowsPrintDevice::defaultPrintDeviceId()
return QString::fromWCharArray(name.data());
}
-#endif // QT_NO_PRINTER
-
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.h b/src/plugins/printsupport/windows/qwindowsprintdevice.h
index 8ab487a59c..2c232d22c5 100644
--- a/src/plugins/printsupport/windows/qwindowsprintdevice.h
+++ b/src/plugins/printsupport/windows/qwindowsprintdevice.h
@@ -47,8 +47,6 @@
#include <qpa/qplatformprintdevice.h>
-#ifndef QT_NO_PRINTER
-
#include <QtCore/qt_windows.h>
QT_BEGIN_NAMESPACE
@@ -95,5 +93,4 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_PRINTER
#endif // QWINDOWSPRINTDEVICE_H
diff --git a/src/plugins/styles/bb10style/bright/button/core_button_inactive.png b/src/plugins/styles/bb10style/bright/button/core_button_inactive.png
index 7769f15e44..7769f15e44 100755..100644
--- a/src/plugins/styles/bb10style/bright/button/core_button_inactive.png
+++ b/src/plugins/styles/bb10style/bright/button/core_button_inactive.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/button/core_button_pressed.png b/src/plugins/styles/bb10style/bright/button/core_button_pressed.png
index 59b5bfa7c2..59b5bfa7c2 100755..100644
--- a/src/plugins/styles/bb10style/bright/button/core_button_pressed.png
+++ b/src/plugins/styles/bb10style/bright/button/core_button_pressed.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png
index f1c2ee3bed..f1c2ee3bed 100755..100644
--- a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png
+++ b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png
index 07b8ea21bf..07b8ea21bf 100755..100644
--- a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png
+++ b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png
index 55f8aee066..55f8aee066 100755..100644
--- a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png
+++ b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png b/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png
index 34daccc27e..34daccc27e 100755..100644
--- a/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png
+++ b/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png b/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png
index 7a1e22321d..7a1e22321d 100755..100644
--- a/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png
+++ b/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png
index 3ff930dea7..3ff930dea7 100755..100644
--- a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png
+++ b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png
index cb4c6a8136..cb4c6a8136 100755..100644
--- a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png
+++ b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png
index 88fd1344d2..88fd1344d2 100755..100644
--- a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png
+++ b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png b/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png
index 79154e0568..79154e0568 100755..100644
--- a/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png
+++ b/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png b/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png
index 8cb79118b9..8cb79118b9 100755..100644
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png
+++ b/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/button/core_button_inactive.png b/src/plugins/styles/bb10style/dark/button/core_button_inactive.png
index 97842e1ac4..97842e1ac4 100755..100644
--- a/src/plugins/styles/bb10style/dark/button/core_button_inactive.png
+++ b/src/plugins/styles/bb10style/dark/button/core_button_inactive.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/button/core_button_pressed.png b/src/plugins/styles/bb10style/dark/button/core_button_pressed.png
index c149b64a26..c149b64a26 100755..100644
--- a/src/plugins/styles/bb10style/dark/button/core_button_pressed.png
+++ b/src/plugins/styles/bb10style/dark/button/core_button_pressed.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png
index 507a77b3ea..507a77b3ea 100755..100644
--- a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png
+++ b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png
index 07b8ea21bf..07b8ea21bf 100755..100644
--- a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png
+++ b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png
index 9b115897e8..9b115897e8 100755..100644
--- a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png
+++ b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png b/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png
index 52aa4e4aa2..52aa4e4aa2 100755..100644
--- a/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png
+++ b/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png b/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png
index 39e3a8a4f5..39e3a8a4f5 100755..100644
--- a/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png
+++ b/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png
index 95fcafb437..95fcafb437 100755..100644
--- a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png
+++ b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png
index fd61937d65..fd61937d65 100755..100644
--- a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png
+++ b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png
index 58a1a57b4c..58a1a57b4c 100755..100644
--- a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png
+++ b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png b/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png
index 384f60758a..384f60758a 100755..100644
--- a/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png
+++ b/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png b/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png
index 803c374015..803c374015 100755..100644
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png
+++ b/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png
Binary files differ