summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/accessible/widgets/itemviews.cpp3
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux_p.h32
-rw-r--r--src/plugins/bearer/connman/qofonoservice_linux_p.h2
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerservice.h24
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.pro1
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp11
-rw-r--r--src/plugins/platforms/android/android.json (renamed from src/plugins/platforms/android/src/android.json)0
-rw-r--r--src/plugins/platforms/android/android.pro81
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp (renamed from src/plugins/platforms/android/src/androidjniaccessibility.cpp)0
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.h (renamed from src/plugins/platforms/android/src/androidjniaccessibility.h)0
-rw-r--r--src/plugins/platforms/android/androidjniclipboard.cpp (renamed from src/plugins/platforms/android/src/androidjniclipboard.cpp)0
-rw-r--r--src/plugins/platforms/android/androidjniclipboard.h (renamed from src/plugins/platforms/android/src/androidjniclipboard.h)0
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp (renamed from src/plugins/platforms/android/src/androidjniinput.cpp)9
-rw-r--r--src/plugins/platforms/android/androidjniinput.h (renamed from src/plugins/platforms/android/src/androidjniinput.h)0
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp (renamed from src/plugins/platforms/android/src/androidjnimain.cpp)456
-rw-r--r--src/plugins/platforms/android/androidjnimain.h (renamed from src/plugins/platforms/android/src/androidjnimain.h)22
-rw-r--r--src/plugins/platforms/android/androidjnimenu.cpp (renamed from src/plugins/platforms/android/src/androidjnimenu.cpp)18
-rw-r--r--src/plugins/platforms/android/androidjnimenu.h (renamed from src/plugins/platforms/android/src/androidjnimenu.h)0
-rw-r--r--src/plugins/platforms/android/androidplatformplugin.cpp (renamed from src/plugins/platforms/android/src/androidplatformplugin.cpp)0
-rw-r--r--src/plugins/platforms/android/androidsurfaceclient.h (renamed from src/plugins/platforms/android/src/raster/qandroidplatformscreen.h)28
-rw-r--r--src/plugins/platforms/android/opengl/opengl.pro32
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp (renamed from src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp)1
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.h (renamed from src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h)0
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp (renamed from src/plugins/platforms/android/src/qandroidinputcontext.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h (renamed from src/plugins/platforms/android/src/qandroidinputcontext.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformaccessibility.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformaccessibility.h (renamed from src/plugins/platforms/android/src/qandroidplatformaccessibility.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.cpp78
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.h66
-rw-r--r--src/plugins/platforms/android/qandroidplatformclipboard.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformclipboard.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformclipboard.h (renamed from src/plugins/platforms/android/src/qandroidplatformclipboard.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp)51
-rw-r--r--src/plugins/platforms/android/qandroidplatformdialoghelpers.h (renamed from src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.h (renamed from src/plugins/platforms/android/src/qandroidplatformfontdatabase.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformintegration.cpp)157
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h (renamed from src/plugins/platforms/android/src/qandroidplatformintegration.h)41
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformmenu.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.h (renamed from src/plugins/platforms/android/src/qandroidplatformmenu.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformmenubar.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.h (renamed from src/plugins/platforms/android/src/qandroidplatformmenubar.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenuitem.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenuitem.h (renamed from src/plugins/platforms/android/src/qandroidplatformmenuitem.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp)48
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.h (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h)22
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.cpp149
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.h82
-rw-r--r--src/plugins/platforms/android/qandroidplatformrasterwindow.cpp78
-rw-r--r--src/plugins/platforms/android/qandroidplatformrasterwindow.h70
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp351
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.h118
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformservices.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.h (renamed from src/plugins/platforms/android/src/qandroidplatformservices.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformtheme.cpp)16
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.h (renamed from src/plugins/platforms/android/src/qandroidplatformtheme.h)1
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp (renamed from src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp)116
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.h (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h)62
-rw-r--r--src/plugins/platforms/android/qandroidsystemlocale.cpp (renamed from src/plugins/platforms/android/src/qandroidsystemlocale.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidsystemlocale.h (renamed from src/plugins/platforms/android/src/qandroidsystemlocale.h)0
-rw-r--r--src/plugins/platforms/android/raster/raster.pro19
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp178
-rw-r--r--src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp161
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp94
-rw-r--r--src/plugins/platforms/android/src/raster/raster.pri7
-rw-r--r--src/plugins/platforms/android/src/src.pri55
-rw-r--r--src/plugins/platforms/cocoa/messages.cpp5
-rw-r--r--src/plugins/platforms/cocoa/messages.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h30
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm28
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h65
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm555
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm51
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm4
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm126
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac_p.h1
-rw-r--r--src/plugins/platforms/direct2d/direct2d.json3
-rw-r--r--src/plugins/platforms/direct2d/direct2d.pro41
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp103
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h71
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp205
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h81
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp218
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h84
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp135
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h95
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h (renamed from src/plugins/platforms/kms/qkmsvthandler.cpp)74
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp131
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h79
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp (renamed from src/plugins/platforms/ios/qiossoftwareinputhandler.h)33
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h58
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp131
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h71
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp1168
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h98
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp179
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h85
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp66
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp177
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h74
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp4
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pri10
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.cpp157
-rw-r--r--src/plugins/platforms/eglfs/qeglfscompositor.cpp203
-rw-r--r--src/plugins/platforms/eglfs/qeglfscontext.cpp33
-rw-r--r--src/plugins/platforms/eglfs/qeglfscontext.h9
-rw-r--r--src/plugins/platforms/eglfs/qeglfscursor.cpp356
-rw-r--r--src/plugins/platforms/eglfs/qeglfscursor.h125
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks.h4
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_stub.cpp129
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp207
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h49
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp68
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h40
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp58
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h41
-rw-r--r--src/plugins/platforms/ios/ios.pro1
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm8
-rw-r--r--src/plugins/platforms/ios/qioswindow.h2
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm17
-rw-r--r--src/plugins/platforms/kms/kms.pro7
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp5
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h4
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp25
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h14
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp32
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.cpp17
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglscreen.cpp10
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.cpp8
-rw-r--r--src/plugins/platforms/platforms.pro7
-rw-r--r--src/plugins/platforms/qnx/qnx.pro7
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp46
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h24
-rw-r--r--src/plugins/platforms/qnx/qqnxbuffer.cpp28
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp18
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp9
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxglobal.cpp63
-rw-r--r--src/plugins/platforms/qnx/qqnxglobal.h59
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp1601
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.h76
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp9
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp92
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h10
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.cpp22
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.cpp50
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp29
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventfilter.h58
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp171
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h7
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp50
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp91
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h6
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp192
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h17
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp323
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h13
-rw-r--r--src/plugins/platforms/windows/accessible/accessible.pri4
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp10
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp47
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp25
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h7
-rw-r--r--src/plugins/platforms/windows/main.cpp4
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp45
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp24
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp96
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h24
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp73
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h7
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp49
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp289
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp59
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp154
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp71
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp23
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsgdiintegration.cpp81
-rw-r--r--src/plugins/platforms/windows/qwindowsgdiintegration.h66
-rw-r--r--src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp)27
-rw-r--r--src/plugins/platforms/windows/qwindowsgdinativeinterface.h (renamed from src/plugins/platforms/kms/qkmsvthandler.h)22
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp89
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp37
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp256
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.cpp16
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp34
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp169
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.h94
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp42
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp30
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp9
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp193
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h38
-rw-r--r--src/plugins/platforms/windows/windows.pri180
-rw-r--r--src/plugins/platforms/windows/windows.pro181
-rw-r--r--src/plugins/platforms/winrt/blit.hlsl14
-rw-r--r--src/plugins/platforms/winrt/main.cpp74
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp393
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.h (renamed from src/plugins/platforms/eglfs/qeglfsbackingstore.h)40
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp153
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.h77
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp63
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.h63
-rw-r--r--src/plugins/platforms/winrt/qwinrteventdispatcher.cpp105
-rw-r--r--src/plugins/platforms/winrt/qwinrteventdispatcher.h (renamed from src/plugins/platforms/eglfs/qeglfscompositor.h)54
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp64
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h)15
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp300
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.h121
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp194
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h86
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp1003
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h179
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp138
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.h80
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp119
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h (renamed from src/plugins/platforms/android/src/raster/qandroidplatformwindow.h)40
-rw-r--r--src/plugins/platforms/winrt/winrt.json3
-rw-r--r--src/plugins/platforms/winrt/winrt.pro55
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp38
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp80
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h20
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp134
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp96
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp21
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.h7
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp17
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp11
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.h1
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro2
-rw-r--r--src/plugins/plugins.pro2
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine.cpp2
258 files changed, 12361 insertions, 6010 deletions
diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp
index b477a6acb7..7cd47f3fec 100644
--- a/src/plugins/accessible/widgets/itemviews.cpp
+++ b/src/plugins/accessible/widgets/itemviews.cpp
@@ -1057,9 +1057,10 @@ QRect QAccessibleTableCell::rect() const
QRect r;
r = view->visualRect(m_index);
- if (!r.isNull())
+ if (!r.isNull()) {
r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
r.translate(view->mapToGlobal(QPoint(0, 0)));
+ }
return r;
}
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h
index dd3f847cfd..6996fef5a7 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h
+++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h
@@ -71,22 +71,22 @@
#ifndef __CONNMAN_DBUS_H
-#define CONNMAN_SERVICE "net.connman"
-#define CONNMAN_PATH "/net/connman"
-
-#define CONNMAN_DEBUG_INTERFACE CONNMAN_SERVICE ".Debug"
-#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error"
-#define CONNMAN_AGENT_INTERFACE CONNMAN_SERVICE ".Agent"
-#define CONNMAN_COUNTER_INTERFACE CONNMAN_SERVICE ".Counter"
-
-#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
-#define CONNMAN_MANAGER_PATH "/"
-
-#define CONNMAN_TASK_INTERFACE CONNMAN_SERVICE ".Task"
-#define CONNMAN_PROFILE_INTERFACE CONNMAN_SERVICE ".Profile"
-#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
-#define CONNMAN_PROVIDER_INTERFACE CONNMAN_SERVICE ".Provider"
-#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
+#define CONNMAN_SERVICE "net.connman"
+#define CONNMAN_PATH "/net/connman"
+
+#define CONNMAN_DEBUG_INTERFACE CONNMAN_SERVICE ".Debug"
+#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error"
+#define CONNMAN_AGENT_INTERFACE CONNMAN_SERVICE ".Agent"
+#define CONNMAN_COUNTER_INTERFACE CONNMAN_SERVICE ".Counter"
+
+#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
+#define CONNMAN_MANAGER_PATH "/"
+
+#define CONNMAN_TASK_INTERFACE CONNMAN_SERVICE ".Task"
+#define CONNMAN_PROFILE_INTERFACE CONNMAN_SERVICE ".Profile"
+#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
+#define CONNMAN_PROVIDER_INTERFACE CONNMAN_SERVICE ".Provider"
+#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/bearer/connman/qofonoservice_linux_p.h b/src/plugins/bearer/connman/qofonoservice_linux_p.h
index 25bffacceb..4802e0dc70 100644
--- a/src/plugins/bearer/connman/qofonoservice_linux_p.h
+++ b/src/plugins/bearer/connman/qofonoservice_linux_p.h
@@ -68,7 +68,7 @@
#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
-#define OFONO_SERVICE "org.ofono"
+#define OFONO_SERVICE "org.ofono"
#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
#define OFONO_MANAGER_PATH "/"
#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
index 7febe27ad2..74a25c1370 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
@@ -99,28 +99,28 @@ typedef enum
NM_ACTIVE_CONNECTION_STATE_ACTIVATED
} NMActiveConnectionState;
-#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
+#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
-#define NM_DBUS_PATH "/org/freedesktop/NetworkManager"
-#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
-#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device"
+#define NM_DBUS_PATH "/org/freedesktop/NetworkManager"
+#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
+#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device"
#define NM_DBUS_INTERFACE_DEVICE_WIRED NM_DBUS_INTERFACE_DEVICE ".Wired"
#define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless"
#define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint"
#define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint"
-#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManagerSettings"
+#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManagerSettings"
-#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManagerSettings.Connection"
-#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings"
+#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManagerSettings.Connection"
+#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings"
#define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active"
#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config"
-#define NM_DBUS_SERVICE_USER_SETTINGS "org.freedesktop.NetworkManagerUserSettings"
-#define NM_DBUS_SERVICE_SYSTEM_SETTINGS "org.freedesktop.NetworkManagerSystemSettings"
+#define NM_DBUS_SERVICE_USER_SETTINGS "org.freedesktop.NetworkManagerUserSettings"
+#define NM_DBUS_SERVICE_SYSTEM_SETTINGS "org.freedesktop.NetworkManagerSystemSettings"
-#define NM_802_11_AP_FLAGS_NONE 0x00000000
-#define NM_802_11_AP_FLAGS_PRIVACY 0x00000001
+#define NM_802_11_AP_FLAGS_NONE 0x00000000
+#define NM_802_11_AP_FLAGS_PRIVACY 0x00000001
#endif
QT_BEGIN_NAMESPACE
@@ -433,7 +433,7 @@ class QNetworkManagerIp4Config : public QObject
public:
explicit QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = 0);
- ~QNetworkManagerIp4Config();
+ ~QNetworkManagerIp4Config();
QStringList domains() const;
bool isValid();
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
index 2490a4ffbe..c206e99e57 100644
--- a/src/plugins/platforminputcontexts/compose/compose.pro
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -8,6 +8,7 @@ QT += gui-private
LIBS += $$QMAKE_LIBS_XKBCOMMON
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
+DEFINES += COMPOSE_X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"'
SOURCES += $$PWD/main.cpp \
$$PWD/qcomposeplatforminputcontext.cpp \
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 11545b16c3..121e734ec1 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -58,6 +58,7 @@
#include <locale.h> // LC_CTYPE
#include <string.h> // strchr, strncmp, etc.
#include <strings.h> // strncasecmp
+#include <clocale> // LC_CTYPE
TableGenerator::TableGenerator() : m_state(NoErrors),
m_systemComposeDir(QString())
@@ -72,17 +73,13 @@ TableGenerator::TableGenerator() : m_state(NoErrors),
void TableGenerator::initPossibleLocations()
{
- // AFAICT there is no way to know the exact location
- // of the compose files. It depends on how Xlib was configured
- // on a specific platform. During the "./configure" process
- // xlib generates a config.h file which contains a bunch of defines,
- // including XLOCALEDIR which points to the location of the compose file dir.
// To add an extra system path use the QTCOMPOSE environment variable
if (qEnvironmentVariableIsSet("QTCOMPOSE")) {
m_possibleLocations.append(QString(qgetenv("QTCOMPOSE")));
}
- m_possibleLocations.append(QStringLiteral("/usr/share/X11/locale"));
- m_possibleLocations.append(QStringLiteral("/usr/lib/X11/locale"));
+
+ m_possibleLocations.append(QStringLiteral(COMPOSE_X11_PREFIX "/share/X11/locale"));
+ m_possibleLocations.append(QStringLiteral(COMPOSE_X11_PREFIX "/lib/X11/locale"));
}
void TableGenerator::findComposeFile()
diff --git a/src/plugins/platforms/android/src/android.json b/src/plugins/platforms/android/android.json
index 6843bd3301..6843bd3301 100644
--- a/src/plugins/platforms/android/src/android.json
+++ b/src/plugins/platforms/android/android.json
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
index aa5ab4ddbd..4d873dd986 100644
--- a/src/plugins/platforms/android/android.pro
+++ b/src/plugins/platforms/android/android.pro
@@ -1,3 +1,80 @@
-TEMPLATE = subdirs
+TARGET = qtforandroid
-SUBDIRS += raster opengl
+PLUGIN_TYPE = platforms
+
+# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
+# Yes, the plugin imports itself statically
+DEFINES += QT_STATICPLUGIN
+
+load(qt_plugin)
+
+!contains(ANDROID_PLATFORM, android-9) {
+ INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include
+ LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid
+} else {
+ LIBS += -ljnigraphics -landroid
+}
+
+QT += core-private gui-private platformsupport-private
+
+CONFIG += qpa/genericunixfontdatabase
+
+OTHER_FILES += $$PWD/android.json
+
+INCLUDEPATH += $$PWD
+
+SOURCES += $$PWD/androidplatformplugin.cpp \
+ $$PWD/androidjnimain.cpp \
+ $$PWD/androidjniaccessibility.cpp \
+ $$PWD/androidjniinput.cpp \
+ $$PWD/androidjnimenu.cpp \
+ $$PWD/androidjniclipboard.cpp \
+ $$PWD/qandroidplatformintegration.cpp \
+ $$PWD/qandroidplatformservices.cpp \
+ $$PWD/qandroidassetsfileenginehandler.cpp \
+ $$PWD/qandroidinputcontext.cpp \
+ $$PWD/qandroidplatformaccessibility.cpp \
+ $$PWD/qandroidplatformfontdatabase.cpp \
+ $$PWD/qandroidplatformdialoghelpers.cpp \
+ $$PWD/qandroidplatformclipboard.cpp \
+ $$PWD/qandroidplatformtheme.cpp \
+ $$PWD/qandroidplatformmenubar.cpp \
+ $$PWD/qandroidplatformmenu.cpp \
+ $$PWD/qandroidplatformmenuitem.cpp \
+ $$PWD/qandroidsystemlocale.cpp \
+ $$PWD/qandroidplatformscreen.cpp \
+ $$PWD/qandroidplatformwindow.cpp \
+ $$PWD/qandroidplatformopenglwindow.cpp \
+ $$PWD/qandroidplatformrasterwindow.cpp \
+ $$PWD/qandroidplatformbackingstore.cpp \
+ $$PWD/qandroidplatformopenglcontext.cpp
+
+HEADERS += $$PWD/qandroidplatformintegration.h \
+ $$PWD/androidjnimain.h \
+ $$PWD/androidjniaccessibility.h \
+ $$PWD/androidjniinput.h \
+ $$PWD/androidjnimenu.h \
+ $$PWD/androidjniclipboard.h \
+ $$PWD/qandroidplatformservices.h \
+ $$PWD/qandroidassetsfileenginehandler.h \
+ $$PWD/qandroidinputcontext.h \
+ $$PWD/qandroidplatformaccessibility.h \
+ $$PWD/qandroidplatformfontdatabase.h \
+ $$PWD/qandroidplatformclipboard.h \
+ $$PWD/qandroidplatformdialoghelpers.h \
+ $$PWD/qandroidplatformtheme.h \
+ $$PWD/qandroidplatformmenubar.h \
+ $$PWD/qandroidplatformmenu.h \
+ $$PWD/qandroidplatformmenuitem.h \
+ $$PWD/qandroidsystemlocale.h \
+ $$PWD/androidsurfaceclient.h \
+ $$PWD/qandroidplatformscreen.h \
+ $$PWD/qandroidplatformwindow.h \
+ $$PWD/qandroidplatformopenglwindow.h \
+ $$PWD/qandroidplatformrasterwindow.h \
+ $$PWD/qandroidplatformbackingstore.h \
+ $$PWD/qandroidplatformopenglcontext.h
+
+#Non-standard install directory, QTBUG-29859
+DESTDIR = $$DESTDIR/android
+target.path = $${target.path}/android
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index b987c49c9c..b987c49c9c 100644
--- a/src/plugins/platforms/android/src/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.h b/src/plugins/platforms/android/androidjniaccessibility.h
index e708138c33..e708138c33 100644
--- a/src/plugins/platforms/android/src/androidjniaccessibility.h
+++ b/src/plugins/platforms/android/androidjniaccessibility.h
diff --git a/src/plugins/platforms/android/src/androidjniclipboard.cpp b/src/plugins/platforms/android/androidjniclipboard.cpp
index 05270ac374..05270ac374 100644
--- a/src/plugins/platforms/android/src/androidjniclipboard.cpp
+++ b/src/plugins/platforms/android/androidjniclipboard.cpp
diff --git a/src/plugins/platforms/android/src/androidjniclipboard.h b/src/plugins/platforms/android/androidjniclipboard.h
index 15cd93202e..15cd93202e 100644
--- a/src/plugins/platforms/android/src/androidjniclipboard.h
+++ b/src/plugins/platforms/android/androidjniclipboard.h
diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 8ce95532d3..55d44b7377 100644
--- a/src/plugins/platforms/android/src/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -471,6 +471,9 @@ namespace QtAndroidInput
case 0x000000ba: // KEYCODE_PROG_BLUE
return Qt::Key_Blue;
+ case 0x000000a5: // KEYCODE_INFO
+ return Qt::Key_Info;
+
case 0x000000a6: // KEYCODE_CHANNEL_UP
return Qt::Key_ChannelUp;
@@ -483,9 +486,15 @@ namespace QtAndroidInput
case 0x000000a9: // KEYCODE_ZOOM_OUT
return Qt::Key_ZoomOut;
+ case 0x000000ac: // KEYCODE_GUIDE
+ return Qt::Key_Guide;
+
case 0x000000af: // KEYCODE_CAPTIONS
return Qt::Key_Subtitle;
+ case 0x000000b0: // KEYCODE_SETTINGS
+ return Qt::Key_Settings;
+
case 0x000000d0: // KEYCODE_CALENDAR
return Qt::Key_Calendar;
diff --git a/src/plugins/platforms/android/src/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h
index a78c7519db..a78c7519db 100644
--- a/src/plugins/platforms/android/src/androidjniinput.h
+++ b/src/plugins/platforms/android/androidjniinput.h
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 6461fa4733..e997a49a25 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -53,6 +53,7 @@
#include <qdebug.h>
#include <qglobal.h>
#include <qobjectdefs.h>
+#include <QtCore/private/qjni_p.h>
#include <stdlib.h>
#include "androidjnimain.h"
@@ -73,14 +74,6 @@
#include <qpa/qwindowsysteminterface.h>
-#ifdef ANDROID_PLUGIN_OPENGL
-# include "qandroidopenglplatformwindow.h"
-#endif
-
-#include <android/native_window_jni.h>
-
-static jmethodID m_redrawSurfaceMethodID = 0;
-
Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
static JavaVM *m_javaVM = NULL;
@@ -90,6 +83,9 @@ static jmethodID m_loadClassMethodID = NULL;
static AAssetManager *m_assetManager = NULL;
static jobject m_resourcesObj;
static jobject m_activityObject = NULL;
+static jmethodID m_createSurfaceMethodID = 0;
+static jmethodID m_setSurfaceGeometryMethodID = 0;
+static jmethodID m_destroySurfaceMethodID = 0;
static bool m_activityActive = true; // defaults to true because when the platform plugin is
// initialized, QtActivity::onResume() has already been called
@@ -110,17 +106,19 @@ static Main m_main = NULL;
static void *m_mainLibraryHnd = NULL;
static QList<QByteArray> m_applicationParams;
-#ifndef ANDROID_PLUGIN_OPENGL
-static jobject m_surface = NULL;
-#else
-static EGLNativeWindowType m_nativeWindow = 0;
-static QSemaphore m_waitForWindowSemaphore;
-static bool m_waitForWindow = false;
-#endif
+struct SurfaceData
+{
+ ~SurfaceData() { delete surface; }
+ QJNIObjectPrivate *surface = 0;
+ AndroidSurfaceClient *client = 0;
+};
+
+QHash<int, AndroidSurfaceClient *> m_surfaces;
+static QMutex m_surfacesMutex;
+static int m_surfaceId = 1;
static QSemaphore m_quitAppSemaphore;
-static QMutex m_surfaceMutex(QMutex::Recursive);
static QSemaphore m_pauseApplicationSemaphore;
static QMutex m_pauseApplicationMutex;
@@ -140,128 +138,18 @@ static const char m_qtTag[] = "Qt";
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
-static inline void checkPauseApplication()
-{
- m_pauseApplicationMutex.lock();
- if (m_pauseApplication) {
- m_pauseApplicationMutex.unlock();
- m_pauseApplicationSemaphore.acquire(); // wait until surface is created
-
- m_pauseApplicationMutex.lock();
- m_pauseApplication = false;
- m_pauseApplicationMutex.unlock();
-
- //FIXME
-// QWindowSystemInterface::handleScreenAvailableGeometryChange(0);
-// QWindowSystemInterface::handleScreenGeometryChange(0);
- } else {
- m_pauseApplicationMutex.unlock();
- }
-}
-
namespace QtAndroid
{
-#ifndef ANDROID_PLUGIN_OPENGL
- void flushImage(const QPoint &pos, const QImage &image, const QRect &destinationRect)
- {
- checkPauseApplication();
- QMutexLocker locker(&m_surfaceMutex);
- if (!m_surface)
- return;
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- int bpp = 2;
- AndroidBitmapInfo info;
- int ret;
-
- if ((ret = AndroidBitmap_getInfo(env.jniEnv, m_surface, &info)) < 0) {
- qWarning() << "AndroidBitmap_getInfo() failed ! error=" << ret;
- m_javaVM->DetachCurrentThread();
- return;
- }
-
- if (info.format != ANDROID_BITMAP_FORMAT_RGB_565) {
- qWarning() << "Bitmap format is not RGB_565!";
- m_javaVM->DetachCurrentThread();
- return;
- }
-
- void *pixels;
- unsigned char *screenBits;
- if ((ret = AndroidBitmap_lockPixels(env.jniEnv, m_surface, &pixels)) < 0) {
- qWarning() << "AndroidBitmap_lockPixels() failed! error=" << ret;
- m_javaVM->DetachCurrentThread();
- return;
- }
-
- screenBits = static_cast<unsigned char *>(pixels);
- int sbpl = info.stride;
- int swidth = info.width;
- int sheight = info.height;
-
- unsigned sposx = pos.x() + destinationRect.x();
- unsigned sposy = pos.y() + destinationRect.y();
-
- screenBits += sposy * sbpl;
-
- unsigned ibpl = image.bytesPerLine();
- unsigned iposx = destinationRect.x();
- unsigned iposy = destinationRect.y();
-
- const unsigned char *imageBits = static_cast<const unsigned char *>(image.bits());
- imageBits += iposy * ibpl;
-
- unsigned width = swidth - sposx < unsigned(destinationRect.width())
- ? (swidth-sposx)
- : destinationRect.width();
- unsigned height = sheight - sposy < unsigned(destinationRect.height())
- ? (sheight - sposy)
- : destinationRect.height();
-
- for (unsigned y = 0; y < height; y++) {
- memcpy(screenBits + y*sbpl + sposx*bpp,
- imageBits + y*ibpl + iposx*bpp,
- width*bpp);
- }
- AndroidBitmap_unlockPixels(env.jniEnv, m_surface);
-
- env.jniEnv->CallStaticVoidMethod(m_applicationClass,
- m_redrawSurfaceMethodID,
- jint(destinationRect.left()),
- jint(destinationRect.top()),
- jint(destinationRect.right() + 1),
- jint(destinationRect.bottom() + 1));
-#warning FIXME dirty hack, figure out why it needs to add 1 to right and bottom !!!!
- }
-
-#else // for #ifndef ANDROID_PLUGIN_OPENGL
- EGLNativeWindowType nativeWindow(bool waitForWindow)
- {
- m_surfaceMutex.lock();
- if (!m_nativeWindow && waitForWindow) {
- m_waitForWindow = true;
- m_surfaceMutex.unlock();
- m_waitForWindowSemaphore.acquire();
- m_waitForWindow = false;
- return m_nativeWindow;
- }
- m_surfaceMutex.unlock();
- return m_nativeWindow;
- }
-#endif
-
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration)
{
- m_surfaceMutex.lock();
+ m_surfacesMutex.lock();
m_androidPlatformIntegration = androidPlatformIntegration;
- m_surfaceMutex.unlock();
+ m_surfacesMutex.unlock();
}
QAndroidPlatformIntegration *androidPlatformIntegration()
{
- QMutexLocker locker(&m_surfaceMutex);
+ QMutexLocker locker(&m_surfacesMutex);
return m_androidPlatformIntegration;
}
@@ -353,14 +241,17 @@ namespace QtAndroid
jobject createBitmap(QImage img, JNIEnv *env)
{
- if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16)
- img = img.convertToFormat(QImage::Format_ARGB32);
+ if (!m_bitmapClass)
+ return 0;
+
+ if (img.format() != QImage::Format_RGBA8888 && img.format() != QImage::Format_RGB16)
+ img = img.convertToFormat(QImage::Format_RGBA8888);
jobject bitmap = env->CallStaticObjectMethod(m_bitmapClass,
m_createBitmapMethodID,
img.width(),
img.height(),
- img.format() == QImage::Format_ARGB32
+ img.format() == QImage::Format_RGBA8888
? m_ARGB_8888_BitmapConfigValue
: m_RGB_565_BitmapConfigValue);
if (!bitmap)
@@ -393,9 +284,24 @@ namespace QtAndroid
return bitmap;
}
+ jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env)
+ {
+ if (format != QImage::Format_RGBA8888
+ && format != QImage::Format_RGB16)
+ return 0;
+
+ return env->CallStaticObjectMethod(m_bitmapClass,
+ m_createBitmapMethodID,
+ width,
+ height,
+ format == QImage::Format_RGB16
+ ? m_RGB_565_BitmapConfigValue
+ : m_ARGB_8888_BitmapConfigValue);
+ }
+
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env)
{
- if (!bitmap)
+ if (!bitmap || !m_bitmapDrawableClass || !m_resourcesObj)
return 0;
return env->NewObject(m_bitmapDrawableClass,
@@ -426,25 +332,76 @@ namespace QtAndroid
return manufacturer + QStringLiteral(" ") + model;
}
+
+ int createSurface(AndroidSurfaceClient *client, const QRect &geometry, bool onTop)
+ {
+ QJNIEnvironmentPrivate env;
+ if (!env)
+ return 0;
+
+ m_surfacesMutex.lock();
+ int surfaceId = m_surfaceId++;
+ m_surfaces[surfaceId] = client;
+ m_surfacesMutex.unlock();
+
+ jint x = 0, y = 0, w = -1, h = -1;
+ if (!geometry.isNull()) {
+ x = geometry.x();
+ y = geometry.y();
+ w = std::max(geometry.width(), 1);
+ h = std::max(geometry.height(), 1);
+ }
+ env->CallStaticVoidMethod(m_applicationClass,
+ m_createSurfaceMethodID,
+ surfaceId,
+ jboolean(onTop),
+ x, y, w, h);
+ return surfaceId;
+ }
+
+ void setSurfaceGeometry(int surfaceId, const QRect &geometry)
+ {
+ QJNIEnvironmentPrivate env;
+ if (!env)
+ return;
+ jint x = 0, y = 0, w = -1, h = -1;
+ if (!geometry.isNull()) {
+ x = geometry.x();
+ y = geometry.y();
+ w = geometry.width();
+ h = geometry.height();
+ }
+ env->CallStaticVoidMethod(m_applicationClass,
+ m_setSurfaceGeometryMethodID,
+ surfaceId,
+ x, y, w, h);
+ }
+
+
+ void destroySurface(int surfaceId)
+ {
+ QMutexLocker lock(&m_surfacesMutex);
+ const auto &it = m_surfaces.find(surfaceId);
+ if (it == m_surfaces.end())
+ return;
+
+ m_surfaces.remove(surfaceId);
+ QJNIEnvironmentPrivate env;
+ if (!env)
+ return;
+
+ env->CallStaticVoidMethod(m_applicationClass,
+ m_destroySurfaceMethodID,
+ surfaceId);
+ }
} // namespace QtAndroid
+
static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobject applicationAssetManager*/)
{
-#ifndef ANDROID_PLUGIN_OPENGL
- m_surface = 0;
-#else
- m_nativeWindow = 0;
- m_waitForWindow = false;
-#endif
-
m_androidPlatformIntegration = 0;
m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler();
-
-#ifdef ANDROID_PLUGIN_OPENGL
return true;
-#else
- return false;
-#endif
}
static void *startMainMethod(void */*data*/)
@@ -520,132 +477,43 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
return pthread_create(&appThread, NULL, startMainMethod, NULL) == 0;
}
-static void pauseQtApp(JNIEnv */*env*/, jobject /*thiz*/)
-{
- m_surfaceMutex.lock();
- m_pauseApplicationMutex.lock();
-
- if (m_androidPlatformIntegration)
- m_androidPlatformIntegration->pauseApp();
- m_pauseApplication = true;
-
- m_pauseApplicationMutex.unlock();
- m_surfaceMutex.unlock();
-}
-
-static void resumeQtApp(JNIEnv */*env*/, jobject /*thiz*/)
-{
- m_surfaceMutex.lock();
- m_pauseApplicationMutex.lock();
- if (m_androidPlatformIntegration)
- m_androidPlatformIntegration->resumeApp();
-
- if (m_pauseApplication)
- m_pauseApplicationSemaphore.release();
-
- m_pauseApplicationMutex.unlock();
- m_surfaceMutex.unlock();
-}
static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/)
{
-#ifndef ANDROID_PLUGIN_OPENGL
- if (m_surface) {
- env->DeleteGlobalRef(m_surface);
- m_surface = 0;
- }
-#else
Q_UNUSED(env);
-#endif
-
m_androidPlatformIntegration = 0;
delete m_androidAssetsFileEngineHandler;
}
static void terminateQt(JNIEnv *env, jclass /*clazz*/)
{
-#ifndef ANDROID_PLUGIN_OPENGL
- if (m_surface)
- env->DeleteGlobalRef(m_surface);
-#endif
env->DeleteGlobalRef(m_applicationClass);
env->DeleteGlobalRef(m_classLoaderObject);
- env->DeleteGlobalRef(m_resourcesObj);
- env->DeleteGlobalRef(m_activityObject);
- env->DeleteGlobalRef(m_bitmapClass);
- env->DeleteGlobalRef(m_ARGB_8888_BitmapConfigValue);
- env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue);
- env->DeleteGlobalRef(m_bitmapDrawableClass);
-}
-
-static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface)
-{
-#ifndef ANDROID_PLUGIN_OPENGL
- if (m_surface)
- env->DeleteGlobalRef(m_surface);
- m_surface = env->NewGlobalRef(jSurface);
-#else
- m_surfaceMutex.lock();
- EGLNativeWindowType nativeWindow = ANativeWindow_fromSurface(env, jSurface);
- bool sameNativeWindow = (nativeWindow != 0 && nativeWindow == m_nativeWindow);
-
- m_nativeWindow = nativeWindow;
- if (m_waitForWindow)
- m_waitForWindowSemaphore.release();
-
- if (m_androidPlatformIntegration) {
- // Use the desktop size.
- // On some devices, the getters for the native window size gives wrong values
- QSize size = QAndroidPlatformIntegration::defaultDesktopSize();
-
- QPlatformScreen *screen = m_androidPlatformIntegration->screen();
- QRect geometry(QPoint(0, 0), size);
- if (screen) {
- QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry);
- QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry);
- }
-
- if (!sameNativeWindow) {
- m_surfaceMutex.unlock();
- m_androidPlatformIntegration->surfaceChanged();
- } else {
- // Resize all top level windows, since they share the same surface
- foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
- QAndroidOpenGLPlatformWindow *window =
- static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
-
- if (window != 0) {
- window->lock();
- window->scheduleResize(size);
-
- QWindowSystemInterface::handleExposeEvent(window->window(),
- QRegion(window->window()->geometry()));
- window->unlock();
- }
- }
-
- m_surfaceMutex.unlock();
- }
-
- } else {
- m_surfaceMutex.unlock();
- }
-#endif // for #ifndef ANDROID_PLUGIN_OPENGL
+ if (m_resourcesObj)
+ env->DeleteGlobalRef(m_resourcesObj);
+ if (m_activityObject)
+ env->DeleteGlobalRef(m_activityObject);
+ if (m_bitmapClass)
+ env->DeleteGlobalRef(m_bitmapClass);
+ if (m_ARGB_8888_BitmapConfigValue)
+ env->DeleteGlobalRef(m_ARGB_8888_BitmapConfigValue);
+ if (m_RGB_565_BitmapConfigValue)
+ env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue);
+ if (m_bitmapDrawableClass)
+ env->DeleteGlobalRef(m_bitmapDrawableClass);
+ m_androidPlatformIntegration = 0;
+ delete m_androidAssetsFileEngineHandler;
}
-static void destroySurface(JNIEnv *env, jobject /*thiz*/)
+static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h)
{
-#ifndef ANDROID_PLUGIN_OPENGL
- if (m_surface) {
- env->DeleteGlobalRef(m_surface);
- m_surface = 0;
+ QMutexLocker lock(&m_surfacesMutex);
+ const auto &it = m_surfaces.find(id);
+ if (it == m_surfaces.end()) {
+ qWarning()<<"Can't find surface" << id;
+ return;
}
-#else
- Q_UNUSED(env);
- m_nativeWindow = 0;
- if (m_androidPlatformIntegration != 0)
- m_androidPlatformIntegration->invalidateNativeSurface();
-#endif
+ it.value()->surfaceChanged(env, jSurface, w, h);
}
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
@@ -668,16 +536,6 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
}
}
-static void lockSurface(JNIEnv */*env*/, jobject /*thiz*/)
-{
- m_surfaceMutex.lock();
-}
-
-static void unlockSurface(JNIEnv */*env*/, jobject /*thiz*/)
-{
- m_surfaceMutex.unlock();
-}
-
static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
{
if (!m_androidPlatformIntegration)
@@ -688,12 +546,8 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry()));
}
-#ifndef ANDROID_PLUGIN_OPENGL
QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen());
QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry()));
-#else
- qWarning("updateWindow: Dirty screen not implemented yet on OpenGL");
-#endif
}
static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state)
@@ -742,15 +596,10 @@ static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint new
static JNINativeMethod methods[] = {
{"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin},
{"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
- {"pauseQtApp", "()V", (void *)pauseQtApp},
- {"resumeQtApp", "()V", (void *)resumeQtApp},
{"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin},
{"terminateQt", "()V", (void *)terminateQt},
{"setDisplayMetrics", "(IIIIDDD)V", (void *)setDisplayMetrics},
- {"setSurface", "(Ljava/lang/Object;)V", (void *)setSurface},
- {"destroySurface", "()V", (void *)destroySurface},
- {"lockSurface", "()V", (void *)lockSurface},
- {"unlockSurface", "()V", (void *)unlockSurface},
+ {"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface},
{"updateWindow", "()V", (void *)updateWindow},
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
{"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged}
@@ -803,43 +652,48 @@ static int registerNatives(JNIEnv *env)
return JNI_FALSE;
}
- GET_AND_CHECK_STATIC_METHOD(m_redrawSurfaceMethodID, m_applicationClass, "redrawSurface", "(IIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_createSurfaceMethodID, m_applicationClass, "createSurface", "(IZIIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setSurfaceGeometryMethodID, m_applicationClass, "setSurfaceGeometry", "(IIIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_destroySurfaceMethodID, m_applicationClass, "destroySurface", "(I)V");
jmethodID methodID;
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;");
jobject activityObject = env->CallStaticObjectMethod(m_applicationClass, methodID);
- m_activityObject = env->NewGlobalRef(activityObject);
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "classLoader", "()Ljava/lang/ClassLoader;");
m_classLoaderObject = env->NewGlobalRef(env->CallStaticObjectMethod(m_applicationClass, methodID));
-
clazz = env->GetObjectClass(m_classLoaderObject);
GET_AND_CHECK_METHOD(m_loadClassMethodID, clazz, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
- FIND_AND_CHECK_CLASS("android/content/ContextWrapper");
- GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;");
- m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(activityObject, methodID));
+ if (activityObject) {
+ m_activityObject = env->NewGlobalRef(activityObject);
- GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;");
- m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(activityObject, methodID));
+ FIND_AND_CHECK_CLASS("android/content/ContextWrapper");
+ GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;");
+ m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(activityObject, methodID));
+
+ GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;");
+ m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(activityObject, methodID));
+
+ FIND_AND_CHECK_CLASS("android/graphics/Bitmap");
+ m_bitmapClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ GET_AND_CHECK_STATIC_METHOD(m_createBitmapMethodID, m_bitmapClass
+ , "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
+ FIND_AND_CHECK_CLASS("android/graphics/Bitmap$Config");
+ jfieldID fieldId;
+ GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
+ m_ARGB_8888_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
+ GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "RGB_565", "Landroid/graphics/Bitmap$Config;");
+ m_RGB_565_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
+
+ FIND_AND_CHECK_CLASS("android/graphics/drawable/BitmapDrawable");
+ m_bitmapDrawableClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ GET_AND_CHECK_METHOD(m_bitmapDrawableConstructorMethodID,
+ m_bitmapDrawableClass,
+ "<init>",
+ "(Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V");
+ }
- FIND_AND_CHECK_CLASS("android/graphics/Bitmap");
- m_bitmapClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- GET_AND_CHECK_STATIC_METHOD(m_createBitmapMethodID, m_bitmapClass
- , "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
- FIND_AND_CHECK_CLASS("android/graphics/Bitmap$Config");
- jfieldID fieldId;
- GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
- m_ARGB_8888_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
- GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "RGB_565", "Landroid/graphics/Bitmap$Config;");
- m_RGB_565_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
-
- FIND_AND_CHECK_CLASS("android/graphics/drawable/BitmapDrawable");
- m_bitmapDrawableClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- GET_AND_CHECK_METHOD(m_bitmapDrawableConstructorMethodID,
- m_bitmapDrawableClass,
- "<init>",
- "(Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V");
return JNI_TRUE;
}
diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index a7b7072ba3..eb8dd87ae0 100644
--- a/src/plugins/platforms/android/src/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -45,16 +45,11 @@
#include <android/log.h>
-#ifdef ANDROID_PLUGIN_OPENGL
-# include <EGL/eglplatform.h>
-#endif
-
-#include <QtCore/qsize.h>
-
#include <jni.h>
#include <android/asset_manager.h>
-class QImage;
+#include <QImage>
+
class QRect;
class QPoint;
class QThread;
@@ -62,6 +57,7 @@ class QAndroidPlatformIntegration;
class QWidget;
class QString;
class QWindow;
+class AndroidSurfaceClient;
namespace QtAndroid
{
@@ -69,11 +65,10 @@ namespace QtAndroid
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration);
void setQtThread(QThread *thread);
-#ifndef ANDROID_PLUGIN_OPENGL
- void flushImage(const QPoint &pos, const QImage &image, const QRect &rect);
-#else
- EGLNativeWindowType nativeWindow(bool waitToCreate = true);
-#endif
+
+ int createSurface(AndroidSurfaceClient * client, const QRect &geometry, bool onTop);
+ void setSurfaceGeometry(int surfaceId, const QRect &geometry);
+ void destroySurface(int surfaceId);
QWindow *topLevelWindowAt(const QPoint &globalPos);
int desktopWidthPixels();
@@ -91,6 +86,7 @@ namespace QtAndroid
void hideStatusBar();
jobject createBitmap(QImage img, JNIEnv *env = 0);
+ jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);
struct AttachedJNIEnv
diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp
index dbdd7c9b8e..dc2afe2b03 100644
--- a/src/plugins/platforms/android/src/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/androidjnimenu.cpp
@@ -143,6 +143,9 @@ namespace QtAndroidMenu
void setActiveTopLevelWindow(QWindow *window)
{
Qt::WindowFlags flags = window ? window->flags() : Qt::WindowFlags();
+ if (!window)
+ return;
+
bool isNonRegularWindow = flags & (Qt::Desktop | Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
if (isNonRegularWindow)
return;
@@ -195,9 +198,9 @@ namespace QtAndroidMenu
static void fillMenuItem(JNIEnv *env, jobject menuItem, bool checkable, bool checked, bool enabled, bool visible, const QIcon &icon=QIcon())
{
- env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable);
- env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked);
- env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled);
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable));
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked));
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled));
if (!icon.isNull()) { // isNull() only checks the d pointer, not the actual image data.
int sz = qMax(36, qgetenv("QT_ANDROID_APP_ICON_SIZE").toInt());
@@ -207,13 +210,13 @@ namespace QtAndroidMenu
: QIcon::Disabled,
QIcon::On).toImage();
if (!img.isNull()) { // Make sure we have a valid image.
- env->CallObjectMethod(menuItem,
- setIconMenuItemMethodID,
- createBitmapDrawable(createBitmap(img, env), env));
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem,
+ setIconMenuItemMethodID,
+ createBitmapDrawable(createBitmap(img, env), env)));
}
}
- env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible);
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible));
}
static int addAllMenuItemsToMenu(JNIEnv *env, jobject menu, QAndroidPlatformMenu *platformMenu) {
@@ -239,6 +242,7 @@ namespace QtAndroidMenu
item->isEnabled(),
item->isVisible(),
item->icon());
+ env->DeleteLocalRef(menuItem);
}
return order;
diff --git a/src/plugins/platforms/android/src/androidjnimenu.h b/src/plugins/platforms/android/androidjnimenu.h
index 7c5422f67b..7c5422f67b 100644
--- a/src/plugins/platforms/android/src/androidjnimenu.h
+++ b/src/plugins/platforms/android/androidjnimenu.h
diff --git a/src/plugins/platforms/android/src/androidplatformplugin.cpp b/src/plugins/platforms/android/androidplatformplugin.cpp
index 2cf5aa1e01..2cf5aa1e01 100644
--- a/src/plugins/platforms/android/src/androidplatformplugin.cpp
+++ b/src/plugins/platforms/android/androidplatformplugin.cpp
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h b/src/plugins/platforms/android/androidsurfaceclient.h
index 9f8807b995..254e47123b 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/androidsurfaceclient.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,24 +39,20 @@
**
****************************************************************************/
-#ifndef QANDROIDPLATFORMSCREEN_H
-#define QANDROIDPLATFORMSCREEN_H
+#ifndef ANDROIDSURFACECLIENT_H
+#define ANDROIDSURFACECLIENT_H
+#include <QMutex>
+#include <jni.h>
-#include <QtPlatformSupport/private/qfbscreen_p.h>
-
-class QAndroidPlatformScreen: public QFbScreen
+class AndroidSurfaceClient
{
- Q_OBJECT
public:
- QAndroidPlatformScreen();
- void topWindowChanged(QWindow *w);
- QDpi logicalDpi() const;
- Qt::ScreenOrientation orientation() const;
- Qt::ScreenOrientation nativeOrientation() const;
-
-public slots:
- QRegion doRedraw();
+ virtual void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) = 0;
+ void lockSurface() { m_surfaceMutex.lock(); }
+ void unlockSurface() { m_surfaceMutex.unlock(); }
+protected:
+ QMutex m_surfaceMutex;
};
-#endif
+#endif // ANDROIDSURFACECLIENT_H
diff --git a/src/plugins/platforms/android/opengl/opengl.pro b/src/plugins/platforms/android/opengl/opengl.pro
deleted file mode 100644
index ea050ca3a0..0000000000
--- a/src/plugins/platforms/android/opengl/opengl.pro
+++ /dev/null
@@ -1,32 +0,0 @@
-TARGET = qtforandroidGL
-
-PLUGIN_TYPE = platforms
-load(qt_plugin)
-
-# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
-# Yes, the plugin imports itself statically
-DEFINES += QT_STATICPLUGIN ANDROID_PLUGIN_OPENGL
-
-!equals(ANDROID_PLATFORM, android-9) {
- INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include
- LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid
-} else {
- LIBS += -ljnigraphics -landroid
-}
-
-EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/../src/opengl/qeglfshooks_android.cpp
-
-INCLUDEPATH += $$PWD/../src/opengl/
-
-HEADERS += \
- $$PWD/../src/opengl/qandroidopenglcontext.h \
- $$PWD/../src/opengl/qandroidopenglplatformwindow.h \
- $$PWD/../src/opengl/qandroidopenglplatformscreen.h
-
-SOURCES += \
- $$PWD/../src/opengl/qandroidopenglcontext.cpp \
- $$PWD/../src/opengl/qandroidopenglplatformwindow.cpp \
- $$PWD/../src/opengl/qandroidopenglplatformscreen.cpp
-
-include($$PWD/../../eglfs/eglfs.pri)
-include($$PWD/../src/src.pri)
diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
index 95844fc649..5f77d1645a 100644
--- a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
@@ -293,6 +293,7 @@ QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &file
AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, path.constData() + prefixSize);
if (assetDir) {
if (AAssetDir_getNextFileName(assetDir)) {
+ AAssetDir_rewind(assetDir);
aad = new QSharedPointer<AndroidAssetDir>(new AndroidAssetDir(assetDir));
m_assetsCacheMutext.lock();
m_assetsCache.insert(path, aad);
diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
index 7bd560886c..7bd560886c 100644
--- a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 326972e71e..326972e71e 100644
--- a/src/plugins/platforms/android/src/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index 041bd0dc49..041bd0dc49 100644
--- a/src/plugins/platforms/android/src/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp
index 229368345b..229368345b 100644
--- a/src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp
+++ b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformaccessibility.h b/src/plugins/platforms/android/qandroidplatformaccessibility.h
index 1b87f11919..1b87f11919 100644
--- a/src/plugins/platforms/android/src/qandroidplatformaccessibility.h
+++ b/src/plugins/platforms/android/qandroidplatformaccessibility.h
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
new file mode 100644
index 0000000000..1df7ce3179
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformbackingstore.h"
+#include "qandroidplatformscreen.h"
+#include "qandroidplatformrasterwindow.h"
+#include <qpa/qplatformscreen.h>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformBackingStore::QAndroidPlatformBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+ Q_ASSERT(window->handle());
+ (static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->setBackingStore(this);
+}
+
+QPaintDevice *QAndroidPlatformBackingStore::paintDevice()
+{
+ return &m_image;
+}
+
+void QAndroidPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(offset);
+
+ (static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->repaint(region);
+}
+
+void QAndroidPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents);
+
+ if (m_image.size() != size)
+ m_image = QImage(size, window()->screen()->handle()->format());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.h b/src/plugins/platforms/android/qandroidplatformbackingstore.h
new file mode 100644
index 0000000000..e6ea3dcce0
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformbackingstore.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMBACKINGSTORE_H
+#define QANDROIDPLATFORMBACKINGSTORE_H
+
+#include <qpa/qplatformbackingstore.h>
+#include <qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformBackingStore : public QPlatformBackingStore
+{
+public:
+ explicit QAndroidPlatformBackingStore(QWindow *window);
+ virtual QPaintDevice *paintDevice();
+ virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ virtual void resize(const QSize &size, const QRegion &staticContents);
+ const QImage image() { return m_image; }
+
+protected:
+ QImage m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDPLATFORMBACKINGSTORE_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp
index bc48b4935b..bc48b4935b 100644
--- a/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp
+++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformclipboard.h b/src/plugins/platforms/android/qandroidplatformclipboard.h
index 644f326934..644f326934 100644
--- a/src/plugins/platforms/android/src/qandroidplatformclipboard.h
+++ b/src/plugins/platforms/android/qandroidplatformclipboard.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
index 4c91e76e0f..4b99f2ce73 100644
--- a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp
+++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
@@ -43,6 +43,8 @@
#include <QtWidgets/QStyle>
#include "qandroidplatformdialoghelpers.h"
#include "androidjnimain.h"
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
namespace QtAndroidDialogHelpers {
static jclass g_messageDialogHelperClass = 0;
@@ -61,49 +63,6 @@ void QAndroidPlatformMessageDialogHelper::exec()
m_loop.exec();
}
-static QString standardButtonText(int sbutton)
-{
- switch (sbutton) {
- case QMessageDialogOptions::Ok:
- return QAndroidPlatformMessageDialogHelper::tr("OK");
- case QMessageDialogOptions::Save:
- return QAndroidPlatformMessageDialogHelper::tr("Save");
- case QMessageDialogOptions::Open:
- return QAndroidPlatformMessageDialogHelper::tr("Open");
- case QMessageDialogOptions::Cancel:
- return QAndroidPlatformMessageDialogHelper::tr("Cancel");
- case QMessageDialogOptions::Close:
- return QAndroidPlatformMessageDialogHelper::tr("Close");
- case QMessageDialogOptions::Apply:
- return QAndroidPlatformMessageDialogHelper::tr("Apply");
- case QMessageDialogOptions::Reset:
- return QAndroidPlatformMessageDialogHelper::tr("Reset");
- case QMessageDialogOptions::Help:
- return QAndroidPlatformMessageDialogHelper::tr("Help");
- case QMessageDialogOptions::Discard:
- return QAndroidPlatformMessageDialogHelper::tr("Discard");
- case QMessageDialogOptions::Yes:
- return QAndroidPlatformMessageDialogHelper::tr("Yes");
- case QMessageDialogOptions::YesToAll:
- return QAndroidPlatformMessageDialogHelper::tr("Yes to All");
- case QMessageDialogOptions::No:
- return QAndroidPlatformMessageDialogHelper::tr("No");
- case QMessageDialogOptions::NoToAll:
- return QAndroidPlatformMessageDialogHelper::tr("No to All");
- case QMessageDialogOptions::SaveAll:
- return QAndroidPlatformMessageDialogHelper::tr("Save All");
- case QMessageDialogOptions::Abort:
- return QAndroidPlatformMessageDialogHelper::tr("Abort");
- case QMessageDialogOptions::Retry:
- return QAndroidPlatformMessageDialogHelper::tr("Retry");
- case QMessageDialogOptions::Ignore:
- return QAndroidPlatformMessageDialogHelper::tr("Ignore");
- case QMessageDialogOptions::RestoreDefaults:
- return QAndroidPlatformMessageDialogHelper::tr("Restore Defaults");
- } // switch
- return QString();
-}
-
bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
, Qt::WindowModality windowModality
, QWindow *parent)
@@ -134,8 +93,10 @@ bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
m_javaMessageDialog.callMethod<void>("setDetailedText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
for (int i = QMessageDialogOptions::FirstButton; i < QMessageDialogOptions::LastButton; i<<=1) {
- if ( opt->standardButtons() & i )
- m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", i, QJNIObjectPrivate::fromString(standardButtonText(i)).object());
+ if ( opt->standardButtons() & i ) {
+ const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(i);
+ m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", i, QJNIObjectPrivate::fromString(text).object());
+ }
}
m_javaMessageDialog.callMethod<void>("show", "(J)V", jlong(static_cast<QObject*>(this)));
diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h b/src/plugins/platforms/android/qandroidplatformdialoghelpers.h
index 88ec91d936..88ec91d936 100644
--- a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h
+++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
index 7f68b44ed8..7f68b44ed8 100644
--- a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
index 3cbfe95d36..3cbfe95d36 100644
--- a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 9bfb6e9a70..3dc8632374 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -40,35 +40,32 @@
****************************************************************************/
#include "qandroidplatformintegration.h"
-#include "qabstracteventdispatcher.h"
-#include "androidjnimain.h"
-#include <QtGui/qguiapplication.h>
-#include <qpa/qwindowsysteminterface.h>
+
+#include <QGuiApplication>
+#include <QOpenGLContext>
#include <QThread>
+
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+
+#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>
+
+#warning sort the headers
+#include "androidjnimain.h"
+#include "qabstracteventdispatcher.h"
+#include "qandroidplatformrasterwindow.h"
+#include "qandroidplatformopenglwindow.h"
+#include "qandroidplatformbackingstore.h"
#include "qandroidplatformservices.h"
#include "qandroidplatformfontdatabase.h"
#include "qandroidplatformclipboard.h"
#include "qandroidplatformaccessibility.h"
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-
-#ifndef ANDROID_PLUGIN_OPENGL
-# include "qandroidplatformscreen.h"
-# include "qandroidplatformwindow.h"
-# include <QtPlatformSupport/private/qfbbackingstore_p.h>
-#else
-# include "qeglfswindow.h"
-# include "androidjnimenu.h"
-# include "qandroidopenglcontext.h"
-# include "qandroidopenglplatformwindow.h"
-# include "qandroidopenglplatformscreen.h"
-# include "qeglfshooks.h"
-# include <QtGui/qopenglcontext.h>
-#endif
-
+#include "qandroidplatformopenglcontext.h"
+#include "qandroidplatformscreen.h"
#include "qandroidplatformtheme.h"
#include "qandroidsystemlocale.h"
+
QT_BEGIN_NAMESPACE
int QAndroidPlatformIntegration::m_defaultGeometryWidth = 320;
@@ -106,12 +103,21 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface();
-#ifndef ANDROID_PLUGIN_OPENGL
+ if (!eglBindAPI(EGL_OPENGL_ES_API))
+ qFatal("Could not bind GL_ES API");
+
+ m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (m_eglDisplay == EGL_NO_DISPLAY)
+ qFatal("Could not open egl display");
+
+ EGLint major, minor;
+ if (!eglInitialize(m_eglDisplay, &major, &minor))
+ qFatal("Could not initialize egl display");
+
m_primaryScreen = new QAndroidPlatformScreen();
screenAdded(m_primaryScreen);
m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
m_primaryScreen->setGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
-#endif
m_mainThread = QThread::currentThread();
QtAndroid::setAndroidPlatformIntegration(this);
@@ -140,83 +146,50 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
switch (cap) {
case ThreadedPixmaps: return true;
case ApplicationState: return true;
- case NativeWidgets: return false;
-
+ case NativeWidgets: return true;
+ case OpenGL: return true;
case ThreadedOpenGL:
if (needsWorkaround())
return false;
// fall through
default:
-#ifndef ANDROID_PLUGIN_OPENGL
- return QPlatformIntegration::hasCapability(cap);
-#else
- return QEglFSIntegration::hasCapability(cap);
-#endif
+ return QPlatformIntegration::hasCapability(cap);
}
}
-#ifndef ANDROID_PLUGIN_OPENGL
QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(QWindow *window) const
{
- return new QFbBackingStore(window);
+ return new QAndroidPlatformBackingStore(window);
}
-QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
+QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- QAndroidPlatformWindow *platformWindow = new QAndroidPlatformWindow(window);
- platformWindow->setWindowState(window->windowState());
-
- return platformWindow;
+ QSurfaceFormat format(context->format());
+ format.setAlphaBufferSize(8);
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+ return new QAndroidPlatformOpenGLContext(format, context->shareHandle(), m_eglDisplay);
}
-QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-#else // !ANDROID_PLUGIN_OPENGL
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
- QAndroidOpenGLPlatformWindow *platformWindow = new QAndroidOpenGLPlatformWindow(window);
- platformWindow->create();
- platformWindow->requestActivateWindow();
- platformWindow->setWindowState(window->windowState());
- QtAndroidMenu::setActiveTopLevelWindow(window);
-
- return platformWindow;
-}
-
-void QAndroidPlatformIntegration::invalidateNativeSurface()
-{
- foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
- QAndroidOpenGLPlatformWindow *window =
- static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
- if (window != 0)
- window->invalidateSurface();
- }
-}
-
-void QAndroidPlatformIntegration::surfaceChanged()
-{
- QAndroidOpenGLPlatformWindow::updateStaticNativeWindow();
- foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
- QAndroidOpenGLPlatformWindow *window =
- static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
- if (window != 0)
- window->resetSurface();
- }
+ if (window->surfaceType() == QSurface::RasterSurface)
+ return new QAndroidPlatformRasterWindow(window);
+ else
+ return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay);
}
-QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const
{
- return new QAndroidOpenGLContext(this,
- QEglFSHooks::hooks()->surfaceFormatFor(context->format()),
- context->shareHandle(),
- display());
+ return createUnixEventDispatcher();
}
-#endif // ANDROID_PLUGIN_OPENGL
QAndroidPlatformIntegration::~QAndroidPlatformIntegration()
{
+ if (m_eglDisplay != EGL_NO_DISPLAY)
+ eglTerminate(m_eglDisplay);
+
delete m_androidPlatformNativeInterface;
delete m_androidFDB;
delete m_androidSystemLocale;
@@ -227,6 +200,7 @@ QAndroidPlatformIntegration::~QAndroidPlatformIntegration()
QtAndroid::setAndroidPlatformIntegration(NULL);
}
+
QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const
{
return m_androidFDB;
@@ -317,8 +291,6 @@ QPlatformAccessibility *QAndroidPlatformIntegration::accessibility() const
}
#endif
-
-#ifndef ANDROID_PLUGIN_OPENGL
void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
{
if (m_primaryScreen)
@@ -330,36 +302,5 @@ void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
if (m_primaryScreen)
QMetaObject::invokeMethod(m_primaryScreen, "setPhysicalSize", Qt::AutoConnection, Q_ARG(QSize, QSize(width, height)));
}
-#else
-void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
-{
- m_defaultGeometryWidth = width;
- m_defaultGeometryHeight = height;
-}
-
-void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
-{
- m_defaultPhysicalSizeWidth = width;
- m_defaultPhysicalSizeHeight = height;
-}
-
-QEglFSScreen *QAndroidPlatformIntegration::createScreen() const
-{
- return new QAndroidOpenGLPlatformScreen(display());
-}
-
-#endif
-
-void QAndroidPlatformIntegration::pauseApp()
-{
- if (QAbstractEventDispatcher::instance(m_mainThread))
- QAbstractEventDispatcher::instance(m_mainThread)->interrupt();
-}
-
-void QAndroidPlatformIntegration::resumeApp()
-{
- if (QAbstractEventDispatcher::instance(m_mainThread))
- QAbstractEventDispatcher::instance(m_mainThread)->wakeUp();
-}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index c5476128a5..0dc2415337 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -47,14 +47,11 @@
#include <qpa/qplatformnativeinterface.h>
#include <QtWidgets/QAction>
+#include <EGL/egl.h>
#include <jni.h>
#include "qandroidinputcontext.h"
-#ifndef ANDROID_PLUGIN_OPENGL
-# include "qandroidplatformscreen.h"
-#else
-# include "qeglfsintegration.h"
-#endif
+#include "qandroidplatformscreen.h"
QT_BEGIN_NAMESPACE
@@ -63,10 +60,6 @@ class QAndroidPlatformServices;
class QAndroidSystemLocale;
class QPlatformAccessibility;
-#ifdef ANDROID_PLUGIN_OPENGL
-class QAndroidOpenGLPlatformWindow;
-#endif
-
class QAndroidPlatformNativeInterface: public QPlatformNativeInterface
{
public:
@@ -75,12 +68,7 @@ public:
QHash<int, QFont> m_fonts;
};
-class QAndroidPlatformIntegration
-#ifndef ANDROID_PLUGIN_OPENGL
- : public QPlatformIntegration
-#else
- : public QEglFSIntegration
-#endif
+class QAndroidPlatformIntegration : public QPlatformIntegration
{
friend class QAndroidPlatformScreen;
@@ -90,17 +78,11 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
-#ifndef ANDROID_PLUGIN_OPENGL
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QAbstractEventDispatcher *createEventDispatcher() const;
QAndroidPlatformScreen *screen() { return m_primaryScreen; }
-#else
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- void invalidateNativeSurface();
- void surfaceChanged();
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
-#endif
virtual void setDesktopSize(int width, int height);
virtual void setDisplayMetrics(int width, int height);
@@ -121,13 +103,11 @@ public:
#endif
QVariant styleHint(StyleHint hint) const;
- Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const Q_DECL_OVERRIDE;
+ Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const;
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
- void pauseApp();
- void resumeApp();
static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh);
static void setDefaultDesktopSize(int gw, int gh);
static void setScreenOrientation(Qt::ScreenOrientation currentOrientation,
@@ -141,20 +121,13 @@ public:
QTouchDevice *touchDevice() const { return m_touchDevice; }
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
-#ifdef ANDROID_PLUGIN_OPENGL
- QEglFSScreen *createScreen() const;
-#endif
-
static bool needsWorkaround();
-
+ EGLDisplay m_eglDisplay;
private:
- friend class QEglFSAndroidHooks;
QTouchDevice *m_touchDevice;
-#ifndef ANDROID_PLUGIN_OPENGL
QAndroidPlatformScreen *m_primaryScreen;
-#endif
QThread *m_mainThread;
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp
index 1ecabb25e2..1ecabb25e2 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.h b/src/plugins/platforms/android/qandroidplatformmenu.h
index 305b64168a..305b64168a 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenu.h
+++ b/src/plugins/platforms/android/qandroidplatformmenu.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/qandroidplatformmenubar.cpp
index 134062fb32..134062fb32 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.h b/src/plugins/platforms/android/qandroidplatformmenubar.h
index 56915335c2..56915335c2 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenubar.h
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp b/src/plugins/platforms/android/qandroidplatformmenuitem.cpp
index bd37834d2a..bd37834d2a 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenuitem.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenuitem.h b/src/plugins/platforms/android/qandroidplatformmenuitem.h
index 5861e8e195..5861e8e195 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenuitem.h
+++ b/src/plugins/platforms/android/qandroidplatformmenuitem.h
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index d94bb241f7..59ca69c004 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -39,49 +40,31 @@
**
****************************************************************************/
-#include "qandroidopenglcontext.h"
-#include "qandroidopenglplatformwindow.h"
+#include "qandroidplatformopenglcontext.h"
+#include "qandroidplatformopenglwindow.h"
#include "qandroidplatformintegration.h"
-#include <QtCore/qdebug.h>
-#include <qpa/qwindowsysteminterface.h>
-
+#include <QSurface>
#include <QtGui/private/qopenglcontext_p.h>
QT_BEGIN_NAMESPACE
-QAndroidOpenGLContext::QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration,
- const QSurfaceFormat &format,
- QPlatformOpenGLContext *share,
- EGLDisplay display,
- EGLenum eglApi)
- : QEglFSContext(format, share, display, eglApi)
- , m_platformIntegration(integration)
+QAndroidPlatformOpenGLContext::QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
+ :QEGLPlatformContext(format, share, display, EGL_OPENGL_ES_API)
{
}
-void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface)
+void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface)
{
- QEglFSContext::swapBuffers(surface);
+ QEGLPlatformContext::swapBuffers(surface);
- if (surface->surface()->surfaceClass() == QSurface::Window) {
- QAndroidOpenGLPlatformWindow *window = static_cast<QAndroidOpenGLPlatformWindow *>(surface);
- window->lock();
- QSize size = window->scheduledResize();
- if (size.isValid()) {
- QRect geometry(QPoint(0, 0), size);
- window->setGeometry(geometry);
- QWindowSystemInterface::handleGeometryChange(window->window(), geometry);
- QWindowSystemInterface::handleExposeEvent(window->window(), QRegion(geometry));
- window->scheduleResize(QSize());
- }
- window->unlock();
- }
+ if (surface->surface()->surfaceClass() == QSurface::Window)
+ static_cast<QAndroidPlatformOpenGLWindow *>(surface)->checkNativeSurface(eglConfig());
}
-bool QAndroidOpenGLContext::makeCurrent(QPlatformSurface *surface)
+bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
{
- bool ret = QEglFSContext::makeCurrent(surface);
+ bool ret = QEGLPlatformContext::makeCurrent(surface);
QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
@@ -94,4 +77,11 @@ bool QAndroidOpenGLContext::makeCurrent(QPlatformSurface *surface)
return ret;
}
+EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+{
+ if (surface->surface()->surfaceClass() == QSurface::Window)
+ return static_cast<QAndroidPlatformOpenGLWindow *>(surface)->eglSurface(eglConfig());
+ return EGL_NO_SURFACE;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h b/src/plugins/platforms/android/qandroidplatformopenglcontext.h
index c419ae8392..29e5f596d5 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.h
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -39,31 +40,24 @@
**
****************************************************************************/
-#ifndef QANDROIDOPENGLCONTEXT_H
-#define QANDROIDOPENGLCONTEXT_H
+#ifndef QANDROIDPLATFORMOPENGLCONTEXT_H
+#define QANDROIDPLATFORMOPENGLCONTEXT_H
-#include <QtCore/qreadwritelock.h>
-#include "qeglfscontext.h"
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
-class QAndroidPlatformIntegration;
-class QAndroidOpenGLContext : public QEglFSContext
+class QAndroidPlatformOpenGLContext : public QEGLPlatformContext
{
public:
- QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration,
- const QSurfaceFormat &format,
- QPlatformOpenGLContext *share,
- EGLDisplay display,
- EGLenum eglApi = EGL_OPENGL_ES_API);
-
+ QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display);
void swapBuffers(QPlatformSurface *surface);
bool makeCurrent(QPlatformSurface *surface);
private:
- const QAndroidPlatformIntegration *m_platformIntegration;
+ virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
};
QT_END_NAMESPACE
-#endif // QANDROIDOPENGLCONTEXT_H
+#endif // QANDROIDPLATFORMOPENGLCONTEXT_H
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
new file mode 100644
index 0000000000..9df6610a99
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformopenglwindow.h"
+
+#include "androidjnimain.h"
+
+#include <QSurfaceFormat>
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include <android/native_window.h>
+#include <android/native_window_jni.h>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformOpenGLWindow::QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display)
+ :QAndroidPlatformWindow(window), m_eglDisplay(display)
+{
+ lockSurface();
+ m_nativeSurfaceId = QtAndroid::createSurface(this, geometry(), bool(window->flags() & Qt::WindowStaysOnTopHint));
+ m_surfaceWaitCondition.wait(&m_surfaceMutex);
+ unlockSurface();
+}
+
+QAndroidPlatformOpenGLWindow::~QAndroidPlatformOpenGLWindow()
+{
+ m_surfaceWaitCondition.wakeOne();
+ lockSurface();
+ if (m_nativeSurfaceId != -1)
+ QtAndroid::destroySurface(m_nativeSurfaceId);
+ clearEgl();
+ unlockSurface();
+}
+
+void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
+{
+ if (rect == geometry())
+ return;
+
+ QAndroidPlatformWindow::setGeometry(rect);
+ QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
+}
+
+EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
+{
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_eglSurface == EGL_NO_SURFACE) {
+ m_surfaceMutex.unlock();
+ checkNativeSurface(config);
+ m_surfaceMutex.lock();
+ }
+ return m_eglSurface;
+}
+
+void QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config)
+{
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_nativeSurfaceId == -1 || !m_androidSurfaceObject.isValid())
+ return;
+
+ createEgl(config);
+
+ // we've create another surface, the window should be repainted
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+}
+
+void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
+{
+ clearEgl();
+ QJNIEnvironmentPrivate env;
+ m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
+ m_androidSurfaceObject = QJNIObjectPrivate();
+ m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
+ if (m_eglSurface == EGL_NO_SURFACE) {
+ EGLint error = eglGetError();
+ eglTerminate(m_eglDisplay);
+ qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error);
+ }
+}
+
+void QAndroidPlatformOpenGLWindow::clearEgl()
+{
+ eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (m_eglSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(m_eglDisplay, m_eglSurface);
+ m_eglSurface = EGL_NO_SURFACE;
+ }
+
+ if (m_nativeWindow) {
+ ANativeWindow_release(m_nativeWindow);
+ m_nativeWindow = 0;
+ }
+}
+
+void QAndroidPlatformOpenGLWindow::surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h)
+{
+ Q_UNUSED(jniEnv);
+ Q_UNUSED(w);
+ Q_UNUSED(h);
+ lockSurface();
+ m_androidSurfaceObject = surface;
+ m_surfaceWaitCondition.wakeOne();
+ unlockSurface();
+
+ // repaint the window
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.h b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
new file mode 100644
index 0000000000..7af8b722aa
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMOPENGLWINDOW_H
+#define QANDROIDPLATFORMOPENGLWINDOW_H
+
+#include <EGL/egl.h>
+#include <QWaitCondition>
+#include <QtCore/private/qjni_p.h>
+
+#include "androidsurfaceclient.h"
+#include "qandroidplatformwindow.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformOpenGLWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
+{
+public:
+ explicit QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display);
+ ~QAndroidPlatformOpenGLWindow();
+
+ void setGeometry(const QRect &rect);
+ EGLSurface eglSurface(EGLConfig config);
+
+ void checkNativeSurface(EGLConfig config);
+
+protected:
+ virtual void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h);
+ void createEgl(EGLConfig config);
+ void clearEgl();
+
+private:
+ EGLDisplay m_eglDisplay;
+ EGLSurface m_eglSurface = EGL_NO_SURFACE;
+ EGLNativeWindowType m_nativeWindow = nullptr;
+
+ int m_nativeSurfaceId = -1;
+ QJNIObjectPrivate m_androidSurfaceObject;
+ QWaitCondition m_surfaceWaitCondition;
+};
+
+QT_END_NAMESPACE
+#endif // QANDROIDPLATFORMOPENGLWINDOW_H
diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
new file mode 100644
index 0000000000..68545c6562
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformrasterwindow.h"
+
+#include "qandroidplatformscreen.h"
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformRasterWindow::QAndroidPlatformRasterWindow(QWindow *window)
+ :QAndroidPlatformWindow(window)
+{
+
+}
+
+void QAndroidPlatformRasterWindow::repaint(const QRegion &region)
+{
+ QRect currentGeometry = geometry().translated(mapToGlobal(QPoint(0,0)));
+
+ QRect dirtyClient = region.boundingRect();
+ QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
+ currentGeometry.top() + dirtyClient.top(),
+ dirtyClient.width(),
+ dirtyClient.height());
+ QRect mOldGeometryLocal = m_oldGeometry;
+ m_oldGeometry = currentGeometry;
+ // If this is a move, redraw the previous location
+ if (mOldGeometryLocal != currentGeometry)
+ platformScreen()->setDirty(mOldGeometryLocal);
+ platformScreen()->setDirty(dirtyRegion);
+}
+
+void QAndroidPlatformRasterWindow::setGeometry(const QRect &rect)
+{
+ m_oldGeometry = geometry();
+ QAndroidPlatformWindow::setGeometry(rect);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.h b/src/plugins/platforms/android/qandroidplatformrasterwindow.h
new file mode 100644
index 0000000000..50c0d497af
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMRASTERWINDOW_H
+#define QANDROIDPLATFORMRASTERWINDOW_H
+
+#include "qandroidplatformwindow.h"
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformBackingStore;
+class QAndroidPlatformRasterWindow : public QObject, public QAndroidPlatformWindow
+{
+ Q_OBJECT
+public:
+ QAndroidPlatformRasterWindow(QWindow *window);
+
+ void setBackingStore(QAndroidPlatformBackingStore *store) { m_backingStore = store; }
+ QAndroidPlatformBackingStore *backingStore() const { return m_backingStore; }
+ void repaint(const QRegion&region);
+
+public slots:
+ void setGeometry(const QRect &rect);
+
+private:
+ QAndroidPlatformBackingStore *m_backingStore = nullptr;
+ QRect m_oldGeometry;
+
+};
+
+QT_END_NAMESPACE
+#endif // QANDROIDPLATFORMRASTERWINDOW_H
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
new file mode 100644
index 0000000000..f59a80d74e
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -0,0 +1,351 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QTime>
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include "qandroidplatformscreen.h"
+#include "qandroidplatformbackingstore.h"
+#include "qandroidplatformintegration.h"
+#include "androidjnimain.h"
+#include "androidjnimenu.h"
+#include "qandroidplatformrasterwindow.h"
+
+#include <android/bitmap.h>
+#include <android/native_window_jni.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QANDROIDPLATFORMSCREEN_DEBUG
+class ScopedProfiler
+{
+public:
+ ScopedProfiler(const QString &msg)
+ {
+ m_msg = msg;
+ }
+ ~ScopedProfiler()
+ {
+ qDebug() << m_msg << m_timer.elapsed();
+ }
+
+private:
+ QTime m_timer;
+ QString m_msg;
+};
+
+# define PROFILE_SCOPE ScopedProfiler ___sp___(__func__)
+#else
+# define PROFILE_SCOPE
+#endif
+
+QAndroidPlatformScreen::QAndroidPlatformScreen():QObject(),QPlatformScreen()
+{
+ m_geometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
+ // Raster only apps should set QT_ANDROID_RASTER_IMAGE_DEPTH to 16
+ // is way much faster than 32
+ if (qgetenv("QT_ANDROID_RASTER_IMAGE_DEPTH").toInt() == 16) {
+ m_format = QImage::Format_RGB16;
+ m_depth = 16;
+ } else {
+ m_format = QImage::Format_ARGB32_Premultiplied;
+ m_depth = 32;
+ }
+ m_physicalSize.setHeight(QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
+ m_physicalSize.setWidth(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth);
+ m_redrawTimer.setSingleShot(true);
+ m_redrawTimer.setInterval(0);
+ connect(&m_redrawTimer, SIGNAL(timeout()), this, SLOT(doRedraw()));
+}
+
+QAndroidPlatformScreen::~QAndroidPlatformScreen()
+{
+ if (m_id != -1) {
+ QtAndroid::destroySurface(m_id);
+ m_surfaceWaitCondition.wakeOne();
+ if (m_nativeSurface)
+ ANativeWindow_release(m_nativeSurface);
+ }
+}
+
+QWindow *QAndroidPlatformScreen::topWindow() const
+{
+ foreach (QAndroidPlatformWindow *w, m_windowStack)
+ if (w->window()->type() == Qt::Window || w->window()->type() == Qt::Dialog)
+ return w->window();
+ return 0;
+}
+
+QWindow *QAndroidPlatformScreen::topLevelAt(const QPoint &p) const
+{
+ foreach (QAndroidPlatformWindow *w, m_windowStack) {
+ if (w->geometry().contains(p, false) && w->window()->isVisible())
+ return w->window();
+ }
+ return 0;
+}
+
+void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window)
+{
+ if (window->parent())
+ return;
+
+ m_windowStack.prepend(window);
+ if (window->isRaster())
+ setDirty(window->geometry());
+
+ QWindow *w = topWindow();
+ QWindowSystemInterface::handleWindowActivated(w);
+ topWindowChanged(w);
+}
+
+void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window)
+{
+ if (window->parent())
+ return;
+
+ m_windowStack.removeOne(window);
+ if (window->isRaster()) {
+ setDirty(window->geometry());
+ }
+ QWindow *w = topWindow();
+ QWindowSystemInterface::handleWindowActivated(w);
+ topWindowChanged(w);
+}
+
+void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window)
+{
+ if (window->parent())
+ return;
+
+ int index = m_windowStack.indexOf(window);
+ if (index <= 0)
+ return;
+ m_windowStack.move(index, 0);
+ if (window->isRaster()) {
+ setDirty(window->geometry());
+ }
+ QWindow *w = topWindow();
+ QWindowSystemInterface::handleWindowActivated(w);
+ topWindowChanged(w);
+}
+
+void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window)
+{
+ if (window->parent())
+ return;
+
+ int index = m_windowStack.indexOf(window);
+ if (index == -1 || index == (m_windowStack.size() - 1))
+ return;
+ m_windowStack.move(index, m_windowStack.size() - 1);
+ if (window->isRaster()) {
+ setDirty(window->geometry());
+ }
+ QWindow *w = topWindow();
+ QWindowSystemInterface::handleWindowActivated(w);
+ topWindowChanged(w);
+}
+
+void QAndroidPlatformScreen::scheduleUpdate()
+{
+ if (!m_redrawTimer.isActive())
+ m_redrawTimer.start();
+}
+
+void QAndroidPlatformScreen::setDirty(const QRect &rect)
+{
+ QRect intersection = rect.intersected(m_geometry);
+ m_repaintRegion += intersection;
+ scheduleUpdate();
+}
+
+void QAndroidPlatformScreen::setPhysicalSize(const QSize &size)
+{
+ m_physicalSize = size;
+}
+
+void QAndroidPlatformScreen::setGeometry(const QRect &rect)
+{
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_geometry == rect)
+ return;
+
+ m_geometry = rect;
+ QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
+ resizeMaximizedWindows();
+
+ if (m_id != -1) {
+ if (m_nativeSurface) {
+ ANativeWindow_release(m_nativeSurface);
+ m_nativeSurface = 0;
+ }
+ QtAndroid::setSurfaceGeometry(m_id, rect);
+ }
+}
+
+void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
+{
+ QtAndroidMenu::setActiveTopLevelWindow(w);
+
+ if (w != 0) {
+ QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
+ if (platformWindow != 0)
+ platformWindow->updateStatusBarVisibility();
+ }
+}
+
+void QAndroidPlatformScreen::doRedraw()
+{
+ PROFILE_SCOPE;
+
+ if (m_repaintRegion.isEmpty())
+ return;
+
+ QVector<QRect> rects = m_repaintRegion.rects();
+
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_id == -1) {
+ m_id = QtAndroid::createSurface(this, m_geometry, true);
+ m_surfaceWaitCondition.wait(&m_surfaceMutex);
+ }
+
+ if (!m_nativeSurface)
+ return;
+
+ ANativeWindow_Buffer nativeWindowBuffer;
+ ARect nativeWindowRect;
+ QRect br = m_repaintRegion.boundingRect();
+ nativeWindowRect.top = br.top();
+ nativeWindowRect.left = br.left();
+ nativeWindowRect.bottom = br.bottom() + 1; // for some reason that I don't understand the QRect bottom needs to +1 to be the same with ARect bottom
+ nativeWindowRect.right = br.right() + 1; // same for the right
+
+ int ret;
+ if ((ret = ANativeWindow_lock(m_nativeSurface, &nativeWindowBuffer, &nativeWindowRect)) < 0) {
+ qWarning() << "ANativeWindow_lock() failed! error=" << ret;
+ return;
+ }
+
+ int bpp = 4;
+ QImage::Format format = QImage::Format_RGBA8888_Premultiplied;
+ if (nativeWindowBuffer.format == WINDOW_FORMAT_RGB_565) {
+ bpp = 2;
+ format = QImage::Format_RGB16;
+ }
+
+ QImage screenImage(reinterpret_cast<uchar *>(nativeWindowBuffer.bits)
+ , nativeWindowBuffer.width, nativeWindowBuffer.height
+ , nativeWindowBuffer.stride * bpp , format);
+
+ QPainter compositePainter(&screenImage);
+ compositePainter.setCompositionMode(QPainter::CompositionMode_Source);
+
+ for (int rectIndex = 0; rectIndex < rects.size(); rectIndex++) {
+ QRegion visibleRegion = rects[rectIndex];
+ foreach (QAndroidPlatformWindow *window, m_windowStack) {
+ if (!window->window()->isVisible()
+ || !window->isRaster())
+ continue;
+
+ foreach (const QRect &rect, visibleRegion.rects()) {
+ QRect targetRect = window->geometry();
+ targetRect &= rect;
+
+ if (targetRect.isNull())
+ continue;
+
+ visibleRegion -= targetRect;
+ QRect windowRect = targetRect.translated(-window->geometry().topLeft());
+ QAndroidPlatformBackingStore *backingStore = static_cast<QAndroidPlatformRasterWindow *>(window)->backingStore();
+ if (backingStore)
+ compositePainter.drawImage(targetRect.topLeft(), backingStore->image(), windowRect);
+ }
+ }
+
+ foreach (const QRect &rect, visibleRegion.rects()) {
+ compositePainter.fillRect(rect, QColor(Qt::transparent));
+ }
+ }
+
+ ret = ANativeWindow_unlockAndPost(m_nativeSurface);
+ if (ret >= 0)
+ m_repaintRegion = QRegion();
+}
+
+QDpi QAndroidPlatformScreen::logicalDpi() const
+{
+ qreal lDpi = QtAndroid::scaledDensity() * 72;
+ return QDpi(lDpi, lDpi);
+}
+
+Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
+{
+ return QAndroidPlatformIntegration::m_orientation;
+}
+
+Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
+{
+ return QAndroidPlatformIntegration::m_nativeOrientation;
+}
+
+void QAndroidPlatformScreen::surfaceChanged(JNIEnv *env, jobject surface, int w, int h)
+{
+ lockSurface();
+ if (surface && w && h) {
+ if (m_nativeSurface)
+ ANativeWindow_release(m_nativeSurface);
+ m_nativeSurface = ANativeWindow_fromSurface(env, surface);
+ } else {
+ if (m_nativeSurface) {
+ ANativeWindow_release(m_nativeSurface);
+ m_nativeSurface = 0;
+ }
+ }
+ unlockSurface();
+ m_surfaceWaitCondition.wakeOne();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h
new file mode 100644
index 0000000000..d3de937548
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformscreen.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMSCREEN_H
+#define QANDROIDPLATFORMSCREEN_H
+
+#include <qpa/qplatformscreen.h>
+#include <QList>
+#include <QPainter>
+#include <QTimer>
+#include <QWaitCondition>
+#include <QtCore/private/qjni_p.h>
+
+#include "androidsurfaceclient.h"
+
+#include <android/native_window.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformWindow;
+class QAndroidPlatformBackingStore;
+
+class QAndroidPlatformScreen: public QObject, public QPlatformScreen, public AndroidSurfaceClient
+{
+ Q_OBJECT
+public:
+ QAndroidPlatformScreen();
+ ~QAndroidPlatformScreen();
+
+ QRect geometry() const { return m_geometry; }
+ int depth() const { return m_depth; }
+ QImage::Format format() const { return m_format; }
+ QSizeF physicalSize() const { return m_physicalSize; }
+
+ inline QWindow *topWindow() const;
+ QWindow *topLevelAt(const QPoint & p) const;
+
+ // compositor api
+ void addWindow(QAndroidPlatformWindow *window);
+ void removeWindow(QAndroidPlatformWindow *window);
+ void raise(QAndroidPlatformWindow *window);
+ void lower(QAndroidPlatformWindow *window);
+
+ void scheduleUpdate();
+ void topWindowChanged(QWindow *w);
+
+public slots:
+ void setDirty(const QRect &rect);
+ void setPhysicalSize(const QSize &size);
+ void setGeometry(const QRect &rect);
+
+protected:
+ typedef QList<QAndroidPlatformWindow *> WindowStackType;
+ WindowStackType m_windowStack;
+ QRegion m_repaintRegion;
+ QTimer m_redrawTimer;
+
+ QRect m_geometry;
+ int m_depth;
+ QImage::Format m_format;
+ QSizeF m_physicalSize;
+
+private:
+ QDpi logicalDpi() const;
+ Qt::ScreenOrientation orientation() const;
+ Qt::ScreenOrientation nativeOrientation() const;
+ void surfaceChanged(JNIEnv *env, jobject surface, int w, int h);
+
+private slots:
+ void doRedraw();
+
+private:
+ int m_id = -1;
+ ANativeWindow* m_nativeSurface = nullptr;
+ QWaitCondition m_surfaceWaitCondition;
+};
+
+QT_END_NAMESPACE
+#endif
diff --git a/src/plugins/platforms/android/src/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp
index 0df882f1f0..0df882f1f0 100644
--- a/src/plugins/platforms/android/src/qandroidplatformservices.cpp
+++ b/src/plugins/platforms/android/qandroidplatformservices.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformservices.h b/src/plugins/platforms/android/qandroidplatformservices.h
index 8368b19043..8368b19043 100644
--- a/src/plugins/platforms/android/src/qandroidplatformservices.h
+++ b/src/plugins/platforms/android/qandroidplatformservices.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 308bb70faf..ab29541f15 100644
--- a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -46,6 +46,7 @@
#include "qandroidplatformdialoghelpers.h"
#include <QVariant>
#include <QFileInfo>
+#include <QCoreApplication>
#include <qandroidplatformintegration.h>
QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *androidPlatformNativeInterface)
@@ -152,6 +153,21 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
}
}
+QString QAndroidPlatformTheme::standardButtonText(int button) const
+{
+ switch (button) {
+ case QMessageDialogOptions::Yes:
+ return QCoreApplication::translate("QAndroidPlatformTheme", "Yes");
+ case QMessageDialogOptions::YesToAll:
+ return QCoreApplication::translate("QAndroidPlatformTheme", "Yes to All");
+ case QMessageDialogOptions::No:
+ return QCoreApplication::translate("QAndroidPlatformTheme", "No");
+ case QMessageDialogOptions::NoToAll:
+ return QCoreApplication::translate("QAndroidPlatformTheme", "No to All");
+ }
+ return QPlatformTheme::standardButtonText(button);
+}
+
bool QAndroidPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
{
if (type == MessageDialog)
diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h
index ec259a9b0a..544061a7a2 100644
--- a/src/plugins/platforms/android/src/qandroidplatformtheme.h
+++ b/src/plugins/platforms/android/qandroidplatformtheme.h
@@ -54,6 +54,7 @@ public:
virtual const QPalette *palette(Palette type = SystemPalette) const;
virtual const QFont *font(Font type = SystemFont) const;
virtual QVariant themeHint(ThemeHint hint) const;
+ QString standardButtonText(int button) const Q_DECL_OVERRIDE;
virtual bool usePlatformNativeDialog(DialogType type) const;
virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index 7ff18526d9..b4231f0283 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -40,63 +41,122 @@
****************************************************************************/
#include "qandroidplatformwindow.h"
+#include "qandroidplatformopenglcontext.h"
+#include "qandroidplatformscreen.h"
#include "androidjnimain.h"
#include <qpa/qwindowsysteminterface.h>
+QT_BEGIN_NAMESPACE
+
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
- : QFbWindow(window)
+ : QPlatformWindow(window)
{
+ m_windowFlags = Qt::Widget;
+ m_windowState = Qt::WindowNoState;
+ static QAtomicInt winIdGenerator(1);
+ m_windowId = winIdGenerator.fetchAndAddRelaxed(1);
+ setWindowState(window->windowState());
}
-void QAndroidPlatformWindow::setGeometry(const QRect &rect)
+void QAndroidPlatformWindow::lower()
{
- QFbWindow::setGeometry(rect);
+ platformScreen()->lower(this);
}
-void QAndroidPlatformWindow::propagateSizeHints()
+void QAndroidPlatformWindow::raise()
{
- //shut up warning from default implementation
+ updateStatusBarVisibility();
+ platformScreen()->raise(this);
}
-void QAndroidPlatformWindow::updateStatusBarVisibility()
+void QAndroidPlatformWindow::setGeometry(const QRect &rect)
{
- Qt::WindowFlags flags = window()->flags();
- bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
- if (!isNonRegularWindow) {
- if (mWindowState & Qt::WindowFullScreen)
- QtAndroid::hideStatusBar();
- else if (mWindowState & Qt::WindowMaximized)
- QtAndroid::showStatusBar();
- }
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
+ QPlatformWindow::setGeometry(rect);
}
-void QAndroidPlatformWindow::raise()
+void QAndroidPlatformWindow::setVisible(bool visible)
{
- updateStatusBarVisibility();
- QFbWindow::raise();
+ if (visible)
+ updateStatusBarVisibility();
+
+ if (visible) {
+ if (m_windowState & Qt::WindowFullScreen)
+ setGeometry(platformScreen()->geometry());
+ else if (m_windowState & Qt::WindowMaximized)
+ setGeometry(platformScreen()->availableGeometry());
+ }
+
+ QPlatformWindow::setVisible(visible);
+
+ if (visible)
+ platformScreen()->addWindow(this);
+ else
+ platformScreen()->removeWindow(this);
+
+ // The Android Activity is activated before Qt is initialized, causing the application state to
+ // never be set to 'active'. We explicitly set this state when the first window becomes visible.
+ if (visible)
+ QtAndroid::setApplicationActive();
}
void QAndroidPlatformWindow::setWindowState(Qt::WindowState state)
{
- if (mWindowState == state)
+ if (m_windowState == state)
return;
+ QPlatformWindow::setWindowState(state);
+ m_windowState = state;
+
if (window()->isVisible())
updateStatusBarVisibility();
+}
- QFbWindow::setWindowState(state);
+void QAndroidPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+ if (m_windowFlags == flags)
+ return;
+
+ m_windowFlags = flags;
}
-void QAndroidPlatformWindow::setVisible(bool visible)
+Qt::WindowFlags QAndroidPlatformWindow::windowFlags() const
{
- if (visible)
- updateStatusBarVisibility();
+ return m_windowFlags;
+}
- QFbWindow::setVisible(visible);
+void QAndroidPlatformWindow::setParent(const QPlatformWindow *window)
+{
+ Q_UNUSED(window);
+}
- // The Android Activity is activated before Qt is initialized, causing the application state to
- // never be set to 'active'. We explicitly set this state when the first window becomes visible.
- if (visible)
- QtAndroid::setApplicationActive();
+QAndroidPlatformScreen *QAndroidPlatformWindow::platformScreen() const
+{
+ return static_cast<QAndroidPlatformScreen *>(window()->screen()->handle());
+}
+
+void QAndroidPlatformWindow::propagateSizeHints()
+{
+ //shut up warning from default implementation
+}
+
+void QAndroidPlatformWindow::requestActivateWindow()
+{
+ platformScreen()->topWindowChanged(window());
+}
+
+void QAndroidPlatformWindow::updateStatusBarVisibility()
+{
+ Qt::WindowFlags flags = window()->flags();
+ bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
+ if (!isNonRegularWindow) {
+ if (m_windowState & Qt::WindowFullScreen)
+ QtAndroid::hideStatusBar();
+ else if (m_windowState & Qt::WindowMaximized)
+ QtAndroid::showStatusBar();
+ }
}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h
index e4ff0444d4..764dd3ab86 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformwindow.h
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -39,53 +40,48 @@
**
****************************************************************************/
-#ifndef QANDROIDOPENGLPLATFORMWINDOW_H
-#define QANDROIDOPENGLPLATFORMWINDOW_H
-
-#include "qeglfswindow.h"
-#include <QtCore/qmutex.h>
-#include <QtCore/qreadwritelock.h>
+#ifndef ANDROIDPLATFORMWINDOW_H
+#define ANDROIDPLATFORMWINDOW_H
+#include <qobject.h>
+#include <qrect.h>
+#include <qpa/qplatformwindow.h>
QT_BEGIN_NAMESPACE
-class QAndroidOpenGLPlatformWindow : public QEglFSWindow
+class QAndroidPlatformScreen;
+
+class QAndroidPlatformWindow: public QPlatformWindow
{
public:
- QAndroidOpenGLPlatformWindow(QWindow *window);
- ~QAndroidOpenGLPlatformWindow();
-
- QSize scheduledResize() const { return m_scheduledResize; }
- void scheduleResize(const QSize &size) { m_scheduledResize = size; }
-
- void lock() { m_lock.lock(); }
- void unlock() { m_lock.unlock(); }
-
- bool isExposed() const;
+ explicit QAndroidPlatformWindow(QWindow *window);
+ void lower();
void raise();
- void invalidateSurface();
- void resetSurface();
- void setWindowState(Qt::WindowState state);
-
void setVisible(bool visible);
- void destroy();
+ void setWindowState(Qt::WindowState state);
+ void setWindowFlags(Qt::WindowFlags flags);
+ Qt::WindowFlags windowFlags() const;
+ void setParent(const QPlatformWindow *window);
+ WId winId() const { return m_windowId; }
+
+ QAndroidPlatformScreen *platformScreen() const;
- static void updateStaticNativeWindow();
+ void propagateSizeHints();
+ void requestActivateWindow();
void updateStatusBarVisibility();
+ inline bool isRaster() const { return window()->surfaceType() == QSurface::RasterSurface; }
-private:
- QSize m_scheduledResize;
- QMutex m_lock;
- Qt::WindowState m_state;
+protected:
+ void setGeometry(const QRect &rect);
- static QReadWriteLock m_staticSurfaceLock;
- static EGLSurface m_staticSurface;
- static EGLNativeWindowType m_staticNativeWindow;
- static QBasicAtomicInt m_referenceCount;
+protected:
+ Qt::WindowFlags m_windowFlags;
+ Qt::WindowState m_windowState;
+
+ WId m_windowId;
};
QT_END_NAMESPACE
-
-#endif // QANDROIDOPENGLPLATFORMWINDOW_H
+#endif // ANDROIDPLATFORMWINDOW_H
diff --git a/src/plugins/platforms/android/src/qandroidsystemlocale.cpp b/src/plugins/platforms/android/qandroidsystemlocale.cpp
index a20f970a44..a20f970a44 100644
--- a/src/plugins/platforms/android/src/qandroidsystemlocale.cpp
+++ b/src/plugins/platforms/android/qandroidsystemlocale.cpp
diff --git a/src/plugins/platforms/android/src/qandroidsystemlocale.h b/src/plugins/platforms/android/qandroidsystemlocale.h
index fc2f6fad98..fc2f6fad98 100644
--- a/src/plugins/platforms/android/src/qandroidsystemlocale.h
+++ b/src/plugins/platforms/android/qandroidsystemlocale.h
diff --git a/src/plugins/platforms/android/raster/raster.pro b/src/plugins/platforms/android/raster/raster.pro
deleted file mode 100644
index 53d8ee7a2b..0000000000
--- a/src/plugins/platforms/android/raster/raster.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TARGET = qtforandroid
-
-PLUGIN_TYPE = platforms
-
-# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
-# Yes, the plugin imports itself statically
-DEFINES += QT_STATICPLUGIN
-
-load(qt_plugin)
-
-!contains(ANDROID_PLATFORM, android-9) {
- INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include
- LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid
-} else {
- LIBS += -ljnigraphics -landroid
-}
-
-include($$PWD/../src/src.pri)
-include($$PWD/../src/raster/raster.pri)
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
deleted file mode 100644
index 6ed805174b..0000000000
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 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 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qandroidopenglplatformwindow.h"
-#include "androidjnimain.h"
-#include "qandroidplatformintegration.h"
-#include <qpa/qwindowsysteminterface.h>
-
-QT_BEGIN_NAMESPACE
-
-EGLSurface QAndroidOpenGLPlatformWindow::m_staticSurface = 0;
-EGLNativeWindowType QAndroidOpenGLPlatformWindow::m_staticNativeWindow = 0;
-QReadWriteLock QAndroidOpenGLPlatformWindow::m_staticSurfaceLock;
-QBasicAtomicInt QAndroidOpenGLPlatformWindow::m_referenceCount = Q_BASIC_ATOMIC_INITIALIZER(0);
-
-QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window)
- : QEglFSWindow(window)
- , m_state(Qt::WindowNoState)
-{
-}
-
-QAndroidOpenGLPlatformWindow::~QAndroidOpenGLPlatformWindow()
-{
- destroy();
-}
-
-bool QAndroidOpenGLPlatformWindow::isExposed() const
-{
- return QtAndroid::nativeWindow(false) != 0 && QEglFSWindow::isExposed();
-}
-
-void QAndroidOpenGLPlatformWindow::invalidateSurface()
-{
- QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event
- QWindowSystemInterface::flushWindowSystemEvents();
-
- m_window = 0;
- m_surface = 0;
-
- if (!m_referenceCount.deref()){
- QWriteLocker locker(&m_staticSurfaceLock);
-
- EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
- eglDestroySurface(display, m_staticSurface);
-
- m_staticSurface = 0;
- m_staticNativeWindow = 0;
- }
-}
-
-void QAndroidOpenGLPlatformWindow::updateStaticNativeWindow()
-{
- QWriteLocker locker(&m_staticSurfaceLock);
- m_staticNativeWindow = QtAndroid::nativeWindow(false);
-}
-
-void QAndroidOpenGLPlatformWindow::resetSurface()
-{
- // Only add a reference if we're not already holding one, otherwise we're just updating
- // the native window pointer
- if (m_window == 0)
- m_referenceCount.ref();
-
- if (m_staticSurface == 0) {
- QWriteLocker locker(&m_staticSurfaceLock);
- QEglFSWindow::resetSurface();
- m_staticSurface = m_surface;
- m_staticNativeWindow = m_window;
- } else {
- QReadLocker locker(&m_staticSurfaceLock);
- m_window = m_staticNativeWindow;
- m_surface = m_staticSurface;
- }
-
- {
- lock();
- // Use the desktop size.
- // On some devices, the getters for the native window size gives wrong values
- scheduleResize(QAndroidPlatformIntegration::defaultDesktopSize());
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
- unlock();
- }
-
- QWindowSystemInterface::flushWindowSystemEvents();
-}
-
-void QAndroidOpenGLPlatformWindow::destroy()
-{
- if (!m_referenceCount.deref()) {
- QEglFSWindow::destroy();
- } else {
- m_window = 0;
- m_surface = 0;
- }
-}
-
-void QAndroidOpenGLPlatformWindow::updateStatusBarVisibility()
-{
- Qt::WindowFlags flags = window()->flags();
- bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
- if (!isNonRegularWindow) {
- if (m_state & Qt::WindowFullScreen)
- QtAndroid::hideStatusBar();
- else if (m_state & Qt::WindowMaximized)
- QtAndroid::showStatusBar();
- }
-}
-
-void QAndroidOpenGLPlatformWindow::raise()
-{
- updateStatusBarVisibility();
-}
-
-void QAndroidOpenGLPlatformWindow::setWindowState(Qt::WindowState state)
-{
- if (m_state == state)
- return;
-
- m_state = state;
- if (window()->isVisible())
- updateStatusBarVisibility();
-}
-
-void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
-{
- if (visible)
- updateStatusBarVisibility();
-
- QEglFSWindow::setVisible(visible);
-
- // The Android Activity is activated before Qt is initialized, causing the application state to
- // never be set to 'active'. We explicitly set this state when the first window becomes visible.
- if (visible)
- QtAndroid::setApplicationActive();
-
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
- QWindowSystemInterface::flushWindowSystemEvents();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
deleted file mode 100644
index 278cd553f4..0000000000
--- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 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 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglfshooks.h"
-#include "androidjnimain.h"
-#include "qandroidplatformintegration.h"
-
-#include <android/native_window.h>
-#include <jni.h>
-
-QT_BEGIN_NAMESPACE
-
-class QEglFSAndroidHooks: public QEglFSHooks
-{
-public:
- void platformInit();
- void platformDestroy();
- EGLNativeDisplayType platformDisplay() const;
- QSize screenSize() const;
- QSizeF physicalScreenSize() const;
- QDpi logicalDpi() const;
- Qt::ScreenOrientation orientation() const;
- Qt::ScreenOrientation nativeOrientation() const;
- int screenDepth() const;
- QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;
- EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format);
- void destroyNativeWindow(EGLNativeWindowType window);
- bool hasCapability(QPlatformIntegration::Capability cap) const;
- QEglFSCursor *createCursor(QEglFSScreen *screen) const;
-};
-
-void QEglFSAndroidHooks::platformInit()
-{
-}
-
-void QEglFSAndroidHooks::platformDestroy()
-{
-}
-
-EGLNativeDisplayType QEglFSAndroidHooks::platformDisplay() const
-{
- return EGL_DEFAULT_DISPLAY;
-}
-
-QSize QEglFSAndroidHooks::screenSize() const
-{
- return QAndroidPlatformIntegration::defaultDesktopSize();
-}
-
-QSizeF QEglFSAndroidHooks::physicalScreenSize() const
-{
- return QSizeF(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth, QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
-}
-
-QDpi QEglFSAndroidHooks::logicalDpi() const
-{
- qreal lDpi = QtAndroid::scaledDensity() * 72;
- return QDpi(lDpi, lDpi);
-}
-
-Qt::ScreenOrientation QEglFSAndroidHooks::orientation() const
-{
- return QAndroidPlatformIntegration::m_orientation;
-}
-
-Qt::ScreenOrientation QEglFSAndroidHooks::nativeOrientation() const
-{
- return QAndroidPlatformIntegration::m_nativeOrientation;
-}
-
-EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format)
-{
- Q_UNUSED(platformWindow);
- Q_UNUSED(size);
- Q_UNUSED(format);
- ANativeWindow *window = QtAndroid::nativeWindow();
- if (window != 0)
- ANativeWindow_acquire(window);
-
- return window;
-}
-
-void QEglFSAndroidHooks::destroyNativeWindow(EGLNativeWindowType window)
-{
- if (window != 0)
- ANativeWindow_release(window);
-}
-
-bool QEglFSAndroidHooks::hasCapability(QPlatformIntegration::Capability capability) const
-{
- switch (capability) {
- case QPlatformIntegration::OpenGL: return true;
- case QPlatformIntegration::ThreadedOpenGL: return true;
- default: return false;
- };
-}
-
-int QEglFSAndroidHooks::screenDepth() const
-{
- // ### Hardcoded
- return 32;
-}
-
-QSurfaceFormat QEglFSAndroidHooks::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
-{
- QSurfaceFormat ret(inputFormat);
- ret.setAlphaBufferSize(8);
- ret.setRedBufferSize(8);
- ret.setGreenBufferSize(8);
- ret.setBlueBufferSize(8);
- return ret;
-}
-
-QEglFSCursor *QEglFSAndroidHooks::createCursor(QEglFSScreen *screen) const
-{
- Q_UNUSED(screen);
- return 0;
-}
-
-static QEglFSAndroidHooks eglFSAndroidHooks;
-QEglFSHooks *platformHooks = &eglFSAndroidHooks;
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
deleted file mode 100644
index 2e59c307c3..0000000000
--- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 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 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qandroidplatformscreen.h"
-#include "qandroidplatformintegration.h"
-#include "androidjnimain.h"
-#include "androidjnimenu.h"
-#include "qandroidplatformwindow.h"
-
-QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen()
-{
- mGeometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
- mFormat = QImage::Format_RGB16;
- mDepth = 16;
- mPhysicalSize.setHeight(QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
- mPhysicalSize.setWidth(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth);
- initializeCompositor();
-}
-
-void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
-{
- QtAndroidMenu::setActiveTopLevelWindow(w);
-
- if (w != 0) {
- QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
- if (platformWindow != 0)
- platformWindow->updateStatusBarVisibility();
- }
-}
-
-QRegion QAndroidPlatformScreen::doRedraw()
-{
- QRegion touched;
- touched = QFbScreen::doRedraw();
- if (touched.isEmpty())
- return touched;
-
- QtAndroid::flushImage(mGeometry.topLeft(), *mScreenImage, touched.boundingRect());
- return touched;
-}
-
-QDpi QAndroidPlatformScreen::logicalDpi() const
-{
- qreal lDpi = QtAndroid::scaledDensity() * 72;
- return QDpi(lDpi, lDpi);
-}
-
-Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
-{
- return QAndroidPlatformIntegration::m_orientation;
-}
-
-Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
-{
- return QAndroidPlatformIntegration::m_nativeOrientation;
-}
diff --git a/src/plugins/platforms/android/src/raster/raster.pri b/src/plugins/platforms/android/src/raster/raster.pri
deleted file mode 100644
index 86e5aa235f..0000000000
--- a/src/plugins/platforms/android/src/raster/raster.pri
+++ /dev/null
@@ -1,7 +0,0 @@
-INCLUDEPATH += $$PWD
-
-SOURCES += $$PWD/qandroidplatformscreen.cpp \
- $$PWD/qandroidplatformwindow.cpp
-
-HEADERS += $$PWD/qandroidplatformscreen.h \
- $$PWD/qandroidplatformwindow.h
diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri
deleted file mode 100644
index 9b64e846f7..0000000000
--- a/src/plugins/platforms/android/src/src.pri
+++ /dev/null
@@ -1,55 +0,0 @@
-load(qt_plugin)
-
-QT += core-private gui-private platformsupport-private
-
-CONFIG += qpa/genericunixfontdatabase
-
-OTHER_FILES += $$PWD/android.json
-
-INCLUDEPATH += $$PWD
-INCLUDEPATH += $$PWD/../../../../3rdparty/android/src
-
-SOURCES += $$PWD/androidplatformplugin.cpp \
- $$PWD/androidjnimain.cpp \
- $$PWD/androidjniaccessibility.cpp \
- $$PWD/androidjniinput.cpp \
- $$PWD/androidjnimenu.cpp \
- $$PWD/androidjniclipboard.cpp \
- $$PWD/qandroidplatformintegration.cpp \
- $$PWD/qandroidplatformservices.cpp \
- $$PWD/qandroidassetsfileenginehandler.cpp \
- $$PWD/qandroidinputcontext.cpp \
- $$PWD/qandroidplatformaccessibility.cpp \
- $$PWD/qandroidplatformfontdatabase.cpp \
- $$PWD/qandroidplatformdialoghelpers.cpp \
- $$PWD/qandroidplatformclipboard.cpp \
- $$PWD/qandroidplatformtheme.cpp \
- $$PWD/qandroidplatformmenubar.cpp \
- $$PWD/qandroidplatformmenu.cpp \
- $$PWD/qandroidplatformmenuitem.cpp \
- $$PWD/qandroidsystemlocale.cpp
-
-
-HEADERS += $$PWD/qandroidplatformintegration.h \
- $$PWD/androidjnimain.h \
- $$PWD/androidjniaccessibility.h \
- $$PWD/androidjniinput.h \
- $$PWD/androidjnimenu.h \
- $$PWD/androidjniclipboard.h \
- $$PWD/qandroidplatformservices.h \
- $$PWD/qandroidassetsfileenginehandler.h \
- $$PWD/qandroidinputcontext.h \
- $$PWD/qandroidplatformaccessibility.h \
- $$PWD/qandroidplatformfontdatabase.h \
- $$PWD/qandroidplatformclipboard.h \
- $$PWD/qandroidplatformdialoghelpers.h \
- $$PWD/qandroidplatformtheme.h \
- $$PWD/qandroidplatformmenubar.h \
- $$PWD/qandroidplatformmenu.h \
- $$PWD/qandroidplatformmenuitem.h \
- $$PWD/qandroidsystemlocale.h
-
-
-#Non-standard install directory, QTBUG-29859
-DESTDIR = $$DESTDIR/android
-target.path = $${target.path}/android
diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp
index 3db1618a50..1fe80b28b1 100644
--- a/src/plugins/platforms/cocoa/messages.cpp
+++ b/src/plugins/platforms/cocoa/messages.cpp
@@ -93,4 +93,9 @@ QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption)
return QPlatformMenuItem::NoRole;
}
+QString msgDialogButtonDiscard()
+{
+ return QCoreApplication::translate("QCocoaTheme", "Don't Save");
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/messages.h b/src/plugins/platforms/cocoa/messages.h
index 09705c1e21..97f3ea7009 100644
--- a/src/plugins/platforms/cocoa/messages.h
+++ b/src/plugins/platforms/cocoa/messages.h
@@ -53,6 +53,8 @@ QString qt_mac_applicationmenu_string(int type);
QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption);
+QString msgDialogButtonDiscard();
+
QT_END_NAMESPACE
#endif // MESSAGES_H
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h
index ffb12ea846..bb218bcabe 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.h
@@ -86,7 +86,7 @@
//
/*
- Cocoa Application Categories
+ Cocoa Application Categories
*/
#include "qglobal.h"
#include "private/qcore_mac_p.h"
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index f9767ce716..327ca00ad6 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -114,7 +114,7 @@ static void cleanupCocoaApplicationDelegate()
- (void)updateScreens:(NSNotification *)notification
{
Q_UNUSED(notification);
- if (QCocoaIntegration *ci = dynamic_cast<QCocoaIntegration *>(QGuiApplicationPrivate::platformIntegration()))
+ if (QCocoaIntegration *ci = QCocoaIntegration::instance())
ci->updateScreens();
}
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 8f74a71b1e..4b637a707d 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -143,7 +143,7 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
[pixelFormat release];
- const GLint interval = 1;
+ const GLint interval = format.swapInterval() >= 0 ? format.swapInterval() : 1;
[m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
if (format.alphaBufferSize() > 0) {
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 3e402673f3..64e1640a69 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -116,6 +116,7 @@ inline NSPoint qt_mac_flipPoint(const QPoint &p)
inline NSPoint qt_mac_flipPoint(const QPointF &p)
{ return NSMakePoint(p.x(), qt_mac_flipYCoordinate(p.y())); }
+NSRect qt_mac_flipRect(const QRect &rect);
NSRect qt_mac_flipRect(const QRect &rect, QWindow *window);
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum);
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 4a5696b35e..d27c134fa3 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -585,6 +585,12 @@ QString qt_mac_applicationName()
return appName;
}
+NSRect qt_mac_flipRect(const QRect &rect)
+{
+ int flippedY = qt_mac_flipYCoordinate(rect.y() + rect.height());
+ return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height());
+}
+
/*
Mac window coordinates are in the first quadrant: 0, 0 is at the lower-left
corner of the primary screen. This function converts the given rect to an
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 111329aaee..8babfcf8ae 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -46,6 +46,10 @@
#include "qcocoaautoreleasepool.h"
#include "qcocoacursor.h"
+#include "qcocoawindow.h"
+#include "qcocoanativeinterface.h"
+#include "qcocoainputcontext.h"
+#include "qcocoaaccessibility.h"
#include "qcocoaclipboard.h"
#include "qcocoadrag.h"
#include "qcocoaservices.h"
@@ -53,6 +57,7 @@
#include <QtCore/QScopedPointer>
#include <qpa/qplatformintegration.h>
+#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
QT_BEGIN_NAMESPACE
@@ -103,23 +108,25 @@ public:
QCocoaIntegration();
~QCocoaIntegration();
+ static QCocoaIntegration *instance();
+
bool hasCapability(QPlatformIntegration::Capability cap) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const;
QAbstractEventDispatcher *createEventDispatcher() const;
- QPlatformFontDatabase *fontDatabase() const;
- QPlatformNativeInterface *nativeInterface() const;
- QPlatformInputContext *inputContext() const;
- QPlatformAccessibility *accessibility() const;
- QPlatformClipboard *clipboard() const;
- QPlatformDrag *drag() const;
+ QCoreTextFontDatabase *fontDatabase() const;
+ QCocoaNativeInterface *nativeInterface() const;
+ QCocoaInputContext *inputContext() const;
+ QCocoaAccessibility *accessibility() const;
+ QCocoaClipboard *clipboard() const;
+ QCocoaDrag *drag() const;
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
- QPlatformServices *services() const;
+ QCocoaServices *services() const;
QVariant styleHint(StyleHint hint) const;
QList<int> possibleKeys(const QKeyEvent *event) const;
@@ -128,18 +135,19 @@ public:
QCocoaScreen *screenAtIndex(int index);
private:
+ static QCocoaIntegration *mInstance;
- QScopedPointer<QPlatformFontDatabase> mFontDb;
+ QScopedPointer<QCoreTextFontDatabase> mFontDb;
- QScopedPointer<QPlatformInputContext> mInputContext;
+ QScopedPointer<QCocoaInputContext> mInputContext;
#ifndef QT_NO_ACCESSIBILITY
- QScopedPointer<QPlatformAccessibility> mAccessibility;
+ QScopedPointer<QCocoaAccessibility> mAccessibility;
#endif
QScopedPointer<QPlatformTheme> mPlatformTheme;
QList<QCocoaScreen *> mScreens;
QCocoaClipboard *mCocoaClipboard;
QScopedPointer<QCocoaDrag> mCocoaDrag;
- QScopedPointer<QPlatformNativeInterface> mNativeInterface;
+ QScopedPointer<QCocoaNativeInterface> mNativeInterface;
QScopedPointer<QCocoaServices> mServices;
QScopedPointer<QCocoaKeyMapper> mKeyboardMapper;
};
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 5f01274d98..e8cf5ca69b 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -58,7 +58,6 @@
#include <qpa/qplatformaccessibility.h>
#include <QtCore/qcoreapplication.h>
-#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
#include <IOKit/graphics/IOGraphicsLib.h>
static void initResources()
@@ -214,6 +213,8 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height
return windowPixmap;
}
+QCocoaIntegration *QCocoaIntegration::mInstance = 0;
+
QCocoaIntegration::QCocoaIntegration()
: mFontDb(new QCoreTextFontDatabase())
, mInputContext(new QCocoaInputContext)
@@ -226,6 +227,10 @@ QCocoaIntegration::QCocoaIntegration()
, mServices(new QCocoaServices)
, mKeyboardMapper(new QCocoaKeyMapper)
{
+ if (mInstance != 0)
+ qWarning("Creating multiple Cocoa platform integrations is not supported");
+ mInstance = this;
+
initResources();
QCocoaAutoReleasePool pool;
@@ -273,6 +278,8 @@ QCocoaIntegration::QCocoaIntegration()
QCocoaIntegration::~QCocoaIntegration()
{
+ mInstance = 0;
+
qt_resetNSApplicationSendEvent();
QCocoaAutoReleasePool pool;
@@ -296,6 +303,11 @@ QCocoaIntegration::~QCocoaIntegration()
}
}
+QCocoaIntegration *QCocoaIntegration::instance()
+{
+ return mInstance;
+}
+
/*!
\brief Synchronizes the screen list, adds new screens, removes deleted ones
*/
@@ -388,22 +400,22 @@ QAbstractEventDispatcher *QCocoaIntegration::createEventDispatcher() const
return new QCocoaEventDispatcher;
}
-QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const
+QCoreTextFontDatabase *QCocoaIntegration::fontDatabase() const
{
return mFontDb.data();
}
-QPlatformNativeInterface *QCocoaIntegration::nativeInterface() const
+QCocoaNativeInterface *QCocoaIntegration::nativeInterface() const
{
return mNativeInterface.data();
}
-QPlatformInputContext *QCocoaIntegration::inputContext() const
+QCocoaInputContext *QCocoaIntegration::inputContext() const
{
return mInputContext.data();
}
-QPlatformAccessibility *QCocoaIntegration::accessibility() const
+QCocoaAccessibility *QCocoaIntegration::accessibility() const
{
#ifndef QT_NO_ACCESSIBILITY
return mAccessibility.data();
@@ -412,12 +424,12 @@ QPlatformAccessibility *QCocoaIntegration::accessibility() const
#endif
}
-QPlatformClipboard *QCocoaIntegration::clipboard() const
+QCocoaClipboard *QCocoaIntegration::clipboard() const
{
return mCocoaClipboard;
}
-QPlatformDrag *QCocoaIntegration::drag() const
+QCocoaDrag *QCocoaIntegration::drag() const
{
return mCocoaDrag.data();
}
@@ -434,7 +446,7 @@ QPlatformTheme *QCocoaIntegration::createPlatformTheme(const QString &name) cons
return QPlatformIntegration::createPlatformTheme(name);
}
-QPlatformServices *QCocoaIntegration::services() const
+QCocoaServices *QCocoaIntegration::services() const
{
return mServices.data();
}
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 5c59c73847..4bcb348acb 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -137,6 +137,7 @@ private:
static void setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness);
};
+QT_END_NAMESPACE
+
#endif // QCOCOANATIVEINTERFACE_H
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index e4237c9b3e..d60cdf10d1 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -73,6 +73,7 @@ public:
QPlatformTheme::IconOptions options = 0) const;
QVariant themeHint(ThemeHint hint) const;
+ QString standardButtonText(int button) const Q_DECL_OVERRIDE;
static const char *name;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index d863861288..109649f24e 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -42,6 +42,7 @@
#import <Cocoa/Cocoa.h>
#include "qcocoatheme.h"
+#include "messages.h"
#include <QtCore/QVariant>
@@ -300,6 +301,11 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
return QPlatformTheme::themeHint(hint);
}
+QString QCocoaTheme::standardButtonText(int button) const
+{
+ return button == QMessageDialogOptions::Discard ? msgDialogButtonDiscard() : QPlatformTheme::standardButtonText(button);
+}
+
QPlatformMenuItem *QCocoaTheme::createPlatformMenuItem() const
{
return new QCocoaMenuItem();
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 452be90108..7b9768fcd9 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -52,34 +52,32 @@
QT_FORWARD_DECLARE_CLASS(QCocoaWindow)
-@interface QNSWindow : NSWindow {
- @public QCocoaWindow *m_cocoaPlatformWindow;
-}
-
-- (void)clearPlatformWindow;
-- (BOOL)canBecomeKeyWindow;
-@end
+@class QNSWindowDelegate;
-@interface QNSPanel : NSPanel {
- @public QCocoaWindow *m_cocoaPlatformWindow;
+@interface QNSWindow : NSPanel {
+@public
+ QCocoaWindow *m_cocoaPlatformWindow;
}
+
- (void)clearPlatformWindow;
-- (BOOL)canBecomeKeyWindow;
@end
-@class QNSWindowDelegate;
-
QT_BEGIN_NAMESPACE
+
// QCocoaWindow
//
-// QCocoaWindow is an NSView (not an NSWindow!) in the sense
-// that it relies on a NSView for all event handling and
-// graphics output and does not require a NSWindow, except for
-// for the window-related functions like setWindowTitle.
+// A QCocoaWindow is backed by a NSView and optionally a NSWindow.
+//
+// The NSView is used for most event handling and graphics output.
//
-// As a consequence of this it is possible to embed the QCocoaWindow
-// in an NSView hierarchy by getting a pointer to the "backing"
-// NSView and not calling QCocoaWindow::show():
+// Top-level QWindows are always backed by a NSWindow in addition to
+// the NSView. Child QWindows can also be backed by NSWindows, which
+// enables proper stacking of GL Widgets and threaded GL rendering
+// to multiple contexts.
+//
+// It is possible to embed the QCocoaWindow in an NSView hierarchy
+// by getting a pointer to the backing NSView and not calling
+// QCocoaWindow::show():
//
// QWindow *qtWindow = new MyWindow();
// qtWindow->create();
@@ -100,6 +98,10 @@ public:
void setGeometry(const QRect &rect);
void setCocoaGeometry(const QRect &rect);
+ void clipChildWindows();
+ void clipWindow(const NSRect &clipRect);
+ void show(bool becauseOfAncestor = false);
+ void hide(bool becauseOfAncestor = false);
void setVisible(bool visible);
void setWindowFlags(Qt::WindowFlags flags);
void setWindowState(Qt::WindowState state);
@@ -135,6 +137,7 @@ public:
void windowDidResize();
bool windowShouldClose();
bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const;
+ bool windowShouldBehaveAsPanel() const;
void setSynchedWindowStateFromWindow();
@@ -167,16 +170,16 @@ public:
void updateExposedGeometry();
QWindow *childWindowAt(QPoint windowPoint);
protected:
- // NSWindow handling. The QCocoaWindow/QNSView can either be displayed
- // in an existing NSWindow or in one created by Qt.
void recreateWindow(const QPlatformWindow *parentWindow);
- NSWindow *createNSWindow();
- void setNSWindow(NSWindow *window);
- void clearNSWindow(NSWindow *window);
+ QNSWindow *createNSWindow();
+ void setNSWindow(QNSWindow *window);
+ void clearNSWindow(QNSWindow *window);
QRect windowGeometry() const;
QCocoaWindow *parentCocoaWindow() const;
void syncWindowState(Qt::WindowState newState);
+ void reinsertChildWindow(QCocoaWindow *child);
+ void removeChildWindow(QCocoaWindow *child);
// private:
public: // for QNSView
@@ -185,12 +188,17 @@ public: // for QNSView
NSView *m_contentView;
QNSView *m_qtView;
- NSWindow *m_nsWindow;
+ QNSWindow *m_nsWindow;
+ QCocoaWindow *m_forwardWindow;
// TODO merge to one variable if possible
bool m_contentViewIsEmbedded; // true if the m_contentView is actually embedded in a "foreign" NSView hiearchy
bool m_contentViewIsToBeEmbedded; // true if the m_contentView is intended to be embedded in a "foreign" NSView hiearchy
+ QCocoaWindow *m_parentCocoaWindow;
+ bool m_isNSWindowChild; // this window is a non-top level QWindow with a NSWindow.
+ QList<QCocoaWindow *> m_childWindows;
+
QNSWindowDelegate *m_nsWindowDelegate;
Qt::WindowFlags m_windowFlags;
Qt::WindowState m_synchedWindowState;
@@ -211,6 +219,8 @@ public: // for QNSView
QRect m_exposedGeometry;
int m_registerTouchCount;
bool m_resizableTransientParent;
+ bool m_hiddenByClipping;
+ bool m_hiddenByAncestor;
static const int NoAlertRequest;
NSInteger m_alertRequest;
@@ -219,6 +229,11 @@ public: // for QNSView
bool m_drawContentBorderGradient;
int m_topContentBorderThickness;
int m_bottomContentBorderThickness;
+
+ // used by showFullScreen in fake mode
+ QRect m_normalGeometry;
+ Qt::WindowFlags m_oldWindowFlags;
+ NSApplicationPresentationOptions m_presentationOptions;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 211ecd60ab..70a08bbea5 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -80,15 +80,10 @@ static bool isMouseEvent(NSEvent *ev)
}
@interface NSWindow (CocoaWindowCategory)
-- (void) clearPlatformWindow;
- (NSRect) legacyConvertRectFromScreen:(NSRect) rect;
@end
@implementation NSWindow (CocoaWindowCategory)
-- (void) clearPlatformWindow
-{
-}
-
- (NSRect) legacyConvertRectFromScreen:(NSRect) rect
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
@@ -104,11 +99,40 @@ static bool isMouseEvent(NSEvent *ev)
@implementation QNSWindow
+- (id)initWithContentRect:(NSRect)contentRect
+ styleMask:(NSUInteger)windowStyle
+ qPlatformWindow:(QCocoaWindow *)qpw
+{
+ self = [super initWithContentRect:contentRect
+ styleMask:windowStyle
+ backing:NSBackingStoreBuffered
+ defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ // set up before the window is shown and needs a proper window)
+
+ if (self) {
+ m_cocoaPlatformWindow = qpw;
+ }
+ return self;
+}
+
- (BOOL)canBecomeKeyWindow
{
- // The default implementation returns NO for title-bar less windows,
- // override and return yes here to make sure popup windows such as
- // the combobox popup can become the key window.
+ // Prevent child NSWindows from becoming the key window in
+ // order keep the active apperance of the top-level window.
+ if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->m_isNSWindowChild)
+ return NO;
+
+ // Only tool or dialog windows should become key:
+ if (m_cocoaPlatformWindow && m_cocoaPlatformWindow->windowShouldBehaveAsPanel()) {
+ Qt::WindowType type = m_cocoaPlatformWindow->window()->type();
+ if (type == Qt::Tool || type == Qt::Dialog)
+ return YES;
+ return NO;
+ }
+
+ // All other windows can become the key window. This includes
+ // popup windows such as the combobox popup, which is a title-bar
+ // less window that by default can't become key.
return YES;
}
@@ -118,7 +142,11 @@ static bool isMouseEvent(NSEvent *ev)
// Windows with a transient parent (such as combobox popup windows)
// cannot become the main window:
- if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->window()->transientParent())
+ if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->m_isNSWindowChild
+ || m_cocoaPlatformWindow->window()->transientParent())
+ canBecomeMain = NO;
+
+ if (m_cocoaPlatformWindow && m_cocoaPlatformWindow->windowShouldBehaveAsPanel())
canBecomeMain = NO;
return canBecomeMain;
@@ -126,47 +154,24 @@ static bool isMouseEvent(NSEvent *ev)
- (void) sendEvent: (NSEvent*) theEvent
{
- [super sendEvent: theEvent];
+ if (m_cocoaPlatformWindow && m_cocoaPlatformWindow->m_forwardWindow) {
+ if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) {
+ QNSView *forwardView = m_cocoaPlatformWindow->m_qtView;
+ if (theEvent.type == NSLeftMouseUp) {
+ [forwardView mouseUp:theEvent];
+ m_cocoaPlatformWindow->m_forwardWindow = 0;
+ } else {
+ [forwardView mouseDragged:theEvent];
+ }
- if (!m_cocoaPlatformWindow)
- return;
+ return;
+ }
- if (m_cocoaPlatformWindow->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
- NSPoint loc = [theEvent locationInWindow];
- NSRect windowFrame = [self legacyConvertRectFromScreen:[self frame]];
- NSRect contentFrame = [[self contentView] frame];
- if (NSMouseInRect(loc, windowFrame, NO) &&
- !NSMouseInRect(loc, contentFrame, NO))
- {
- QNSView *contentView = (QNSView *) m_cocoaPlatformWindow->contentView();
- [contentView handleFrameStrutMouseEvent: theEvent];
+ if (theEvent.type == NSLeftMouseDown) {
+ m_cocoaPlatformWindow->m_forwardWindow = 0;
}
}
-}
-
-- (void)clearPlatformWindow
-{
- m_cocoaPlatformWindow = 0;
-}
-
-@end
-
-@implementation QNSPanel
-
-- (BOOL)canBecomeKeyWindow
-{
- if (!m_cocoaPlatformWindow)
- return NO;
- // Only tool or dialog windows should become key:
- if (m_cocoaPlatformWindow
- && (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
- return YES;
- return NO;
-}
-
-- (void) sendEvent: (NSEvent*) theEvent
-{
[super sendEvent: theEvent];
if (!m_cocoaPlatformWindow)
@@ -199,8 +204,11 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_contentView(nil)
, m_qtView(nil)
, m_nsWindow(0)
+ , m_forwardWindow(0)
, m_contentViewIsEmbedded(false)
, m_contentViewIsToBeEmbedded(false)
+ , m_parentCocoaWindow(0)
+ , m_isNSWindowChild(false)
, m_nsWindowDelegate(0)
, m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal)
@@ -215,11 +223,14 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_isExposed(false)
, m_registerTouchCount(0)
, m_resizableTransientParent(false)
+ , m_hiddenByClipping(false)
+ , m_hiddenByAncestor(false)
, m_alertRequest(NoAlertRequest)
, monitor(nil)
, m_drawContentBorderGradient(false)
, m_topContentBorderThickness(0)
, m_bottomContentBorderThickness(0)
+ , m_normalGeometry(QRect(0,0,-1,-1))
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@@ -259,8 +270,21 @@ QCocoaWindow::~QCocoaWindow()
QCocoaAutoReleasePool pool;
clearNSWindow(m_nsWindow);
- if (parent())
+ if (m_isNSWindowChild) {
+ if (m_parentCocoaWindow)
+ m_parentCocoaWindow->removeChildWindow(this);
+ } else if (parent()) {
[m_contentView removeFromSuperview];
+ } else if (m_qtView) {
+ [[NSNotificationCenter defaultCenter] removeObserver:m_qtView
+ name:nil object:m_nsWindow];
+ }
+
+ foreach (QCocoaWindow *child, m_childWindows) {
+ [m_nsWindow removeChildWindow:child->m_nsWindow];
+ child->m_parentCocoaWindow = 0;
+ }
+
[m_contentView release];
[m_nsWindow release];
[m_nsWindowDelegate release];
@@ -272,8 +296,16 @@ QSurfaceFormat QCocoaWindow::format() const
return window()->requestedFormat();
}
-void QCocoaWindow::setGeometry(const QRect &rect)
+void QCocoaWindow::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 (qt_window_private(const_cast<QWindow *>(window()))->positionPolicy
+ == QWindowPrivate::WindowFrameInclusive) {
+ const QMargins margins = frameMargins();
+ rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top()));
+ }
if (geometry() == rect)
return;
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
@@ -291,7 +323,16 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
return;
}
- if (m_nsWindow) {
+ if (m_isNSWindowChild) {
+ QPlatformWindow::setGeometry(rect);
+ NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSRect parentWindowFrame = [parentNSWindow contentRectForFrameRect:parentNSWindow.frame];
+ clipWindow(parentWindowFrame);
+
+ // call this here: updateGeometry in qnsview.mm is a no-op for this case
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
+ QWindowSystemInterface::handleExposeEvent(window(), rect);
+ } else if (m_nsWindow) {
NSRect bounds = qt_mac_flipRect(rect, window());
[m_nsWindow setFrame:[m_nsWindow frameRectForContentRect:bounds] display:YES animate:NO];
} else {
@@ -301,8 +342,99 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
// will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
}
+void QCocoaWindow::clipChildWindows()
+{
+ foreach (QCocoaWindow *childWindow, m_childWindows) {
+ childWindow->clipWindow(m_nsWindow.frame);
+ }
+}
+
+void QCocoaWindow::clipWindow(const NSRect &clipRect)
+{
+ if (!m_isNSWindowChild)
+ return;
+
+ NSRect clippedWindowRect = NSZeroRect;
+ if (!NSIsEmptyRect(clipRect)) {
+ NSRect windowFrame = qt_mac_flipRect(QRect(window()->mapToGlobal(QPoint(0, 0)), geometry().size()), window());
+ clippedWindowRect = NSIntersectionRect(windowFrame, clipRect);
+ // Clipping top/left offsets the content. Move it back.
+ NSPoint contentViewOffset = NSMakePoint(qMax(CGFloat(0), NSMinX(clippedWindowRect) - NSMinX(windowFrame)),
+ qMax(CGFloat(0), NSMaxY(windowFrame) - NSMaxY(clippedWindowRect)));
+ [m_contentView setBoundsOrigin:contentViewOffset];
+ }
+
+ if (NSIsEmptyRect(clippedWindowRect)) {
+ if (!m_hiddenByClipping) {
+ // We dont call hide() here as we will recurse further down
+ [m_nsWindow orderOut:nil];
+ m_hiddenByClipping = true;
+ }
+ } else {
+ [m_nsWindow setFrame:clippedWindowRect display:YES animate:NO];
+ if (m_hiddenByClipping) {
+ m_hiddenByClipping = false;
+ if (!m_hiddenByAncestor) {
+ [m_nsWindow orderFront:nil];
+ m_parentCocoaWindow->reinsertChildWindow(this);
+ }
+ }
+ }
+
+ // recurse
+ foreach (QCocoaWindow *childWindow, m_childWindows) {
+ childWindow->clipWindow(clippedWindowRect);
+ }
+}
+
+void QCocoaWindow::hide(bool becauseOfAncestor)
+{
+ bool visible = [m_nsWindow isVisible];
+
+ if (!m_hiddenByAncestor && !visible) // Already explicitly hidden
+ return;
+ if (m_hiddenByAncestor && becauseOfAncestor) // Trying to hide some child again
+ return;
+
+ m_hiddenByAncestor = becauseOfAncestor;
+
+ if (!visible) // Could have been clipped before
+ return;
+
+ foreach (QCocoaWindow *childWindow, m_childWindows)
+ childWindow->hide(true);
+
+ [m_nsWindow orderOut:nil];
+}
+
+void QCocoaWindow::show(bool becauseOfAncestor)
+{
+ if ([m_nsWindow isVisible])
+ return;
+
+ if (m_parentCocoaWindow && ![m_parentCocoaWindow->m_nsWindow isVisible]) {
+ m_hiddenByAncestor = true; // Parent still hidden, don't show now
+ } else if ((becauseOfAncestor == m_hiddenByAncestor) // Was NEITHER explicitly hidden
+ && !m_hiddenByClipping) { // ... NOR clipped
+ if (m_isNSWindowChild) {
+ m_hiddenByAncestor = false;
+ setCocoaGeometry(window()->geometry());
+ }
+ if (!m_hiddenByClipping) { // setCocoaGeometry() can change the clipping status
+ [m_nsWindow orderFront:nil];
+ if (m_isNSWindowChild)
+ m_parentCocoaWindow->reinsertChildWindow(this);
+ foreach (QCocoaWindow *childWindow, m_childWindows)
+ childWindow->show(true);
+ }
+ }
+}
+
void QCocoaWindow::setVisible(bool visible)
{
+ if (m_isNSWindowChild && m_hiddenByClipping)
+ return;
+
QCocoaAutoReleasePool pool;
QCocoaWindow *parentCocoaWindow = 0;
if (window()->transientParent())
@@ -367,8 +499,10 @@ void QCocoaWindow::setVisible(bool visible)
m_hasModalSession = true;
} else if ([m_nsWindow canBecomeKeyWindow]) {
[m_nsWindow makeKeyAndOrderFront:nil];
+ foreach (QCocoaWindow *childWindow, m_childWindows)
+ childWindow->show(true);
} else {
- [m_nsWindow orderFront: nil];
+ show();
}
// We want the events to properly reach the popup, dialog, and tool
@@ -392,28 +526,27 @@ void QCocoaWindow::setVisible(bool visible)
// qDebug() << "close" << this;
if (m_glContext)
m_glContext->windowWasHidden();
+ QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
+ Q_ASSERT(cocoaEventDispatcher != 0);
+ QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
if (m_nsWindow) {
if (m_hasModalSession) {
- QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
- Q_ASSERT(cocoaEventDispatcher != 0);
- QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
cocoaEventDispatcherPrivate->endModalSession(window());
m_hasModalSession = false;
-
- [m_nsWindow orderOut:m_nsWindow];
- if (m_nsWindow == [NSApp keyWindow] && !cocoaEventDispatcherPrivate->currentModalSession()) {
- // Probably because we call runModalSession: outside [NSApp run] in QCocoaEventDispatcher
- // (e.g., when show()-ing a modal QDialog instead of exec()-ing it), it can happen that
- // the current NSWindow is still key after being ordered out. Then, after checking we
- // don't have any other modal session left, it's safe to make the main window key again.
- NSWindow *mainWindow = [NSApp mainWindow];
- if (mainWindow && [mainWindow canBecomeKeyWindow])
- [mainWindow makeKeyWindow];
- }
} else {
if ([m_nsWindow isSheet])
[NSApp endSheet:m_nsWindow];
- [m_nsWindow orderOut:m_nsWindow];
+ }
+
+ hide();
+ if (m_nsWindow == [NSApp keyWindow] && !cocoaEventDispatcherPrivate->currentModalSession()) {
+ // Probably because we call runModalSession: outside [NSApp run] in QCocoaEventDispatcher
+ // (e.g., when show()-ing a modal QDialog instead of exec()-ing it), it can happen that
+ // the current NSWindow is still key after being ordered out. Then, after checking we
+ // don't have any other modal session left, it's safe to make the main window key again.
+ NSWindow *mainWindow = [NSApp mainWindow];
+ if (mainWindow && [mainWindow canBecomeKeyWindow])
+ [mainWindow makeKeyWindow];
}
} else {
[m_contentView setHidden:YES];
@@ -520,7 +653,7 @@ void QCocoaWindow::setWindowShadow(Qt::WindowFlags flags)
void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (m_nsWindow) {
+ if (m_nsWindow && !m_isNSWindowChild) {
NSUInteger styleMask = windowStyleMask(flags);
NSInteger level = this->windowLevel(flags);
[m_nsWindow setStyleMask:styleMask];
@@ -532,15 +665,21 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- Qt::WindowType type = window()->type();
- if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) {
- NSWindowCollectionBehavior behavior = [m_nsWindow collectionBehavior];
+ NSWindowCollectionBehavior behavior = [m_nsWindow collectionBehavior];
+ if (windowShouldBehaveAsPanel()) {
+ behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
+ behavior |= NSWindowCollectionBehaviorFullScreenAuxiliary;
+ } else {
if (flags & Qt::WindowFullscreenButtonHint)
behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
else
behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
- [m_nsWindow setCollectionBehavior:behavior];
}
+ [m_nsWindow setCollectionBehavior:behavior];
+
+ [m_nsWindow setAnimationBehavior:(flags & Qt::Popup) == Qt::Popup
+ ? NSWindowAnimationBehaviorUtilityWindow
+ : NSWindowAnimationBehaviorDefault];
}
#endif
}
@@ -618,16 +757,55 @@ void QCocoaWindow::raise()
// ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
if (!m_nsWindow)
return;
- if ([m_nsWindow isVisible])
- [m_nsWindow orderFront: m_nsWindow];
+ if (m_isNSWindowChild) {
+ QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
+ siblings.removeOne(this);
+ siblings.append(this);
+ if (m_hiddenByClipping)
+ return;
+ }
+ if ([m_nsWindow isVisible]) {
+ if (m_isNSWindowChild) {
+ // -[NSWindow orderFront:] doesn't work with attached windows.
+ // The only solution is to remove and add the child window.
+ // This will place it on top of all the other NSWindows.
+ NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ [parentNSWindow removeChildWindow:m_nsWindow];
+ [parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
+ } else {
+ [m_nsWindow orderFront: m_nsWindow];
+ }
+ }
}
void QCocoaWindow::lower()
{
if (!m_nsWindow)
return;
- if ([m_nsWindow isVisible])
- [m_nsWindow orderBack: m_nsWindow];
+ if (m_isNSWindowChild) {
+ QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
+ siblings.removeOne(this);
+ siblings.prepend(this);
+ if (m_hiddenByClipping)
+ return;
+ }
+ if ([m_nsWindow isVisible]) {
+ if (m_isNSWindowChild) {
+ // -[NSWindow orderBack:] doesn't work with attached windows.
+ // The only solution is to remove and add all the child windows except this one.
+ // This will keep the current window at the bottom while adding the others on top of it,
+ // hopefully in the same order (this is not documented anywhere in the Cocoa documentation).
+ NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSArray *children = [parentNSWindow.childWindows copy];
+ for (NSWindow *child in children)
+ if (m_nsWindow != child) {
+ [parentNSWindow removeChildWindow:child];
+ [parentNSWindow addChildWindow:child ordered:NSWindowAbove];
+ }
+ } else {
+ [m_nsWindow orderBack: m_nsWindow];
+ }
+ }
}
bool QCocoaWindow::isExposed() const
@@ -773,6 +951,9 @@ void QCocoaWindow::windowWillMove()
void QCocoaWindow::windowDidMove()
{
+ if (m_isNSWindowChild)
+ return;
+
[m_qtView updateGeometry];
}
@@ -781,6 +962,10 @@ void QCocoaWindow::windowDidResize()
if (!m_nsWindow)
return;
+ if (m_isNSWindowChild)
+ return;
+
+ clipChildWindows();
[m_qtView updateGeometry];
}
@@ -808,6 +993,14 @@ bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const
return ((type & Qt::Popup) == Qt::Popup);
}
+bool QCocoaWindow::windowShouldBehaveAsPanel() const
+{
+ // Before merging QNSPanel and QNSWindow, we used NSPanel for popup-type
+ // windows (Popup, Tool, ToolTip, SplashScreen) and dialogs
+ Qt::WindowType type = window()->type();
+ return (type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog;
+}
+
void QCocoaWindow::setCurrentContext(QCocoaGLContext *context)
{
m_glContext = context;
@@ -820,8 +1013,18 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
{
+ bool wasNSWindowChild = m_isNSWindowChild;
+ bool needsNSWindow = m_isNSWindowChild || !parentWindow;
+
+ QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow;
+ m_parentCocoaWindow = const_cast<QCocoaWindow *>(static_cast<const QCocoaWindow *>(parentWindow));
+
+ // No child QNSWindow should notify its QNSView
+ if (m_nsWindow && m_qtView && m_parentCocoaWindow && !oldParentCocoaWindow)
+ [[NSNotificationCenter defaultCenter] removeObserver:m_qtView
+ name:nil object:m_nsWindow];
// Remove current window (if any)
- if (m_nsWindow) {
+ if (m_nsWindow && !needsNSWindow) {
clearNSWindow(m_nsWindow);
[m_nsWindow close];
[m_nsWindow release];
@@ -830,22 +1033,64 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
m_nsWindowDelegate = 0;
}
+ if (needsNSWindow) {
+ bool noPreviousWindow = m_nsWindow == 0;
+ if (noPreviousWindow)
+ m_nsWindow = createNSWindow();
+
+ // Only non-child QNSWindows should notify their QNSViews
+ // (but don't register more than once).
+ if (m_qtView && (noPreviousWindow || (wasNSWindowChild && !m_isNSWindowChild)))
+ [[NSNotificationCenter defaultCenter] addObserver:m_qtView
+ selector:@selector(windowNotification:)
+ name:nil // Get all notifications
+ object:m_nsWindow];
+
+ if (oldParentCocoaWindow) {
+ if (!m_isNSWindowChild || oldParentCocoaWindow != m_parentCocoaWindow)
+ oldParentCocoaWindow->removeChildWindow(this);
+ m_forwardWindow = oldParentCocoaWindow;
+ }
+
+ setNSWindow(m_nsWindow);
+ }
+
+
if (m_contentViewIsToBeEmbedded) {
// An embedded window doesn't have its own NSWindow.
} else if (!parentWindow) {
- // Create a new NSWindow if this is a top-level window.
- m_nsWindow = createNSWindow();
- setNSWindow(m_nsWindow);
-
// QPlatformWindow subclasses must sync up with QWindow on creation:
propagateSizeHints();
setWindowFlags(window()->flags());
setWindowTitle(window()->title());
setWindowState(window()->windowState());
+ } else if (m_isNSWindowChild) {
+ m_nsWindow.styleMask = NSBorderlessWindowMask;
+ m_nsWindow.hasShadow = NO;
+ m_nsWindow.level = NSNormalWindowLevel;
+ NSWindowCollectionBehavior collectionBehavior =
+ NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorIgnoresCycle;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
+ collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary;
+ m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
+ }
+#endif
+ m_nsWindow.collectionBehavior = collectionBehavior;
+ setCocoaGeometry(window()->geometry());
+
+ QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
+ if (siblings.contains(this)) {
+ if (!m_hiddenByClipping)
+ m_parentCocoaWindow->reinsertChildWindow(this);
+ } else {
+ if (!m_hiddenByClipping)
+ [m_parentCocoaWindow->m_nsWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
+ siblings.append(this);
+ }
} else {
// Child windows have no NSWindow, link the NSViews instead.
- const QCocoaWindow *parentCococaWindow = static_cast<const QCocoaWindow *>(parentWindow);
- [parentCococaWindow->m_contentView addSubview : m_contentView];
+ [m_parentCocoaWindow->m_contentView addSubview : m_contentView];
QRect rect = window()->geometry();
NSRect frame = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
[m_contentView setFrame:frame];
@@ -857,6 +1102,19 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
setOpacity(opacity);
}
+void QCocoaWindow::reinsertChildWindow(QCocoaWindow *child)
+{
+ int childIndex = m_childWindows.indexOf(child);
+ Q_ASSERT(childIndex != -1);
+
+ for (int i = childIndex; i < m_childWindows.size(); i++) {
+ NSWindow *nsChild = m_childWindows[i]->m_nsWindow;
+ if (i != childIndex)
+ [m_nsWindow removeChildWindow:nsChild];
+ [m_nsWindow addChildWindow:nsChild ordered:NSWindowAbove];
+ }
+}
+
void QCocoaWindow::requestActivateWindow()
{
NSWindow *window = [m_contentView window];
@@ -864,63 +1122,33 @@ void QCocoaWindow::requestActivateWindow()
[ window makeKeyWindow ];
}
-NSWindow * QCocoaWindow::createNSWindow()
+QNSWindow * QCocoaWindow::createNSWindow()
{
QCocoaAutoReleasePool pool;
QRect rect = initialGeometry(window(), window()->geometry(), defaultWindowWidth, defaultWindowHeight);
NSRect frame = qt_mac_flipRect(rect, window());
- Qt::WindowType type = window()->type();
Qt::WindowFlags flags = window()->flags();
- NSUInteger styleMask = windowStyleMask(flags);
- NSWindow *createdWindow = 0;
-
- // Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen)
- // and dialogs
- if ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog) {
- QNSPanel *window;
- window = [[QNSPanel alloc] initWithContentRect:frame
- styleMask: styleMask
- backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
- // before the window is shown and needs a proper window.).
- if ((type & Qt::Popup) == Qt::Popup)
- [window setHasShadow:YES];
- [window setHidesOnDeactivate: NO];
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- // Make popup winows show on the same desktop as the parent full-screen window.
- [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
-
- if ((type & Qt::Popup) == Qt::Popup)
- [window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
- }
-#endif
- window->m_cocoaPlatformWindow = this;
- createdWindow = window;
+ NSUInteger styleMask;
+ if (m_isNSWindowChild) {
+ styleMask = NSBorderlessWindowMask;
} else {
- QNSWindow *window;
- window = [[QNSWindow alloc] initWithContentRect:frame
- styleMask: styleMask
- backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
- // before the window is shown and needs a proper window.).
- window->m_cocoaPlatformWindow = this;
-
- createdWindow = window;
+ styleMask = windowStyleMask(flags);
}
+ QNSWindow *createdWindow = [[QNSWindow alloc] initWithContentRect:frame styleMask:styleMask qPlatformWindow:this];
+
+ Qt::WindowFlags type = window()->type();
+ createdWindow.hidesOnDeactivate = type == Qt::Tool || type == Qt::ToolTip;
+
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if ([createdWindow respondsToSelector:@selector(setRestorable:)])
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
[createdWindow setRestorable: NO];
+ }
#endif
- NSInteger level = windowLevel(flags);
- [createdWindow setLevel:level];
-
if (window()->format().alphaBufferSize() > 0) {
[createdWindow setBackgroundColor:[NSColor clearColor]];
[createdWindow setOpaque:NO];
@@ -933,10 +1161,12 @@ NSWindow * QCocoaWindow::createNSWindow()
return createdWindow;
}
-void QCocoaWindow::setNSWindow(NSWindow *window)
+void QCocoaWindow::setNSWindow(QNSWindow *window)
{
- m_nsWindowDelegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
- [window setDelegate:m_nsWindowDelegate];
+ if (!m_nsWindowDelegate) {
+ m_nsWindowDelegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
+ [window setDelegate:m_nsWindowDelegate];
+ }
// Prevent Cocoa from releasing the window on close. Qt
// handles the close event asynchronously and we want to
@@ -944,31 +1174,33 @@ void QCocoaWindow::setNSWindow(NSWindow *window)
// QCocoaWindow is deleted by Qt.
[window setReleasedWhenClosed : NO];
-
- if (m_qtView)
- [[NSNotificationCenter defaultCenter] addObserver:m_qtView
- selector:@selector(windowNotification:)
- name:nil // Get all notifications
- object:m_nsWindow];
-
- [m_contentView setPostsFrameChangedNotifications: NO];
- [window setContentView:m_contentView];
- [m_contentView setPostsFrameChangedNotifications: YES];
+ if (window.contentView != m_contentView) {
+ [m_contentView setPostsFrameChangedNotifications: NO];
+ [window setContentView:m_contentView];
+ [m_contentView setPostsFrameChangedNotifications: YES];
+ }
}
-void QCocoaWindow::clearNSWindow(NSWindow *window)
+void QCocoaWindow::clearNSWindow(QNSWindow *window)
{
[window setContentView:nil];
[window setDelegate:nil];
[window clearPlatformWindow];
- [[NSNotificationCenter defaultCenter] removeObserver:m_contentView
- name:nil object:window];
+ if (m_isNSWindowChild) {
+ m_parentCocoaWindow->removeChildWindow(this);
+ }
+}
+
+void QCocoaWindow::removeChildWindow(QCocoaWindow *child)
+{
+ m_childWindows.removeOne(child);
+ [m_nsWindow removeChildWindow:child->m_nsWindow];
}
// Returns the current global screen geometry for the nswindow associated with this window.
QRect QCocoaWindow::windowGeometry() const
{
- if (!m_nsWindow)
+ if (!m_nsWindow || m_isNSWindowChild)
return geometry();
NSRect rect = [m_nsWindow frame];
@@ -1015,13 +1247,35 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
}
if ((m_synchedWindowState & Qt::WindowFullScreen) != (newState & Qt::WindowFullScreen)) {
+ bool fakeFullScreen = true;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- [m_nsWindow toggleFullScreen : m_nsWindow];
- } else {
- // TODO: "normal" fullscreen
+ if (window()->flags() & Qt::WindowFullscreenButtonHint) {
+ fakeFullScreen = false;
+ [m_nsWindow toggleFullScreen : m_nsWindow];
+ }
}
#endif
+ if (fakeFullScreen) {
+ if (newState & Qt::WindowFullScreen) {
+ QScreen *screen = window()->screen();
+ if (screen) {
+ if (m_normalGeometry.width() < 0) {
+ m_oldWindowFlags = m_windowFlags;
+ window()->setFlags(window()->flags() | Qt::FramelessWindowHint);
+ m_normalGeometry = windowGeometry();
+ setGeometry(screen->geometry());
+ m_presentationOptions = [NSApp presentationOptions];
+ [NSApp setPresentationOptions : m_presentationOptions | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock];
+ }
+ }
+ } else {
+ window()->setFlags(m_oldWindowFlags);
+ setGeometry(m_normalGeometry);
+ m_normalGeometry.setRect(0, 0, -1, -1);
+ [NSApp setPresentationOptions : m_presentationOptions];
+ }
+ }
}
// New state is now the current synched state
@@ -1054,16 +1308,21 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor)
// for a popup window.) Qt expects the set cursor to "stick":
// it should be accociated with the window until a different
// cursor is set.
-
- // Cocoa has different abstractions. We can set the cursor *now*:
- if (m_windowUnderMouse)
- [cursor set];
- // or we can set the cursor on mouse enter/leave using tracking
- // areas. This is done in QNSView, save the cursor:
if (m_windowCursor != cursor) {
[m_windowCursor release];
m_windowCursor = [cursor retain];
}
+
+ // Use the built in cursor rect API if the QCocoaWindow has a NSWindow.
+ // Othervise, set the cursor if this window is under the mouse. In
+ // this case QNSView::cursorUpdate will set the cursor as the pointer
+ // moves.
+ if (m_nsWindow && m_qtView) {
+ [m_nsWindow invalidateCursorRectsForView : m_qtView];
+ } else {
+ if (m_windowUnderMouse)
+ [cursor set];
+ }
}
void QCocoaWindow::registerTouch(bool enable)
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index ed9aad1654..58c732de98 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -229,7 +229,21 @@ static QTouchDevice *touchDevice = 0;
- (void)updateGeometry
{
QRect geometry;
- if (m_platformWindow->m_nsWindow) {
+
+ if (m_platformWindow->m_isNSWindowChild) {
+ return;
+#if 0
+ //geometry = qt_mac_toQRect([self frame]);
+ qDebug() << "nsview updateGeometry" << m_platformWindow->window();
+ QRect screenRect = qt_mac_toQRect([m_platformWindow->m_nsWindow convertRectToScreen:[self frame]]);
+ qDebug() << "screenRect" << screenRect;
+
+ screenRect.moveTop(qt_mac_flipYCoordinate(screenRect.y() + screenRect.height()));
+ geometry = QRect(m_platformWindow->window()->parent()->mapFromGlobal(screenRect.topLeft()), screenRect.size());
+ qDebug() << "geometry" << geometry;
+#endif
+ //geometry = QRect(screenRect.origin.x, qt_mac_flipYCoordinate(screenRect.origin.y + screenRect.size.height), screenRect.size.width, screenRect.size.height);
+ } else if (m_platformWindow->m_nsWindow) {
// top level window, get window rect and flip y.
NSRect rect = [self frame];
NSRect windowRect = [[self window] frame];
@@ -310,10 +324,9 @@ static QTouchDevice *touchDevice = 0;
m_platformWindow->exposeWindow();
} else if (notificationName == NSWindowDidChangeScreenNotification) {
if (m_window) {
- QCocoaIntegration *ci = static_cast<QCocoaIntegration *>(QGuiApplicationPrivate::platformIntegration());
NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
if (screenIndex != NSNotFound) {
- QCocoaScreen *cocoaScreen = ci->screenAtIndex(screenIndex);
+ QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen());
}
}
@@ -551,14 +564,20 @@ static QTouchDevice *touchDevice = 0;
QPointF qtWindowPoint;
QPointF qtScreenPoint;
- [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
+ QNSView *targetView = self;
+ if (m_platformWindow && m_platformWindow->m_forwardWindow
+ && (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)) {
+ targetView = m_platformWindow->m_forwardWindow->m_qtView;
+ }
+
+ [targetView convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
ulong timestamp = [theEvent timestamp] * 1000;
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
nativeDrag->setLastMouseEvent(theEvent, self);
Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- QWindowSystemInterface::handleMouseEvent(m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers);
+ QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers);
}
- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
@@ -689,8 +708,18 @@ static QTouchDevice *touchDevice = 0;
-(void)cursorUpdate:(NSEvent *)theEvent
{
Q_UNUSED(theEvent)
- if (m_platformWindow->m_windowCursor)
+ // Set the cursor manually if there is no NSWindow.
+ if (!m_platformWindow->m_nsWindow && m_platformWindow->m_windowCursor)
[m_platformWindow->m_windowCursor set];
+ else
+ [super cursorUpdate:theEvent];
+}
+
+-(void)resetCursorRects
+{
+ // Use the cursor rect API if there is a NSWindow
+ if (m_platformWindow->m_nsWindow && m_platformWindow->m_windowCursor)
+ [self addCursorRect:[self visibleRect] cursor:m_platformWindow->m_windowCursor];
}
- (void)mouseMoved:(NSEvent *)theEvent
@@ -1619,7 +1648,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (NSDragOperation) draggingSourceOperationMaskForLocal:(BOOL)isLocal
{
Q_UNUSED(isLocal);
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
return qt_mac_mapDropActions(nativeDrag->currentDrag()->supportedActions());
}
@@ -1650,7 +1679,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
if ([sender draggingSource] != nil) {
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
response = QWindowSystemInterface::handleDrag(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
@@ -1678,14 +1707,14 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
if ([sender draggingSource] != nil) {
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
response = QWindowSystemInterface::handleDrop(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
response = QWindowSystemInterface::handleDrop(m_window, &mimeData, qt_windowPoint, qtAllowed);
}
if (response.isAccepted()) {
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
nativeDrag->setAcceptedAction(response.acceptedAction());
}
return response.isAccepted();
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index e8f26aa8c4..a438950a55 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -45,7 +45,7 @@
#include "qcocoahelpers.h"
#include "qcocoaaccessibility.h"
#include "qcocoaaccessibilityelement.h"
-#include <qpa/qplatformintegration.h>
+#include "qcocoaintegration.h"
#include <QtGui/qaccessible.h>
#include <QtCore/QDebug>
@@ -63,7 +63,7 @@
- (id)accessibilityAttributeValue:(NSString *)attribute {
// activate accessibility updates
- QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true);
+ QCocoaIntegration::instance()->accessibility()->setActive(true);
if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
if (m_window->accessibleRoot())
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index f363b1772f..3e92a45a62 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -591,20 +591,43 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
return;
switch (key) {
- case PPK_CollateCopies:
+
+ // The following keys are properties or derived values and so cannot be set
+ case PPK_PageRect:
+ break;
+ case PPK_PaperRect:
+ break;
+ case PPK_PaperSources:
+ break;
+ case PPK_SupportsMultipleCopies:
+ break;
+ case PPK_SupportedResolutions:
break;
+
+ // The following keys are settings that are unsupported by the Mac PrintEngine
case PPK_ColorMode:
break;
- case PPK_Creator:
+ case PPK_CustomBase:
break;
- case PPK_DocumentName:
+ case PPK_Duplex:
+ // TODO Add support using PMSetDuplex / PMGetDuplex
+ break;
+ case PPK_FontEmbedding:
break;
case PPK_PageOrder:
+ // TODO Check if can be supported via Cups Options
break;
case PPK_PaperSource:
+ // TODO Check if can be supported via Cups Options
+ break;
+ case PPK_PrinterProgram:
break;
case PPK_SelectionOption:
break;
+ case PPK_WindowsPageSize:
+ break;
+
+ // The following keys are properties and settings that are supported by the Mac PrintEngine
case PPK_Resolution: {
PMPrinter printer;
UInt32 count;
@@ -633,7 +656,15 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
break;
}
-
+ case PPK_CollateCopies:
+ PMSetCollate(d->settings(), value.toBool());
+ break;
+ case PPK_Creator:
+ d->m_creator = value.toString();
+ break;
+ case PPK_DocumentName:
+ PMPrintSettingsSetJobName(d->settings(), QCFString(value.toString()));
+ break;
case PPK_FullPage:
d->fullPage = value.toBool();
break;
@@ -642,18 +673,15 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
PMSetCopies(d->settings(), value.toInt(), false);
break;
case PPK_Orientation: {
- if (d->state == QPrinter::Active) {
- qWarning("QMacPrintEngine::setOrientation: Orientation cannot be changed during a print job, ignoring change");
- } else {
- QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt());
- if (d->hasCustomPaperSize && (d->orient != newOrientation))
- d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
- d->orient = newOrientation;
- PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape;
- PMSetOrientation(d->format(), o, false);
- PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
- }
- break; }
+ QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt());
+ if (d->hasCustomPaperSize && (d->orient != newOrientation))
+ d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
+ d->orient = newOrientation;
+ PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape;
+ PMSetOrientation(d->format(), o, false);
+ PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
+ break;
+ }
case PPK_OutputFileName:
d->outputFilename = value.toString();
break;
@@ -709,9 +737,7 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->hasCustomPageMargins = true;
break;
}
-
- default:
- break;
+ // No default so that compiler will complain if new keys added and not handled in this engine
}
}
@@ -724,16 +750,63 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
return *d->valueCache.find(key);
switch (key) {
- case PPK_CollateCopies:
- ret = false;
- break;
+
+ // The following keys are settings that are unsupported by the Mac PrintEngine
+ // Return sensible default values to ensure consistent behavior across platforms
case PPK_ColorMode:
ret = QPrinter::Color;
break;
+ case PPK_CustomBase:
+ // Special case, leave null
+ break;
+ case PPK_Duplex:
+ // TODO Add support using PMSetDuplex / PMGetDuplex
+ ret = QPrinter::DuplexNone;
+ break;
+ case PPK_FontEmbedding:
+ ret = false;
+ break;
+ case PPK_PageOrder:
+ // TODO Check if can be supported via Cups Options
+ ret = QPrinter::FirstPageFirst;
+ break;
+ case PPK_PaperSource:
+ // TODO Check if can be supported via Cups Options
+ ret = QPrinter::Auto;
+ break;
+ case PPK_PaperSources: {
+ // TODO Check if can be supported via Cups Options
+ QList<QVariant> out;
+ out << int(QPrinter::Auto);
+ ret = out;
+ break;
+ }
+ case PPK_PrinterProgram:
+ ret = QString();
+ break;
+ case PPK_SelectionOption:
+ ret = QString();
+ break;
+ case PPK_WindowsPageSize:
+ // Special case, leave null
+ break;
+
+ // The following keys are properties and settings that are supported by the Mac PrintEngine
+ case PPK_CollateCopies: {
+ Boolean status;
+ PMGetCollate(d->settings(), &status);
+ ret = bool(status);
+ break;
+ }
case PPK_Creator:
+ ret = d->m_creator;
break;
- case PPK_DocumentName:
+ case PPK_DocumentName: {
+ CFStringRef name;
+ PMPrintSettingsGetJobName(d->settings(), &name);
+ ret = QCFString::toQString(name);
break;
+ }
case PPK_FullPage:
ret = d->fullPage;
break;
@@ -757,10 +830,6 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_OutputFileName:
ret = d->outputFilename;
break;
- case PPK_PageOrder:
- break;
- case PPK_PaperSource:
- break;
case PPK_PageRect: {
// PageRect is returned in device pixels
QRect r;
@@ -855,8 +924,7 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
ret = margins;
break;
}
- default:
- break;
+ // No default so that compiler will complain if new keys added and not handled in this engine
}
return ret;
}
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
index 644a07184f..e3a8520811 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h
+++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
@@ -125,6 +125,7 @@ public:
NSPrintInfo *printInfo;
PMResolution resolution;
QString outputFilename;
+ QString m_creator;
bool fullPage;
QPaintEngine *paintEngine;
bool hasCustomPaperSize;
diff --git a/src/plugins/platforms/direct2d/direct2d.json b/src/plugins/platforms/direct2d/direct2d.json
new file mode 100644
index 0000000000..aaea92f0ef
--- /dev/null
+++ b/src/plugins/platforms/direct2d/direct2d.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "direct2d" ]
+}
diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro
new file mode 100644
index 0000000000..4f986b57d7
--- /dev/null
+++ b/src/plugins/platforms/direct2d/direct2d.pro
@@ -0,0 +1,41 @@
+TARGET = qdirect2d
+
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QWindowsDirect2DIntegrationPlugin
+load(qt_plugin)
+
+QT *= core-private
+QT *= gui-private
+QT *= platformsupport-private
+
+LIBS *= -ld2d1 -ld3d11 -ldwrite
+
+include(../windows/windows.pri)
+
+SOURCES += \
+ qwindowsdirect2dpaintengine.cpp \
+ qwindowsdirect2dpaintdevice.cpp \
+ qwindowsdirect2dplatformpixmap.cpp \
+ qwindowsdirect2dcontext.cpp \
+ qwindowsdirect2dbitmap.cpp \
+ qwindowsdirect2dbackingstore.cpp \
+ qwindowsdirect2dintegration.cpp \
+ qwindowsdirect2dplatformplugin.cpp \
+ qwindowsdirect2ddevicecontext.cpp \
+ qwindowsdirect2dnativeinterface.cpp \
+ qwindowsdirect2dwindow.cpp
+
+HEADERS += \
+ qwindowsdirect2dpaintengine.h \
+ qwindowsdirect2dpaintdevice.h \
+ qwindowsdirect2dplatformpixmap.h \
+ qwindowsdirect2dcontext.h \
+ qwindowsdirect2dhelpers.h \
+ qwindowsdirect2dbitmap.h \
+ qwindowsdirect2dbackingstore.h \
+ qwindowsdirect2dintegration.h \
+ qwindowsdirect2ddevicecontext.h \
+ qwindowsdirect2dnativeinterface.h \
+ qwindowsdirect2dwindow.h
+
+OTHER_FILES += direct2d.json
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
new file mode 100644
index 0000000000..079ad6f127
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dbackingstore.h"
+#include "qwindowsdirect2dintegration.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+#include "qwindowsdirect2dwindow.h"
+
+#include "qwindowscontext.h"
+
+#include <QtGui/QWindow>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsDirect2DBackingStore
+ \brief Backing store for windows.
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+static inline QWindowsDirect2DPlatformPixmap *platformPixmap(QPixmap *p)
+{
+ return static_cast<QWindowsDirect2DPlatformPixmap *>(p->handle());
+}
+
+QWindowsDirect2DBackingStore::QWindowsDirect2DBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+}
+
+QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore()
+{
+}
+
+QPaintDevice *QWindowsDirect2DBackingStore::paintDevice()
+{
+ return m_pixmap.data();
+}
+
+void QWindowsDirect2DBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ QPlatformWindow *pw = window->handle();
+ if (pw && m_pixmap)
+ static_cast<QWindowsDirect2DWindow *>(pw)->flush(platformPixmap(m_pixmap.data())->bitmap(), region, offset);
+}
+
+void QWindowsDirect2DBackingStore::resize(const QSize &size, const QRegion &region)
+{
+ Q_UNUSED(region);
+
+ QScopedPointer<QPixmap> oldPixmap(m_pixmap.take());
+ m_pixmap.reset(new QPixmap(size.width(), size.height()));
+
+ if (oldPixmap) {
+ foreach (const QRect &rect, region.rects())
+ platformPixmap(m_pixmap.data())->copy(oldPixmap->handle(), rect);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
new file mode 100644
index 0000000000..9776d234e8
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DBACKINGSTORE_H
+#define QWINDOWSDIRECT2DBACKINGSTORE_H
+
+#include "qwindowsdirect2dplatformpixmap.h"
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/qpa/qplatformbackingstore.h>
+#include <QtGui/QPixmap>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBackingStore : public QPlatformBackingStore
+{
+ Q_DISABLE_COPY(QWindowsDirect2DBackingStore)
+
+public:
+ QWindowsDirect2DBackingStore(QWindow *window);
+ ~QWindowsDirect2DBackingStore();
+
+ QPaintDevice *paintDevice() 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;
+
+private:
+ QScopedPointer<QPixmap> m_pixmap;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DBACKINGSTORE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
new file mode 100644
index 0000000000..85c56bc73e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include <QtGui/QImage>
+#include <QtGui/QColor>
+
+#include <wrl.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBitmapPrivate
+{
+public:
+ QWindowsDirect2DBitmapPrivate(ID2D1DeviceContext *dc = 0, ID2D1Bitmap1 *bm = 0)
+ : bitmap(bm)
+ , deviceContext(new QWindowsDirect2DDeviceContext(dc))
+ {
+ deviceContext->get()->SetTarget(bm);
+ }
+
+ D2D1_BITMAP_PROPERTIES1 bitmapProperties() const
+ {
+ FLOAT dpiX, dpiY;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&dpiX, &dpiY);
+
+ return D2D1::BitmapProperties1(
+ D2D1_BITMAP_OPTIONS_TARGET,
+ D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
+ D2D1_ALPHA_MODE_PREMULTIPLIED),
+ dpiX, dpiY);
+
+ }
+
+ bool resize(int width, int height, const void *data = 0, int pitch = 0)
+ {
+ deviceContext->get()->SetTarget(0);
+ bitmap.Reset();
+
+ D2D1_SIZE_U size = {
+ width, height
+ };
+
+ HRESULT hr = deviceContext->get()->CreateBitmap(size, data, pitch,
+ bitmapProperties(),
+ bitmap.ReleaseAndGetAddressOf());
+ if (SUCCEEDED(hr))
+ deviceContext->get()->SetTarget(bitmap.Get());
+ else
+ qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+
+ return SUCCEEDED(hr);
+ }
+
+ QImage toImage(const QRect &rect)
+ {
+ if (!bitmap)
+ return QImage();
+
+ ComPtr<ID2D1Bitmap1> mappingCopy;
+
+ HRESULT hr = S_OK;
+ D2D1_SIZE_U size = bitmap->GetPixelSize();
+
+ D2D1_BITMAP_PROPERTIES1 properties = bitmapProperties();
+ properties.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ;
+
+ hr = deviceContext->get()->CreateBitmap(size, NULL, NULL,
+ properties, &mappingCopy);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ hr = mappingCopy->CopyFromBitmap(NULL, bitmap.Get(), NULL);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy from bitmap: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ D2D1_MAPPED_RECT mappedRect;
+ hr = mappingCopy->Map(D2D1_MAP_OPTIONS_READ, &mappedRect);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not map: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ return QImage(static_cast<const uchar *>(mappedRect.bits),
+ size.width, size.height, mappedRect.pitch,
+ QImage::Format_ARGB32_Premultiplied).copy(rect);
+ }
+
+ QScopedPointer<QWindowsDirect2DDeviceContext> deviceContext;
+ ComPtr<ID2D1Bitmap1> bitmap;
+};
+
+QWindowsDirect2DBitmap::QWindowsDirect2DBitmap()
+ : d_ptr(new QWindowsDirect2DBitmapPrivate)
+{
+}
+
+QWindowsDirect2DBitmap::QWindowsDirect2DBitmap(ID2D1Bitmap1 *bitmap, ID2D1DeviceContext *dc)
+ : d_ptr(new QWindowsDirect2DBitmapPrivate(dc, bitmap))
+{
+}
+
+QWindowsDirect2DBitmap::~QWindowsDirect2DBitmap()
+{
+}
+
+bool QWindowsDirect2DBitmap::resize(int width, int height)
+{
+ Q_D(QWindowsDirect2DBitmap);
+ return d->resize(width, height);
+}
+
+bool QWindowsDirect2DBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DBitmap);
+
+ QImage converted = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
+ return d->resize(converted.width(), converted.height(),
+ converted.constBits(), converted.bytesPerLine());
+}
+
+ID2D1Bitmap1* QWindowsDirect2DBitmap::bitmap() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+ return d->bitmap.Get();
+}
+
+QWindowsDirect2DDeviceContext *QWindowsDirect2DBitmap::deviceContext() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+ return d->deviceContext.data();
+}
+
+void QWindowsDirect2DBitmap::fill(const QColor &color)
+{
+ Q_D(QWindowsDirect2DBitmap);
+
+ d->deviceContext->begin();
+ d->deviceContext->get()->Clear(to_d2d_color_f(color));
+ d->deviceContext->end();
+}
+
+QImage QWindowsDirect2DBitmap::toImage(const QRect &rect)
+{
+ Q_D(QWindowsDirect2DBitmap);
+ return d->toImage(rect);
+}
+
+QSize QWindowsDirect2DBitmap::size() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+
+ D2D1_SIZE_U size = d->bitmap->GetPixelSize();
+ return QSize(size.width, size.height);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
new file mode 100644
index 0000000000..d7015ef342
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DBITMAP_H
+#define QWINDOWSDIRECT2DBITMAP_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/QImage>
+
+struct ID2D1DeviceContext;
+struct ID2D1Bitmap1;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DDeviceContext;
+class QWindowsDirect2DBitmapPrivate;
+class QWindowsDirect2DBitmap
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DBitmap)
+ Q_DISABLE_COPY(QWindowsDirect2DBitmap)
+public:
+ QWindowsDirect2DBitmap();
+ QWindowsDirect2DBitmap(ID2D1Bitmap1 *bitmap, ID2D1DeviceContext *dc);
+ ~QWindowsDirect2DBitmap();
+
+ bool resize(int width, int height);
+ bool fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+
+ ID2D1Bitmap1* bitmap() const;
+ QWindowsDirect2DDeviceContext* deviceContext() const;
+
+ void fill(const QColor &color);
+ QImage toImage(const QRect &rect = QRect());
+
+ QSize size() const;
+
+private:
+ QScopedPointer<QWindowsDirect2DBitmapPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DBITMAP_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
new file mode 100644
index 0000000000..58002fb0dd
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dintegration.h"
+
+#include <d3d11_1.h>
+#include <d2d1_1.h>
+#include <d2d1_1helper.h>
+#include <dxgi1_2.h>
+#include <wrl.h>
+#include <dwrite.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContextPrivate
+{
+public:
+ bool init()
+ {
+ HRESULT hr;
+
+ D3D_FEATURE_LEVEL level;
+
+ D3D_DRIVER_TYPE typeAttempts[] = {
+ D3D_DRIVER_TYPE_HARDWARE,
+ D3D_DRIVER_TYPE_WARP
+ };
+ const int ntypes = int(sizeof(typeAttempts) / sizeof(typeAttempts[0]));
+
+ for (int i = 0; i < ntypes; i++) {
+ hr = D3D11CreateDevice(NULL,
+ typeAttempts[i],
+ NULL,
+ D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+ NULL,
+ 0,
+ D3D11_SDK_VERSION,
+ &d3dDevice,
+ &level,
+ &d3dDeviceContext);
+
+ if (SUCCEEDED(hr))
+ break;
+ }
+
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct3D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ ComPtr<IDXGIDevice> dxgiDevice;
+ ComPtr<IDXGIAdapter> dxgiAdapter;
+
+ hr = d3dDevice.As(&dxgiDevice);
+ if (FAILED(hr)) {
+ qWarning("%s: DXGI Device interface query failed on D3D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter));
+ if (FAILED(hr)) {
+ qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
+ if (FAILED(hr)) {
+ qWarning("%s: Failed to probe DXGI Adapter for parent DXGI Factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ D2D1_FACTORY_OPTIONS options = {};
+
+#ifdef QT_D2D_DEBUG_OUTPUT
+ qDebug("Turning on Direct2D debugging messages");
+ options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
+#endif // QT_D2D_DEBUG_OUTPUT
+
+ hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, options, d2dFactory.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D Factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = d2dFactory->CreateDevice(dxgiDevice.Get(), &d2dDevice);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create D2D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
+ static_cast<IUnknown **>(&directWriteFactory));
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create DirectWrite factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = directWriteFactory->GetGdiInterop(&directWriteGdiInterop);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create DirectWrite GDI Interop: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ return true;
+ }
+
+ ComPtr<ID3D11Device> d3dDevice;
+ ComPtr<ID2D1Factory1> d2dFactory;
+ ComPtr<ID2D1Device> d2dDevice;
+ ComPtr<IDXGIFactory2> dxgiFactory;
+ ComPtr<ID3D11DeviceContext> d3dDeviceContext;
+ ComPtr<IDWriteFactory> directWriteFactory;
+ ComPtr<IDWriteGdiInterop> directWriteGdiInterop;
+};
+
+QWindowsDirect2DContext::QWindowsDirect2DContext()
+ : d_ptr(new QWindowsDirect2DContextPrivate)
+{
+}
+
+QWindowsDirect2DContext::~QWindowsDirect2DContext() {}
+
+bool QWindowsDirect2DContext::init()
+{
+ Q_D(QWindowsDirect2DContext);
+ return d->init();
+}
+
+QWindowsDirect2DContext *QWindowsDirect2DContext::instance()
+{
+ return QWindowsDirect2DIntegration::instance()->direct2DContext();
+}
+
+ID3D11Device *QWindowsDirect2DContext::d3dDevice() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d3dDevice.Get();
+}
+
+ID2D1Device *QWindowsDirect2DContext::d2dDevice() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d2dDevice.Get();
+}
+
+ID2D1Factory1 *QWindowsDirect2DContext::d2dFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d2dFactory.Get();
+}
+
+IDXGIFactory2 *QWindowsDirect2DContext::dxgiFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->dxgiFactory.Get();
+}
+
+ID3D11DeviceContext *QWindowsDirect2DContext::d3dDeviceContext() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d3dDeviceContext.Get();
+}
+
+IDWriteFactory *QWindowsDirect2DContext::dwriteFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->directWriteFactory.Get();
+}
+
+IDWriteGdiInterop *QWindowsDirect2DContext::dwriteGdiInterop() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->directWriteGdiInterop.Get();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
new file mode 100644
index 0000000000..0025463dd5
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DCONTEXT_H
+#define QWINDOWSDIRECT2DCONTEXT_H
+
+#include <QtCore/QScopedPointer>
+
+struct ID3D11Device;
+struct ID2D1Device;
+struct ID2D1Factory1;
+struct IDXGIFactory2;
+struct ID3D11DeviceContext;
+struct IDWriteFactory;
+struct IDWriteGdiInterop;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContextPrivate;
+class QWindowsDirect2DContext
+{
+ Q_DECLARE_PRIVATE( QWindowsDirect2DContext )
+
+public:
+ QWindowsDirect2DContext();
+ virtual ~QWindowsDirect2DContext();
+
+ bool init();
+
+ static QWindowsDirect2DContext *instance();
+
+ ID3D11Device *d3dDevice() const;
+ ID2D1Device *d2dDevice() const;
+ ID2D1Factory1 *d2dFactory() const;
+ IDXGIFactory2 *dxgiFactory() const;
+ ID3D11DeviceContext *d3dDeviceContext() const;
+ IDWriteFactory *dwriteFactory() const;
+ IDWriteGdiInterop *dwriteGdiInterop() const;
+
+private:
+ QScopedPointer<QWindowsDirect2DContextPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DCONTEXT_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
new file mode 100644
index 0000000000..27e94e4be4
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include <wrl.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DDeviceContextPrivate {
+public:
+ QWindowsDirect2DDeviceContextPrivate(ID2D1DeviceContext *dc)
+ : deviceContext(dc)
+ , refCount(0)
+ {
+ if (!dc) {
+ HRESULT hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
+ D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
+ &deviceContext);
+ if (FAILED(hr))
+ qFatal("%s: Couldn't create Direct2D Device Context: %#x", __FUNCTION__, hr);
+ }
+
+ Q_ASSERT(deviceContext);
+ }
+
+ void begin()
+ {
+ Q_ASSERT(deviceContext);
+ Q_ASSERT(refCount >= 0);
+
+ if (refCount == 0)
+ deviceContext->BeginDraw();
+
+ refCount++;
+ }
+
+ bool end()
+ {
+ Q_ASSERT(deviceContext);
+ Q_ASSERT(refCount > 0);
+
+ bool success = true;
+ refCount--;
+
+ if (refCount == 0) {
+ D2D1_TAG tag1, tag2;
+ HRESULT hr = deviceContext->EndDraw(&tag1, &tag2);
+
+ if (FAILED(hr)) {
+ success = false;
+ qWarning("%s: EndDraw failed: %#x, tag1: %lld, tag2: %lld", __FUNCTION__, hr, tag1, tag2);
+ }
+ }
+
+ return success;
+ }
+
+ ComPtr<ID2D1DeviceContext> deviceContext;
+ int refCount;
+};
+
+QWindowsDirect2DDeviceContext::QWindowsDirect2DDeviceContext(ID2D1DeviceContext *dc)
+ : d_ptr(new QWindowsDirect2DDeviceContextPrivate(dc))
+{
+}
+
+QWindowsDirect2DDeviceContext::~QWindowsDirect2DDeviceContext()
+{
+
+}
+
+ID2D1DeviceContext *QWindowsDirect2DDeviceContext::get() const
+{
+ Q_D(const QWindowsDirect2DDeviceContext);
+ Q_ASSERT(d->deviceContext);
+
+ return d->deviceContext.Get();
+}
+
+void QWindowsDirect2DDeviceContext::begin()
+{
+ Q_D(QWindowsDirect2DDeviceContext);
+ d->begin();
+}
+
+bool QWindowsDirect2DDeviceContext::end()
+{
+ Q_D(QWindowsDirect2DDeviceContext);
+ return d->end();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
new file mode 100644
index 0000000000..4986efb967
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DDEVICECONTEXT_H
+#define QWINDOWSDIRECT2DDEVICECONTEXT_H
+
+#include "qwindowsdirect2dhelpers.h"
+
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * Convenience class for handling device contexts. We have to call BeginDraw
+ * before anything can happen, and EndDraw once we're done, for every frame and
+ * pretty much any kind of operation.
+ *
+ * Unfortunately, these calls cannot be interleaved, and there is no way to check
+ * what state a device context is in.
+ *
+ * The end result is that the following throws an error if we don't track it:
+ * QPixmap pmap;
+ * QPainter painter(&pmap);
+ * pmap.clear();
+ *
+ * Here BeginDraw would first be called through the paint device, then when we clear
+ * the pixmap we would have to call it again. There is no way to know what state
+ * the device context is in when performing the clear, and activating the dc is an
+ * error. Bummer.
+ *
+ * Hence we keep a reference count here and only activate/deactivate the device
+ * if the refcount is zero.
+ *
+ * In a nutshell: Do not call BeginDraw/EndDraw yourself on the device pointer, do
+ * so through the begin/end members below.
+ */
+
+class QWindowsDirect2DDeviceContextPrivate;
+class QWindowsDirect2DDeviceContext
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DDeviceContext)
+public:
+ QWindowsDirect2DDeviceContext(ID2D1DeviceContext *dc);
+ ~QWindowsDirect2DDeviceContext();
+
+ ID2D1DeviceContext *get() const;
+
+ void begin();
+ bool end();
+
+private:
+ QScopedPointer<QWindowsDirect2DDeviceContextPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DDEVICECONTEXT_H
diff --git a/src/plugins/platforms/kms/qkmsvthandler.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
index 5e5afd3161..98248515e6 100644
--- a/src/plugins/platforms/kms/qkmsvthandler.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
@@ -39,62 +39,58 @@
**
****************************************************************************/
-#include <qkmsvthandler.h>
-#include <QtCore/private/qcrashhandler_p.h>
-#include <QtGui/private/qguiapplication_p.h>
-#include <sys/ioctl.h>
-#include <linux/vt.h>
-#include <linux/kd.h>
+#ifndef QWINDOWSDIRECT2DHELPERS_H
+#define QWINDOWSDIRECT2DHELPERS_H
-#ifdef K_OFF
-#define KBD_OFF_MODE K_OFF
-#else
-#define KBD_OFF_MODE K_RAW
-#endif
+#include <QtCore/QRectF>
+#include <QtCore/QSizeF>
+#include <QtCore/QPointF>
+#include <QtGui/QColor>
+#include <QtGui/QTransform>
-QT_BEGIN_NAMESPACE
+#include <d2d1_1helper.h>
-QKmsVTHandler *QKmsVTHandler::self = 0;
+QT_BEGIN_NAMESPACE
-QKmsVTHandler::QKmsVTHandler(QObject *parent)
- : QObject(parent), m_tty(-1)
+Q_DECL_CONSTEXPR inline D2D1_RECT_U to_d2d_rect_u(const QRect &qrect)
{
- Q_ASSERT(!self);
- self = this;
-
- if (!isatty(0))
- return;
+ return D2D1::RectU(qrect.x(), qrect.y(), qrect.x() + qrect.width(), qrect.y() + qrect.height());
+}
- m_tty = 0;
+Q_DECL_CONSTEXPR inline D2D1_RECT_F to_d2d_rect_f(const QRectF &qrect)
+{
+ return D2D1::RectF(qrect.x(), qrect.y(), qrect.x() + qrect.width(), qrect.y() + qrect.height());
+}
- ioctl(m_tty, KDGKBMODE, &m_oldKbdMode);
- if (!qgetenv("QT_KMS_TTYKBD").toInt()) {
- ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE);
- QGuiApplicationPrivate *appd = QGuiApplicationPrivate::instance();
- Q_ASSERT(appd);
- QSegfaultHandler::initialize(appd->argv, appd->argc);
- QSegfaultHandler::installCrashHandler(crashHandler);
- }
+Q_DECL_CONSTEXPR inline D2D1_SIZE_U to_d2d_size_u(const QSizeF &qsize)
+{
+ return D2D1::SizeU(qsize.width(), qsize.height());
}
-QKmsVTHandler::~QKmsVTHandler()
+Q_DECL_CONSTEXPR inline D2D1_SIZE_U to_d2d_size_u(const QSize &qsize)
{
- self->cleanup();
- self = 0;
+ return D2D1::SizeU(qsize.width(), qsize.height());
}
-void QKmsVTHandler::cleanup()
+Q_DECL_CONSTEXPR inline D2D1_POINT_2F to_d2d_point_2f(const QPointF &qpoint)
{
- if (m_tty == -1)
- return;
+ return D2D1::Point2F(qpoint.x(), qpoint.y());
+}
- ioctl(m_tty, KDSKBMODE, m_oldKbdMode);
+Q_DECL_CONSTEXPR inline D2D1::ColorF to_d2d_color_f(const QColor &c)
+{
+ return D2D1::ColorF(c.redF(), c.greenF(), c.blueF(), c.alphaF());
}
-void QKmsVTHandler::crashHandler()
+Q_DECL_CONSTEXPR inline D2D1_MATRIX_3X2_F to_d2d_matrix_3x2_f(const QTransform &transform)
{
- Q_ASSERT(self);
- self->cleanup();
+ Q_ASSERT(transform.isAffine());
+
+ return D2D1::Matrix3x2F(transform.m11(), transform.m12(),
+ transform.m21(), transform.m22(),
+ transform.m31(), transform.m32());
}
QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DHELPERS_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
new file mode 100644
index 0000000000..1a26d7029e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dintegration.h"
+#include "qwindowsdirect2dbackingstore.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dnativeinterface.h"
+#include "qwindowsdirect2dwindow.h"
+
+#include "qwindowscontext.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DIntegrationPrivate
+{
+public:
+ QWindowsDirect2DNativeInterface m_nativeInterface;
+ QWindowsDirect2DContext m_d2dContext;
+};
+
+QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList &paramList)
+{
+ QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList);
+
+ if (!integration->init()) {
+ delete integration;
+ integration = 0;
+ }
+
+ return integration;
+}
+
+QWindowsDirect2DIntegration::~QWindowsDirect2DIntegration()
+{
+
+}
+
+ QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::instance()
+ {
+ return static_cast<QWindowsDirect2DIntegration *>(QWindowsIntegration::instance());
+ }
+
+ QPlatformWindow *QWindowsDirect2DIntegration::createPlatformWindow(QWindow *window) const
+ {
+ QWindowsWindowData data = createWindowData(window);
+ return data.hwnd ? new QWindowsDirect2DWindow(window, data)
+ : Q_NULLPTR;
+ }
+
+ QPlatformNativeInterface *QWindowsDirect2DIntegration::nativeInterface() const
+ {
+ return &d->m_nativeInterface;
+ }
+
+QPlatformPixmap *QWindowsDirect2DIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+{
+ switch (type) {
+ case QPlatformPixmap::BitmapType:
+ return new QRasterPlatformPixmap(type);
+ break;
+ default:
+ return new QWindowsDirect2DPlatformPixmap(type);
+ break;
+ }
+}
+
+QPlatformBackingStore *QWindowsDirect2DIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QWindowsDirect2DBackingStore(window);
+}
+
+QWindowsDirect2DContext *QWindowsDirect2DIntegration::direct2DContext() const
+{
+ return &d->m_d2dContext;
+}
+
+QWindowsDirect2DIntegration::QWindowsDirect2DIntegration(const QStringList &paramList)
+ : QWindowsIntegration(paramList)
+ , d(new QWindowsDirect2DIntegrationPrivate)
+{
+}
+
+bool QWindowsDirect2DIntegration::init()
+{
+ return d->m_d2dContext.init();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
new file mode 100644
index 0000000000..a46d5c0126
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DINTEGRATION_H
+#define QWINDOWSDIRECT2DINTEGRATION_H
+
+#include "qwindowsintegration.h"
+
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContext;
+class QWindowsDirect2DIntegrationPrivate;
+
+class QWindowsDirect2DIntegration : public QWindowsIntegration
+{
+public:
+ static QWindowsDirect2DIntegration *create(const QStringList &paramList);
+
+ virtual ~QWindowsDirect2DIntegration();
+
+ static QWindowsDirect2DIntegration *instance();
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+
+ QWindowsDirect2DContext *direct2DContext() const;
+
+private:
+ explicit QWindowsDirect2DIntegration(const QStringList &paramList);
+ bool init();
+
+ QScopedPointer<QWindowsDirect2DIntegrationPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DINTEGRATION_H
diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
index 5dad6b8d86..6792d92de5 100644
--- a/src/plugins/platforms/ios/qiossoftwareinputhandler.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
@@ -39,33 +39,26 @@
**
****************************************************************************/
-#ifndef QIOSSOFTWAREINPUTHANDLER_H
-#define QIOSSOFTWAREINPUTHANDLER_H
+#include "qwindowsdirect2dnativeinterface.h"
-#include <QtCore/QObject>
-#include <QtCore/QPointer>
-#include <QtWidgets/QWidget>
+#include <QtGui/QBackingStore>
QT_BEGIN_NAMESPACE
-class QIOSSoftwareInputHandler : public QObject
+void *QWindowsDirect2DNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
{
- Q_OBJECT
+ if (!bs || !bs->handle()) {
+ qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
-public:
- QIOSSoftwareInputHandler() : m_CurrentFocusWidget(0), m_CurrentFocusObject(0) {}
- bool eventFilter(QObject *obj, QEvent *event);
+ // getDC is so common we don't want to print an "invalid key" line for it
+ if (resource == "getDC")
+ return 0;
-private slots:
- void activeFocusChanged(bool focus);
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
-private:
- bool closeSoftwareInputPanel(QWidget *widget);
-
- QPointer<QWidget> m_currentFocusWidget;
- QPointer<QObject> m_currentFocusObject;
-};
+}
QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
new file mode 100644
index 0000000000..ee3f7f6eed
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DNATIVEINTERFACE_H
+#define QWINDOWSDIRECT2DNATIVEINTERFACE_H
+
+#include "qwindowsnativeinterface.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DNativeInterface : public QWindowsNativeInterface
+{
+ Q_OBJECT
+public:
+ void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
new file mode 100644
index 0000000000..85dbaab2ce
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dpaintengine.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include "qwindowswindow.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPaintDevicePrivate
+{
+public:
+ QWindowsDirect2DPaintDevicePrivate(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags f)
+ : engine(new QWindowsDirect2DPaintEngine(bitmap))
+ , bitmap(bitmap)
+ , flags(f)
+ {}
+
+ QScopedPointer<QWindowsDirect2DPaintEngine> engine;
+ QWindowsDirect2DBitmap *bitmap;
+ QInternal::PaintDeviceFlags flags;
+};
+
+QWindowsDirect2DPaintDevice::QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags flags)
+ : d_ptr(new QWindowsDirect2DPaintDevicePrivate(bitmap, flags))
+{
+}
+
+QPaintEngine *QWindowsDirect2DPaintDevice::paintEngine() const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ return d->engine.data();
+}
+
+int QWindowsDirect2DPaintDevice::devType() const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ return d->flags;
+}
+
+int QWindowsDirect2DPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ switch (metric) {
+ case QPaintDevice::PdmWidth:
+ return d->bitmap->bitmap()->GetPixelSize().width;
+ break;
+ case QPaintDevice::PdmHeight:
+ return d->bitmap->bitmap()->GetPixelSize().height;
+ break;
+ case QPaintDevice::PdmNumColors:
+ return INT_MAX;
+ break;
+ case QPaintDevice::PdmDepth:
+ return 32;
+ break;
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmPhysicalDpiX:
+ {
+ FLOAT x, y;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
+ return x;
+ }
+ break;
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiY:
+ {
+ FLOAT x, y;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
+ return y;
+ }
+ break;
+ case QPaintDevice::PdmDevicePixelRatio:
+ return 1;
+ break;
+ case QPaintDevice::PdmWidthMM:
+ case QPaintDevice::PdmHeightMM:
+ return -1;
+ break;
+ }
+
+ return -1;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
new file mode 100644
index 0000000000..c799083d84
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPAINTDEVICE_H
+#define QWINDOWSDIRECT2DPAINTDEVICE_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/QPaintDevice>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPaintDevicePrivate;
+class QWindowsDirect2DPaintDevice : public QPaintDevice
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPaintDevice)
+
+public:
+ QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags flags);
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
+ int devType() const Q_DECL_OVERRIDE;
+
+protected:
+ int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWindowsDirect2DPaintDevicePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPAINTDEVICE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
new file mode 100644
index 0000000000..e19a6be47b
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -0,0 +1,1168 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dpaintengine.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include "qwindowsfontengine.h"
+#include "qwindowsfontenginedirectwrite.h"
+#include "qwindowsfontdatabase.h"
+#include "qwindowsintegration.h"
+
+#include <QtGui/private/qpaintengine_p.h>
+#include <QtGui/private/qtextengine_p.h>
+#include <QtGui/private/qfontengine_p.h>
+#include <QtGui/private/qstatictext_p.h>
+
+#include <wrl.h>
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+// The enum values below are set as tags on the device context
+// in the various draw methods. When EndDraw is called the device context
+// will report the last set tag number in case of errors
+// along with an error code
+
+// Microsoft keeps a list of d2d error codes here:
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd370979(v=vs.85).aspx
+enum {
+ D2DDebugDrawInitialStateTag = -1,
+ D2DDebugDrawImageTag = 1,
+ D2DDebugFillTag,
+ D2DDebugDrawPixmapTag,
+ D2DDebugDrawStaticTextItemTag,
+ D2DDebugDrawTextItemTag
+};
+#define D2D_TAG(tag) d->dc()->SetTags(tag, tag)
+
+Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
+
+static inline ID2D1Factory1 *factory()
+{
+ return QWindowsDirect2DContext::instance()->d2dFactory();
+}
+
+// XXX reduce code duplication between painterPathToPathGeometry and
+// vectorPathToID2D1PathGeometry, the two are quite similar
+
+static ComPtr<ID2D1PathGeometry1> painterPathToPathGeometry(const QPainterPath &path)
+{
+ ComPtr<ID2D1PathGeometry1> geometry;
+ ComPtr<ID2D1GeometrySink> sink;
+
+ HRESULT hr = factory()->CreatePathGeometry(&geometry);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ hr = geometry->Open(&sink);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ switch (path.fillRule()) {
+ case Qt::WindingFill:
+ sink->SetFillMode(D2D1_FILL_MODE_WINDING);
+ break;
+ case Qt::OddEvenFill:
+ sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);
+ break;
+ }
+
+ bool inFigure = false;
+
+ for (int i = 0; i < path.elementCount(); i++) {
+ const QPainterPath::Element element = path.elementAt(i);
+
+ switch (element.type) {
+ case QPainterPath::MoveToElement:
+ if (inFigure)
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ sink->BeginFigure(to_d2d_point_2f(element), D2D1_FIGURE_BEGIN_FILLED);
+ inFigure = true;
+ break;
+
+ case QPainterPath::LineToElement:
+ sink->AddLine(to_d2d_point_2f(element));
+ break;
+
+ case QPainterPath::CurveToElement:
+ {
+ const QPainterPath::Element data1 = path.elementAt(++i);
+ const QPainterPath::Element data2 = path.elementAt(++i);
+
+ Q_ASSERT(i < path.elementCount());
+
+ Q_ASSERT(data1.type == QPainterPath::CurveToDataElement);
+ Q_ASSERT(data2.type == QPainterPath::CurveToDataElement);
+
+ D2D1_BEZIER_SEGMENT segment;
+
+ segment.point1 = to_d2d_point_2f(element);
+ segment.point2 = to_d2d_point_2f(data1);
+ segment.point3 = to_d2d_point_2f(data2);
+
+ sink->AddBezier(segment);
+ }
+ break;
+
+ case QPainterPath::CurveToDataElement:
+ qWarning("%s: Unhandled Curve Data Element", __FUNCTION__);
+ break;
+ }
+ }
+
+ if (inFigure)
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ sink->Close();
+
+ return geometry;
+}
+
+static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias)
+{
+ ComPtr<ID2D1PathGeometry1> pathGeometry;
+ HRESULT hr = factory()->CreatePathGeometry(pathGeometry.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ if (path.isEmpty())
+ return pathGeometry;
+
+ ComPtr<ID2D1GeometrySink> sink;
+ hr = pathGeometry->Open(sink.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ sink->SetFillMode(path.hasWindingFill() ? D2D1_FILL_MODE_WINDING
+ : D2D1_FILL_MODE_ALTERNATE);
+
+ bool inFigure = false;
+
+ const QPainterPath::ElementType *types = path.elements();
+ const int count = path.elementCount();
+ const qreal *points = 0;
+
+ QScopedArrayPointer<qreal> rounded_points;
+
+ if (alias) {
+ // Aliased painting, round to whole numbers
+ rounded_points.reset(new qreal[count * 2]);
+ points = rounded_points.data();
+
+ for (int i = 0; i < (count * 2); i++)
+ rounded_points[i] = qRound(path.points()[i]);
+ } else {
+ // Antialiased painting, keep original numbers
+ points = path.points();
+ }
+
+ Q_ASSERT(points);
+
+ if (types) {
+ qreal x, y;
+
+ for (int i = 0; i < count; i++) {
+ x = points[i * 2];
+ y = points[i * 2 + 1];
+
+ switch (types[i]) {
+ case QPainterPath::MoveToElement:
+ if (inFigure)
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ sink->BeginFigure(D2D1::Point2F(x, y), D2D1_FIGURE_BEGIN_FILLED);
+ inFigure = true;
+ break;
+
+ case QPainterPath::LineToElement:
+ sink->AddLine(D2D1::Point2F(x, y));
+ break;
+
+ case QPainterPath::CurveToElement:
+ {
+ Q_ASSERT((i + 2) < count);
+ Q_ASSERT(types[i+1] == QPainterPath::CurveToDataElement);
+ Q_ASSERT(types[i+2] == QPainterPath::CurveToDataElement);
+
+ i++;
+ const qreal x2 = points[i * 2];
+ const qreal y2 = points[i * 2 + 1];
+
+ i++;
+ const qreal x3 = points[i * 2];
+ const qreal y3 = points[i * 2 + 1];
+
+ D2D1_BEZIER_SEGMENT segment = {
+ D2D1::Point2F(x, y),
+ D2D1::Point2F(x2, y2),
+ D2D1::Point2F(x3, y3)
+ };
+
+ sink->AddBezier(segment);
+ }
+ break;
+
+ case QPainterPath::CurveToDataElement:
+ qWarning("%s: Unhandled Curve Data Element", __FUNCTION__);
+ break;
+ }
+ }
+ } else {
+ sink->BeginFigure(D2D1::Point2F(points[0], points[1]), D2D1_FIGURE_BEGIN_FILLED);
+ inFigure = true;
+
+ for (int i = 1; i < count; i++)
+ sink->AddLine(D2D1::Point2F(points[i * 2], points[i * 2 + 1]));
+ }
+
+ if (inFigure) {
+ if (path.hasImplicitClose())
+ sink->AddLine(D2D1::Point2F(points[0], points[1]));
+
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+ }
+
+ sink->Close();
+
+ return pathGeometry;
+}
+
+class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsDirect2DPaintEngine)
+public:
+ QWindowsDirect2DPaintEnginePrivate(QWindowsDirect2DBitmap *bm)
+ : bitmap(bm)
+ , clipPushed(false)
+ {
+ pen.reset();
+ brush.reset();
+
+ dc()->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+ }
+
+ QWindowsDirect2DBitmap *bitmap;
+
+ QPainterPath clipPath;
+ bool clipPushed;
+
+ QPointF currentBrushOrigin;
+
+ struct {
+ bool emulate;
+ QPen qpen;
+ ComPtr<ID2D1Brush> brush;
+ ComPtr<ID2D1StrokeStyle1> strokeStyle;
+
+ inline void reset() {
+ emulate = false;
+ qpen = QPen();
+ brush.Reset();
+ strokeStyle.Reset();
+ }
+ } pen;
+
+ struct {
+ bool emulate;
+ QBrush qbrush;
+ ComPtr<ID2D1Brush> brush;
+
+ inline void reset() {
+ emulate = false;
+ brush.Reset();
+ qbrush = QBrush();
+ }
+ } brush;
+
+ inline ID2D1DeviceContext *dc() const
+ {
+ Q_ASSERT(bitmap);
+ return bitmap->deviceContext()->get();
+ }
+
+ inline D2D1_INTERPOLATION_MODE interpolationMode() const
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ // XXX are we choosing the right d2d interpolation modes?
+ return (q->state()->renderHints & QPainter::SmoothPixmapTransform) ? D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC
+ : D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
+ }
+
+ inline D2D1_ANTIALIAS_MODE antialiasMode() const
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ return (q->state()->renderHints & QPainter::Antialiasing) ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
+ : D2D1_ANTIALIAS_MODE_ALIASED;
+ }
+
+ void updateTransform()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ // Note the loss of info going from 3x3 to 3x2 matrix here
+ dc()->SetTransform(to_d2d_matrix_3x2_f(q->state()->transform()));
+ }
+
+ void updateOpacity()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ qreal opacity = q->state()->opacity;
+ if (brush.brush)
+ brush.brush->SetOpacity(opacity);
+ if (pen.brush)
+ pen.brush->SetOpacity(opacity);
+ }
+
+ void pushClip()
+ {
+ popClip();
+
+ ComPtr<ID2D1PathGeometry1> geometry = painterPathToPathGeometry(clipPath);
+ if (!geometry)
+ return;
+
+ dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(),
+ geometry.Get(),
+ antialiasMode(),
+ D2D1::IdentityMatrix(),
+ 1.0,
+ NULL,
+ D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND),
+ NULL);
+ clipPushed = true;
+ }
+
+ void popClip()
+ {
+ if (clipPushed) {
+ dc()->PopLayer();
+ clipPushed = false;
+ }
+ }
+
+ void updateClipEnabled()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ if (!q->state()->clipEnabled)
+ popClip();
+ else if (!clipPushed)
+ pushClip();
+ }
+
+ void updateClipPath(const QPainterPath &path, Qt::ClipOperation operation)
+ {
+ switch (operation) {
+ case Qt::NoClip:
+ popClip();
+ break;
+ case Qt::ReplaceClip:
+ clipPath = path;
+ pushClip();
+ break;
+ case Qt::IntersectClip:
+ clipPath &= path;
+ pushClip();
+ break;
+ }
+ }
+
+ void updateCompositionMode()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ QPainter::CompositionMode mode = q->state()->compositionMode();
+
+ switch (mode) {
+ case QPainter::CompositionMode_Source:
+ dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_COPY);
+ break;
+ case QPainter::CompositionMode_SourceOver:
+ dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_SOURCE_OVER);
+ break;
+
+ default:
+ qWarning("Unsupported composition mode: %d", mode);
+ break;
+ }
+ }
+
+ void updateBrush(const QBrush &newBrush)
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+
+ if (qbrush_fast_equals(brush.qbrush, newBrush))
+ return;
+
+ brush.brush = to_d2d_brush(newBrush, &brush.emulate);
+ brush.qbrush = newBrush;
+
+ if (brush.brush) {
+ brush.brush->SetOpacity(q->state()->opacity);
+ applyBrushOrigin(currentBrushOrigin);
+ }
+ }
+
+ void updateBrushOrigin()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+
+ negateCurrentBrushOrigin();
+ applyBrushOrigin(q->state()->brushOrigin);
+ }
+
+ void negateCurrentBrushOrigin()
+ {
+ if (brush.brush && !currentBrushOrigin.isNull()) {
+ D2D1_MATRIX_3X2_F transform;
+ brush.brush->GetTransform(&transform);
+
+ brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
+ * D2D1::Matrix3x2F::Translation(-currentBrushOrigin.x(),
+ -currentBrushOrigin.y()));
+ }
+ }
+
+ void applyBrushOrigin(const QPointF &origin)
+ {
+ if (brush.brush && !origin.isNull()) {
+ D2D1_MATRIX_3X2_F transform;
+ brush.brush->GetTransform(&transform);
+
+ brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
+ * D2D1::Matrix3x2F::Translation(origin.x(), origin.y()));
+ }
+
+ currentBrushOrigin = origin;
+ }
+
+ void updatePen()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ const QPen &newPen = q->state()->pen;
+
+ if (qpen_fast_equals(newPen, pen.qpen))
+ return;
+
+ pen.reset();
+ pen.qpen = newPen;
+
+ if (newPen.style() == Qt::NoPen)
+ return;
+
+ pen.brush = to_d2d_brush(newPen.brush(), &pen.emulate);
+ if (!pen.brush)
+ return;
+
+ pen.brush->SetOpacity(q->state()->opacity);
+
+ D2D1_STROKE_STYLE_PROPERTIES1 props = {};
+
+ switch (newPen.capStyle()) {
+ case Qt::SquareCap:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_SQUARE;
+ break;
+ case Qt::RoundCap:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_ROUND;
+ case Qt::FlatCap:
+ default:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_FLAT;
+ break;
+ }
+
+ switch (newPen.joinStyle()) {
+ case Qt::BevelJoin:
+ props.lineJoin = D2D1_LINE_JOIN_BEVEL;
+ break;
+ case Qt::RoundJoin:
+ props.lineJoin = D2D1_LINE_JOIN_ROUND;
+ break;
+ case Qt::MiterJoin:
+ default:
+ props.lineJoin = D2D1_LINE_JOIN_MITER;
+ break;
+ }
+
+ props.miterLimit = newPen.miterLimit() * qreal(2.0); // D2D and Qt miter specs differ
+ props.dashOffset = newPen.dashOffset();
+ props.transformType = qIsNull(newPen.widthF()) ? D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE
+ : newPen.isCosmetic() ? D2D1_STROKE_TRANSFORM_TYPE_FIXED
+ : D2D1_STROKE_TRANSFORM_TYPE_NORMAL;
+
+ switch (newPen.style()) {
+ case Qt::SolidLine:
+ props.dashStyle = D2D1_DASH_STYLE_SOLID;
+ break;
+
+ case Qt::DotLine:
+ case Qt::DashDotLine:
+ case Qt::DashDotDotLine:
+ // Try and match Qt's raster engine in output as closely as possible
+ if (newPen.widthF() <= 1.0)
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_FLAT;
+
+ // fall through
+ default:
+ props.dashStyle = D2D1_DASH_STYLE_CUSTOM;
+ break;
+ }
+
+ HRESULT hr;
+
+ if (props.dashStyle == D2D1_DASH_STYLE_CUSTOM) {
+ QVector<qreal> dashes = newPen.dashPattern();
+ QVector<FLOAT> converted(dashes.size());
+
+ for (int i = 0; i < dashes.size(); i++) {
+ converted[i] = dashes[i];
+ }
+
+ hr = factory()->CreateStrokeStyle(props, converted.constData(), converted.size(), &pen.strokeStyle);
+ } else {
+ hr = factory()->CreateStrokeStyle(props, NULL, 0, &pen.strokeStyle);
+ }
+
+ if (FAILED(hr))
+ qWarning("%s: Could not create stroke style: %#x", __FUNCTION__, hr);
+ }
+
+ ComPtr<ID2D1Brush> to_d2d_brush(const QBrush &newBrush, bool *needsEmulation)
+ {
+ HRESULT hr;
+ ComPtr<ID2D1Brush> result;
+
+ Q_ASSERT(needsEmulation);
+
+ *needsEmulation = false;
+
+ switch (newBrush.style()) {
+ case Qt::NoBrush:
+ break;
+
+ case Qt::SolidPattern:
+ {
+ ComPtr<ID2D1SolidColorBrush> solid;
+
+ hr = dc()->CreateSolidColorBrush(to_d2d_color_f(newBrush.color()), &solid);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create solid color brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = solid.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert solid color brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+
+ case Qt::Dense1Pattern:
+ case Qt::Dense2Pattern:
+ case Qt::Dense3Pattern:
+ case Qt::Dense4Pattern:
+ case Qt::Dense5Pattern:
+ case Qt::Dense6Pattern:
+ case Qt::Dense7Pattern:
+ case Qt::HorPattern:
+ case Qt::VerPattern:
+ case Qt::CrossPattern:
+ case Qt::BDiagPattern:
+ case Qt::FDiagPattern:
+ case Qt::DiagCrossPattern:
+ {
+ ComPtr<ID2D1BitmapBrush1> bitmapBrush;
+ D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = {
+ D2D1_EXTEND_MODE_WRAP,
+ D2D1_EXTEND_MODE_WRAP,
+ interpolationMode()
+ };
+
+ QImage brushImg = qt_imageForBrush(newBrush.style(), false);
+ brushImg.setColor(0, newBrush.color().rgba());
+ brushImg.setColor(1, qRgba(0, 0, 0, 0));
+
+ QWindowsDirect2DBitmap bitmap;
+ bool success = bitmap.fromImage(brushImg, Qt::AutoColor);
+ if (!success) {
+ qWarning("%s: Could not create Direct2D bitmap from Qt pattern brush image", __FUNCTION__);
+ break;
+ }
+
+ hr = dc()->CreateBitmapBrush(bitmap.bitmap(),
+ bitmapBrushProperties,
+ &bitmapBrush);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = bitmapBrush.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+
+ case Qt::LinearGradientPattern:
+ case Qt::RadialGradientPattern:
+ case Qt::ConicalGradientPattern:
+ *needsEmulation = true;
+ break;
+
+ case Qt::TexturePattern:
+ {
+ ComPtr<ID2D1BitmapBrush1> bitmapBrush;
+ D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = {
+ D2D1_EXTEND_MODE_WRAP,
+ D2D1_EXTEND_MODE_WRAP,
+ interpolationMode()
+ };
+
+ QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(newBrush.texture().handle());
+ QWindowsDirect2DBitmap *bitmap = pp->bitmap();
+ hr = dc()->CreateBitmapBrush(bitmap->bitmap(),
+ bitmapBrushProperties,
+ &bitmapBrush);
+
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create texture brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = bitmapBrush.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert texture brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+ }
+
+ if (result && !newBrush.transform().isIdentity())
+ result->SetTransform(to_d2d_matrix_3x2_f(newBrush.transform()));
+
+ return result;
+ }
+
+ void updateHints()
+ {
+ dc()->SetAntialiasMode(antialiasMode());
+ }
+};
+
+QWindowsDirect2DPaintEngine::QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap *bitmap)
+ : QPaintEngineEx(*(new QWindowsDirect2DPaintEnginePrivate(bitmap)))
+{
+ QPaintEngine::PaintEngineFeatures unsupported =
+ // As of 1.1 Direct2D gradient support is deficient for linear and radial gradients
+ QPaintEngine::LinearGradientFill
+ | QPaintEngine::RadialGradientFill
+
+ // As of 1.1 Direct2D does not support conical gradients at all
+ | QPaintEngine::ConicalGradientFill
+
+ // As of 1.1 Direct2D does not natively support complex composition modes
+ // However, using Direct2D effects that implement them should be possible
+ | QPaintEngine::PorterDuff
+ | QPaintEngine::BlendModes
+ | QPaintEngine::RasterOpModes
+
+ // As of 1.1 Direct2D does not natively support perspective transforms
+ // However, writing a custom effect that implements them should be possible
+ // The built-in 3D transform effect unfortunately changes output image size, making
+ // it unusable for us.
+ | QPaintEngine::PerspectiveTransform;
+
+ gccaps &= ~unsupported;
+}
+
+bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ d->bitmap->deviceContext()->begin();
+ d->dc()->SetTransform(D2D1::Matrix3x2F::Identity());
+
+ QRect clip(0, 0, pdev->width(), pdev->height());
+ if (!systemClip().isEmpty())
+ clip &= systemClip().boundingRect();
+
+ d->dc()->PushAxisAlignedClip(to_d2d_rect_f(clip), D2D1_ANTIALIAS_MODE_ALIASED);
+
+ D2D_TAG(D2DDebugDrawInitialStateTag);
+
+ return true;
+}
+
+bool QWindowsDirect2DPaintEngine::end()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ // First pop any user-applied clipping
+ d->popClip();
+ // Now the system clip from begin() above
+ d->dc()->PopAxisAlignedClip();
+ return d->bitmap->deviceContext()->end();
+}
+
+QPaintEngine::Type QWindowsDirect2DPaintEngine::type() const
+{
+ return QPaintEngine::Direct2D;
+}
+
+void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugFillTag);
+
+ if (path.isEmpty())
+ return;
+
+ d->updateBrush(brush);
+
+ if (d->brush.emulate) {
+ // We mostly (only?) get here when gradients are required.
+ // We could probably natively support linear and radial gradients that have pad reflect
+
+ QImage img(d->bitmap->size(), QImage::Format_ARGB32);
+ img.fill(Qt::transparent);
+
+ QPainter p;
+ QPaintEngine *engine = img.paintEngine();
+ if (engine->isExtended() && p.begin(&img)) {
+ QPaintEngineEx *extended = static_cast<QPaintEngineEx *>(engine);
+ extended->fill(path, brush);
+ if (!p.end())
+ qWarning("%s: Paint Engine end returned false", __FUNCTION__);
+
+ drawImage(img.rect(), img, img.rect());
+ } else {
+ qWarning("%s: Could not fall back to QImage", __FUNCTION__);
+ }
+
+ return;
+ }
+
+ if (!d->brush.brush)
+ return;
+
+ ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ if (!geometry) {
+ qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
+ return;
+ }
+
+ d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get());
+}
+
+// For clipping we convert everything to painter paths since it allows
+// calculating intersections easily. It might be faster to convert to
+// ID2D1Geometry and use its operations, although that needs to measured.
+// The implementation would be more complex in any case.
+
+void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
+{
+ clip(path.convertToPainterPath(), op);
+}
+
+void QWindowsDirect2DPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
+{
+ QPainterPath p;
+ p.addRect(rect);
+ clip(p, op);
+}
+
+void QWindowsDirect2DPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
+{
+ QPainterPath p;
+ p.addRegion(region);
+ clip(p, op);
+}
+
+void QWindowsDirect2DPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateClipPath(path, op);
+}
+
+void QWindowsDirect2DPaintEngine::clipEnabledChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateClipEnabled();
+}
+
+void QWindowsDirect2DPaintEngine::penChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updatePen();
+}
+
+void QWindowsDirect2DPaintEngine::brushChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateBrush(state()->brush);
+}
+
+void QWindowsDirect2DPaintEngine::brushOriginChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateBrushOrigin();
+}
+
+void QWindowsDirect2DPaintEngine::opacityChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateOpacity();
+}
+
+void QWindowsDirect2DPaintEngine::compositionModeChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateCompositionMode();
+}
+
+void QWindowsDirect2DPaintEngine::renderHintsChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateHints();
+}
+
+void QWindowsDirect2DPaintEngine::transformChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateTransform();
+}
+
+void QWindowsDirect2DPaintEngine::drawImage(const QRectF &rectangle, const QImage &image,
+ const QRectF &sr, Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawImageTag);
+
+ QPixmap pixmap = QPixmap::fromImage(image, flags);
+ drawPixmap(rectangle, pixmap, sr);
+}
+
+void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
+ const QPixmap &pm,
+ const QRectF &sr)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawPixmapTag);
+
+ if (pm.isNull())
+ return;
+
+ if (pm.handle()->pixelType() == QPlatformPixmap::BitmapType) {
+ QImage i = pm.toImage();
+ i.setColor(0, qRgba(0, 0, 0, 0));
+ i.setColor(1, d->pen.qpen.color().rgba());
+ drawImage(r, i, sr);
+ return;
+ }
+
+ QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(pm.handle());
+ QWindowsDirect2DBitmap *bitmap = pp->bitmap();
+
+ if (bitmap->bitmap() != d->bitmap->bitmap()) {
+ // Good, src bitmap != dst bitmap
+ if (sr.isValid())
+ d->dc()->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(r), state()->opacity,
+ d->interpolationMode(),
+ to_d2d_rect_f(sr));
+ else
+ d->dc()->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(r), state()->opacity,
+ d->interpolationMode());
+ } else {
+ // Ok, so the source pixmap and destination pixmap is the same.
+ // D2D is not fond of this scenario, deal with it through
+ // an intermediate bitmap
+ QWindowsDirect2DBitmap intermediate;
+
+ if (sr.isValid()) {
+ bool r = intermediate.resize(sr.width(), sr.height());
+ if (!r) {
+ qWarning("%s: Could not resize intermediate bitmap to source rect size", __FUNCTION__);
+ return;
+ }
+
+ D2D1_RECT_U d2d_sr = to_d2d_rect_u(sr.toRect());
+ HRESULT hr = intermediate.bitmap()->CopyFromBitmap(NULL,
+ bitmap->bitmap(),
+ &d2d_sr);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy source rect area from source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ return;
+ }
+ } else {
+ bool r = intermediate.resize(bitmap->size().width(),
+ bitmap->size().height());
+ if (!r) {
+ qWarning("%s: Could not resize intermediate bitmap to source bitmap size", __FUNCTION__);
+ return;
+ }
+
+ HRESULT hr = intermediate.bitmap()->CopyFromBitmap(NULL,
+ bitmap->bitmap(),
+ NULL);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ return;
+ }
+ }
+
+ d->dc()->DrawBitmap(intermediate.bitmap(),
+ to_d2d_rect_f(r), state()->opacity,
+ d->interpolationMode());
+ }
+}
+
+static ComPtr<IDWriteFontFace> fontFaceFromFontEngine(QFontEngine *fe)
+{
+ ComPtr<IDWriteFontFace> fontFace;
+
+ switch (fe->type()) {
+ case QFontEngine::Win:
+ {
+ QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe);
+ QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
+
+ HGDIOBJ oldfont = wfe->selectDesignFont();
+ HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
+ DeleteObject(SelectObject(wfed->hdc, oldfont));
+ if (FAILED(hr))
+ qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
+
+ }
+ break;
+
+#ifndef QT_NO_DIRECTWRITE
+
+ case QFontEngine::DirectWrite:
+ {
+ QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(fe);
+ fontFace = wfedw->directWriteFontFace();
+ }
+ break;
+
+#endif // QT_NO_DIRECTWRITE
+
+ default:
+ qWarning("%s: Unknown font engine!", __FUNCTION__);
+ break;
+ }
+
+ return fontFace;
+}
+
+void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticTextItem)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawStaticTextItemTag);
+
+ if (qpen_style(d->pen.qpen) == Qt::NoPen)
+ return;
+
+ if (staticTextItem->numGlyphs == 0)
+ return;
+
+ // If we can't support the current configuration with Direct2D, fall back to slow path
+ // Most common cases are perspective transform and gradient brush as pen
+ if ((state()->transform().isAffine() == false) || d->pen.emulate) {
+ QPaintEngineEx::drawStaticTextItem(staticTextItem);
+ return;
+ }
+
+ ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->fontEngine());
+ if (!fontFace) {
+ qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
+ QPaintEngineEx::drawStaticTextItem(staticTextItem);
+ return;
+ }
+
+ QVector<UINT16> glyphIndices(staticTextItem->numGlyphs);
+ QVector<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
+ QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
+
+ // XXX Are we generating a lot of cache misses here?
+ for (int i = 0; i < staticTextItem->numGlyphs; i++) {
+ glyphIndices[i] = UINT16(staticTextItem->glyphs[i]); // Imperfect conversion here
+
+ // This looks a little funky because the positions are precalculated
+ glyphAdvances[i] = 0;
+ glyphOffsets[i].advanceOffset = staticTextItem->glyphPositions[i].x.toReal();
+ // Qt and Direct2D seem to disagree on the direction of the ascender offset...
+ glyphOffsets[i].ascenderOffset = staticTextItem->glyphPositions[i].y.toReal() * -1;
+ }
+
+ drawGlyphRun(D2D1::Point2F(0, 0),
+ fontFace.Get(),
+ staticTextItem->font,
+ staticTextItem->numGlyphs,
+ glyphIndices.constData(),
+ glyphAdvances.constData(),
+ glyphOffsets.constData(),
+ false);
+}
+
+void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawTextItemTag);
+
+ if (qpen_style(d->pen.qpen) == Qt::NoPen)
+ return;
+
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+ if (ti.glyphs.numGlyphs == 0)
+ return;
+
+ // If we can't support the current configuration with Direct2D, fall back to slow path
+ // Most common cases are perspective transform and gradient brush as pen
+ if ((state()->transform().isAffine() == false) || d->pen.emulate) {
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
+ ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(ti.fontEngine);
+ if (!fontFace) {
+ qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
+ QVector<UINT16> glyphIndices(ti.glyphs.numGlyphs);
+ QVector<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
+ QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
+
+ // XXX Are we generating a lot of cache misses here?
+ for (int i = 0; i < ti.glyphs.numGlyphs; i++) {
+ glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]); // Imperfect conversion here
+ glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal();
+ glyphOffsets[i].advanceOffset = ti.glyphs.offsets[i].x.toReal();
+
+ // XXX Should we negate the y value like for static text items?
+ glyphOffsets[i].ascenderOffset = ti.glyphs.offsets[i].y.toReal();
+ }
+
+ const bool rtl = (ti.flags & QTextItem::RightToLeft);
+ const QPointF offset(rtl ? ti.width.toReal() : 0, 0);
+
+ drawGlyphRun(to_d2d_point_2f(p + offset),
+ fontFace.Get(),
+ ti.font(),
+ ti.glyphs.numGlyphs,
+ glyphIndices.constData(),
+ glyphAdvances.constData(),
+ glyphOffsets.constData(),
+ rtl);
+}
+
+// Points (1/72 inches) to Microsoft's Device Independent Pixels (1/96 inches)
+inline static Q_DECL_CONSTEXPR FLOAT pointSizeToDIP(qreal pointSize)
+{
+ return pointSize + (pointSize / qreal(3.0));
+}
+
+inline static FLOAT pixelSizeToDIP(int pixelSize)
+{
+ FLOAT dpiX, dpiY;
+ factory()->GetDesktopDpi(&dpiX, &dpiY);
+
+ return FLOAT(pixelSize) / (dpiY / 96.0f);
+}
+
+inline static FLOAT fontSizeInDIP(const QFont &font)
+{
+ // Direct2d wants the font size in DIPs (Device Independent Pixels), each of which is 1/96 inches.
+ if (font.pixelSize() == -1) {
+ // font size was set as points
+ return pointSizeToDIP(font.pointSizeF());
+ } else {
+ // font size was set as pixels
+ return pixelSizeToDIP(font.pixelSize());
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawGlyphRun(const D2D1_POINT_2F &pos,
+ IDWriteFontFace *fontFace,
+ const QFont &font,
+ int numGlyphs,
+ const UINT16 *glyphIndices,
+ const FLOAT *glyphAdvances,
+ const DWRITE_GLYPH_OFFSET *glyphOffsets,
+ bool rtl)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ DWRITE_GLYPH_RUN glyphRun = {
+ fontFace, // IDWriteFontFace *fontFace;
+ fontSizeInDIP(font), // FLOAT fontEmSize;
+ numGlyphs, // UINT32 glyphCount;
+ glyphIndices, // const UINT16 *glyphIndices;
+ glyphAdvances, // const FLOAT *glyphAdvances;
+ glyphOffsets, // const DWRITE_GLYPH_OFFSET *glyphOffsets;
+ FALSE, // BOOL isSideways;
+ rtl ? 1 : 0 // UINT32 bidiLevel;
+ };
+
+ const bool antiAlias = bool((state()->renderHints & QPainter::TextAntialiasing)
+ && !(font.styleStrategy() & QFont::NoAntialias));
+ d->dc()->SetTextAntialiasMode(antiAlias ? D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE
+ : D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
+
+ d->dc()->DrawGlyphRun(pos,
+ &glyphRun,
+ NULL,
+ d->pen.brush.Get(),
+ DWRITE_MEASURING_MODE_GDI_CLASSIC);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
new file mode 100644
index 0000000000..6c74a07e88
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPAINTENGINE_H
+#define QWINDOWSDIRECT2DPAINTENGINE_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/private/qpaintengineex_p.h>
+
+#include <d2d1_1.h>
+#include <dwrite_1.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPaintEnginePrivate;
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPaintEngine : public QPaintEngineEx
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPaintEngine)
+
+public:
+ QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap *bitmap);
+
+ bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE;
+ bool end() Q_DECL_OVERRIDE;
+
+ Type type() const Q_DECL_OVERRIDE;
+
+ void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
+
+ void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+ void clip(const QRect &rect, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+ void clip(const QRegion &region, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+ void clip(const QPainterPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+
+ void clipEnabledChanged() Q_DECL_OVERRIDE;
+ void penChanged() Q_DECL_OVERRIDE;
+ void brushChanged() Q_DECL_OVERRIDE;
+ void brushOriginChanged() Q_DECL_OVERRIDE;
+ void opacityChanged() Q_DECL_OVERRIDE;
+ void compositionModeChanged() Q_DECL_OVERRIDE;
+ void renderHintsChanged() Q_DECL_OVERRIDE;
+ void transformChanged() Q_DECL_OVERRIDE;
+
+ void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
+
+ void drawStaticTextItem(QStaticTextItem *staticTextItem) Q_DECL_OVERRIDE;
+ void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE;
+
+private:
+ void drawGlyphRun(const D2D1_POINT_2F &pos, IDWriteFontFace *fontFace, const QFont &font,
+ int numGlyphs, const UINT16 *glyphIndices, const FLOAT *glyphAdvances,
+ const DWRITE_GLYPH_OFFSET *glyphOffsets, bool rtl);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPAINTENGINE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
new file mode 100644
index 0000000000..072c4b3c0e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2dhelpers.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QImage>
+#include <QtGui/QPaintDevice>
+#include <QtGui/QPaintEngine>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPlatformPixmapPrivate
+{
+public:
+ QWindowsDirect2DPlatformPixmapPrivate()
+ : bitmap(new QWindowsDirect2DBitmap)
+ , device(new QWindowsDirect2DPaintDevice(bitmap.data(), QInternal::Pixmap))
+ , devicePixelRatio(1.0)
+ {}
+
+ QScopedPointer<QWindowsDirect2DBitmap> bitmap;
+ QScopedPointer<QWindowsDirect2DPaintDevice> device;
+ qreal devicePixelRatio;
+};
+
+static int qt_d2dpixmap_serno = 0;
+
+QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(PixelType pixelType)
+ : QPlatformPixmap(pixelType, Direct2DClass)
+ , d_ptr(new QWindowsDirect2DPlatformPixmapPrivate)
+{
+ setSerialNumber(qt_d2dpixmap_serno++);
+}
+
+QWindowsDirect2DPlatformPixmap::~QWindowsDirect2DPlatformPixmap()
+{
+
+}
+
+void QWindowsDirect2DPlatformPixmap::resize(int width, int height)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+
+ if (!d->bitmap->resize(width, height)) {
+ qWarning("%s: Could not resize bitmap", __FUNCTION__);
+ return;
+ }
+
+ is_null = false;
+ w = width;
+ h = height;
+ this->d = 32;
+}
+
+void QWindowsDirect2DPlatformPixmap::fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+
+ if (!d->bitmap->fromImage(image, flags)) {
+ qWarning("%s: Could not init from image", __FUNCTION__);
+ return;
+ }
+
+ is_null = false;
+ w = image.width();
+ h = image.height();
+ this->d = 32;
+}
+
+int QWindowsDirect2DPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+
+ Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice::PaintDeviceMetric metric);
+ return qt_paint_device_metric(d->device.data(), metric);
+}
+
+void QWindowsDirect2DPlatformPixmap::fill(const QColor &color)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+ d->bitmap->fill(color);
+}
+
+bool QWindowsDirect2DPlatformPixmap::hasAlphaChannel() const
+{
+ return true;
+}
+
+QImage QWindowsDirect2DPlatformPixmap::toImage() const
+{
+ return toImage(QRect());
+}
+
+QImage QWindowsDirect2DPlatformPixmap::toImage(const QRect &rect) const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+
+ bool active = d->device->paintEngine()->isActive();
+
+ if (active)
+ d->device->paintEngine()->end();
+
+ QImage result = d->bitmap->toImage(rect);
+
+ if (active)
+ d->device->paintEngine()->begin(d->device.data());
+
+ return result;
+}
+
+QPaintEngine* QWindowsDirect2DPlatformPixmap::paintEngine() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->device->paintEngine();
+}
+
+qreal QWindowsDirect2DPlatformPixmap::devicePixelRatio() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->devicePixelRatio;
+}
+
+void QWindowsDirect2DPlatformPixmap::setDevicePixelRatio(qreal scaleFactor)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+ d->devicePixelRatio = scaleFactor;
+}
+
+QWindowsDirect2DBitmap *QWindowsDirect2DPlatformPixmap::bitmap() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->bitmap.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
new file mode 100644
index 0000000000..e6684ea423
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPLATFORMPIXMAP_H
+#define QWINDOWSDIRECT2DPLATFORMPIXMAP_H
+
+#include <QtGui/qpa/qplatformpixmap.h>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPlatformPixmapPrivate;
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPlatformPixmap : public QPlatformPixmap
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPlatformPixmap)
+public:
+ QWindowsDirect2DPlatformPixmap(PixelType pixelType);
+ ~QWindowsDirect2DPlatformPixmap();
+
+ virtual void resize(int width, int height);
+ virtual void fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags);
+
+ virtual int metric(QPaintDevice::PaintDeviceMetric metric) const;
+ virtual void fill(const QColor &color);
+
+ virtual bool hasAlphaChannel() const;
+
+ virtual QImage toImage() const;
+ virtual QImage toImage(const QRect &rect) const;
+
+ virtual QPaintEngine* paintEngine() const;
+
+ virtual qreal devicePixelRatio() const;
+ virtual void setDevicePixelRatio(qreal scaleFactor);
+
+ QWindowsDirect2DBitmap *bitmap() const;
+
+private:
+ QScopedPointer<QWindowsDirect2DPlatformPixmapPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPLATFORMPIXMAP_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
new file mode 100644
index 0000000000..f75bb49fd9
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dintegration.h"
+
+#include <QtGui/qpa/qplatformintegrationplugin.h>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "direct2d.json")
+public:
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QPlatformIntegration *QWindowsDirect2DIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ if (system.compare(system, QStringLiteral("direct2d"), Qt::CaseInsensitive) == 0)
+ return QWindowsDirect2DIntegration::create(paramList);
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#include "qwindowsdirect2dplatformplugin.moc"
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
new file mode 100644
index 0000000000..bf860f982e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dwindow.h"
+#include "qwindowsdirect2ddevicecontext.h"
+#include "qwindowsdirect2dhelpers.h"
+
+#include <d3d11.h>
+#include <d2d1_1.h>
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+QWindowsDirect2DWindow::QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data)
+ : QWindowsWindow(window, data)
+ , m_needsFullFlush(true)
+{
+ DXGI_SWAP_CHAIN_DESC1 desc = {};
+
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ desc.SampleDesc.Count = 1;
+ desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ desc.BufferCount = 1;
+ desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
+
+ HRESULT hr = QWindowsDirect2DContext::instance()->dxgiFactory()->CreateSwapChainForHwnd(
+ QWindowsDirect2DContext::instance()->d3dDevice(), // [in] IUnknown *pDevice
+ handle(), // [in] HWND hWnd
+ &desc, // [in] const DXGI_SWAP_CHAIN_DESC1 *pDesc
+ NULL, // [in] const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc
+ NULL, // [in] IDXGIOutput *pRestrictToOutput
+ m_swapChain.ReleaseAndGetAddressOf()); // [out] IDXGISwapChain1 **ppSwapChain
+
+ if (FAILED(hr))
+ qWarning("%s: Could not create swap chain: %#x", __FUNCTION__, hr);
+
+ hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
+ D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
+ m_deviceContext.GetAddressOf());
+ if (FAILED(hr))
+ qWarning("%s: Couldn't create Direct2D Device context: %#x", __FUNCTION__, hr);
+}
+
+QWindowsDirect2DWindow::~QWindowsDirect2DWindow()
+{
+}
+
+void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion &region, const QPoint &offset)
+{
+ DXGI_SWAP_CHAIN_DESC1 desc;
+ HRESULT hr = m_swapChain->GetDesc1(&desc);
+ QRect geom = geometry();
+
+ if (FAILED(hr) || (desc.Width != geom.width()) || (desc.Height != geom.height())) {
+ resizeSwapChain(geom.size());
+ m_swapChain->GetDesc1(&desc);
+ }
+
+ setupBitmap();
+ if (!m_bitmap)
+ return;
+
+ m_bitmap->deviceContext()->begin();
+
+ ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get();
+ if (!m_needsFullFlush) {
+ QRegion clipped = region;
+ clipped &= QRect(0, 0, desc.Width, desc.Height);
+
+ foreach (const QRect &rect, clipped.rects()) {
+ QRectF rectF(rect);
+ dc->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(rectF),
+ 1.0,
+ D2D1_INTERPOLATION_MODE_LINEAR,
+ to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
+ }
+ } else {
+ QRectF rectF(0, 0, desc.Width, desc.Height);
+ dc->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(rectF),
+ 1.0,
+ D2D1_INTERPOLATION_MODE_LINEAR,
+ to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
+ m_needsFullFlush = false;
+ }
+
+ m_bitmap->deviceContext()->end();
+ m_swapChain->Present(1, 0);
+}
+
+void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
+{
+ if (!m_swapChain)
+ return;
+
+ m_bitmap.reset();
+ m_deviceContext->SetTarget(Q_NULLPTR);
+
+ HRESULT hr = m_swapChain->ResizeBuffers(0,
+ size.width(), size.height(),
+ DXGI_FORMAT_UNKNOWN,
+ 0);
+ if (FAILED(hr))
+ qWarning("%s: Could not resize swap chain: %#x", __FUNCTION__, hr);
+
+ m_needsFullFlush = true;
+}
+
+void QWindowsDirect2DWindow::setupBitmap()
+{
+ if (m_bitmap)
+ return;
+
+ if (!m_deviceContext)
+ return;
+
+ if (!m_swapChain)
+ return;
+
+ ComPtr<IDXGISurface1> backBufferSurface;
+ HRESULT hr = m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBufferSurface));
+ if (FAILED(hr)) {
+ qWarning("%s: Could not query backbuffer for DXGI Surface: %#x", __FUNCTION__, hr);
+ return;
+ }
+
+ ComPtr<ID2D1Bitmap1> backBufferBitmap;
+ hr = m_deviceContext->CreateBitmapFromDxgiSurface(backBufferSurface.Get(), NULL, backBufferBitmap.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D Bitmap from DXGI Surface: %#x", __FUNCTION__, hr);
+ return;
+ }
+
+ m_bitmap.reset(new QWindowsDirect2DBitmap(backBufferBitmap.Get(), m_deviceContext.Get()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
new file mode 100644
index 0000000000..7996904639
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DWINDOW_H
+#define QWINDOWSDIRECT2DWINDOW_H
+
+#include "qwindowswindow.h"
+#include "qwindowsdirect2dbitmap.h"
+
+#include <dxgi1_2.h>
+#include <wrl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DWindow : public QWindowsWindow
+{
+public:
+ QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data);
+ ~QWindowsDirect2DWindow();
+
+ void flush(QWindowsDirect2DBitmap *bitmap, const QRegion &region, const QPoint &offset);
+
+private:
+ void resizeSwapChain(const QSize &size);
+ void setupBitmap();
+
+private:
+ Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
+ Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext;
+ QScopedPointer<QWindowsDirect2DBitmap> m_bitmap;
+ bool m_needsFullFlush;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DWINDOW_H
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index b56d75a16e..16510095db 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -281,12 +281,16 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_CLEAR , Qt::Key_Clear);
insert(DIKS_MENU , Qt::Key_Menu);
insert(DIKS_HELP , Qt::Key_Help);
+ insert(DIKS_INFO , Qt::Key_Info);
+ insert(DIKS_EXIT , Qt::Key_Exit);
+ insert(DIKS_SETUP , Qt::Key_Settings);
insert(DIKS_CD , Qt::Key_CD);
insert(DIKS_INTERNET , Qt::Key_HomePage);
insert(DIKS_MAIL , Qt::Key_LaunchMail);
insert(DIKS_FAVORITES , Qt::Key_Favorites);
insert(DIKS_PHONE , Qt::Key_Phone);
+ insert(DIKS_PROGRAM , Qt::Key_Guide);
insert(DIKS_TIME , Qt::Key_Time);
insert(DIKS_RED , Qt::Key_Red);
diff --git a/src/plugins/platforms/eglfs/eglfs.pri b/src/plugins/platforms/eglfs/eglfs.pri
index 390061c168..7afa9c9e11 100644
--- a/src/plugins/platforms/eglfs/eglfs.pri
+++ b/src/plugins/platforms/eglfs/eglfs.pri
@@ -12,21 +12,15 @@ DEFINES += MESA_EGL_NO_X11_HEADERS
SOURCES += $$PWD/qeglfsintegration.cpp \
$$PWD/qeglfswindow.cpp \
- $$PWD/qeglfsbackingstore.cpp \
$$PWD/qeglfsscreen.cpp \
$$PWD/qeglfshooks_stub.cpp \
- $$PWD/qeglfscursor.cpp \
- $$PWD/qeglfscontext.cpp \
- $$PWD/qeglfscompositor.cpp
+ $$PWD/qeglfscontext.cpp
HEADERS += $$PWD/qeglfsintegration.h \
$$PWD/qeglfswindow.h \
- $$PWD/qeglfsbackingstore.h \
$$PWD/qeglfsscreen.h \
- $$PWD/qeglfscursor.h \
$$PWD/qeglfshooks.h \
- $$PWD/qeglfscontext.h \
- $$PWD/qeglfscompositor.h
+ $$PWD/qeglfscontext.h
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
deleted file mode 100644
index 03531916cf..0000000000
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 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 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglfsbackingstore.h"
-#include "qeglfscompositor.h"
-#include "qeglfscursor.h"
-#include "qeglfswindow.h"
-#include "qeglfscontext.h"
-
-#include <QtGui/QOpenGLPaintDevice>
-#include <QtGui/QOpenGLShaderProgram>
-
-QT_BEGIN_NAMESPACE
-
-QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
- : QPlatformBackingStore(window),
- m_window(static_cast<QEglFSWindow *>(window->handle())),
- m_texture(0)
-{
- m_window->setBackingStore(this);
-}
-
-QPaintDevice *QEglFSBackingStore::paintDevice()
-{
- return &m_image;
-}
-
-void QEglFSBackingStore::updateTexture()
-{
- glBindTexture(GL_TEXTURE_2D, m_texture);
-
- if (!m_dirty.isNull()) {
- QRegion fixed;
- QRect imageRect = m_image.rect();
- m_dirty |= imageRect;
-
- 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;
- }
-
- 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();
- }
-}
-
-void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(window);
- Q_UNUSED(region);
- Q_UNUSED(offset);
-
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglBackingStore::flush %p", window);
-#endif
-
- QEglFSWindow *rootWin = m_window->screen()->rootWindow();
- if (!rootWin || !rootWin->isRaster())
- return;
-
- m_window->create();
- rootWin->screen()->rootContext()->makeCurrent(rootWin->window());
- updateTexture();
- QEglFSCompositor::instance()->schedule(rootWin->screen());
-}
-
-void QEglFSBackingStore::beginPaint(const QRegion &rgn)
-{
- m_dirty |= rgn;
-}
-
-void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents)
-{
- Q_UNUSED(staticContents);
-
- QEglFSWindow *rootWin = m_window->screen()->rootWindow();
- if (!rootWin || !rootWin->isRaster())
- return;
-
- m_image = QImage(size, QImage::Format_RGB32);
- m_window->create();
-
- rootWin->screen()->rootContext()->makeCurrent(rootWin->window());
- initializeOpenGLFunctions();
-
- 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/eglfs/qeglfscompositor.cpp b/src/plugins/platforms/eglfs/qeglfscompositor.cpp
deleted file mode 100644
index 845bb5b3b5..0000000000
--- a/src/plugins/platforms/eglfs/qeglfscompositor.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 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 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglfscompositor.h"
-#include "qeglfswindow.h"
-#include "qeglfscontext.h"
-
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLShaderProgram>
-#include <QtGui/QOpenGLFramebufferObject>
-
-QT_BEGIN_NAMESPACE
-
-static QEglFSCompositor *compositor = 0;
-
-QEglFSCompositor::QEglFSCompositor()
- : m_screen(0),
- m_program(0),
- m_initialized(false)
-{
- Q_ASSERT(!compositor);
- m_updateTimer.setSingleShot(true);
- m_updateTimer.setInterval(0);
- connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
-}
-
-QEglFSCompositor::~QEglFSCompositor()
-{
- Q_ASSERT(compositor == this);
- delete m_program;
- compositor = 0;
-}
-
-void QEglFSCompositor::schedule(QEglFSScreen *screen)
-{
- m_screen = screen;
- if (!m_updateTimer.isActive())
- m_updateTimer.start();
-}
-
-void QEglFSCompositor::renderAll()
-{
- QEglFSWindow *rootWin = m_screen->rootWindow();
- if (!rootWin)
- return;
-
- Q_ASSERT(rootWin->hasNativeWindow());
- QOpenGLContext *context = m_screen->rootContext();
- Q_ASSERT(context);
-
- context->makeCurrent(rootWin->window());
- if (!m_initialized) {
- initializeOpenGLFunctions();
- m_initialized = true;
- }
- ensureProgram();
- m_program->bind();
-
- QList<QEglFSWindow *> windows = m_screen->windows();
- for (int i = 0; i < windows.size(); ++i) {
- QEglFSWindow *window = windows.at(i);
- uint texture = window->texture();
- if (texture)
- render(window, texture, window->isRaster());
- }
-
- m_program->release();
- context->swapBuffers(rootWin->window());
-}
-
-void QEglFSCompositor::ensureProgram()
-{
- 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"
- "uniform bool isRaster;\n"
- "void main() {\n"
- " lowp vec4 c = texture2D(texture, textureCoord);\n"
- " gl_FragColor = isRaster ? c.bgra : c.rgba;\n"
- "}\n";
-
- m_program = new QOpenGLShaderProgram;
-
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- m_program->link();
-
- m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
- m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
- m_isRasterEntry = m_program->uniformLocation("isRaster");
- }
-}
-
-void QEglFSCompositor::render(QEglFSWindow *window, uint texture, bool raster)
-{
- const GLfloat textureCoordinates[] = {
- 0, 0,
- 1, 0,
- 1, 1,
- 0, 1
- };
-
- QRectF sr = window->screen()->geometry();
- QRect r = window->window()->geometry();
- QPoint tl = r.topLeft();
- QPoint br = r.bottomRight();
-
- GLfloat x1 = (tl.x() / sr.width()) * 2 - 1;
- GLfloat x2 = (br.x() / sr.width()) * 2 - 1;
- GLfloat y1 = ((sr.height() - tl.y()) / sr.height()) * 2 - 1;
- GLfloat y2 = ((sr.height() - br.y()) / sr.height()) * 2 - 1;
-
- if (!raster)
- qSwap(y1, y2);
-
- const GLfloat vertexCoordinates[] = {
- x1, y1,
- x2, y1,
- x2, y2,
- x1, y2
- };
-
- glViewport(0, 0, sr.width(), sr.height());
-
- glEnableVertexAttribArray(m_vertexCoordEntry);
- glEnableVertexAttribArray(m_textureCoordEntry);
-
- glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
- glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- m_program->setUniformValue(m_isRasterEntry, raster);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(m_vertexCoordEntry);
- glDisableVertexAttribArray(m_textureCoordEntry);
-}
-
-QEglFSCompositor *QEglFSCompositor::instance()
-{
- if (!compositor)
- compositor = new QEglFSCompositor;
- return compositor;
-}
-
-void QEglFSCompositor::destroy()
-{
- delete compositor;
- compositor = 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp
index 2c6846132d..86ceb0721b 100644
--- a/src/plugins/platforms/eglfs/qeglfscontext.cpp
+++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp
@@ -41,11 +41,12 @@
#include "qeglfscontext.h"
#include "qeglfswindow.h"
-#include "qeglfscursor.h"
#include "qeglfshooks.h"
#include "qeglfsintegration.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtGui/QSurface>
#include <QtDebug>
@@ -54,31 +55,10 @@ QT_BEGIN_NAMESPACE
QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
EGLDisplay display, EGLenum eglApi)
: QEGLPlatformContext(QEglFSHooks::hooks()->surfaceFormatFor(format), share, display,
- QEglFSIntegration::chooseConfig(display, QEglFSHooks::hooks()->surfaceFormatFor(format)), eglApi),
- m_swapIntervalSet(false)
+ QEglFSIntegration::chooseConfig(display, QEglFSHooks::hooks()->surfaceFormatFor(format)), eglApi)
{
}
-bool QEglFSContext::makeCurrent(QPlatformSurface *surface)
-{
- bool success = QEGLPlatformContext::makeCurrent(surface);
-
- if (success && !m_swapIntervalSet) {
- m_swapIntervalSet = true;
- int swapInterval = 1;
- QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
- if (!swapIntervalString.isEmpty()) {
- bool ok;
- swapInterval = swapIntervalString.toInt(&ok);
- if (!ok)
- swapInterval = 1;
- }
- eglSwapInterval(eglDisplay(), swapInterval);
- }
-
- return success;
-}
-
EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
if (surface->surface()->surfaceClass() == QSurface::Window)
@@ -89,10 +69,10 @@ EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface
void QEglFSContext::swapBuffers(QPlatformSurface *surface)
{
+ // draw the cursor
if (surface->surface()->surfaceClass() == QSurface::Window) {
- QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
- // draw the cursor
- if (QEglFSCursor *cursor = static_cast<QEglFSCursor *>(window->screen()->cursor()))
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ if (QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(window->screen()->cursor()))
cursor->paintOnScreen();
}
@@ -101,4 +81,3 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface)
}
QT_END_NAMESPACE
-
diff --git a/src/plugins/platforms/eglfs/qeglfscontext.h b/src/plugins/platforms/eglfs/qeglfscontext.h
index 8db340252c..22a7c67e46 100644
--- a/src/plugins/platforms/eglfs/qeglfscontext.h
+++ b/src/plugins/platforms/eglfs/qeglfscontext.h
@@ -42,7 +42,6 @@
#ifndef QEGLFSCONTEXT_H
#define QEGLFSCONTEXT_H
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
@@ -52,12 +51,8 @@ class QEglFSContext : public QEGLPlatformContext
public:
QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLenum eglApi = EGL_OPENGL_ES_API);
- bool makeCurrent(QPlatformSurface *surface);
- EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
- void swapBuffers(QPlatformSurface *surface);
-
-private:
- bool m_swapIntervalSet;
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp
deleted file mode 100644
index 0066426769..0000000000
--- a/src/plugins/platforms/eglfs/qeglfscursor.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 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 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglfscursor.h"
-#include <qpa/qwindowsysteminterface.h>
-#include <QtGui/QOpenGLContext>
-#include <QtCore/QJsonDocument>
-#include <QtCore/QJsonArray>
-#include <QtCore/QJsonObject>
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-QEglFSCursor::QEglFSCursor(QEglFSScreen *screen)
- : m_screen(screen), m_program(0), m_vertexCoordEntry(0), m_textureCoordEntry(0), m_textureEntry(0)
-{
- initCursorAtlas();
-
- // initialize the cursor
-#ifndef QT_NO_CURSOR
- QCursor cursor(Qt::ArrowCursor);
- setCurrentCursor(&cursor);
-#endif
-}
-
-QEglFSCursor::~QEglFSCursor()
-{
- resetResources();
-}
-
-void QEglFSCursor::resetResources()
-{
- if (QOpenGLContext::currentContext()) {
- glDeleteProgram(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;
-}
-
-GLuint QEglFSCursor::createShader(GLenum shaderType, const char *program)
-{
- GLuint shader = glCreateShader(shaderType);
- glShaderSource(shader, 1 /* count */, &program, NULL /* lengths */);
- glCompileShader(shader);
- GLint status;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- if (status == GL_TRUE)
- return shader;
-
- GLint length;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
- char *infoLog = new char[length];
- glGetShaderInfoLog(shader, length, NULL, infoLog);
- qDebug("%s shader compilation error: %s", shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment", infoLog);
- delete [] infoLog;
- return 0;
-}
-
-GLuint QEglFSCursor::createProgram(GLuint vshader, GLuint fshader)
-{
- GLuint program = glCreateProgram();
- glAttachShader(program, vshader);
- glAttachShader(program, fshader);
- glLinkProgram(program);
- GLint status;
- glGetProgramiv(program, GL_LINK_STATUS, &status);
- if (status == GL_TRUE)
- return program;
-
- GLint length;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
- char *infoLog = new char[length];
- glGetProgramInfoLog(program, length, NULL, infoLog);
- qDebug("program link error: %s", infoLog);
- delete [] infoLog;
- return 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";
-
- GLuint vertexShader = createShader(GL_VERTEX_SHADER, textureVertexProgram);
- GLuint fragmentShader = createShader(GL_FRAGMENT_SHADER, textureFragmentProgram);
- m_program = createProgram(vertexShader, fragmentShader);
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
-
- m_vertexCoordEntry = glGetAttribLocation(m_program, "vertexCoordEntry");
- m_textureCoordEntry = glGetAttribLocation(m_program, "textureCoordEntry");
- m_textureEntry = glGetUniformLocation(m_program, "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(json);
- file.open(QFile::ReadOnly);
- QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
- QJsonObject object = doc.object();
-
- QString atlas = object.value("image").toString();
- Q_ASSERT(!atlas.isEmpty());
-
- const int cursorsPerRow = object.value("cursorsPerRow").toDouble();
- Q_ASSERT(cursorsPerRow);
- m_cursorAtlas.cursorsPerRow = cursorsPerRow;
-
- const QJsonArray hotSpots = object.value("hotSpots").toArray();
- Q_ASSERT(hotSpots.count() == Qt::LastCursor);
- 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 - 1) / 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)
-{
- 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
-
-void QEglFSCursor::update(const QRegion &rgn)
-{
- QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(m_cursor.pos), rgn);
- QWindowSystemInterface::flushWindowSystemEvents();
-}
-
-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)
-{
- const QRect oldCursorRect = cursorRect();
- m_cursor.pos = pos;
- update(oldCursorRect | cursorRect());
-}
-
-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());
-}
-
-void QEglFSCursor::paintOnScreen()
-{
- 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);
-}
-
-void QEglFSCursor::draw(const QRectF &r)
-{
- 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);
-
- glUseProgram(m_program);
-
- 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
- };
-
- glBindTexture(GL_TEXTURE_2D, m_cursor.texture);
-
- glEnableVertexAttribArray(m_vertexCoordEntry);
- glEnableVertexAttribArray(m_textureCoordEntry);
-
- glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, cursorCoordinates);
- glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
-
- glUniform1i(m_textureEntry, 0);
-
- 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);
- glDisable(GL_BLEND);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(m_vertexCoordEntry);
- glDisableVertexAttribArray(m_textureCoordEntry);
-
- glUseProgram(0);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.h b/src/plugins/platforms/eglfs/qeglfscursor.h
deleted file mode 100644
index 71ff73b8f3..0000000000
--- a/src/plugins/platforms/eglfs/qeglfscursor.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 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 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEGLFSCURSOR_H
-#define QEGLFSCURSOR_H
-
-#include <qpa/qplatformcursor.h>
-#include <QtGui/QOpenGLFunctions>
-#include "qeglfsscreen.h"
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLShaderProgram;
-class QEglFSScreen;
-
-class QEglFSCursor : public QPlatformCursor, public QOpenGLFunctions
-{
-public:
- QEglFSCursor(QEglFSScreen *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;
-
- virtual void paintOnScreen();
-
- void resetResources();
-
-protected:
-#ifndef QT_NO_CURSOR
- bool setCurrentCursor(QCursor *cursor);
-#endif
- void draw(const QRectF &rect);
- void update(const QRegion &region);
-
- GLuint createShader(GLenum shaderType, const char *program);
- GLuint createProgram(GLuint vshader, GLuint fshader);
-
- QEglFSScreen *m_screen;
-
- // 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;
-
-private:
- void createShaderPrograms();
- static void createCursorTexture(uint *texture, const QImage &image);
- void initCursorAtlas();
-
- // 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 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;
-
- GLuint m_program;
- int m_vertexCoordEntry;
- int m_textureCoordEntry;
- int m_textureEntry;
-};
-
-QT_END_NAMESPACE
-
-#endif // QEGLFSCURSOR_H
-
diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h
index 0251e27f96..67f4d1803d 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks.h
+++ b/src/plugins/platforms/eglfs/qeglfshooks.h
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
-class QEglFSCursor;
+class QEGLPlatformCursor;
class QEglFSScreen;
class QEglFSHooks
@@ -73,7 +73,7 @@ public:
const QSurfaceFormat &format);
virtual void destroyNativeWindow(EGLNativeWindowType window);
virtual bool hasCapability(QPlatformIntegration::Capability cap) const;
- virtual QEglFSCursor *createCursor(QEglFSScreen *screen) const;
+ virtual QEGLPlatformCursor *createCursor(QPlatformScreen *screen) const;
virtual bool filterConfig(EGLDisplay display, EGLConfig config) const;
virtual void waitForVSync() const;
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
index 4368f37e50..dbfd8d99dc 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
@@ -40,7 +40,8 @@
****************************************************************************/
#include "qeglfshooks.h"
-#include "qeglfscursor.h"
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtCore/QRegularExpression>
#include <fcntl.h>
@@ -48,7 +49,6 @@
#include <linux/fb.h>
#include <sys/ioctl.h>
-#include <private/qmath_p.h>
#include <private/qcore_unix_p.h>
QT_BEGIN_NAMESPACE
@@ -100,105 +100,12 @@ EGLNativeDisplayType QEglFSHooks::platformDisplay() const
QSizeF QEglFSHooks::physicalScreenSize() const
{
- static QSizeF size;
- if (size.isEmpty()) {
-
- // Note: in millimeters
- int width = qgetenv("QT_QPA_EGLFS_PHYSICAL_WIDTH").toInt();
- int height = qgetenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT").toInt();
-
- if (width && height) {
- // no need to read fb0
- size.setWidth(width);
- size.setHeight(height);
- return size;
- }
-
- struct fb_var_screeninfo vinfo;
- int w = -1;
- int h = -1;
- QSize screenResolution;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) {
- qWarning("EGLFS: Could not query variable screen info.");
- } else {
- w = vinfo.width;
- h = vinfo.height;
- screenResolution = QSize(vinfo.xres, vinfo.yres);
- }
- } else {
- screenResolution = screenSize();
- }
-
- const int defaultPhysicalDpi = 100;
- size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w));
- size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h));
-
- if (w <= 0 || h <= 0) {
- qWarning("EGLFS: Unable to query physical screen size, defaulting to %d dpi.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH "
- "and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).",
- defaultPhysicalDpi);
- }
-
- // override fb0 from environment var setting
- if (width)
- size.setWidth(width);
- if (height)
- size.setWidth(height);
- }
- return size;
+ return q_physicalScreenSizeFromFb(framebuffer, screenSize());
}
QSize QEglFSHooks::screenSize() const
{
- static QSize size;
-
- if (size.isEmpty()) {
- int width = qgetenv("QT_QPA_EGLFS_WIDTH").toInt();
- int height = qgetenv("QT_QPA_EGLFS_HEIGHT").toInt();
-
- if (width && height) {
- // no need to read fb0
- size.setWidth(width);
- size.setHeight(height);
- return size;
- }
-
- struct fb_var_screeninfo vinfo;
-
- int xres = -1;
- int yres = -1;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) {
- qWarning("EGLFS: Could not query variable screen info.");
- } else {
- xres = vinfo.xres;
- yres = vinfo.yres;
- }
- }
-
- const int defaultWidth = 800;
- const int defaultHeight = 600;
- size.setWidth(xres <= 0 ? defaultWidth : xres);
- size.setHeight(yres <= 0 ? defaultHeight : yres);
-
- if (xres <= 0 || yres <= 0) {
- qWarning("EGLFS: Unable to query screen resolution, defaulting to %dx%d.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_WIDTH and QT_QPA_EGLFS_HEIGHT.",
- defaultWidth, defaultHeight);
- }
-
- // override fb0 from environment var setting
- if (width)
- size.setWidth(width);
- if (height)
- size.setHeight(height);
- }
-
- return size;
+ return q_screenSizeFromFb(framebuffer);
}
QDpi QEglFSHooks::logicalDpi() const
@@ -222,29 +129,7 @@ Qt::ScreenOrientation QEglFSHooks::orientation() const
int QEglFSHooks::screenDepth() const
{
- static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt();
-
- if (depth == 0) {
- struct fb_var_screeninfo vinfo;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1)
- qWarning("EGLFS: Could not query variable screen info.");
- else
- depth = vinfo.bits_per_pixel;
- }
-
- const int defaultDepth = 32;
-
- if (depth <= 0) {
- depth = defaultDepth;
-
- qWarning("EGLFS: Unable to query screen depth, defaulting to %d.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_DEPTH.", defaultDepth);
- }
- }
-
- return depth;
+ return q_screenDepthFromFb(framebuffer);
}
QImage::Format QEglFSHooks::screenFormat() const
@@ -283,9 +168,9 @@ bool QEglFSHooks::hasCapability(QPlatformIntegration::Capability cap) const
return false;
}
-QEglFSCursor *QEglFSHooks::createCursor(QEglFSScreen *screen) const
+QEGLPlatformCursor *QEglFSHooks::createCursor(QPlatformScreen *screen) const
{
- return new QEglFSCursor(screen);
+ return new QEGLPlatformCursor(screen);
}
void QEglFSHooks::waitForVSync() const
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index d6832493f1..472e58cc72 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -42,25 +42,15 @@
#include "qeglfsintegration.h"
#include "qeglfswindow.h"
-#include "qeglfsbackingstore.h"
-#include "qeglfscompositor.h"
#include "qeglfshooks.h"
+#include "qeglfscontext.h"
#include <QtGui/private/qguiapplication_p.h>
-#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#include <QtPlatformSupport/private/qgenericunixservices_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
-#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/qevdevtouch_p.h>
-#endif
-
#include <qpa/qplatformwindow.h>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QOpenGLContext>
@@ -68,10 +58,6 @@
#include <QtGui/QOffscreenSurface>
#include <qpa/qplatformcursor.h>
-#include <qpa/qplatforminputcontextfactory_p.h>
-
-#include "qeglfscontext.h"
-
#include <EGL/egl.h>
static void initResources()
@@ -82,10 +68,6 @@ static void initResources()
QT_BEGIN_NAMESPACE
QEglFSIntegration::QEglFSIntegration()
- : mFontDb(new QGenericUnixFontDatabase)
- , mServices(new QGenericUnixServices)
- , mScreen(0)
- , mInputContext(0)
{
mDisableInputHandlers = qgetenv("QT_QPA_EGLFS_DISABLE_INPUT").toInt();
@@ -94,9 +76,6 @@ QEglFSIntegration::QEglFSIntegration()
QEglFSIntegration::~QEglFSIntegration()
{
- QEglFSCompositor::destroy();
- delete mScreen;
- eglTerminate(mDisplay);
QEglFSHooks::hooks()->platformDestroy();
}
@@ -106,33 +85,12 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
if (QEglFSHooks::hooks() && QEglFSHooks::hooks()->hasCapability(cap))
return true;
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return true;
- case ThreadedOpenGL: return true;
- case WindowManagement: return false;
- default: return QPlatformIntegration::hasCapability(cap);
- }
-}
-
-QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
-{
- QWindowSystemInterface::flushWindowSystemEvents();
- QEglFSWindow *w = new QEglFSWindow(window);
- w->create();
- if (window->type() != Qt::ToolTip)
- w->requestActivateWindow();
- return w;
-}
-
-QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
-{
- return new QEglFSBackingStore(window);
+ return QEGLPlatformIntegration::hasCapability(cap);
}
QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay);
+ return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(context->format()), context->shareHandle(), display());
}
QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
@@ -141,164 +99,40 @@ QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOf
return new QEGLPbuffer(screen->display(), QEglFSHooks::hooks()->surfaceFormatFor(surface->requestedFormat()), surface);
}
-QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
-{
- return mFontDb.data();
-}
-
-QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-
void QEglFSIntegration::initialize()
{
QEglFSHooks::hooks()->platformInit();
- EGLint major, minor;
-
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
- qWarning("Could not bind GL_ES API\n");
- qFatal("EGL error");
- }
-
- mDisplay = eglGetDisplay(QEglFSHooks::hooks() ? QEglFSHooks::hooks()->platformDisplay() : EGL_DEFAULT_DISPLAY);
- if (mDisplay == EGL_NO_DISPLAY) {
- qWarning("Could not open egl display\n");
- qFatal("EGL error");
- }
-
- if (!eglInitialize(mDisplay, &major, &minor)) {
- qWarning("Could not initialize egl display\n");
- qFatal("EGL error");
- }
-
- mScreen = createScreen();
- screenAdded(mScreen);
-
- mInputContext = QPlatformInputContextFactory::create();
+ QEGLPlatformIntegration::initialize();
if (!mDisableInputHandlers)
createInputHandlers();
}
-QEglFSScreen *QEglFSIntegration::createScreen() const
-{
- return new QEglFSScreen(mDisplay);
-}
-
-QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
-{
- switch (hint)
- {
- case QPlatformIntegration::ShowIsFullScreen:
- return mScreen->rootWindow() == 0;
- default:
- return QPlatformIntegration::styleHint(hint);
- }
-}
-
-QPlatformServices *QEglFSIntegration::services() const
+EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const
{
- return mServices.data();
+ return QEglFSHooks::hooks()->platformDisplay();
}
-QPlatformNativeInterface *QEglFSIntegration::nativeInterface() const
+QEGLPlatformScreen *QEglFSIntegration::createScreen() const
{
- return const_cast<QEglFSIntegration *>(this);
+ return new QEglFSScreen(display());
}
-enum ResourceType {
- EglDisplay,
- EglWindow,
- EglContext
-};
-
-static int resourceType(const QByteArray &key)
+QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const
{
- static const QByteArray names[] = { // match ResourceType
- QByteArrayLiteral("egldisplay"),
- QByteArrayLiteral("eglwindow"),
- QByteArrayLiteral("eglcontext")
- };
- 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);
+ return new QEglFSWindow(window);
}
-void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglDisplay:
- result = mScreen->display();
- 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 = mScreen->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)
+QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglContext:
- if (context->handle())
- result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext();
- break;
+ switch (hint)
+ {
+ case QPlatformIntegration::ShowIsFullScreen:
+ return screen()->compositingWindow() == 0;
default:
- break;
+ return QPlatformIntegration::styleHint(hint);
}
-
- return result;
-}
-
-static void *eglContextForContext(QOpenGLContext *context)
-{
- Q_ASSERT(context);
-
- QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(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;
}
EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
@@ -326,13 +160,4 @@ EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceForm
return chooser.chooseConfig();
}
-void QEglFSIntegration::createInputHandlers()
-{
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
- new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
- new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
-#endif
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index 12c8158bd1..9ff5bd6f3b 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -42,61 +42,34 @@
#ifndef QEGLFSINTEGRATION_H
#define QEGLFSINTEGRATION_H
-#include "qeglfsscreen.h"
-
-#include <qpa/qplatformintegration.h>
-#include <qpa/qplatformnativeinterface.h>
+#include <QtPlatformSupport/private/qeglplatformintegration_p.h>
#include <qpa/qplatformscreen.h>
+#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
-class QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface
+class QEglFSIntegration : public QEGLPlatformIntegration
{
public:
QEglFSIntegration();
~QEglFSIntegration();
- bool hasCapability(QPlatformIntegration::Capability cap) const;
-
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
- QPlatformNativeInterface *nativeInterface() const;
-
- QPlatformFontDatabase *fontDatabase() const;
- QPlatformServices *services() const;
-
- QAbstractEventDispatcher *createEventDispatcher() const;
- void initialize();
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
- QVariant styleHint(QPlatformIntegration::StyleHint hint) const;
+ void initialize() Q_DECL_OVERRIDE;
- // QPlatformNativeInterface
- void *nativeResourceForIntegration(const QByteArray &resource);
- void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
- void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ QVariant styleHint(QPlatformIntegration::StyleHint hint) const Q_DECL_OVERRIDE;
- NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
-
- QPlatformScreen *screen() const { return mScreen; }
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format);
- EGLDisplay display() const { return mDisplay; }
-
- QPlatformInputContext *inputContext() const { return mInputContext; }
-
protected:
- virtual QEglFSScreen *createScreen() const;
+ QEGLPlatformScreen *createScreen() const Q_DECL_OVERRIDE;
+ QEGLPlatformWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
private:
- void createInputHandlers();
-
- EGLDisplay mDisplay;
- QScopedPointer<QPlatformFontDatabase> mFontDb;
- QScopedPointer<QPlatformServices> mServices;
- QEglFSScreen *mScreen;
- QPlatformInputContext *mInputContext;
bool mDisableInputHandlers;
};
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 758b461b3f..11c1160ce9 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -39,39 +39,25 @@
**
****************************************************************************/
-#include "qeglfscursor.h"
#include "qeglfsscreen.h"
#include "qeglfswindow.h"
#include "qeglfshooks.h"
-
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
-#include <QtPlatformSupport/private/qdevicediscovery_p.h>
-#endif
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
- : m_dpy(dpy),
+ : QEGLPlatformScreen(dpy),
m_surface(EGL_NO_SURFACE),
m_cursor(0),
+ m_rootWindow(0),
m_rootContext(0)
{
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglScreen %p\n", this);
#endif
- QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
- bool hideCursor = false;
- if (hideCursorVal.isEmpty()) {
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse));
- hideCursor = dis->scanConnectedDevices().isEmpty();
-#endif
- } else {
- hideCursor = hideCursorVal.toInt() != 0;
- }
- if (!hideCursor)
- m_cursor = QEglFSHooks::hooks()->createCursor(this);
+ m_cursor = QEglFSHooks::hooks()->createCursor(this);
}
QEglFSScreen::~QEglFSScreen()
@@ -124,50 +110,4 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface)
m_surface = surface;
}
-void QEglFSScreen::addWindow(QEglFSWindow *window)
-{
- if (!m_windows.contains(window)) {
- m_windows.append(window);
- topWindowChanged(window);
- }
-}
-
-void QEglFSScreen::removeWindow(QEglFSWindow *window)
-{
- m_windows.removeOne(window);
- if (!m_windows.isEmpty())
- topWindowChanged(m_windows.last());
-}
-
-void QEglFSScreen::moveToTop(QEglFSWindow *window)
-{
- m_windows.removeOne(window);
- m_windows.append(window);
- topWindowChanged(window);
-}
-
-void QEglFSScreen::changeWindowIndex(QEglFSWindow *window, int newIdx)
-{
- int idx = m_windows.indexOf(window);
- if (idx != -1 && idx != newIdx) {
- m_windows.move(idx, newIdx);
- if (newIdx == m_windows.size() - 1)
- topWindowChanged(m_windows.last());
- }
-}
-
-QEglFSWindow *QEglFSScreen::rootWindow()
-{
- Q_FOREACH (QEglFSWindow *window, m_windows) {
- if (window->hasNativeWindow())
- return window;
- }
- return 0;
-}
-
-void QEglFSScreen::topWindowChanged(QPlatformWindow *window)
-{
- Q_UNUSED(window);
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 11d66b7e0f..13f7cfddd8 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -42,7 +42,7 @@
#ifndef QEGLFSSCREEN_H
#define QEGLFSSCREEN_H
-#include <qpa/qplatformscreen.h>
+#include <QtPlatformSupport/private/qeglplatformscreen_p.h>
#include <QtCore/QTextStream>
@@ -50,52 +50,48 @@
QT_BEGIN_NAMESPACE
-class QEglFSCursor;
+class QEGLPlatformCursor;
class QEglFSWindow;
class QOpenGLContext;
-class QEglFSScreen : public QPlatformScreen
+class QEglFSScreen : public QEGLPlatformScreen
{
public:
QEglFSScreen(EGLDisplay display);
~QEglFSScreen();
- QRect geometry() const;
- int depth() const;
- QImage::Format format() const;
+ QRect geometry() const Q_DECL_OVERRIDE;
+ int depth() const Q_DECL_OVERRIDE;
+ QImage::Format format() const Q_DECL_OVERRIDE;
- QSizeF physicalSize() const;
- QDpi logicalDpi() const;
- Qt::ScreenOrientation nativeOrientation() const;
- Qt::ScreenOrientation orientation() const;
+ QSizeF physicalSize() const Q_DECL_OVERRIDE;
+ QDpi logicalDpi() const Q_DECL_OVERRIDE;
+ Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE;
+ Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
- QPlatformCursor *cursor() const;
+ QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
- EGLDisplay display() const { return m_dpy; }
EGLSurface primarySurface() const { return m_surface; }
- QList<QEglFSWindow *> windows() const { return m_windows; }
- void addWindow(QEglFSWindow *window);
- void removeWindow(QEglFSWindow *window);
- void moveToTop(QEglFSWindow *window);
- void changeWindowIndex(QEglFSWindow *window, int newIdx);
- QEglFSWindow *rootWindow();
- QOpenGLContext *rootContext() { return m_rootContext; }
+ QEGLPlatformWindow *compositingWindow() Q_DECL_OVERRIDE { return m_rootWindow; }
+ QOpenGLContext *compositingContext() Q_DECL_OVERRIDE { return m_rootContext; }
+
+ void setRootWindow(QEGLPlatformWindow *window) { m_rootWindow = window; }
void setRootContext(QOpenGLContext *context) { m_rootContext = context; }
protected:
void setPrimarySurface(EGLSurface surface);
- virtual void topWindowChanged(QPlatformWindow *window);
private:
friend class QEglFSWindow;
EGLDisplay m_dpy;
EGLSurface m_surface;
- QEglFSCursor *m_cursor;
- QList<QEglFSWindow *> m_windows;
+ QEGLPlatformCursor *m_cursor;
+ QEGLPlatformWindow *m_rootWindow;
QOpenGLContext *m_rootContext;
};
QT_END_NAMESPACE
+
#endif // QEGLFSSCREEN_H
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index bba00da128..279e7bbc91 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -41,13 +41,11 @@
#include "qeglfswindow.h"
#include "qeglfshooks.h"
-#include "qeglfscursor.h"
-#include "qeglfsbackingstore.h"
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
#include <QtGui/QOpenGLContext>
-
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtDebug>
@@ -55,11 +53,9 @@
QT_BEGIN_NAMESPACE
QEglFSWindow::QEglFSWindow(QWindow *w)
- : QPlatformWindow(w)
+ : QEGLPlatformWindow(w)
, m_surface(0)
, m_window(0)
- , m_wid(0)
- , m_backingStore(0)
, m_flags(0)
{
#ifdef QEGL_EXTRA_DEBUG
@@ -72,41 +68,24 @@ QEglFSWindow::~QEglFSWindow()
destroy();
}
-static WId newWId()
-{
- static WId id = 0;
-
- if (id == std::numeric_limits<WId>::max())
- qWarning("EGLFS: Out of window IDs");
-
- return ++id;
-}
-
void QEglFSWindow::create()
{
if (m_flags.testFlag(Created))
return;
+ QEGLPlatformWindow::create();
+
m_flags = Created;
- m_wid = newWId();
- if (window()->type() == Qt::Desktop) {
- QRect rect(QPoint(), QEglFSHooks::hooks()->screenSize());
- QPlatformWindow::setGeometry(rect);
- QWindowSystemInterface::handleGeometryChange(window(), rect);
+ if (window()->type() == Qt::Desktop)
return;
- }
-
- // Save the original surface type before changing to OpenGLSurface.
- if (window()->surfaceType() == QSurface::RasterSurface)
- m_flags |= IsRaster;
// Stop if there is already a window backed by a native window and surface. Additional
// raster windows will not have their own native window, surface and context. Instead,
// they will be composited onto the root window's surface.
QEglFSScreen *screen = this->screen();
if (screen->primarySurface() != EGL_NO_SURFACE) {
- if (m_flags.testFlag(IsRaster) && screen->rootWindow()->m_flags.testFlag(IsRaster))
+ if (isRaster() && screen->compositingWindow())
return;
#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)
@@ -118,7 +97,6 @@ void QEglFSWindow::create()
return;
}
- window()->setSurfaceType(QSurface::OpenGLSurface);
m_flags |= HasNativeWindow;
setGeometry(QRect()); // will become fullscreen
QWindowSystemInterface::handleExposeEvent(window(), geometry());
@@ -126,18 +104,19 @@ void QEglFSWindow::create()
EGLDisplay display = static_cast<QEglFSScreen *>(screen)->display();
QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat());
m_config = QEglFSIntegration::chooseConfig(display, platformFormat);
- m_format = q_glFormatFromConfig(display, m_config);
+ m_format = q_glFormatFromConfig(display, m_config, platformFormat);
resetSurface();
screen->setPrimarySurface(m_surface);
- if (m_flags.testFlag(IsRaster)) {
+ if (isRaster()) {
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
context->setFormat(window()->requestedFormat());
context->setScreen(window()->screen());
context->create();
screen->setRootContext(context);
+ screen->setRootWindow(this);
}
}
@@ -145,7 +124,7 @@ void QEglFSWindow::destroy()
{
QEglFSScreen *screen = this->screen();
if (m_flags.testFlag(HasNativeWindow)) {
- QEglFSCursor *cursor = static_cast<QEglFSCursor *>(screen->cursor());
+ QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(screen->cursor());
if (cursor)
cursor->resetResources();
@@ -188,7 +167,7 @@ void QEglFSWindow::resetSurface()
void QEglFSWindow::setVisible(bool visible)
{
- QList<QEglFSWindow *> windows = screen()->windows();
+ QList<QEGLPlatformWindow *> windows = screen()->windows();
if (window()->type() != Qt::Desktop) {
if (visible) {
@@ -234,11 +213,6 @@ QRect QEglFSWindow::geometry() const
return QPlatformWindow::geometry();
}
-WId QEglFSWindow::winId() const
-{
- return m_wid;
-}
-
void QEglFSWindow::requestActivateWindow()
{
if (window()->type() != Qt::Desktop)
@@ -258,7 +232,7 @@ void QEglFSWindow::raise()
void QEglFSWindow::lower()
{
- QList<QEglFSWindow *> windows = screen()->windows();
+ QList<QEGLPlatformWindow *> windows = screen()->windows();
if (window()->type() != Qt::Desktop && windows.count() > 1) {
int idx = windows.indexOf(this);
if (idx > 0) {
@@ -288,12 +262,4 @@ QEglFSScreen *QEglFSWindow::screen() const
return static_cast<QEglFSScreen *>(QPlatformWindow::screen());
}
-uint QEglFSWindow::texture() const
-{
- if (m_backingStore)
- return m_backingStore->texture();
-
- return 0;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index ee3c194a7c..f93a9d54bc 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -45,42 +45,32 @@
#include "qeglfsintegration.h"
#include "qeglfsscreen.h"
-#include <qpa/qplatformwindow.h>
+#include <QtPlatformSupport/private/qeglplatformwindow_p.h>
QT_BEGIN_NAMESPACE
-class QEglFSBackingStore;
-
-class QEglFSWindow : public QPlatformWindow
+class QEglFSWindow : public QEGLPlatformWindow
{
public:
QEglFSWindow(QWindow *w);
~QEglFSWindow();
- void setGeometry(const QRect &);
- QRect geometry() const;
- WId winId() const;
- void setVisible(bool visible);
- void requestActivateWindow();
- void raise();
- void lower();
+ void create() Q_DECL_OVERRIDE;
+ void destroy();
+
+ void setGeometry(const QRect &) Q_DECL_OVERRIDE;
+ QRect geometry() const Q_DECL_OVERRIDE;
+ void setVisible(bool visible) Q_DECL_OVERRIDE;
+ void requestActivateWindow() Q_DECL_OVERRIDE;
+ void raise() Q_DECL_OVERRIDE;
+ void lower() Q_DECL_OVERRIDE;
+ QSurfaceFormat format() const Q_DECL_OVERRIDE;
+ EGLNativeWindowType eglWindow() const Q_DECL_OVERRIDE;
EGLSurface surface() const;
- QSurfaceFormat format() const;
- EGLNativeWindowType eglWindow() const;
-
QEglFSScreen *screen() const;
- void create();
- void destroy();
-
bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); }
- bool isRaster() const { return m_flags.testFlag(IsRaster); }
-
- QEglFSBackingStore *backingStore() { return m_backingStore; }
- void setBackingStore(QEglFSBackingStore *backingStore) { m_backingStore = backingStore; }
-
- uint texture() const;
virtual void invalidateSurface();
virtual void resetSurface();
@@ -92,13 +82,10 @@ protected:
private:
EGLConfig m_config;
QSurfaceFormat m_format;
- WId m_wid;
- QEglFSBackingStore *m_backingStore;
enum Flag {
Created = 0x01,
- IsRaster = 0x02,
- HasNativeWindow = 0x04
+ HasNativeWindow = 0x02
};
Q_DECLARE_FLAGS(Flags, Flag);
Flags m_flags;
diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro
index 72716e6a4c..1dfb07ba08 100644
--- a/src/plugins/platforms/ios/ios.pro
+++ b/src/plugins/platforms/ios/ios.pro
@@ -38,4 +38,3 @@ HEADERS = \
qiosglobal.h \
qiosservices.h
-#HEADERS = qiossoftwareinputhandler.h
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index 0a6a00b753..2fe679fc20 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -44,6 +44,9 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QWindow>
#include <QtGui/QScreen>
+
+#include <QtGui/private/qwindow_p.h>
+
#include "qiosscreen.h"
#include "qiosglobal.h"
#include "qioswindow.h"
@@ -105,11 +108,10 @@
if (hiddenFromPlist)
return YES;
QWindow *focusWindow = QGuiApplication::focusWindow();
- if (!focusWindow || !focusWindow->handle())
+ if (!focusWindow)
return [UIApplication sharedApplication].statusBarHidden;
- QWindow *topLevel = static_cast<QIOSWindow *>(focusWindow->handle())->topLevelWindow();
- return topLevel->windowState() == Qt::WindowFullScreen;
+ return qt_window_private(focusWindow)->topLevelWindow()->windowState() == Qt::WindowFullScreen;
}
@end
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index 8a5eb589d2..fc99543aa6 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -87,8 +87,6 @@ public:
WId winId() const { return WId(m_view); };
- QWindow *topLevelWindow() const;
-
private:
void applyGeometry(const QRect &rect);
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 7a0ff055ec..15a52e89ec 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -636,23 +636,6 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow)
}
}
-QWindow *QIOSWindow::topLevelWindow() const
-{
- QWindow *window = this->window();
- while (window) {
- QWindow *parent = window->parent();
- if (!parent)
- parent = window->transientParent();
-
- if (!parent)
- break;
-
- window = parent;
- }
-
- return window;
-}
-
void QIOSWindow::requestActivateWindow()
{
// Note that several windows can be active at the same time if they exist in the same
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
index 612a878736..1b3678f13a 100644
--- a/src/plugins/platforms/kms/kms.pro
+++ b/src/plugins/platforms/kms/kms.pro
@@ -21,8 +21,8 @@ SOURCES = main.cpp \
qkmscursor.cpp \
qkmsdevice.cpp \
qkmsbackingstore.cpp \
- qkmsnativeinterface.cpp \
- qkmsvthandler.cpp
+ qkmsnativeinterface.cpp
+
HEADERS = qkmsintegration.h \
qkmsscreen.h \
qkmscontext.h \
@@ -30,8 +30,7 @@ HEADERS = qkmsintegration.h \
qkmscursor.h \
qkmsdevice.h \
qkmsbackingstore.h \
- qkmsnativeinterface.h \
- qkmsvthandler.h
+ qkmsnativeinterface.h
OTHER_FILES += \
kms.json
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
index 80c5887a28..63c6d08bdc 100644
--- a/src/plugins/platforms/kms/qkmsintegration.cpp
+++ b/src/plugins/platforms/kms/qkmsintegration.cpp
@@ -46,7 +46,6 @@
#include "qkmsbackingstore.h"
#include "qkmscontext.h"
#include "qkmsnativeinterface.h"
-#include "qkmsvthandler.h"
#if !defined(QT_NO_EVDEV)
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
@@ -56,6 +55,8 @@
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qfbvthandler_p.h>
+
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
@@ -68,7 +69,7 @@ QKmsIntegration::QKmsIntegration()
m_nativeInterface(new QKmsNativeInterface)
{
setenv("EGL_PLATFORM", "drm",1);
- m_vtHandler = new QKmsVTHandler;
+ m_vtHandler = new QFbVtHandler;
m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_DRM | QDeviceDiscovery::Device_DRM_PrimaryGPU, 0);
if (m_deviceDiscovery) {
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
index 0a626e6bd2..bba4f53d7c 100644
--- a/src/plugins/platforms/kms/qkmsintegration.h
+++ b/src/plugins/platforms/kms/qkmsintegration.h
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
class QKmsScreen;
class QKmsDevice;
-class QKmsVTHandler;
+class QFbVtHandler;
class QKmsIntegration : public QObject, public QPlatformIntegration
{
@@ -85,7 +85,7 @@ private:
QList<QKmsDevice *> m_devices;
QPlatformFontDatabase *m_fontDatabase;
QPlatformNativeInterface *m_nativeInterface;
- QKmsVTHandler *m_vtHandler;
+ QFbVtHandler *m_vtHandler;
QDeviceDiscovery *m_deviceDiscovery;
};
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index 53f48d5480..b1b13e862f 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -43,18 +43,22 @@
#include "qlinuxfbscreen.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/qfbbackingstore_p.h>
#include <QtPlatformSupport/private/qfbwindow_p.h>
#include <QtPlatformSupport/private/qfbcursor_p.h>
#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/private/qpixmap_raster_p.h>
+#include <qpa/qplatforminputcontextfactory_p.h>
QT_BEGIN_NAMESPACE
QLinuxFbIntegration::QLinuxFbIntegration(const QStringList &paramList)
- : m_fontDb(new QGenericUnixFontDatabase())
+ : m_fontDb(new QGenericUnixFontDatabase),
+ m_services(new QGenericUnixServices)
{
m_primaryScreen = new QLinuxFbScreen(paramList);
}
@@ -70,21 +74,21 @@ void QLinuxFbIntegration::initialize()
screenAdded(m_primaryScreen);
else
qWarning("linuxfb: Failed to initialize screen");
+
+ m_inputContext = QPlatformInputContextFactory::create();
+
+ m_vtHandler.reset(new QFbVtHandler);
}
bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case WindowManagement: return false;
default: return QPlatformIntegration::hasCapability(cap);
}
}
-QPlatformPixmap *QLinuxFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
-{
- return new QRasterPlatformPixmap(type);
-}
-
QPlatformBackingStore *QLinuxFbIntegration::createPlatformBackingStore(QWindow *window) const
{
return new QFbBackingStore(window);
@@ -109,7 +113,12 @@ QList<QPlatformScreen *> QLinuxFbIntegration::screens() const
QPlatformFontDatabase *QLinuxFbIntegration::fontDatabase() const
{
- return m_fontDb;
+ return m_fontDb.data();
+}
+
+QPlatformServices *QLinuxFbIntegration::services() const
+{
+ return m_services.data();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index 965a6e4642..67742ecab9 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -46,9 +46,9 @@
QT_BEGIN_NAMESPACE
-class QLinuxFbIntegrationPrivate;
class QAbstractEventDispatcher;
class QLinuxFbScreen;
+class QFbVtHandler;
class QLinuxFbIntegration : public QPlatformIntegration
{
@@ -59,21 +59,25 @@ public:
void initialize() Q_DECL_OVERRIDE;
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
- QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+
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; }
QList<QPlatformScreen *> screens() const;
private:
QLinuxFbScreen *m_primaryScreen;
- QPlatformFontDatabase *m_fontDb;
-
+ QPlatformInputContext *m_inputContext;
+ QScopedPointer<QPlatformFontDatabase> m_fontDb;
+ QScopedPointer<QPlatformServices> m_services;
+ QScopedPointer<QFbVtHandler> m_vtHandler;
};
QT_END_NAMESPACE
#endif // QLINUXFBINTEGRATION_H
-
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index 735a43daf7..c0691a38fc 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -41,6 +41,7 @@
#include "qlinuxfbscreen.h"
#include <QtPlatformSupport/private/qfbcursor_p.h>
+#include <QtCore/QRegularExpression>
#include <QtGui/QPainter>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
@@ -318,11 +319,11 @@ QLinuxFbScreen::~QLinuxFbScreen()
bool QLinuxFbScreen::initialize()
{
- QRegExp ttyRx(QLatin1String("tty=(.*)"));
- QRegExp fbRx(QLatin1String("fb=(.*)"));
- QRegExp mmSizeRx(QLatin1String("mmsize=(\\d+)x(\\d+)"));
- QRegExp sizeRx(QLatin1String("size=(\\d+)x(\\d+)"));
- QRegExp offsetRx(QLatin1String("offset=(\\d+)x(\\d+)"));
+ QRegularExpression ttyRx(QLatin1String("tty=(.*)"));
+ QRegularExpression fbRx(QLatin1String("fb=(.*)"));
+ QRegularExpression mmSizeRx(QLatin1String("mmsize=(\\d+)x(\\d+)"));
+ QRegularExpression sizeRx(QLatin1String("size=(\\d+)x(\\d+)"));
+ QRegularExpression offsetRx(QLatin1String("offset=(\\d+)x(\\d+)"));
QString fbDevice, ttyDevice;
QSize userMmSize;
@@ -331,18 +332,19 @@ bool QLinuxFbScreen::initialize()
// Parse arguments
foreach (const QString &arg, mArgs) {
+ QRegularExpressionMatch match;
if (arg == QLatin1String("nographicsmodeswitch"))
doSwitchToGraphicsMode = false;
- else if (sizeRx.indexIn(arg) != -1)
- userGeometry.setSize(QSize(sizeRx.cap(1).toInt(), sizeRx.cap(2).toInt()));
- else if (offsetRx.indexIn(arg) != -1)
- userGeometry.setTopLeft(QPoint(offsetRx.cap(1).toInt(), offsetRx.cap(2).toInt()));
- else if (ttyRx.indexIn(arg) != -1)
- ttyDevice = ttyRx.cap(1);
- else if (fbRx.indexIn(arg) != -1)
- fbDevice = fbRx.cap(1);
- else if (mmSizeRx.indexIn(arg) != -1)
- userMmSize = QSize(mmSizeRx.cap(1).toInt(), mmSizeRx.cap(2).toInt());
+ else if (arg.contains(sizeRx, &match))
+ userGeometry.setSize(QSize(match.captured(1).toInt(), match.captured(2).toInt()));
+ else if (arg.contains(offsetRx, &match))
+ userGeometry.setTopLeft(QPoint(match.captured(1).toInt(), match.captured(2).toInt()));
+ else if (arg.contains(ttyRx, &match))
+ ttyDevice = match.captured(1);
+ else if (arg.contains(fbRx, &match))
+ fbDevice = match.captured(1);
+ else if (arg.contains(mmSizeRx, &match))
+ userMmSize = QSize(match.captured(1).toInt(), match.captured(2).toInt());
}
if (fbDevice.isEmpty()) {
diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp
index 76b4b5b0eb..7f5c25f239 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.cpp
+++ b/src/plugins/platforms/minimal/qminimalintegration.cpp
@@ -41,17 +41,20 @@
#include "qminimalintegration.h"
#include "qminimalbackingstore.h"
-#ifndef Q_OS_WIN
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#else
-#include <QtCore/private/qeventdispatcher_win_p.h>
-#endif
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformfontdatabase.h>
+#if !defined(Q_OS_WIN)
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#elif defined(Q_OS_WINRT)
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#else
+#include <QtCore/private/qeventdispatcher_win_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
static const char debugBackingStoreEnvironmentVariable[] = "QT_DEBUG_BACKINGSTORE";
@@ -132,7 +135,11 @@ QPlatformBackingStore *QMinimalIntegration::createPlatformBackingStore(QWindow *
QAbstractEventDispatcher *QMinimalIntegration::createEventDispatcher() const
{
#ifdef Q_OS_WIN
+#ifndef Q_OS_WINRT
return new QEventDispatcherWin32;
+#else // !Q_OS_WINRT
+ return new QEventDispatcherWinRT;
+#endif // Q_OS_WINRT
#else
return createUnixEventDispatcher();
#endif
diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
index ebc402550e..d26b20d364 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
+++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
@@ -101,16 +101,6 @@ QMinimalEglScreen::QMinimalEglScreen(EGLNativeDisplayType display)
}
qWarning("Initialized display %d %d\n", major, minor);
-
- int swapInterval = 1;
- QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
- if (!swapIntervalString.isEmpty()) {
- bool ok;
- swapInterval = swapIntervalString.toInt(&ok);
- if (!ok)
- swapInterval = 1;
- }
- eglSwapInterval(m_dpy, swapInterval);
}
QMinimalEglScreen::~QMinimalEglScreen()
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
index a1da8e3a16..76881db6fc 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
@@ -52,7 +52,11 @@
#endif
#elif defined(Q_OS_WIN)
#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
+#ifndef Q_OS_WINRT
#include <QtCore/private/qeventdispatcher_win_p.h>
+#else
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#endif
#endif
#include <QtGui/private/qpixmap_raster_p.h>
@@ -143,7 +147,11 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const
#if defined(Q_OS_UNIX)
return createUnixEventDispatcher();
#elif defined(Q_OS_WIN)
+#ifndef Q_OS_WINRT
return new QOffscreenEventDispatcher<QEventDispatcherWin32>();
+#else // !Q_OS_WINRT
+ return new QOffscreenEventDispatcher<QEventDispatcherWinRT>();
+#endif // Q_OS_WINRT
#else
return 0;
#endif
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 377ca32e64..584efa1665 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -15,7 +15,12 @@ mac {
else: SUBDIRS += cocoa
}
-win32: SUBDIRS += windows
+win32:!winrt: SUBDIRS += windows
+winrt: SUBDIRS += winrt
+
+contains(QT_CONFIG, direct2d) {
+ SUBDIRS += direct2d
+}
qnx {
SUBDIRS += qnx
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index bc7219de5c..c605126091 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -45,7 +45,8 @@ SOURCES = main.cpp \
qqnxabstractvirtualkeyboard.cpp \
qqnxservices.cpp \
qqnxcursor.cpp \
- qqnxrasterwindow.cpp
+ qqnxrasterwindow.cpp \
+ qqnxglobal.cpp
HEADERS = main.h \
qqnxbuffer.h \
@@ -62,7 +63,9 @@ HEADERS = main.h \
qqnxabstractcover.h \
qqnxservices.h \
qqnxcursor.h \
- qqnxrasterwindow.h
+ qqnxrasterwindow.h \
+ qqnxscreeneventfilter.h \
+ qqnxglobal.h
CONFIG(qqnx_screeneventthread) {
DEFINES += QQNX_SCREENEVENTTHREAD
diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
index a42f73415e..800cb96bdf 100644
--- a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
+++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -49,6 +49,7 @@ QQnxAbstractVirtualKeyboard::QQnxAbstractVirtualKeyboard(QObject *parent)
, m_visible(false)
, m_locale(QLocale::system())
, m_keyboardMode(Default)
+ , m_enterKeyType(DefaultReturn)
{
}
@@ -59,26 +60,35 @@ void QQnxAbstractVirtualKeyboard::setKeyboardMode(KeyboardMode mode)
m_keyboardMode = mode;
- applyKeyboardMode(mode);
+ if (m_visible)
+ applyKeyboardOptions();
}
-void QQnxAbstractVirtualKeyboard::setInputHintsFromObject(QObject *focusObject)
+void QQnxAbstractVirtualKeyboard::setEnterKeyType(EnterKeyType type)
{
- if (focusObject) {
- const Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(
- focusObject->property("inputMethodHints").toInt());
- if (hints & Qt::ImhEmailCharactersOnly) {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::Email);
- } else if (hints & Qt::ImhDialableCharactersOnly) {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::Phone);
- } else if (hints & Qt::ImhUrlCharactersOnly) {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::Web);
- } else if (hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhDigitsOnly ||
- hints & Qt::ImhDate || hints & Qt::ImhTime) {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::NumPunc);
- } else {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::Default);
- }
+ if (type == m_enterKeyType)
+ return;
+
+ m_enterKeyType = type;
+
+ if (m_visible)
+ applyKeyboardOptions();
+}
+
+void QQnxAbstractVirtualKeyboard::setInputHints(int inputHints)
+{
+ if (inputHints & Qt::ImhEmailCharactersOnly) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Email);
+ } else if (inputHints & Qt::ImhDialableCharactersOnly) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Phone);
+ } else if (inputHints & Qt::ImhUrlCharactersOnly) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Url);
+ } else if (inputHints & Qt::ImhFormattedNumbersOnly || inputHints & Qt::ImhDigitsOnly) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Number);
+ } else if (inputHints & Qt::ImhDate || inputHints & Qt::ImhTime) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::NumPunc); // Use NumPunc so that : is available.
+ } else if (inputHints & Qt::ImhHiddenText) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Password);
} else {
setKeyboardMode(QQnxAbstractVirtualKeyboard::Default);
}
diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
index 9b911e1dec..bff8c56835 100644
--- a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
+++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -51,18 +51,20 @@ class QQnxAbstractVirtualKeyboard : public QObject
{
Q_OBJECT
public:
- // NOTE: Not all the following keyboard modes are currently used.
+ // Keyboard Types currently supported.
// Default - Regular Keyboard
// Url/Email - Enhanced keys for each types.
// Web - Regular keyboard with two blank keys, currently unused.
// NumPunc - Numbers & Punctionation, alternate to Symbol
+ // Number - Number pad
// Symbol - All symbols, alternate to NumPunc, currently unused.
- // Phone - Phone enhanced keyboard - currently unused as no alternate keyboard available to access a-zA-Z
- // Pin - Keyboard for entering Pins (Hex values) currently unused.
+ // Phone - Phone enhanced keyboard
+ // Pin - Keyboard for entering Pins (Hex values).
+ // Password - Keyboard with lots of extra characters for password input.
+ // Alphanumeric - Similar to password without any of the security implications.
//
- // SPECIAL NOTE: Usage of NumPunc may have to be removed, ABC button is non-functional.
- //
- enum KeyboardMode { Default, Url, Email, Web, NumPunc, Symbol, Phone, Pin };
+ enum KeyboardMode { Default, Url, Email, Web, NumPunc, Number, Symbol, Phone, Pin, Password, Alphanumeric };
+ enum EnterKeyType { DefaultReturn, Connect, Done, Go, Join, Next, Search, Send, Submit };
explicit QQnxAbstractVirtualKeyboard(QObject *parent = 0);
@@ -74,8 +76,11 @@ public:
QLocale locale() const { return m_locale; }
void setKeyboardMode(KeyboardMode mode);
- void setInputHintsFromObject(QObject *focusObject);
+ void setEnterKeyType(EnterKeyType type);
+
+ void setInputHints(int inputHints);
KeyboardMode keyboardMode() const { return m_keyboardMode; }
+ EnterKeyType enterKeyType() const { return m_enterKeyType; }
Q_SIGNALS:
void heightChanged(int height);
@@ -83,7 +88,7 @@ Q_SIGNALS:
void localeChanged(const QLocale &locale);
protected:
- virtual void applyKeyboardMode(KeyboardMode mode) = 0;
+ virtual void applyKeyboardOptions() = 0;
void setHeight(int height);
void setVisible(bool visible);
@@ -94,6 +99,7 @@ private:
bool m_visible;
QLocale m_locale;
KeyboardMode m_keyboardMode;
+ EnterKeyType m_enterKeyType;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxbuffer.cpp b/src/plugins/platforms/qnx/qqnxbuffer.cpp
index abb8a07026..e9afd5232b 100644
--- a/src/plugins/platforms/qnx/qqnxbuffer.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuffer.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxbuffer.h"
#include <QtCore/QDebug>
@@ -66,34 +68,30 @@ QQnxBuffer::QQnxBuffer(screen_buffer_t buffer)
qBufferDebug() << Q_FUNC_INFO << "normal";
// Get size of buffer
- errno = 0;
int size[2];
- int result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_BUFFER_SIZE, size);
- if (result != 0)
- qFatal("QQNX: failed to query buffer size, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_BUFFER_SIZE, size),
+ "Failed to query buffer size");
// Get stride of buffer
- errno = 0;
int stride;
- result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride);
- if (result != 0)
- qFatal("QQNX: failed to query buffer stride, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride),
+ "Failed to query buffer stride");
// Get access to buffer's data
errno = 0;
uchar *dataPtr = 0;
- result = screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, (void **)&dataPtr);
- if (result != 0)
- qFatal("QQNX: failed to query buffer pointer, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(
+ screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, (void **)&dataPtr),
+ "Failed to query buffer pointer");
+
if (dataPtr == 0)
qFatal("QQNX: buffer pointer is NULL, errno=%d", errno);
// Get format of buffer
- errno = 0;
int screenFormat;
- result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_FORMAT, &screenFormat);
- if (result != 0)
- qFatal("QQNX: failed to query buffer format, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_FORMAT, &screenFormat),
+ "Failed to query buffer format");
// Convert screen format to QImage format
QImage::Format imageFormat = QImage::Format_Invalid;
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index 984de67d7d..45a7bab871 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -86,8 +86,9 @@ void QQnxEglWindow::createEGLSurface()
// the window's buffers before we create the EGL surface
const QSize surfaceSize = requestedBufferSize();
if (!surfaceSize.isValid()) {
- qFatal("QQNX: Trying to create 0 size EGL surface. "
+ qWarning("QQNX: Trying to create 0 size EGL surface. "
"Please set a valid window size before calling QOpenGLContext::makeCurrent()");
+ return;
}
setBufferSize(surfaceSize);
@@ -104,8 +105,8 @@ void QQnxEglWindow::createEGLSurface()
, platformOpenGLContext()->getEglConfig(),
(EGLNativeWindowType) nativeHandle(), eglSurfaceAttrs);
if (m_eglSurface == EGL_NO_SURFACE) {
- QQnxGLContext::checkEGLError("eglCreateWindowSurface");
- qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError());
+ const EGLenum error = QQnxGLContext::checkEGLError("eglCreateWindowSurface");
+ qWarning("QQNX: failed to create EGL surface, err=%d", error);
}
}
@@ -141,6 +142,8 @@ void QQnxEglWindow::swapEGLBuffers()
EGLSurface QQnxEglWindow::getSurface()
{
if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
+ const QMutexLocker locker(&m_mutex); //Set geomety must not reset the requestedBufferSize till
+ //the surface is created
if (m_eglSurface != EGL_NO_SURFACE) {
platformOpenGLContext()->doneCurrent();
destroyEGLSurface();
@@ -172,17 +175,9 @@ void QQnxEglWindow::setGeometry(const QRect &rect)
QSize QQnxEglWindow::requestedBufferSize() const
{
- const QMutexLocker locker(&m_mutex);
return m_requestedBufferSize;
}
-void QQnxEglWindow::adjustBufferSize()
-{
- const QSize windowSize = window()->size();
- if (windowSize != bufferSize())
- setBufferSize(windowSize);
-}
-
void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext)
{
// This function does not take ownership of the platform gl context.
@@ -220,7 +215,6 @@ int QQnxEglWindow::pixelFormat() const
void QQnxEglWindow::resetBuffers()
{
- const QMutexLocker locker(&m_mutex);
m_requestedBufferSize = QSize();
}
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h
index fc53afcd7a..a6a223c58e 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.h
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.h
@@ -68,8 +68,6 @@ public:
// Called by QQnxGLContext::createSurface()
QSize requestedBufferSize() const;
- void adjustBufferSize();
-
protected:
int pixelFormat() const;
void resetBuffers();
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 34e8150928..3a365be408 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -132,7 +132,7 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
}
}
- m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs());
+ m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs(format));
if (m_eglContext == EGL_NO_CONTEXT) {
checkEGLError("eglCreateContext");
qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError());
@@ -227,7 +227,8 @@ bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
eglResult = eglMakeCurrent(ms_eglDisplay, m_currentEglSurface, m_currentEglSurface, m_eglContext);
if (eglResult != EGL_TRUE) {
checkEGLError("eglMakeCurrent");
- qFatal("QQNX: failed to set current EGL context, err=%d", eglGetError());
+ qWarning("QQNX: failed to set current EGL context, err=%d", eglGetError());
+ return false;
}
return (eglResult == EGL_TRUE);
}
@@ -274,13 +275,13 @@ EGLDisplay QQnxGLContext::getEglDisplay() {
return ms_eglDisplay;
}
-EGLint *QQnxGLContext::contextAttrs()
+EGLint *QQnxGLContext::contextAttrs(const QSurfaceFormat &format)
{
qGLContextDebug() << Q_FUNC_INFO;
// Choose EGL settings based on OpenGL version
#if defined(QT_OPENGL_ES_2)
- static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, format.version().first, EGL_NONE };
return attrs;
#else
return 0;
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h
index 2b12657da9..af89586bd5 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.h
+++ b/src/plugins/platforms/qnx/qqnxglcontext.h
@@ -88,7 +88,7 @@ private:
EGLContext m_eglContext;
EGLSurface m_currentEglSurface;
- static EGLint *contextAttrs();
+ static EGLint *contextAttrs(const QSurfaceFormat &format);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxglobal.cpp b/src/plugins/platforms/qnx/qqnxglobal.cpp
new file mode 100644
index 0000000000..cef37af84e
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxglobal.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+**
+** Copyright (C) 2011 - 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <errno.h>
+
+#include <QDebug>
+#include "qqnxintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+void qScreenCheckError(int rc, const char *funcInfo, const char *message, bool critical)
+{
+ if (!rc && (QQnxIntegration::options() & QQnxIntegration::AlwaysFlushScreenContext)
+ && QQnxIntegration::screenContext() != 0) {
+ rc = screen_flush_context(QQnxIntegration::screenContext(), 0);
+ }
+
+ if (rc) {
+ if (critical)
+ qCritical("%s - Screen: %s - Error: %s (%i)", funcInfo, message, strerror(errno), errno);
+ else
+ qWarning("%s - Screen: %s - Error: %s (%i)", funcInfo, message, strerror(errno), errno);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxglobal.h b/src/plugins/platforms/qnx/qqnxglobal.h
new file mode 100644
index 0000000000..8cfbfb084a
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxglobal.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+**
+** Copyright (C) 2011 - 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQNXGLOBAL_H
+#define QQNXGLOBAL_H
+
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+void qScreenCheckError(int rc, const char *funcInfo, const char *message, bool critical);
+
+#define Q_SCREEN_CHECKERROR(x, message) \
+qScreenCheckError(x, Q_FUNC_INFO, message, false)
+
+#define Q_SCREEN_CRITICALERROR(x, message) \
+qScreenCheckError(x, Q_FUNC_INFO, message, true)
+
+QT_END_NAMESPACE
+
+#endif // QQNXGLOBAL_H
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
index 580553f6e2..619883e843 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -40,10 +40,10 @@
****************************************************************************/
#include "qqnxinputcontext_imf.h"
-#include "qqnxeventthread.h"
#include "qqnxabstractvirtualkeyboard.h"
#include "qqnxintegration.h"
#include "qqnxscreen.h"
+#include "qqnxscreeneventhandler.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QInputMethodEvent>
@@ -54,6 +54,8 @@
#include <QtCore/QVariant>
#include <QtCore/QVariantHash>
#include <QtCore/QWaitCondition>
+#include <QtCore/QQueue>
+#include <QtCore/QGlobalStatic>
#include <dlfcn.h>
#include "imf/imf_client.h"
@@ -62,9 +64,9 @@
#include <sys/keycodes.h>
#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG)
-#define qInputContextIMFEventDebug qDebug
+#define qInputContextIMFRequestDebug qDebug
#else
-#define qInputContextIMFEventDebug QT_NO_QDEBUG_MACRO
+#define qInputContextIMFRequestDebug QT_NO_QDEBUG_MACRO
#endif
#if defined(QQNXINPUTCONTEXT_DEBUG)
@@ -73,492 +75,426 @@
#define qInputContextDebug QT_NO_QDEBUG_MACRO
#endif
-/** TODO:
- Support inputMethodHints to restrict input (needs additional features in IMF).
-*/
+static QQnxInputContext *sInputContextInstance;
+static QColor sSelectedColor(0,0xb8,0,85);
-#define STRX(x) #x
-#define STR(x) STRX(x)
-
-// Someone tell me why input_control methods are in this namespace, but the rest is not.
-using namespace InputMethodSystem;
-
-#define qs(x) QString::fromLatin1(x)
-#define iarg(name) event->mArgs[qs(#name)] = QVariant::fromValue(name)
-#define parg(name) event->mArgs[qs(#name)] = QVariant::fromValue((void*)name)
-namespace
-{
-
-spannable_string_t *toSpannableString(const QString &text);
+static const input_session_t *sSpellCheckSession = 0;
static const input_session_t *sInputSession = 0;
-bool isSessionOkay(input_session_t *ic)
+static bool isSessionOkay(input_session_t *ic)
{
return ic !=0 && sInputSession != 0 && ic->component_id == sInputSession->component_id;
}
enum ImfEventType
{
- ImfBeginBatchEdit,
- ImfClearMetaKeyStates,
ImfCommitText,
ImfDeleteSurroundingText,
- ImfEndBatchEdit,
ImfFinishComposingText,
- ImfGetCursorCapsMode,
ImfGetCursorPosition,
- ImfGetExtractedText,
- ImfGetSelectedText,
ImfGetTextAfterCursor,
ImfGetTextBeforeCursor,
- ImfPerformEditorAction,
- ImfReportFullscreenMode,
ImfSendEvent,
- ImfSendAsyncEvent,
ImfSetComposingRegion,
ImfSetComposingText,
- ImfSetSelection
+ ImfIsTextSelected,
+ ImfIsAllTextSelected,
};
-// We use this class as a round about way to support a posting synchronous event into
-// Qt's main thread from the IMF thread.
-class ImfEventResult
-{
-public:
- ImfEventResult()
- {
- m_mutex.lock();
- }
-
- ~ImfEventResult()
- {
- m_mutex.unlock();
- }
-
- void wait()
- {
- m_wait.wait(&m_mutex);
- }
-
- void signal()
- {
- m_wait.wakeAll();
- }
-
- void setResult(const QVariant& result)
- {
- m_mutex.lock();
- m_retVal = result;
- signal();
- m_mutex.unlock();
- }
-
- QVariant result()
- {
- return m_retVal;
- }
-
-private:
- QVariant m_retVal;
- QMutex m_mutex;
- QWaitCondition m_wait;
+struct SpellCheckInfo {
+ SpellCheckInfo(void *_context, void (*_spellCheckDone)(void *, const QString &, const QList<int> &))
+ : context(_context), spellCheckDone(_spellCheckDone) {}
+ void *context;
+ void (*spellCheckDone)(void *, const QString &, const QList<int> &);
};
+Q_GLOBAL_STATIC(QQueue<SpellCheckInfo>, sSpellCheckQueue)
-class ImfEvent : public QEvent
+// IMF requests all arrive on IMF's own thread and have to be posted to the main thread to be processed.
+class QQnxImfRequest
{
- public:
- ImfEvent(input_session_t *session, ImfEventType type, ImfEventResult *result) :
- QEvent((QEvent::Type)sUserEventType),
- m_session(session),
- m_imfType(type),
- m_result(result)
- {
- }
- ~ImfEvent() { }
-
- input_session_t *m_session;
- ImfEventType m_imfType;
- QVariantHash m_args;
- ImfEventResult *m_result;
-
- static int sUserEventType;
+public:
+ QQnxImfRequest(input_session_t *_session, ImfEventType _type)
+ : session(_session), type(_type)
+ { }
+ ~QQnxImfRequest() { }
+
+ input_session_t *session;
+ ImfEventType type;
+ union {
+ struct {
+ int32_t n;
+ int32_t flags;
+ bool before;
+ spannable_string_t *result;
+ } gtac; // ic_get_text_before_cursor/ic_get_text_after_cursor
+ struct {
+ int32_t result;
+ } gcp; // ic_get_cursor_position
+ struct {
+ int32_t start;
+ int32_t end;
+ int32_t result;
+ } scr; // ic_set_composing_region
+ struct {
+ spannable_string_t* text;
+ int32_t new_cursor_position;
+ int32_t result;
+ } sct; // ic_set_composing_text
+ struct {
+ spannable_string_t* text;
+ int32_t new_cursor_position;
+ int32_t result;
+ } ct; // ic_commit_text
+ struct {
+ int32_t result;
+ } fct; // ic_finish_composing_text
+ struct {
+ int32_t left_length;
+ int32_t right_length;
+ int32_t result;
+ } dst; // ic_delete_surrounding_text
+ struct {
+ event_t *event;
+ int32_t result;
+ } sae; // ic_send_async_event/ic_send_event
+ struct {
+ int32_t *pIsSelected;
+ int32_t result;
+ } its; // ic_is_text_selected/ic_is_all_text_selected
+ };
};
-int ImfEvent::sUserEventType = QEvent::registerEventType();
-static int32_t imfBeginBatchEdit(input_session_t *ic)
+// Invoke an IMF initiated request synchronously on Qt's main thread. As describe below all
+// IMF requests are made from another thread but need to be executed on the main thread.
+static void executeIMFRequest(QQnxImfRequest *event)
+{
+ QMetaObject::invokeMethod(sInputContextInstance,
+ "processImfEvent",
+ Qt::BlockingQueuedConnection,
+ Q_ARG(QQnxImfRequest*, event));
+}
+
+// The following functions (ic_*) are callback functions called by the input system to query information
+// about the text object that currently has focus or to make changes to it. All calls are made from the
+// input system's own thread. The pattern for each callback function is to copy its parameters into
+// a QQnxImfRequest structure and call executeIMFRequest to have it passed synchronously to Qt's main thread.
+// Any return values should be pre-initialised with suitable default values as in some cases
+// (e.g. a stale session) the call will return without having executed any request specific code.
+//
+// To make the correspondence more obvious, the names of these functions match those defined in the headers.
+// They're in an anonymous namespace to avoid compiler conflicts with external functions defined with the
+// same names.
+namespace
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfBeginBatchEdit, &result);
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_begin_batch_edit(input_session_t *ic)
+{
+ Q_UNUSED(ic);
- return ret;
+ // Ignore silently.
+ return 0;
}
-static int32_t imfClearMetaKeyStates(input_session_t *ic, int32_t states)
+// End composition, committing the supplied text.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_commit_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfClearMetaKeyStates, &result);
- iarg(states);
-
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
+ QQnxImfRequest event(ic, ImfCommitText);
+ event.ct.text = text;
+ event.ct.new_cursor_position = new_cursor_position;
+ event.ct.result = -1;
+ executeIMFRequest(&event);
- return ret;
+ return event.ct.result;
}
-static int32_t imfCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
+// Delete left_length characters before and right_length characters after the cursor.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_delete_surrounding_text(input_session_t *ic, int32_t left_length, int32_t right_length)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfCommitText, &result);
- parg(text);
- iarg(new_cursor_position);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfDeleteSurroundingText);
+ event.dst.left_length = left_length;
+ event.dst.right_length = right_length;
+ event.dst.result = -1;
+ executeIMFRequest(&event);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
-
- return ret;
+ return event.dst.result;
}
-static int32_t imfDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length)
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_end_batch_edit(input_session_t *ic)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfDeleteSurroundingText, &result);
- iarg(left_length);
- iarg(right_length);
+ Q_UNUSED(ic);
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
-
- return ret;
+ // Ignore silently.
+ return 0;
}
-static int32_t imfEndBatchEdit(input_session_t *ic)
+// End composition, committing what's there.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_finish_composing_text(input_session_t *ic)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfEndBatchEdit, &result);
-
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
+ QQnxImfRequest event(ic, ImfFinishComposingText);
+ event.fct.result = -1;
+ executeIMFRequest(&event);
- return ret;
+ return event.fct.result;
}
-static int32_t imfFinishComposingText(input_session_t *ic)
+// Return the position of the cursor.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_get_cursor_position(input_session_t *ic)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfFinishComposingText, &result);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfGetCursorPosition);
+ event.gcp.result = -1;
+ executeIMFRequest(&event);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
-
- return ret;
+ return event.gcp.result;
}
-static int32_t imfGetCursorCapsMode(input_session_t *ic, int32_t req_modes)
+// Return the n characters after the cursor.
+// See comment at beginning of namespace declaration for general information
+static spannable_string_t *ic_get_text_after_cursor(input_session_t *ic, int32_t n, int32_t flags)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetCursorCapsMode, &result);
- iarg(req_modes);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfGetTextAfterCursor);
+ event.gtac.n = n;
+ event.gtac.flags = flags;
+ event.gtac.result = 0;
+ executeIMFRequest(&event);
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ return event.gtac.result;
}
-static int32_t imfGetCursorPosition(input_session_t *ic)
+// Return the n characters before the cursor.
+// See comment at beginning of namespace declaration for general information
+static spannable_string_t *ic_get_text_before_cursor(input_session_t *ic, int32_t n, int32_t flags)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetCursorPosition, &result);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfGetTextBeforeCursor);
+ event.gtac.n = n;
+ event.gtac.flags = flags;
+ event.gtac.result = 0;
+ executeIMFRequest(&event);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
-
- return ret;
+ return event.gtac.result;
}
-static extracted_text_t *imfGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
+// Process an event from IMF. Primarily used for reflecting back keyboard events.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_send_event(input_session_t *ic, event_t *event)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic)) {
- extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1);
- et->text = (spannable_string_t *)calloc(sizeof(spannable_string_t),1);
- return et;
- }
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetExtractedText, &result);
- parg(request);
- iarg(flags);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest imfEvent(ic, ImfSendEvent);
+ imfEvent.sae.event = event;
+ imfEvent.sae.result = -1;
+ executeIMFRequest(&imfEvent);
- result.wait();
- return result.result().value<extracted_text_t *>();
+ return imfEvent.sae.result;
}
-static spannable_string_t *imfGetSelectedText(input_session_t *ic, int32_t flags)
+// Same as ic_send_event.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_send_async_event(input_session_t *ic, event_t *event)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetSelectedText, &result);
- iarg(flags);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ // There's no difference from our point of view between ic_send_event & ic_send_async_event
+ QQnxImfRequest imfEvent(ic, ImfSendEvent);
+ imfEvent.sae.event = event;
+ imfEvent.sae.result = -1;
+ executeIMFRequest(&imfEvent);
- result.wait();
- return result.result().value<extracted_text_t *>();
+ return imfEvent.sae.result;
}
-static spannable_string_t *imfGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags)
+// Set the range of text between start and end as the composition range.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_set_composing_region(input_session_t *ic, int32_t start, int32_t end)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetTextAfterCursor, &result);
- iarg(n);
- iarg(flags);
+ QQnxImfRequest event(ic, ImfSetComposingRegion);
+ event.scr.start = start;
+ event.scr.end = end;
+ event.scr.result = -1;
+ executeIMFRequest(&event);
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- return result.result().value<extracted_text_t *>();
+ return event.scr.result;
}
-static spannable_string_t *imfGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags)
+// Update the composition range with the supplied text. This can be called when no composition
+// range is in effect in which case one is started at the current cursor position.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_set_composing_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
+ QQnxImfRequest event(ic, ImfSetComposingText);
+ event.sct.text = text;
+ event.sct.new_cursor_position = new_cursor_position;
+ event.sct.result = -1;
+ executeIMFRequest(&event);
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetTextBeforeCursor, &result);
- iarg(n);
- iarg(flags);
-
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- return result.result().value<extracted_text_t *>();
+ return event.sct.result;
}
-static int32_t imfPerformEditorAction(input_session_t *ic, int32_t editor_action)
+// Indicate if any text is selected
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_is_text_selected(input_session_t* ic, int32_t* pIsSelected)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfPerformEditorAction, &result);
- iarg(editor_action);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfIsTextSelected);
+ event.its.pIsSelected = pIsSelected;
+ event.its.result = -1;
+ executeIMFRequest(&event);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ return event.its.result;
}
-static int32_t imfReportFullscreenMode(input_session_t *ic, int32_t enabled)
+// Indicate if all text is selected
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_is_all_text_selected(input_session_t* ic, int32_t* pIsSelected)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfReportFullscreenMode, &result);
- iarg(enabled);
+ QQnxImfRequest event(ic, ImfIsAllTextSelected);
+ event.its.pIsSelected = pIsSelected;
+ event.its.result = -1;
+ executeIMFRequest(&event);
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ return event.its.result;
}
-static int32_t imfSendEvent(input_session_t *ic, event_t *event)
-{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEvent *imfEvent = new ImfEvent(ic, ImfSendEvent, 0);
- imfEvent->m_args[qs("event")] = QVariant::fromValue(static_cast<void *>(event));
+// LCOV_EXCL_START - exclude from code coverage analysis
+// The following functions are defined in the IMF headers but are not currently called.
- QCoreApplication::postEvent(QCoreApplication::instance(), imfEvent);
+// Not currently used
+static int32_t ic_perform_editor_action(input_session_t *ic, int32_t editor_action)
+{
+ Q_UNUSED(ic);
+ Q_UNUSED(editor_action);
+ qCritical() << "ic_perform_editor_action not implemented";
return 0;
}
-static int32_t imfSendAsyncEvent(input_session_t *ic, event_t *event)
+// Not currently used
+static int32_t ic_report_fullscreen_mode(input_session_t *ic, int32_t enabled)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEvent *imfEvent = new ImfEvent(ic, ImfSendAsyncEvent, 0);
- imfEvent->m_args[qs("event")] = QVariant::fromValue(static_cast<void *>(event));
-
- QCoreApplication::postEvent(QCoreApplication::instance(), imfEvent);
+ Q_UNUSED(ic);
+ Q_UNUSED(enabled);
+ qCritical() << "ic_report_fullscreen_mode not implemented";
return 0;
}
-static int32_t imfSetComposingRegion(input_session_t *ic, int32_t start, int32_t end)
+// Not currently used
+static extracted_text_t *ic_get_extracted_text(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ Q_UNUSED(ic);
+ Q_UNUSED(request);
+ Q_UNUSED(flags);
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfSetComposingRegion, &result);
- iarg(start);
- iarg(end);
+ qCritical() << "ic_get_extracted_text not implemented";
+ return 0;
+}
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+// Not currently used
+static spannable_string_t *ic_get_selected_text(input_session_t *ic, int32_t flags)
+{
+ Q_UNUSED(ic);
+ Q_UNUSED(flags);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ qCritical() << "ic_get_selected_text not implemented";
+ return 0;
}
-static int32_t imfSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
+// Not currently used
+static int32_t ic_get_cursor_caps_mode(input_session_t *ic, int32_t req_modes)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ Q_UNUSED(ic);
+ Q_UNUSED(req_modes);
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfSetComposingText, &result);
- parg(text);
- iarg(new_cursor_position);
+ qCritical() << "ic_get_cursor_caps_mode not implemented";
+ return 0;
+}
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+// Not currently used
+static int32_t ic_clear_meta_key_states(input_session_t *ic, int32_t states)
+{
+ Q_UNUSED(ic);
+ Q_UNUSED(states);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ qCritical() << "ic_clear_meta_key_states not implemented";
+ return 0;
}
-static int32_t imfSetSelection(input_session_t *ic, int32_t start, int32_t end)
+// Not currently used
+static int32_t ic_set_selection(input_session_t *ic, int32_t start, int32_t end)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ Q_UNUSED(ic);
+ Q_UNUSED(start);
+ Q_UNUSED(end);
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfSetSelection, &result);
- iarg(start);
- iarg(end);
+ qCritical() << "ic_set_selection not implemented";
+ return 0;
+}
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+// End of un-hittable code
+// LCOV_EXCL_STOP
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
-}
static connection_interface_t ic_funcs = {
- imfBeginBatchEdit,
- imfClearMetaKeyStates,
- imfCommitText,
- imfDeleteSurroundingText,
- imfEndBatchEdit,
- imfFinishComposingText,
- imfGetCursorCapsMode,
- imfGetCursorPosition,
- imfGetExtractedText,
- imfGetSelectedText,
- imfGetTextAfterCursor,
- imfGetTextBeforeCursor,
- imfPerformEditorAction,
- imfReportFullscreenMode,
- NULL, //ic_send_key_event
- imfSendEvent,
- imfSendAsyncEvent,
- imfSetComposingRegion,
- imfSetComposingText,
- imfSetSelection,
- NULL, //ic_set_candidates,
+ ic_begin_batch_edit,
+ ic_clear_meta_key_states,
+ ic_commit_text,
+ ic_delete_surrounding_text,
+ ic_end_batch_edit,
+ ic_finish_composing_text,
+ ic_get_cursor_caps_mode,
+ ic_get_cursor_position,
+ ic_get_extracted_text,
+ ic_get_selected_text,
+ ic_get_text_after_cursor,
+ ic_get_text_before_cursor,
+ ic_perform_editor_action,
+ ic_report_fullscreen_mode,
+ 0, //ic_send_key_event
+ ic_send_event,
+ ic_send_async_event,
+ ic_set_composing_region,
+ ic_set_composing_text,
+ ic_set_selection,
+ 0, //ic_set_candidates,
+ 0, //ic_get_cursor_offset,
+ 0, //ic_get_selection,
+ ic_is_text_selected,
+ ic_is_all_text_selected,
+ 0, //ic_get_max_cursor_offset_t
};
+} // namespace
+
static void
-initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType, int eventId)
+initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType, int eventId, int eventSize)
{
static int s_transactionId;
// Make sure structure is squeaky clean since it's not clear just what is significant.
- memset(pEvent, 0, sizeof(event_t));
+ memset(pEvent, 0, eventSize);
pEvent->event_type = eventType;
pEvent->event_id = eventId;
pEvent->pid = getpid();
@@ -566,31 +502,20 @@ initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType,
pEvent->transaction_id = ++s_transactionId;
}
-spannable_string_t *toSpannableString(const QString &text)
+static spannable_string_t *toSpannableString(const QString &text)
{
qInputContextDebug() << Q_FUNC_INFO << text;
- spannable_string_t *pString = reinterpret_cast<spannable_string_t *>(malloc(sizeof(spannable_string_t)));
- pString->str = (wchar_t *)malloc(sizeof(wchar_t) * text.length() + 1);
- pString->length = text.length();
+ spannable_string_t *pString = static_cast<spannable_string_t *>(malloc(sizeof(spannable_string_t)));
+ pString->str = static_cast<wchar_t *>(malloc(sizeof(wchar_t) * text.length() + 1));
+ pString->length = text.toWCharArray(pString->str);
pString->spans = 0;
pString->spans_count = 0;
-
- const QChar *pData = text.constData();
- wchar_t *pDst = pString->str;
-
- while (!pData->isNull())
- {
- *pDst = pData->unicode();
- pDst++;
- pData++;
- }
- *pDst = 0;
+ pString->str[pString->length] = 0;
return pString;
}
-} // namespace
static const input_session_t *(*p_ictrl_open_session)(connection_interface_t *) = 0;
static void (*p_ictrl_close_session)(input_session_t *) = 0;
@@ -645,27 +570,30 @@ QT_BEGIN_NAMESPACE
QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVirtualKeyboard &keyboard) :
QPlatformInputContext(),
- m_lastCaretPos(0),
+ m_caretPosition(0),
m_isComposing(false),
+ m_isUpdatingText(false),
m_inputPanelVisible(false),
m_inputPanelLocale(QLocale::c()),
+ m_focusObject(0),
m_integration(integration),
- m_virtualKeyboad(keyboard)
+ m_virtualKeyboard(keyboard)
{
qInputContextDebug() << Q_FUNC_INFO;
if (!imfAvailable())
return;
- if ( p_imf_client_init() != 0 ) {
+ // Save a pointer to ourselves so we can execute calls from IMF through executeIMFRequest
+ // In practice there will only ever be a single instance.
+ Q_ASSERT(sInputContextInstance == 0);
+ sInputContextInstance = this;
+
+ if (p_imf_client_init() != 0) {
s_imfInitFailed = true;
qCritical("imf_client_init failed - IMF services will be unavailable");
}
- QCoreApplication::instance()->installEventFilter(this);
-
- // p_vkb_init_selection_service();
-
connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool)));
connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale)));
keyboardVisibilityChanged(keyboard.isVisible());
@@ -676,168 +604,75 @@ QQnxInputContext::~QQnxInputContext()
{
qInputContextDebug() << Q_FUNC_INFO;
+ Q_ASSERT(sInputContextInstance == this);
+ sInputContextInstance = 0;
+
if (!imfAvailable())
return;
- QCoreApplication::instance()->removeEventFilter(this);
p_imf_client_disconnect();
}
-#define getarg(type, name) type name = imfEvent->mArgs[qs(#name)].value<type>()
-#define getparg(type, name) type name = (type)(imfEvent->mArgs[qs(#name)].value<void*>())
-
bool QQnxInputContext::isValid() const
{
return imfAvailable();
}
-bool QQnxInputContext::eventFilter(QObject *obj, QEvent *event)
+void QQnxInputContext::processImfEvent(QQnxImfRequest *imfEvent)
{
- if (event->type() == ImfEvent::sUserEventType) {
- // Forward the event to our real handler.
- ImfEvent *imfEvent = static_cast<ImfEvent *>(event);
- switch (imfEvent->m_imfType) {
- case ImfBeginBatchEdit: {
- int32_t ret = onBeginBatchEdit(imfEvent->m_session);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfClearMetaKeyStates: {
- getarg(int32_t, states);
- int32_t ret = onClearMetaKeyStates(imfEvent->m_session, states);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfCommitText: {
- getparg(spannable_string_t*, text);
- getarg(int32_t, new_cursor_position);
- int32_t ret = onCommitText(imfEvent->m_session, text, new_cursor_position);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfDeleteSurroundingText: {
- getarg(int32_t, left_length);
- getarg(int32_t, right_length);
- int32_t ret = onDeleteSurroundingText(imfEvent->m_session, left_length, right_length);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfEndBatchEdit: {
- int32_t ret = onEndBatchEdit(imfEvent->m_session);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfFinishComposingText: {
- int32_t ret = onFinishComposingText(imfEvent->m_session);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfGetCursorCapsMode: {
- getarg(int32_t, req_modes);
- int32_t ret = onGetCursorCapsMode(imfEvent->m_session, req_modes);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfGetCursorPosition: {
- int32_t ret = onGetCursorPosition(imfEvent->m_session);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfGetExtractedText: {
- getparg(extracted_text_request_t*, request);
- getarg(int32_t, flags);
- extracted_text_t *ret = onGetExtractedText(imfEvent->m_session, request, flags);
- imfEvent->m_result->setResult(QVariant::fromValue(static_cast<void *>(ret)));
- break;
- }
+ // If input session is no longer current, just bail, imfEvent should already be set with the appropriate
+ // return value. The only exception is spell check events since they're not associated with the
+ // object with focus.
+ if (imfEvent->type != ImfSendEvent || imfEvent->sae.event->event_type != EVENT_SPELL_CHECK) {
+ if (!isSessionOkay(imfEvent->session))
+ return;
+ }
- case ImfGetSelectedText: {
- getarg(int32_t, flags);
- spannable_string_t *ret = onGetSelectedText(imfEvent->m_session, flags);
- imfEvent->m_result->setResult(QVariant::fromValue(static_cast<void *>(ret)));
- break;
- }
+ switch (imfEvent->type) {
+ case ImfCommitText:
+ imfEvent->ct.result = onCommitText(imfEvent->ct.text, imfEvent->ct.new_cursor_position);
+ break;
- case ImfGetTextAfterCursor: {
- getarg(int32_t, n);
- getarg(int32_t, flags);
- spannable_string_t *ret = onGetTextAfterCursor(imfEvent->m_session, n, flags);
- imfEvent->m_result->setResult(QVariant::fromValue(static_cast<void *>(ret)));
- break;
- }
+ case ImfDeleteSurroundingText:
+ imfEvent->dst.result = onDeleteSurroundingText(imfEvent->dst.left_length, imfEvent->dst.right_length);
+ break;
- case ImfGetTextBeforeCursor: {
- getarg(int32_t, n);
- getarg(int32_t, flags);
- spannable_string_t *ret = onGetTextBeforeCursor(imfEvent->m_session, n, flags);
- imfEvent->m_result->setResult(QVariant::fromValue((void*)ret));
- break;
- }
+ case ImfFinishComposingText:
+ imfEvent->fct.result = onFinishComposingText();
+ break;
- case ImfPerformEditorAction: {
- getarg(int32_t, editor_action);
- int32_t ret = onPerformEditorAction(imfEvent->m_session, editor_action);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
+ case ImfGetCursorPosition:
+ imfEvent->gcp.result = onGetCursorPosition();
+ break;
- case ImfReportFullscreenMode: {
- getarg(int32_t, enabled);
- int32_t ret = onReportFullscreenMode(imfEvent->m_session, enabled);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
+ case ImfGetTextAfterCursor:
+ imfEvent->gtac.result = onGetTextAfterCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
+ break;
- case ImfSendEvent: {
- getparg(event_t*, event);
- onSendEvent(imfEvent->m_session, event);
- break;
- }
+ case ImfGetTextBeforeCursor:
+ imfEvent->gtac.result = onGetTextBeforeCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
+ break;
- case ImfSendAsyncEvent: {
- getparg(event_t*, event);
- onSendAsyncEvent(imfEvent->m_session, event);
- break;
- }
+ case ImfSendEvent:
+ imfEvent->sae.result = onSendEvent(imfEvent->sae.event);
+ break;
- case ImfSetComposingRegion: {
- getarg(int32_t, start);
- getarg(int32_t, end);
- int32_t ret = onSetComposingRegion(imfEvent->m_session, start, end);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
+ case ImfSetComposingRegion:
+ imfEvent->scr.result = onSetComposingRegion(imfEvent->scr.start, imfEvent->scr.end);
+ break;
- case ImfSetComposingText: {
- getparg(spannable_string_t*, text);
- getarg(int32_t, new_cursor_position);
- int32_t ret = onSetComposingText(imfEvent->m_session, text, new_cursor_position);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
+ case ImfSetComposingText:
+ imfEvent->sct.result = onSetComposingText(imfEvent->sct.text, imfEvent->sct.new_cursor_position);
+ break;
- case ImfSetSelection: {
- getarg(int32_t, start);
- getarg(int32_t, end);
- int32_t ret = onSetSelection(imfEvent->m_session, start, end);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
- }; //switch
+ case ImfIsTextSelected:
+ imfEvent->its.result = onIsTextSelected(imfEvent->its.pIsSelected);
+ break;
- return true;
- } else {
- // standard event processing
- return QObject::eventFilter(obj, event);
- }
+ case ImfIsAllTextSelected:
+ imfEvent->its.result = onIsAllTextSelected(imfEvent->its.pIsSelected);
+ break;
+ }; //switch
}
bool QQnxInputContext::filterEvent( const QEvent *event )
@@ -845,12 +680,12 @@ bool QQnxInputContext::filterEvent( const QEvent *event )
qInputContextDebug() << Q_FUNC_INFO << event;
switch (event->type()) {
- case QEvent::CloseSoftwareInputPanel: {
+ case QEvent::CloseSoftwareInputPanel:
return dispatchCloseSoftwareInputPanel();
- }
- case QEvent::RequestSoftwareInputPanel: {
+
+ case QEvent::RequestSoftwareInputPanel:
return dispatchRequestSoftwareInputPanel();
- }
+
default:
return false;
}
@@ -869,12 +704,30 @@ void QQnxInputContext::reset()
endComposition();
}
-void QQnxInputContext::update(Qt::InputMethodQueries queries)
+void QQnxInputContext::commit()
{
qInputContextDebug() << Q_FUNC_INFO;
- reset();
+ endComposition();
+}
- QPlatformInputContext::update(queries);
+void QQnxInputContext::update(Qt::InputMethodQueries queries)
+{
+ qInputContextDebug() << Q_FUNC_INFO << queries;
+
+ if (queries & Qt::ImCursorPosition) {
+ int lastCaret = m_caretPosition;
+ updateCursorPosition();
+ // If caret position has changed we need to inform IMF unless this is just due to our own action
+ // such as committing text.
+ if (hasSession() && !m_isUpdatingText && lastCaret != m_caretPosition) {
+ caret_event_t caretEvent;
+ initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED, sizeof(caretEvent));
+ caretEvent.old_pos = lastCaret;
+ caretEvent.new_pos = m_caretPosition;
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_event caret changed" << lastCaret << m_caretPosition;
+ p_ictrl_dispatch_event(&caretEvent.event);
+ }
+ }
}
void QQnxInputContext::closeSession()
@@ -887,16 +740,23 @@ void QQnxInputContext::closeSession()
p_ictrl_close_session((input_session_t *)sInputSession);
sInputSession = 0;
}
+ // These are likely already in the right state but this depends on the text control
+ // having called reset or commit. So, just in case, set them to proper values.
+ m_isComposing = false;
+ m_composingText.clear();
}
-void QQnxInputContext::openSession()
+bool QQnxInputContext::openSession()
{
- qInputContextDebug() << Q_FUNC_INFO;
if (!imfAvailable())
- return;
+ return false;
closeSession();
sInputSession = p_ictrl_open_session(&ic_funcs);
+
+ qInputContextDebug() << Q_FUNC_INFO;
+
+ return sInputSession != 0;
}
bool QQnxInputContext::hasSession()
@@ -918,79 +778,89 @@ bool QQnxInputContext::hasSelectedText()
bool QQnxInputContext::dispatchRequestSoftwareInputPanel()
{
+ qInputContextDebug() << Q_FUNC_INFO << "requesting keyboard" << m_inputPanelVisible;
m_virtualKeyboard.showKeyboard();
- qInputContextDebug() << Q_FUNC_INFO << "requesting virtual keyboard";
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input || !inputMethodAccepted())
- return true;
-
- if (!hasSession())
- openSession();
- // This also means that the caret position has moved
- QInputMethodQueryEvent query(Qt::ImCursorPosition);
- QCoreApplication::sendEvent(input, &query);
- int caretPos = query.value(Qt::ImCursorPosition).toInt();
- caret_event_t caretEvent;
- memset(&caretEvent, 0, sizeof(caret_event_t));
- initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED);
- caretEvent.old_pos = m_lastCaretPos;
- m_lastCaretPos = caretEvent.new_pos = caretPos;
- p_ictrl_dispatch_event((event_t *)&caretEvent);
return true;
}
bool QQnxInputContext::dispatchCloseSoftwareInputPanel()
{
+ qInputContextDebug() << Q_FUNC_INFO << "hiding keyboard" << m_inputPanelVisible;
m_virtualKeyboard.hideKeyboard();
- qInputContextDebug() << Q_FUNC_INFO << "hiding virtual keyboard";
- // This also means we are stopping composition, but we should already have done that.
return true;
}
/**
* IMF Event Dispatchers.
*/
-bool QQnxInputContext::dispatchFocusEvent(FocusEventId id, int hints)
+bool QQnxInputContext::dispatchFocusGainEvent(int inputHints)
{
- qInputContextDebug() << Q_FUNC_INFO;
+ if (hasSession())
+ dispatchFocusLossEvent();
- if (!sInputSession) {
- qWarning() << Q_FUNC_INFO << "Attempt to dispatch a focus event with no input session.";
- return false;
- }
+ QObject *input = qGuiApp->focusObject();
- if (!imfAvailable())
+ if (!input || !openSession())
return false;
// Set the last caret position to 0 since we don't really have one and we don't
// want to have the old one.
- m_lastCaretPos = 0;
+ m_caretPosition = 0;
+
+ QInputMethodQueryEvent query(Qt::ImHints);
+ QCoreApplication::sendEvent(input, &query);
focus_event_t focusEvent;
- memset(&focusEvent, 0, sizeof(focusEvent));
- initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, id);
+ initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_GAINED, sizeof(focusEvent));
focusEvent.style = DEFAULT_STYLE;
- if (hints && Qt::ImhNoPredictiveText)
+ if (inputHints & Qt::ImhNoPredictiveText)
focusEvent.style |= NO_PREDICTION | NO_AUTO_CORRECTION;
- if (hints && Qt::ImhNoAutoUppercase)
+ if (inputHints & Qt::ImhNoAutoUppercase)
focusEvent.style |= NO_AUTO_TEXT;
+ // Following styles are mutually exclusive
+ if (inputHints & Qt::ImhHiddenText) {
+ focusEvent.style |= IMF_PASSWORD_TYPE;
+ } else if (inputHints & Qt::ImhDialableCharactersOnly) {
+ focusEvent.style |= IMF_PHONE_TYPE;
+ } else if (inputHints & Qt::ImhUrlCharactersOnly) {
+ focusEvent.style |= IMF_URL_TYPE;
+ } else if (inputHints & Qt::ImhEmailCharactersOnly) {
+ focusEvent.style |= IMF_EMAIL_TYPE;
+ }
+
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_event focus gain style:" << focusEvent.style;
+
p_ictrl_dispatch_event((event_t *)&focusEvent);
return true;
}
-bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap)
+void QQnxInputContext::dispatchFocusLossEvent()
{
- if (!imfAvailable())
+ if (hasSession()) {
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_event focus lost";
+
+ focus_event_t focusEvent;
+ initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_LOST, sizeof(focusEvent));
+ p_ictrl_dispatch_event((event_t *)&focusEvent);
+ closeSession();
+ }
+}
+
+bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap, int sequenceId)
+{
+ Q_UNUSED(scan);
+
+ if (!hasSession())
return false;
int key = (flags & KEY_SYM_VALID) ? sym : cap;
- bool navKey = false;
- switch ( key ) {
+ bool navigationKey = false;
+ switch (key) {
case KEYCODE_RETURN:
/* In a single line edit we should end composition because enter might be used by something.
endComposition();
@@ -1007,27 +877,22 @@ bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan
break;
case KEYCODE_LEFT:
key = NAVIGATE_LEFT;
- navKey = true;
+ navigationKey = true;
break;
case KEYCODE_RIGHT:
key = NAVIGATE_RIGHT;
- navKey = true;
+ navigationKey = true;
break;
case KEYCODE_UP:
key = NAVIGATE_UP;
- navKey = true;
+ navigationKey = true;
break;
case KEYCODE_DOWN:
key = NAVIGATE_DOWN;
- navKey = true;
+ navigationKey = true;
break;
- case KEYCODE_CAPS_LOCK:
- case KEYCODE_LEFT_SHIFT:
- case KEYCODE_RIGHT_SHIFT:
case KEYCODE_LEFT_CTRL:
case KEYCODE_RIGHT_CTRL:
- case KEYCODE_LEFT_ALT:
- case KEYCODE_RIGHT_ALT:
case KEYCODE_MENU:
case KEYCODE_LEFT_HYPER:
case KEYCODE_RIGHT_HYPER:
@@ -1041,85 +906,183 @@ bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan
break;
}
- if ( mod & KEYMOD_CTRL ) {
- // If CTRL is pressed, just let AIR handle it. But terminate any composition first
- //endComposition();
- return false;
- }
-
// Pass the keys we don't know about on through
if ( key == 0 )
return false;
- // IMF doesn't need key releases so just swallow them.
- if (!(flags & KEY_DOWN))
- return true;
-
- if ( navKey ) {
+ if (navigationKey) {
// Even if we're forwarding up events, we can't do this for
// navigation keys.
if ( flags & KEY_DOWN ) {
navigation_event_t navEvent;
- initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key);
+ initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key, sizeof(navEvent));
navEvent.magnitude = 1;
- qInputContextDebug() << Q_FUNC_INFO << "dispatch navigation event " << key;
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_even navigation" << key;
p_ictrl_dispatch_event(&navEvent.event);
}
- }
- else {
+ } else {
key_event_t keyEvent;
- initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP);
- keyEvent.key_code = key;
- keyEvent.character = 0;
- keyEvent.meta_key_state = 0;
+ initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP,
+ sizeof(keyEvent));
+ keyEvent.key_code = cap;
+ keyEvent.character = sym;
+ keyEvent.meta_key_state = mod;
+ keyEvent.sequence_id = sequenceId;
p_ictrl_dispatch_event(&keyEvent.event);
- qInputContextDebug() << Q_FUNC_INFO << "dispatch key event " << key;
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_even key" << key;
}
- scan = 0;
return true;
}
-void QQnxInputContext::endComposition()
+void QQnxInputContext::updateCursorPosition()
{
- if (!m_isComposing)
+ QObject *input = qGuiApp->focusObject();
+ if (!input)
return;
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ QInputMethodQueryEvent query(Qt::ImCursorPosition);
+ QCoreApplication::sendEvent(input, &query);
+ m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
+
+ qInputContextDebug() << Q_FUNC_INFO << m_caretPosition;
+}
+
+void QQnxInputContext::endComposition()
+{
+ if (!m_isComposing)
return;
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_composingText);
- m_composingText = QString();
- m_isComposing = false;
- QCoreApplication::sendEvent(input, &event);
+ finishComposingText();
- action_event_t actionEvent;
- memset(&actionEvent, 0, sizeof(actionEvent));
- initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION);
- p_ictrl_dispatch_event(&actionEvent.event);
+ if (hasSession()) {
+ action_event_t actionEvent;
+ initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION, sizeof(actionEvent));
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_even end composition";
+ p_ictrl_dispatch_event(&actionEvent.event);
+ }
}
-void QQnxInputContext::setComposingText(QString const& composingText)
+void QQnxInputContext::updateComposition(spannable_string_t *text, int32_t new_cursor_position)
{
- m_composingText = composingText;
+ QObject *input = qGuiApp->focusObject();
+ if (!input)
+ return;
+
+ if (new_cursor_position > 0)
+ new_cursor_position += text->length - 1;
+
+ m_composingText = QString::fromWCharArray(text->str, text->length);
m_isComposing = true;
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return;
+ qInputContextDebug() << Q_FUNC_INFO << m_composingText << new_cursor_position;
QList<QInputMethodEvent::Attribute> attributes;
- QTextCharFormat format;
- format.setFontUnderline(true);
- attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, composingText.length(), format));
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ new_cursor_position,
+ 1,
+ QVariant()));
+
+ for (unsigned int i = 0; i < text->spans_count; ++i) {
+ QColor highlightColor;
+ bool underline = false;
+
+ if ((text->spans[i].attributes_mask & COMPOSED_TEXT_ATTRIB) != 0)
+ underline = true;
+
+ if ((text->spans[i].attributes_mask & ACTIVE_REGION_ATTRIB) != 0) {
+ underline = true;
+ highlightColor = m_highlightColor[ActiveRegion];
+ } else if ((text->spans[i].attributes_mask & AUTO_CORRECTION_ATTRIB) != 0) {
+ highlightColor = m_highlightColor[AutoCorrected];
+ } else if ((text->spans[i].attributes_mask & REVERT_CORRECTION_ATTRIB) != 0) {
+ highlightColor = m_highlightColor[Reverted];
+ }
- QInputMethodEvent event(composingText, attributes);
+ if (underline || highlightColor.isValid()) {
+ QTextCharFormat format;
+ if (underline)
+ format.setFontUnderline(true);
+ if (highlightColor.isValid())
+ format.setBackground(QBrush(highlightColor));
+ qInputContextDebug() << " attrib: " << underline << highlightColor << text->spans[i].start << text->spans[i].end;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, text->spans[i].start,
+ text->spans[i].end - text->spans[i].start + 1, QVariant(format)));
+ }
+ }
+ QInputMethodEvent event(m_composingText, attributes);
+ m_isUpdatingText = true;
QCoreApplication::sendEvent(input, &event);
+ m_isUpdatingText = false;
+
+ updateCursorPosition();
+}
+
+void QQnxInputContext::finishComposingText()
+{
+ QObject *input = qGuiApp->focusObject();
+
+ if (input) {
+ qInputContextDebug() << Q_FUNC_INFO << m_composingText;
+
+ QInputMethodEvent event;
+ event.setCommitString(m_composingText);
+ m_isUpdatingText = true;
+ QCoreApplication::sendEvent(input, &event);
+ m_isUpdatingText = false;
+ }
+ m_composingText = QString();
+ m_isComposing = false;
+
+ updateCursorPosition();
+}
+
+// Return the index relative to a UTF-16 sequence of characters for a index that is relative to the
+// corresponding UTF-32 character string given a starting index in the UTF-16 string and a count
+// of the number of lead surrogates prior to that index. Updates the highSurrogateCount to reflect the
+// new surrogate characters encountered.
+static int adjustIndex(const QChar *text, int utf32Index, int utf16StartIndex, int *highSurrogateCount)
+{
+ int utf16Index = utf32Index + *highSurrogateCount;
+ while (utf16StartIndex < utf16Index) {
+ if (text[utf16StartIndex].isHighSurrogate()) {
+ ++utf16Index;
+ ++*highSurrogateCount;
+ }
+ ++utf16StartIndex;
+ }
+ return utf16StartIndex;
+}
+
+int QQnxInputContext::handleSpellCheck(spell_check_event_t *event)
+{
+ // These should never happen.
+ if (sSpellCheckQueue->isEmpty() || event->event.event_id != NOTIFY_SP_CHECK_MISSPELLINGS)
+ return -1;
+
+ SpellCheckInfo callerInfo = sSpellCheckQueue->dequeue();
+ spannable_string_t* spellCheckData = *event->data;
+ QString text = QString::fromWCharArray(spellCheckData->str, spellCheckData->length);
+ // Generate the list of indices indicating misspelled words in the text. We use end + 1
+ // since it's more conventional to have the end index point just past the string. We also
+ // can't use the indices directly since they are relative to UTF-32 encoded data and the
+ // conversion to Qt's UTF-16 internal format might cause lengthening.
+ QList<int> indices;
+ int adjustment = 0;
+ int index = 0;
+ for (unsigned int i = 0; i < spellCheckData->spans_count; ++i) {
+ if (spellCheckData->spans[i].attributes_mask & MISSPELLED_WORD_ATTRIB) {
+ index = adjustIndex(text.data(), spellCheckData->spans[i].start, index, &adjustment);
+ indices.push_back(index);
+ index = adjustIndex(text.data(), spellCheckData->spans[i].end + 1, index, &adjustment);
+ indices.push_back(index);
+ }
+ }
+ callerInfo.spellCheckDone(callerInfo.context, text, indices);
+
+ return 0;
}
int32_t QQnxInputContext::processEvent(event_t *event)
@@ -1128,7 +1091,7 @@ int32_t QQnxInputContext::processEvent(event_t *event)
switch (event->event_type) {
case EVENT_SPELL_CHECK: {
qInputContextDebug() << Q_FUNC_INFO << "EVENT_SPELL_CHECK";
- result = 0;
+ result = handleSpellCheck(reinterpret_cast<spell_check_event_t *>(event));
break;
}
@@ -1140,19 +1103,24 @@ int32_t QQnxInputContext::processEvent(event_t *event)
event->event_id == NAVIGATE_LEFT ? KEYCODE_LEFT :
event->event_id == NAVIGATE_RIGHT ? KEYCODE_RIGHT : 0;
- QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, key, 0, 0, 0);
- QQnxEventThread::injectKeyboardEvent(KEY_CAP_VALID, key, 0, 0, 0);
+ QQnxScreenEventHandler::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, key, 0, 0, 0);
+ QQnxScreenEventHandler::injectKeyboardEvent(KEY_CAP_VALID, key, 0, 0, 0);
result = 0;
break;
}
case EVENT_KEY: {
- qInputContextDebug() << Q_FUNC_INFO << "EVENT_KEY";
- key_event_t *kevent = static_cast<key_event_t *>(event);
-
- QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_SYM_VALID | KEY_CAP_VALID, kevent->key_code, 0, 0, kevent->key_code);
- QQnxEventThread::injectKeyboardEvent(KEY_SYM_VALID | KEY_CAP_VALID, kevent->key_code, 0, 0, kevent->key_code);
-
+ key_event_t *kevent = reinterpret_cast<key_event_t *>(event);
+ int keySym = kevent->character != 0 ? kevent->character : kevent->key_code;
+ int keyCap = kevent->key_code;
+ int modifiers = 0;
+ if (kevent->meta_key_state & META_SHIFT_ON)
+ modifiers |= KEYMOD_SHIFT;
+ int flags = KEY_SYM_VALID | KEY_CAP_VALID;
+ if (event->event_id == IMF_KEY_DOWN)
+ flags |= KEY_DOWN;
+ qInputContextDebug() << Q_FUNC_INFO << "EVENT_KEY" << flags << keySym;
+ QQnxScreenEventHandler::injectKeyboardEvent(flags, keySym, modifiers, 0, keyCap);
result = 0;
break;
}
@@ -1179,339 +1147,175 @@ int32_t QQnxInputContext::processEvent(event_t *event)
* IMF Event Handlers
*/
-int32_t QQnxInputContext::onBeginBatchEdit(input_session_t *ic)
-{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // We don't care.
- return 0;
-}
-
-int32_t QQnxInputContext::onClearMetaKeyStates(input_session_t *ic, int32_t states)
-{
- Q_UNUSED(states);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onClearMetaKeyStates is unsupported.";
- return 0;
-}
-
-int32_t QQnxInputContext::onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
+int32_t QQnxInputContext::onCommitText(spannable_string_t *text, int32_t new_cursor_position)
{
- Q_UNUSED(new_cursor_position); // TODO: How can we set the cursor position it's not part of the API.
- if (!isSessionOkay(ic))
- return 0;
-
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
-
- QString commitString = QString::fromWCharArray(text->str, text->length);
-
- qInputContextDebug() << Q_FUNC_INFO << "Committing [" << commitString << "]";
-
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(commitString, 0, 0);
+ Q_UNUSED(new_cursor_position);
- QCoreApplication::sendEvent(input, &event);
- m_composingText = QString();
+ updateComposition(text, new_cursor_position);
+ finishComposingText();
return 0;
}
-int32_t QQnxInputContext::onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length)
+int32_t QQnxInputContext::onDeleteSurroundingText(int32_t left_length, int32_t right_length)
{
qInputContextDebug() << Q_FUNC_INFO << "L:" << left_length << " R:" << right_length;
- if (!isSessionOkay(ic))
- return 0;
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
-
- if (hasSelectedText()) {
- QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, KEYCODE_DELETE, 0, 0, 0);
- QQnxEventThread::injectKeyboardEvent(KEY_CAP_VALID, KEYCODE_DELETE, 0, 0, 0);
- reset();
+ if (!input)
return 0;
- }
int replacementLength = left_length + right_length;
int replacementStart = -left_length;
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(QLatin1String(""), replacementStart, replacementLength);
- QCoreApplication::sendEvent(input, &event);
-
- return 0;
-}
-
-int32_t QQnxInputContext::onEndBatchEdit(input_session_t *ic)
-{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- return 0;
-}
-
-int32_t QQnxInputContext::onFinishComposingText(input_session_t *ic)
-{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
+ finishComposingText();
- // Only update the control, no need to send a message back to imf (don't call
- // end composition)
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_composingText);
- m_composingText = QString();
- m_isComposing = false;
+ QInputMethodEvent event;
+ event.setCommitString(QString(), replacementStart, replacementLength);
+ m_isUpdatingText = true;
QCoreApplication::sendEvent(input, &event);
+ m_isUpdatingText = false;
- return 0;
-}
-
-int32_t QQnxInputContext::onGetCursorCapsMode(input_session_t *ic, int32_t req_modes)
-{
- Q_UNUSED(req_modes);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onGetCursorCapsMode is unsupported.";
+ updateCursorPosition();
return 0;
}
-int32_t QQnxInputContext::onGetCursorPosition(input_session_t *ic)
+int32_t QQnxInputContext::onFinishComposingText()
{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ finishComposingText();
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
-
- QInputMethodQueryEvent query(Qt::ImCursorPosition);
- QCoreApplication::sendEvent(input, &query);
- m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt();
-
- return m_lastCaretPos;
-}
-
-extracted_text_t *QQnxInputContext::onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
-{
- Q_UNUSED(flags);
- Q_UNUSED(request);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic)) {
- extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1);
- et->text = reinterpret_cast<spannable_string_t *>(calloc(sizeof(spannable_string_t),1));
- return et;
- }
-
- // Used to update dictionaries, but not supported right now.
- extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1);
- et->text = reinterpret_cast<spannable_string_t *>(calloc(sizeof(spannable_string_t),1));
-
- return et;
+ return 0;
}
-spannable_string_t *QQnxInputContext::onGetSelectedText(input_session_t *ic, int32_t flags)
+int32_t QQnxInputContext::onGetCursorPosition()
{
- Q_UNUSED(flags);
qInputContextDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ if (!input)
return 0;
- QInputMethodQueryEvent query(Qt::ImCurrentSelection);
- QCoreApplication::sendEvent(input, &query);
- QString text = query.value(Qt::ImCurrentSelection).toString();
+ updateCursorPosition();
- return toSpannableString(text);
+ return m_caretPosition;
}
-spannable_string_t *QQnxInputContext::onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags)
+spannable_string_t *QQnxInputContext::onGetTextAfterCursor(int32_t n, int32_t flags)
{
Q_UNUSED(flags);
qInputContextDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ if (!input)
return toSpannableString("");
QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
QCoreApplication::sendEvent(input, &query);
QString text = query.value(Qt::ImSurroundingText).toString();
- m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt();
+ m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
- return toSpannableString(text.mid(m_lastCaretPos+1, n));
+ return toSpannableString(text.mid(m_caretPosition, n));
}
-spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags)
+spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(int32_t n, int32_t flags)
{
Q_UNUSED(flags);
qInputContextDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ if (!input)
return toSpannableString("");
QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
QCoreApplication::sendEvent(input, &query);
QString text = query.value(Qt::ImSurroundingText).toString();
- m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt();
+ m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
- if (n < m_lastCaretPos)
- return toSpannableString(text.mid(m_lastCaretPos - n, n));
+ if (n < m_caretPosition)
+ return toSpannableString(text.mid(m_caretPosition - n, n));
else
- return toSpannableString(text.mid(0, m_lastCaretPos));
-}
-
-int32_t QQnxInputContext::onPerformEditorAction(input_session_t *ic, int32_t editor_action)
-{
- Q_UNUSED(editor_action);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onPerformEditorAction is unsupported.";
-
- return 0;
-}
-
-int32_t QQnxInputContext::onReportFullscreenMode(input_session_t *ic, int32_t enabled)
-{
- Q_UNUSED(enabled);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onReportFullscreenMode is unsupported.";
-
- return 0;
-}
-
-int32_t QQnxInputContext::onSendEvent(input_session_t *ic, event_t *event)
-{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- return processEvent(event);
+ return toSpannableString(text.mid(0, m_caretPosition));
}
-int32_t QQnxInputContext::onSendAsyncEvent(input_session_t *ic, event_t *event)
+int32_t QQnxInputContext::onSendEvent(event_t *event)
{
qInputContextDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return 0;
-
return processEvent(event);
}
-int32_t QQnxInputContext::onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end)
+int32_t QQnxInputContext::onSetComposingRegion(int32_t start, int32_t end)
{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ if (!input)
return 0;
QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
QCoreApplication::sendEvent(input, &query);
QString text = query.value(Qt::ImSurroundingText).toString();
- m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt();
+ m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
- QString empty = QString::fromLatin1("");
- text = text.mid(start, end - start);
+ qInputContextDebug() << Q_FUNC_INFO << text;
+
+ m_isUpdatingText = true;
// Delete the current text.
+ QInputMethodEvent deleteEvent;
+ deleteEvent.setCommitString(QString(), start - m_caretPosition, end - start);
+ QCoreApplication::sendEvent(input, &deleteEvent);
+
+ m_composingText = text.mid(start, end - start);
+ m_isComposing = true;
+
QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(empty, attributes);
- event.setCommitString(empty, start - m_lastCaretPos, end - start);
- QCoreApplication::sendEvent(input, &event);
+ QTextCharFormat format;
+ format.setFontUnderline(true);
+ attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, m_composingText.length(), format));
+
+ QInputMethodEvent setTextEvent(m_composingText, attributes);
+ QCoreApplication::sendEvent(input, &setTextEvent);
- // Move the specified text into a preedit string.
- setComposingText(text);
+ m_isUpdatingText = false;
return 0;
}
-int32_t QQnxInputContext::onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
+int32_t QQnxInputContext::onSetComposingText(spannable_string_t *text, int32_t new_cursor_position)
{
- Q_UNUSED(new_cursor_position);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
+ if (text->length > 0) {
+ updateComposition(text, new_cursor_position);
+ } else {
+ // If the composing text is empty we can simply end composition, the visual effect is the same.
+ // However, sometimes one wants to display hint text in an empty text field and for this to work
+ // QQuickTextEdit.inputMethodComposing has to be false if the composition string is empty.
+ m_composingText.clear();
+ finishComposingText();
+ }
+ return 0;
+}
- m_isComposing = true;
+int32_t QQnxInputContext::onIsTextSelected(int32_t* pIsSelected)
+{
+ *pIsSelected = hasSelectedText();
- QString preeditString = QString::fromWCharArray(text->str, text->length);
- setComposingText(preeditString);
+ qInputContextDebug() << Q_FUNC_INFO << *pIsSelected;
return 0;
}
-int32_t QQnxInputContext::onSetSelection(input_session_t *ic, int32_t start, int32_t end)
+int32_t QQnxInputContext::onIsAllTextSelected(int32_t* pIsSelected)
{
- Q_UNUSED(start);
- Q_UNUSED(end);
- qInputContextDebug() << Q_FUNC_INFO;
+ QObject *input = qGuiApp->focusObject();
+ if (!input)
+ return -1;
- if (!isSessionOkay(ic))
- return 0;
+ QInputMethodQueryEvent query(Qt::ImCurrentSelection | Qt::ImSurroundingText);
+ QCoreApplication::sendEvent(input, &query);
+
+ *pIsSelected = query.value(Qt::ImSurroundingText).toString().length() == query.value(Qt::ImCurrentSelection).toString().length();
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onSetSelection is unsupported.";
+ qInputContextDebug() << Q_FUNC_INFO << *pIsSelected;
return 0;
}
@@ -1556,19 +1360,74 @@ void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale)
}
}
+void QQnxInputContext::setHighlightColor(int index, const QColor &color)
+{
+ qInputContextDebug() << Q_FUNC_INFO << "setHighlightColor" << index << color << qGuiApp->focusObject();
+
+ if (!sInputContextInstance)
+ return;
+
+ // If the focus has changed, revert all colors to the default.
+ if (sInputContextInstance->m_focusObject != qGuiApp->focusObject()) {
+ QColor invalidColor;
+ sInputContextInstance->m_highlightColor[ActiveRegion] = sSelectedColor;
+ sInputContextInstance->m_highlightColor[AutoCorrected] = invalidColor;
+ sInputContextInstance->m_highlightColor[Reverted] = invalidColor;
+ sInputContextInstance->m_focusObject = qGuiApp->focusObject();
+ }
+ if (index >= 0 && index <= Reverted)
+ sInputContextInstance->m_highlightColor[index] = color;
+}
+
void QQnxInputContext::setFocusObject(QObject *object)
{
qInputContextDebug() << Q_FUNC_INFO << "input item=" << object;
+ // Ensure the colors are reset if we've a change in focus object
+ setHighlightColor(-1, QColor());
+
if (!inputMethodAccepted()) {
if (m_inputPanelVisible)
hideInputPanel();
+ if (hasSession())
+ dispatchFocusLossEvent();
} else {
- m_virtualKeyboard.setInputHintsFromObject(object);
+ QInputMethodQueryEvent query(Qt::ImHints);
+ QCoreApplication::sendEvent(object, &query);
+ int inputHints = query.value(Qt::ImHints).toInt();
+
+ dispatchFocusGainEvent(inputHints);
+
+ m_virtualKeyboard.setInputHints(inputHints);
if (!m_inputPanelVisible)
showInputPanel();
}
}
+bool QQnxInputContext::checkSpelling(const QString &text, void *context, void (*spellCheckDone)(void *context, const QString &text, const QList<int> &indices))
+{
+ qInputContextDebug() << Q_FUNC_INFO << "text" << text;
+
+ if (!imfAvailable())
+ return false;
+
+ if (!sSpellCheckSession)
+ sSpellCheckSession = p_ictrl_open_session(&ic_funcs);
+
+ action_event_t spellEvent;
+ initEvent(&spellEvent.event, sSpellCheckSession, EVENT_ACTION, ACTION_CHECK_MISSPELLINGS, sizeof(spellEvent));
+ int len = text.length();
+ spellEvent.event_data = alloca(sizeof(wchar_t) * (len + 1));
+ spellEvent.length_data = text.toWCharArray(static_cast<wchar_t*>(spellEvent.event_data)) * sizeof(wchar_t);
+
+ int rc = p_ictrl_dispatch_event(reinterpret_cast<event_t*>(&spellEvent));
+
+ if (rc == 0) {
+ sSpellCheckQueue->enqueue(SpellCheckInfo(context, spellCheckDone));
+ return true;
+ }
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.h b/src/plugins/platforms/qnx/qqnxinputcontext_imf.h
index 1980a99ed9..5028215bbe 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.h
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.h
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -43,9 +43,11 @@
#define QQNXINPUTCONTEXT_H
#include <qpa/qplatforminputcontext.h>
+#include "qqnxscreeneventfilter.h"
#include <QtCore/QLocale>
#include <QtCore/QMetaType>
+#include <QtCore/QList>
#include <qpa/qplatformintegration.h>
#include "imf/imf_client.h"
@@ -55,21 +57,30 @@ QT_BEGIN_NAMESPACE
class QQnxAbstractVirtualKeyboard;
class QQnxIntegration;
+class QQnxImfRequest;
-class QQnxInputContext : public QPlatformInputContext
+class QQnxInputContext : public QPlatformInputContext, public QQnxScreenEventFilter
{
Q_OBJECT
public:
explicit QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVirtualKeyboard &keyboard);
~QQnxInputContext();
+ // Indices for selecting and setting highlight colors.
+ enum HighlightIndex {
+ ActiveRegion,
+ AutoCorrected,
+ Reverted,
+ };
+
bool isValid() const;
bool filterEvent(const QEvent *event);
QRectF keyboardRect() const;
void reset();
+ void commit();
void update(Qt::InputMethodQueries);
- bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
+ bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap, int sequenceId);
void showInputPanel();
@@ -79,61 +90,62 @@ public:
QLocale locale() const;
void setFocusObject(QObject *object);
-protected:
- // Filters only for IMF events.
- bool eventFilter(QObject *obj, QEvent *event);
+ static void setHighlightColor(int index, const QColor &color);
+
+ static bool checkSpelling(const QString &text, void *context, void (*spellCheckDone)(void *context, const QString &text, const QList<int> &indices));
private Q_SLOTS:
void keyboardVisibilityChanged(bool visible);
void keyboardLocaleChanged(const QLocale &locale);
+ void processImfEvent(QQnxImfRequest *event);
private:
// IMF Event dispatchers
- bool dispatchFocusEvent(FocusEventId id, int hints = Qt::ImhNone);
+ bool dispatchFocusGainEvent(int inputHints);
+ void dispatchFocusLossEvent();
bool dispatchRequestSoftwareInputPanel();
bool dispatchCloseSoftwareInputPanel();
+ int handleSpellCheck(spell_check_event_t *event);
int32_t processEvent(event_t *event);
void closeSession();
- void openSession();
+ bool openSession();
bool hasSession();
+ void updateCursorPosition();
void endComposition();
- void setComposingText(QString const &composingText);
+ void finishComposingText();
bool hasSelectedText();
+ void updateComposition(spannable_string_t *text, int32_t new_cursor_position);
// IMF Event handlers - these events will come in from QCoreApplication.
- int32_t onBeginBatchEdit(input_session_t *ic);
- int32_t onClearMetaKeyStates(input_session_t *ic, int32_t states);
- int32_t onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position);
- int32_t onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length);
- int32_t onEndBatchEdit(input_session_t *ic);
- int32_t onFinishComposingText(input_session_t *ic);
- int32_t onGetCursorCapsMode(input_session_t *ic, int32_t req_modes);
- int32_t onGetCursorPosition(input_session_t *ic);
- extracted_text_t *onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags);
- spannable_string_t *onGetSelectedText(input_session_t *ic, int32_t flags);
- spannable_string_t *onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags);
- spannable_string_t *onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags);
- int32_t onPerformEditorAction(input_session_t *ic, int32_t editor_action);
- int32_t onReportFullscreenMode(input_session_t *ic, int32_t enabled);
- int32_t onSendEvent(input_session_t *ic, event_t *event);
- int32_t onSendAsyncEvent(input_session_t *ic, event_t *event);
- int32_t onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end);
- int32_t onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position);
- int32_t onSetSelection(input_session_t *ic, int32_t start, int32_t end);
+ int32_t onCommitText(spannable_string_t *text, int32_t new_cursor_position);
+ int32_t onDeleteSurroundingText(int32_t left_length, int32_t right_length);
+ int32_t onGetCursorCapsMode(int32_t req_modes);
+ int32_t onFinishComposingText();
+ int32_t onGetCursorPosition();
+ spannable_string_t *onGetTextAfterCursor(int32_t n, int32_t flags);
+ spannable_string_t *onGetTextBeforeCursor(int32_t n, int32_t flags);
+ int32_t onSendEvent(event_t *event);
+ int32_t onSetComposingRegion(int32_t start, int32_t end);
+ int32_t onSetComposingText(spannable_string_t *text, int32_t new_cursor_position);
+ int32_t onIsTextSelected(int32_t* pIsSelected);
+ int32_t onIsAllTextSelected(int32_t* pIsSelected);
int32_t onForceUpdate();
- int m_lastCaretPos;
+ int m_caretPosition;
bool m_isComposing;
QString m_composingText;
+ bool m_isUpdatingText;
bool m_inputPanelVisible;
QLocale m_inputPanelLocale;
+ // The object that had focus when the last highlight color was set.
+ QObject *m_focusObject;
+ // Indexed by HighlightIndex
+ QColor m_highlightColor[3];
QQnxIntegration *m_integration;
- QQnxAbstractVirtualKeyboard &m_virtualKeyboad;
+ QQnxAbstractVirtualKeyboard &m_virtualKeyboard;
};
-Q_DECLARE_METATYPE(extracted_text_t*)
-
QT_END_NAMESPACE
#endif // QQNXINPUTCONTEXT_H
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
index f444d34b5e..9270f1ed6b 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -46,6 +46,7 @@
#include <QtCore/QDebug>
#include <QtGui/QGuiApplication>
+#include <QtGui/QInputMethodEvent>
#if defined(QQNXINPUTCONTEXT_DEBUG)
#define qInputContextDebug qDebug
@@ -179,7 +180,11 @@ void QQnxInputContext::setFocusObject(QObject *object)
if (m_inputPanelVisible)
hideInputPanel();
} else {
- m_virtualKeyboard.setInputHintsFromObject(object);
+ QInputMethodQueryEvent query(Qt::ImHints);
+ QCoreApplication::sendEvent(object, &query);
+ int inputHints = query.value(Qt::ImHints).toInt();
+
+ m_virtualKeyboard.setInputHints(inputHints);
if (!m_inputPanelVisible)
showInputPanel();
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 52f836abbe..b39311353c 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxintegration.h"
#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
@@ -123,6 +125,10 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
options |= QQnxIntegration::FullScreenApplication;
}
+ if (!paramList.contains(QLatin1String("flush-screen-context"))) {
+ options |= QQnxIntegration::AlwaysFlushScreenContext;
+ }
+
// On Blackberry the first window is treated as a root window
#ifdef Q_OS_BLACKBERRY
if (!paramList.contains(QLatin1String("no-rootwindow"))) {
@@ -165,14 +171,12 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#if !defined(QT_NO_DRAGANDDROP)
, m_drag(new QSimpleDrag())
#endif
- , m_options(parseOptions(paramList))
{
+ ms_options = parseOptions(paramList);
qIntegrationDebug() << Q_FUNC_INFO;
// Open connection to QNX composition manager
- errno = 0;
- int result = screen_create_context(&m_screenContext, SCREEN_APPLICATION_CONTEXT);
- if (result != 0)
- qFatal("QQnx: failed to connect to composition manager, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(screen_create_context(&ms_screenContext, SCREEN_APPLICATION_CONTEXT),
+ "Failed to create screen context");
// Not on BlackBerry, it has specialized event dispatcher which also handles navigator events
#if !defined(Q_OS_BLACKBERRY) && defined(QQNX_PPS)
@@ -191,7 +195,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
// Create/start event thread
#if defined(QQNX_SCREENEVENTTHREAD)
- m_screenEventThread = new QQnxScreenEventThread(m_screenContext, m_screenEventHandler);
+ m_screenEventThread = new QQnxScreenEventThread(ms_screenContext, m_screenEventHandler);
m_screenEventThread->start();
#endif
@@ -251,6 +255,9 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#if defined(QQNX_PPS)
// Set up the input context
m_inputContext = new QQnxInputContext(this, *m_virtualKeyboard);
+#if defined(QQNX_IMF)
+ m_screenEventHandler->addScreenEventFilter(m_inputContext);
+#endif
#endif
}
@@ -271,17 +278,6 @@ QQnxIntegration::~QQnxIntegration()
delete m_drag;
#endif
-#if defined(QQNX_PPS)
- // Destroy the hardware button notifier
- delete m_buttonsNotifier;
-
- // Destroy input context
- delete m_inputContext;
-#endif
-
- // Destroy the keyboard class.
- delete m_virtualKeyboard;
-
#if !defined(QT_NO_CLIPBOARD)
// Delete the clipboard
delete m_clipboard;
@@ -314,13 +310,24 @@ QQnxIntegration::~QQnxIntegration()
destroyDisplays();
// Close connection to QNX composition manager
- screen_destroy_context(m_screenContext);
+ screen_destroy_context(ms_screenContext);
#if !defined(QT_NO_OPENGL)
// Cleanup global OpenGL resources
QQnxGLContext::shutdown();
#endif
+#if defined(QQNX_PPS)
+ // Destroy the hardware button notifier
+ delete m_buttonsNotifier;
+
+ // Destroy input context
+ delete m_inputContext;
+#endif
+
+ // Destroy the keyboard class.
+ delete m_virtualKeyboard;
+
// Destroy services class
delete m_services;
@@ -355,10 +362,10 @@ QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const
const bool needRootWindow = options() & RootWindow;
switch (surfaceType) {
case QSurface::RasterSurface:
- return new QQnxRasterWindow(window, m_screenContext, needRootWindow);
+ return new QQnxRasterWindow(window, ms_screenContext, needRootWindow);
#if !defined(QT_NO_OPENGL)
case QSurface::OpenGLSurface:
- return new QQnxEglWindow(window, m_screenContext, needRootWindow);
+ return new QQnxEglWindow(window, ms_screenContext, needRootWindow);
#endif
default:
qFatal("QQnxWindow: unsupported window API");
@@ -441,7 +448,7 @@ QPlatformDrag *QQnxIntegration::drag() const
QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
qIntegrationDebug() << Q_FUNC_INFO;
- if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication))
+ if ((hint == ShowIsFullScreen) && (ms_options & FullScreenApplication))
return true;
return QPlatformIntegration::styleHint(hint);
@@ -495,11 +502,10 @@ void QQnxIntegration::createDisplays()
{
qIntegrationDebug() << Q_FUNC_INFO;
// Query number of displays
- errno = 0;
- int displayCount;
- int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount);
- if (result != 0)
- qFatal("QQnxIntegration: failed to query display count, errno=%d", errno);
+ int displayCount = 0;
+ int result = screen_get_context_property_iv(ms_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT,
+ &displayCount);
+ Q_SCREEN_CRITICALERROR(result, "Failed to query display count");
if (displayCount < 1) {
// Never happens, even if there's no display, libscreen returns 1
@@ -507,23 +513,20 @@ void QQnxIntegration::createDisplays()
}
// Get all displays
- errno = 0;
screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
- result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS, (void **)displays);
- if (result != 0)
- qFatal("QQnxIntegration: failed to query displays, errno=%d", errno);
+ result = screen_get_context_property_pv(ms_screenContext, SCREEN_PROPERTY_DISPLAYS,
+ (void **)displays);
+ Q_SCREEN_CRITICALERROR(result, "Failed to query displays");
// If it's primary, we create a QScreen for it even if it's not attached
// since Qt will dereference QGuiApplication::primaryScreen()
createDisplay(displays[0], /*isPrimary=*/true);
for (int i=1; i<displayCount; i++) {
- int isAttached = 0;
- result = screen_get_display_property_iv(displays[i], SCREEN_PROPERTY_ATTACHED, &isAttached);
- if (result != 0) {
- qWarning("QQnxIntegration: failed to query display attachment, errno=%d", errno);
- isAttached = 1; // assume attached
- }
+ int isAttached = 1;
+ result = screen_get_display_property_iv(displays[i], SCREEN_PROPERTY_ATTACHED,
+ &isAttached);
+ Q_SCREEN_CHECKERROR(result, "Failed to query display attachment");
if (!isAttached) {
qIntegrationDebug() << Q_FUNC_INFO << "Skipping non-attached display" << i;
@@ -537,7 +540,7 @@ void QQnxIntegration::createDisplays()
void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary)
{
- QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary);
+ QQnxScreen *screen = new QQnxScreen(ms_screenContext, display, isPrimary);
m_screens.append(screen);
screenAdded(screen);
screen->adjustOrientation();
@@ -584,11 +587,20 @@ QQnxScreen *QQnxIntegration::primaryDisplay() const
return m_screens.first();
}
-QQnxIntegration::Options QQnxIntegration::options() const
+QQnxIntegration::Options QQnxIntegration::options()
+{
+ return ms_options;
+}
+
+screen_context_t QQnxIntegration::screenContext()
{
- return m_options;
+ return ms_screenContext;
}
+screen_context_t QQnxIntegration::ms_screenContext = 0;
+
+QQnxIntegration::Options QQnxIntegration::ms_options = 0;
+
bool QQnxIntegration::supportsNavigatorEvents() const
{
// If QQNX_PPS or Q_OS_BLACKBERRY is defined then we have navigator
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index 8b5614fe4f..b5f03d4727 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -85,7 +85,8 @@ public:
enum Option { // Options to be passed on command line.
NoOptions = 0x0,
FullScreenApplication = 0x1,
- RootWindow = 0x2
+ RootWindow = 0x2,
+ AlwaysFlushScreenContext = 0x4
};
Q_DECLARE_FLAGS(Options, Option)
explicit QQnxIntegration(const QStringList &paramList);
@@ -137,7 +138,8 @@ public:
void createDisplay(screen_display_t display, bool isPrimary);
void removeDisplay(QQnxScreen *screen);
QQnxScreen *primaryDisplay() const;
- Options options() const;
+ static Options options();
+ static screen_context_t screenContext();
private:
void createDisplays();
@@ -146,7 +148,7 @@ private:
static void addWindow(screen_window_t qnxWindow, QWindow *window);
static void removeWindow(screen_window_t qnxWindow);
- screen_context_t m_screenContext;
+ static screen_context_t ms_screenContext;
#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_screenEventThread;
#endif
@@ -176,7 +178,7 @@ private:
static QQnxWindowMapper ms_windowMapper;
static QMutex ms_windowMapperMutex;
- const Options m_options;
+ static Options ms_options;
friend class QQnxWindow;
};
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
index e468b051cd..df9d96739a 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
@@ -44,6 +44,9 @@
#include "qqnxglcontext.h"
#include "qqnxscreen.h"
#include "qqnxwindow.h"
+#if defined(QQNX_IMF)
+#include "qqnxinputcontext_imf.h"
+#endif
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
@@ -85,10 +88,27 @@ void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource,
void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
{
+ QQnxWindow *qnxWindow = static_cast<QQnxWindow*>(window);
+
if (name == QStringLiteral("mmRendererWindowName")) {
- QQnxWindow *qnxWindow = static_cast<QQnxWindow*>(window);
qnxWindow->setMMRendererWindowName(value.toString());
+ } else if (name == QStringLiteral("windowGroup")) {
+ if (value.isNull())
+ qnxWindow->joinWindowGroup(QByteArray());
+ else if (value.canConvert<QByteArray>())
+ qnxWindow->joinWindowGroup(value.toByteArray());
}
}
+QPlatformNativeInterface::NativeResourceForIntegrationFunction QQnxNativeInterface::nativeResourceFunctionForIntegration(const QByteArray &resource)
+{
+#if defined(QQNX_IMF)
+ if (resource == "blackberryIMFSetHighlightColor")
+ return reinterpret_cast<NativeResourceForIntegrationFunction>(QQnxInputContext::setHighlightColor);
+ if (resource == "blackberryIMFCheckSpelling")
+ return reinterpret_cast<NativeResourceForIntegrationFunction>(QQnxInputContext::checkSpelling);
+#endif
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.h b/src/plugins/platforms/qnx/qqnxnativeinterface.h
index dfd386214e..e2fdd32689 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.h
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h
@@ -51,8 +51,10 @@ class QQnxNativeInterface : public QPlatformNativeInterface
public:
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
+
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
+ NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
index 0d8daac0ee..2c0639e8e3 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxrasterwindow.h"
#include "qqnxscreen.h"
@@ -108,10 +110,9 @@ void QQnxRasterWindow::post(const QRegion &dirty)
int dirtyRect[4] = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() };
// Update the display with contents of render buffer
- errno = 0;
- int result = screen_post_window(nativeHandle(), currentBuffer.nativeBuffer(), 1, dirtyRect, 0);
- if (result != 0)
- qFatal("QQnxWindow: failed to post window buffer, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_post_window(nativeHandle(), currentBuffer.nativeBuffer(), 1, dirtyRect, 0),
+ "Failed to post window");
// Advance to next nender buffer
m_previousBufferIndex = m_currentBufferIndex++;
@@ -141,28 +142,23 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer()
// Check if render buffer is invalid
if (m_currentBufferIndex == -1) {
// Get all buffers available for rendering
- errno = 0;
screen_buffer_t buffers[MAX_BUFFER_COUNT];
- int result = screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers);
- if (result != 0)
- qFatal("QQnxRasterWindow: failed to query window buffers, errno=%d", errno);
+ const int result = screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_RENDER_BUFFERS,
+ (void **)buffers);
+ Q_SCREEN_CRITICALERROR(result, "Failed to query window buffers");
// Wrap each buffer and clear
for (int i = 0; i < MAX_BUFFER_COUNT; ++i) {
m_buffers[i] = QQnxBuffer(buffers[i]);
// Clear Buffer
- errno = 0;
int bg[] = { SCREEN_BLIT_COLOR, 0x00000000, SCREEN_BLIT_END };
- result = screen_fill(screen()->nativeContext(), buffers[i], bg);
- if (result != 0)
- qFatal("QQnxWindow: failed to clear window buffer, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_fill(screen()->nativeContext(), buffers[i], bg),
+ "Failed to clear window buffer");
}
- errno = 0;
- result = screen_flush_blits(screen()->nativeContext(), 0);
- if (result != 0)
- qFatal("QQnxWindow: failed to flush blits, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_flush_blits(screen()->nativeContext(), 0),
+ "Failed to flush blits");
// Use the first available render buffer
m_currentBufferIndex = 0;
@@ -172,11 +168,17 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer()
return m_buffers[m_currentBufferIndex];
}
+void QQnxRasterWindow::setParent(const QPlatformWindow *wnd)
+{
+ QQnxWindow::setParent(wnd);
+ adjustBufferSize();
+}
+
void QQnxRasterWindow::adjustBufferSize()
{
// When having a raster window we don't need any buffers, since
// Qt will draw to the parent TLW backing store.
- const QSize windowSize = m_parentWindow ? QSize(1,1) : window()->size();
+ const QSize windowSize = window()->parent() ? QSize(1,1) : window()->size();
if (windowSize != bufferSize())
setBufferSize(windowSize);
}
@@ -226,20 +228,16 @@ void QQnxRasterWindow::blitPreviousToCurrent(const QRegion &region, int dx, int
SCREEN_BLIT_END };
// Queue blit operation
- errno = 0;
- const int result = screen_blit(m_screenContext, currentBuffer.nativeBuffer(),
- previousBuffer.nativeBuffer(), attribs);
- if (result != 0)
- qFatal("QQnxWindow: failed to blit buffers, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_blit(m_screenContext, currentBuffer.nativeBuffer(),
+ previousBuffer.nativeBuffer(), attribs),
+ "Failed to blit buffers");
}
// Check if flush requested
if (flush) {
// Wait for all blits to complete
- errno = 0;
- const int result = screen_flush_blits(m_screenContext, SCREEN_WAIT_IDLE);
- if (result != 0)
- qFatal("QQnxWindow: failed to flush blits, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_flush_blits(m_screenContext, SCREEN_WAIT_IDLE),
+ "Failed to flush blits");
// Buffer was modified outside the CPU
currentBuffer.invalidateInCache();
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.h b/src/plugins/platforms/qnx/qqnxrasterwindow.h
index ad34b3ccf2..2be5f63464 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.h
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.h
@@ -60,6 +60,8 @@ public:
bool hasBuffers() const { return !bufferSize().isEmpty(); }
+ void setParent(const QPlatformWindow *window);
+
void adjustBufferSize();
protected:
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 3a0607f214..a6c69164c7 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxscreen.h"
#include "qqnxwindow.h"
#include "qqnxcursor.h"
@@ -75,10 +77,9 @@ QT_BEGIN_NAMESPACE
static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
int val[2];
- errno = 0;
const int result = screen_get_display_property_iv(display, SCREEN_PROPERTY_PHYSICAL_SIZE, val);
+ Q_SCREEN_CHECKERROR(result, "Failed to query display physical size");
if (result != 0) {
- qFatal("QQnxScreen: failed to query display physical size, errno=%d", errno);
return QSize(150, 90);
}
@@ -163,19 +164,16 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,
{
qScreenDebug() << Q_FUNC_INFO;
// Cache initial orientation of this display
- errno = 0;
- int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION, &m_initialRotation);
- if (result != 0)
- qFatal("QQnxScreen: failed to query display rotation, errno=%d", errno);
+ int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION,
+ &m_initialRotation);
+ Q_SCREEN_CHECKERROR(result, "Failed to query display rotation");
m_currentRotation = m_initialRotation;
// Cache size of this display in pixels
- errno = 0;
int val[2];
- result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_SIZE, val);
- if (result != 0)
- qFatal("QQnxScreen: failed to query display size, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(screen_get_display_property_iv(m_display, SCREEN_PROPERTY_SIZE, val),
+ "Failed to query display size");
m_currentGeometry = m_initialGeometry = QRect(0, 0, val[0], val[1]);
@@ -200,6 +198,9 @@ QQnxScreen::~QQnxScreen()
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->setScreen(0);
+ if (m_coverWindow)
+ m_coverWindow->setScreen(0);
+
delete m_cursor;
}
@@ -505,7 +506,6 @@ void QQnxScreen::raiseWindow(QQnxWindow *window)
if (window != m_coverWindow) {
removeWindow(window);
m_childWindows.push_back(window);
- updateHierarchy();
}
}
@@ -516,7 +516,6 @@ void QQnxScreen::lowerWindow(QQnxWindow *window)
if (window != m_coverWindow) {
removeWindow(window);
m_childWindows.push_front(window);
- updateHierarchy();
}
}
@@ -671,7 +670,7 @@ void QQnxScreen::newWindowCreated(void *window)
// Otherwise, assume that if a foreign window already has a Z-Order both negative and
// less than the default Z-Order installed by mmrender on windows it creates,
// the windows should be treated as an underlay. Otherwise, we treat it as an overlay.
- if (!windowName.isEmpty() && windowName.startsWith("BbVideoWindowControl")) {
+ if (!windowName.isEmpty() && windowName.startsWith("MmRendererVideoWindowControl")) {
addMultimediaWindow(windowName, windowHandle);
} else if (!findWindow(windowHandle)) {
if (zorder <= MAX_UNDERLAY_ZORDER)
@@ -728,8 +727,6 @@ void QQnxScreen::activateWindowGroup(const QByteArray &id)
if (m_coverWindow)
m_coverWindow->setExposed(false);
-
- QWindowSystemInterface::handleWindowActivated(window);
}
void QQnxScreen::deactivateWindowGroup(const QByteArray &id)
@@ -744,8 +741,6 @@ void QQnxScreen::deactivateWindowGroup(const QByteArray &id)
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->setExposed(false);
-
- QWindowSystemInterface::handleWindowActivated(rootWindow()->window());
}
QQnxWindow *QQnxScreen::rootWindow() const
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index 61c47e6c72..d39a210d4b 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -80,7 +80,7 @@ public:
int nativeFormat() const { return (depth() == 32) ? SCREEN_FORMAT_RGBA8888 : SCREEN_FORMAT_RGB565; }
screen_display_t nativeDisplay() const { return m_display; }
screen_context_t nativeContext() const { return m_screenContext; }
- const char *windowGroupName() const { return rootWindow()->groupName().constData(); }
+ const char *windowGroupName() const { return m_rootWindow ? m_rootWindow->groupName().constData() : 0; }
QQnxWindow *findWindow(screen_window_t windowHandle);
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventfilter.h b/src/plugins/platforms/qnx/qqnxscreeneventfilter.h
new file mode 100644
index 0000000000..f9ecadd2a9
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxscreeneventfilter.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQNXSCREENEVENTFILTER_H
+#define QQNXSCREENEVENTFILTER_H
+
+QT_BEGIN_NAMESPACE
+
+class QQnxScreenEventFilter
+{
+protected:
+ ~QQnxScreenEventFilter() {}
+
+public:
+ virtual bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap, int sequenceId) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index 6f06797393..8757e391ef 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxscreeneventhandler.h"
#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
@@ -46,6 +48,7 @@
#include "qqnxintegration.h"
#include "qqnxkeytranslator.h"
#include "qqnxscreen.h"
+#include "qqnxscreeneventfilter.h"
#include <QDebug>
#include <QGuiApplication>
@@ -90,14 +93,22 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration)
}
}
+void QQnxScreenEventHandler::addScreenEventFilter(QQnxScreenEventFilter *filter)
+{
+ m_eventFilters.append(filter);
+}
+
+void QQnxScreenEventHandler::removeScreenEventFilter(QQnxScreenEventFilter *filter)
+{
+ m_eventFilters.removeOne(filter);
+}
+
bool QQnxScreenEventHandler::handleEvent(screen_event_t event)
{
// get the event type
- errno = 0;
int qnxType;
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType);
- if (result)
- qFatal("QQNX: failed to query event type, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType),
+ "Failed to query event type");
return handleEvent(event, qnxType);
}
@@ -228,35 +239,44 @@ void QQnxScreenEventHandler::processEventsFromScreenThread()
void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
{
// get flags of key event
- errno = 0;
int flags;
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
- if (result)
- qFatal("QQNX: failed to query event flags, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags),
+ "Failed to query event flags");
// get key code
- errno = 0;
int sym;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym);
- if (result)
- qFatal("QQNX: failed to query event sym, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym),
+ "Failed to query event sym");
int modifiers;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers);
- if (result)
- qFatal("QQNX: failed to query event modifiers, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers),
+ "Failed to query event modifieres");
int scan;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan);
- if (result)
- qFatal("QQNX: failed to query event modifiers, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan),
+ "Failed to query event scan");
int cap;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap);
- if (result)
- qFatal("QQNX: failed to query event cap, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap),
+ "Failed to query event cap");
+
+ int sequenceId = 0;
+#if defined(Q_OS_BLACKBERRY)
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_SEQUENCE_ID, &sequenceId),
+ "Failed to query event seqId");
+#endif
- injectKeyboardEvent(flags, sym, modifiers, scan, cap);
+ bool inject = true;
+ Q_FOREACH (QQnxScreenEventFilter *filter, m_eventFilters) {
+ if (filter->handleKeyboardEvent(flags, sym, modifiers, scan, cap, sequenceId)) {
+ inject = false;
+ break;
+ }
+ }
+
+ if (inject)
+ injectKeyboardEvent(flags, sym, modifiers, scan, cap);
}
void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
@@ -266,35 +286,32 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
// Query the window that was clicked
screen_window_t qnxWindow;
void *handle;
- int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
- if (result)
- qFatal("QQNX: failed to query event window, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle),
+ "Failed to query event window");
qnxWindow = static_cast<screen_window_t>(handle);
// Query the button states
int buttonState = 0;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState);
- if (result)
- qFatal("QQNX: failed to query event button state, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState),
+ "Failed to query event button state");
// Query the window position
int windowPos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
- if (result)
- qFatal("QQNX: failed to query event window position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos),
+ "Failed to query event window position");
// Query the screen position
int pos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
- if (result)
- qFatal("QQNX: failed to query event position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos),
+ "Failed to query event position");
// Query the wheel delta
int wheelDelta = 0;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta);
- if (result)
- qFatal("QQNX: failed to query event wheel delta, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta),
+ "Failed to query event wheel delta");
// Map window handle to top-level QWindow
QWindow *w = QQnxIntegration::window(qnxWindow);
@@ -314,10 +331,6 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
}
}
- // If we don't have a navigator, we don't get activation events.
- if (buttonState && w && w != QGuiApplication::focusWindow() && !m_qnxIntegration->supportsNavigatorEvents())
- QWindowSystemInterface::handleWindowActivated(w);
-
m_lastMouseWindow = qnxWindow;
// Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale
@@ -376,34 +389,36 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
{
// get display coordinates of touch
- errno = 0;
int pos[2];
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
- if (result)
- qFatal("QQNX: failed to query event position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos),
+ "Failed to query event position");
QCursor::setPos(pos[0], pos[1]);
// get window coordinates of touch
- errno = 0;
int windowPos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
- if (result)
- qFatal("QQNX: failed to query event window position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos),
+ "Failed to query event window position");
// determine which finger touched
- errno = 0;
int touchId;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId);
- if (result)
- qFatal("QQNX: failed to query event touch id, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId),
+ "Failed to query event touch id");
// determine which window was touched
- errno = 0;
void *handle;
- result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
- if (result)
- qFatal("QQNX: failed to query event window, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle),
+ "Failed to query event window");
+
+ errno = 0;
+ int touchArea[2];
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SIZE, touchArea),
+ "Failed to query event touch area");
+
+ int touchPressure;
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_PRESSURE, &touchPressure),
+ "Failed to query event touch pressure");
screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
@@ -439,14 +454,23 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
QPointF(static_cast<qreal>(pos[0]) / screenSize.width(),
static_cast<qreal>(pos[1]) / screenSize.height());
- m_touchPoints[touchId].area = QRectF(w->geometry().left() + windowPos[0],
- w->geometry().top() + windowPos[1], 0.0, 0.0);
+ m_touchPoints[touchId].area = QRectF(w->geometry().left() + windowPos[0] - (touchArea[0]>>1),
+ w->geometry().top() + windowPos[1] - (touchArea[1]>>1),
+ 0.0, 0.0);
QWindow *parent = w->parent();
while (parent) {
m_touchPoints[touchId].area.translate(parent->geometry().topLeft());
parent = parent->parent();
}
+ //Qt expects the pressure between 0 and 1. There is however no definit upper limit for
+ //the integer value of touch event pressure. The 200 was determined by experiment, it
+ //usually does not get higher than that.
+ m_touchPoints[touchId].pressure = static_cast<qreal>(touchPressure)/200.0;
+ // Can happen, because there is no upper limit for pressure
+ if (m_touchPoints[touchId].pressure > 1)
+ m_touchPoints[touchId].pressure = 1;
+
// determine event type and update state of current touch point
QEvent::Type type = QEvent::None;
switch (qnxType) {
@@ -489,8 +513,9 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event)
{
screen_window_t window = 0;
- if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
- qFatal("QQnx: failed to query window property, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window),
+ "Failed to query window property");
Q_EMIT windowClosed(window);
@@ -503,8 +528,9 @@ void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event)
void QQnxScreenEventHandler::handleCreateEvent(screen_event_t event)
{
screen_window_t window = 0;
- if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
- qFatal("QQnx: failed to query window property, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window),
+ "Failed to query window property");
Q_EMIT newWindowCreated(window);
}
@@ -556,8 +582,9 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event)
{
errno = 0;
int objectType;
- if (screen_get_event_property_iv(event, SCREEN_PROPERTY_OBJECT_TYPE, &objectType) != 0)
- qFatal("QQNX: failed to query object type property, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_OBJECT_TYPE, &objectType),
+ "Failed to query object type property");
if (objectType != SCREEN_OBJECT_TYPE_WINDOW)
return;
@@ -589,9 +616,15 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi
if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0)
qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno);
- QWindow *w = focus ? QQnxIntegration::window(window) : 0;
-
- QWindowSystemInterface::handleWindowActivated(w);
+ QWindow *focusWindow = QQnxIntegration::window(window);
+ if (focus) {
+ QWindowSystemInterface::handleWindowActivated(focusWindow);
+ } else if (focusWindow == QGuiApplication::focusWindow()) {
+ // Deactivate only if the window was the focus window.
+ // Screen might send a keyboard focus event for a newly created
+ // window on the secondary screen, with focus 0.
+ QWindowSystemInterface::handleWindowActivated(0);
+ }
}
#include "moc_qqnxscreeneventhandler.cpp"
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
index 1fdb2c83cd..a7bcd449ee 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -49,6 +49,7 @@
QT_BEGIN_NAMESPACE
class QQnxIntegration;
+class QQnxScreenEventFilter;
#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
#endif
@@ -59,6 +60,9 @@ class QQnxScreenEventHandler : public QObject
public:
explicit QQnxScreenEventHandler(QQnxIntegration *integration);
+ void addScreenEventFilter(QQnxScreenEventFilter *filter);
+ void removeScreenEventFilter(QQnxScreenEventFilter *filter);
+
bool handleEvent(screen_event_t event);
bool handleEvent(screen_event_t event, int qnxType);
@@ -99,6 +103,7 @@ private:
screen_window_t m_lastMouseWindow;
QTouchDevice *m_touchDevice;
QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
+ QList<QQnxScreenEventFilter*> m_eventFilters;
#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_eventThread;
#endif
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
index 25a597bab9..156ba8a780 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxscreeneventthread.h"
#include "qqnxscreeneventhandler.h"
@@ -92,30 +94,34 @@ void QQnxScreenEventThread::run()
{
qScreenEventThreadDebug() << Q_FUNC_INFO << "screen event thread started";
+ int errorCounter = 0;
// loop indefinitely
while (!m_quit) {
screen_event_t event;
// create screen event
- errno = 0;
- int result = screen_create_event(&event);
- if (result)
- qFatal("QQNX: failed to create screen event, errno=%d", errno);
-
+ Q_SCREEN_CHECKERROR(screen_create_event(&event), "Failed to create screen event");
// block until screen event is available
- errno = 0;
- result = screen_get_event(m_screenContext, event, -1);
- if (result)
- qFatal("QQNX: failed to get screen event, errno=%d", errno);
+ const int result = screen_get_event(m_screenContext, event, -1);
+ Q_SCREEN_CRITICALERROR(result, "Failed to get screen event");
+ // Only allow 50 consecutive errors before we exit the thread
+ if (!result) {
+ errorCounter++;
+ if (errorCounter > 50)
+ m_quit = true;
+
+ screen_destroy_event(event);
+ continue;
+ } else {
+ errorCounter = 0;
+ }
// process received event
// get the event type
- errno = 0;
int qnxType;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType);
- if (result)
- qFatal("QQNX: failed to query screen event type, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType),
+ "Failed to query screen event type");
if (qnxType == SCREEN_EVENT_USER) {
// treat all user events as shutdown requests
@@ -145,25 +151,19 @@ void QQnxScreenEventThread::shutdown()
screen_event_t event;
// create screen event
- errno = 0;
- int result = screen_create_event(&event);
- if (result)
- qFatal("QQNX: failed to create screen event, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_create_event(&event),
+ "Failed to create screen event");
// set the event type as user
- errno = 0;
int type = SCREEN_EVENT_USER;
- result = screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type);
- if (result)
- qFatal("QQNX: failed to set screen event type, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type),
+ "Failed to set screen type");
// NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events
// post event to event loop so it will wake up and die
- errno = 0;
- result = screen_send_event(m_screenContext, event, getpid());
- if (result)
- qFatal("QQNX: failed to set screen event type, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_send_event(m_screenContext, event, getpid()),
+ "Failed to set screen event type");
// cleanup
screen_destroy_event(event);
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
index 11eb4a5082..08de94a082 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -46,6 +46,9 @@
#include <bps/event.h>
#include <bps/locale.h>
#include <bps/virtualkeyboard.h>
+#if defined(Q_OS_BLACKBERRY)
+#include <bbndk.h>
+#endif
#if defined(QQNXVIRTUALKEYBOARD_DEBUG)
#define qVirtualKeyboardDebug qDebug
@@ -89,7 +92,7 @@ bool QQnxVirtualKeyboardBps::showKeyboard()
// They keyboard's mode is global between applications, we have to set it each time
if ( !isVisible() )
- applyKeyboardMode(keyboardMode());
+ applyKeyboardOptions();
virtualkeyboard_show();
return true;
@@ -102,48 +105,76 @@ bool QQnxVirtualKeyboardBps::hideKeyboard()
return true;
}
-void QQnxVirtualKeyboardBps::applyKeyboardMode(KeyboardMode mode)
+void QQnxVirtualKeyboardBps::applyKeyboardOptions()
{
- virtualkeyboard_layout_t layout = VIRTUALKEYBOARD_LAYOUT_DEFAULT;
+ virtualkeyboard_layout_t layout = keyboardLayout();
+ virtualkeyboard_enter_t enter = enterKey();
- switch (mode) {
- case Url:
- layout = VIRTUALKEYBOARD_LAYOUT_URL;
- break;
+ qVirtualKeyboardDebug() << Q_FUNC_INFO << "mode=" << keyboardMode() << "enterKey=" << enterKeyType();
- case Email:
- layout = VIRTUALKEYBOARD_LAYOUT_EMAIL;
- break;
+ virtualkeyboard_change_options(layout, enter);
+}
+virtualkeyboard_layout_t QQnxVirtualKeyboardBps::keyboardLayout() const
+{
+ switch (keyboardMode()) {
+ case Url:
+ return VIRTUALKEYBOARD_LAYOUT_URL;
+ case Email:
+ return VIRTUALKEYBOARD_LAYOUT_EMAIL;
case Web:
- layout = VIRTUALKEYBOARD_LAYOUT_WEB;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_WEB;
case NumPunc:
- layout = VIRTUALKEYBOARD_LAYOUT_NUM_PUNC;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_NUM_PUNC;
+ case Number:
+ return VIRTUALKEYBOARD_LAYOUT_NUMBER;
case Symbol:
- layout = VIRTUALKEYBOARD_LAYOUT_SYMBOL;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_SYMBOL;
case Phone:
- layout = VIRTUALKEYBOARD_LAYOUT_PHONE;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_PHONE;
case Pin:
- layout = VIRTUALKEYBOARD_LAYOUT_PIN;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_PIN;
+ case Password:
+ return VIRTUALKEYBOARD_LAYOUT_PASSWORD;
+#if defined(Q_OS_BLACKBERRY)
+#if BBNDK_VERSION_AT_LEAST(10, 2, 1)
+ case Alphanumeric:
+ return VIRTUALKEYBOARD_LAYOUT_ALPHANUMERIC;
+#endif
+#endif
case Default: // fall through
default:
- layout = VIRTUALKEYBOARD_LAYOUT_DEFAULT;
- break;
+ return VIRTUALKEYBOARD_LAYOUT_DEFAULT;
}
- qVirtualKeyboardDebug() << Q_FUNC_INFO << "mode=" << mode;
+ return VIRTUALKEYBOARD_LAYOUT_DEFAULT;
+}
+
+virtualkeyboard_enter_t QQnxVirtualKeyboardBps::enterKey() const
+{
+ switch (enterKeyType()) {
+ case Connect:
+ return VIRTUALKEYBOARD_ENTER_CONNECT;
+ case Done:
+ return VIRTUALKEYBOARD_ENTER_DONE;
+ case Go:
+ return VIRTUALKEYBOARD_ENTER_GO;
+ case Join:
+ return VIRTUALKEYBOARD_ENTER_JOIN;
+ case Next:
+ return VIRTUALKEYBOARD_ENTER_NEXT;
+ case Search:
+ return VIRTUALKEYBOARD_ENTER_SEARCH;
+ case Send:
+ return VIRTUALKEYBOARD_ENTER_SEND;
+ case Submit:
+ return VIRTUALKEYBOARD_ENTER_SUBMIT;
+ case Default: // fall through
+ default:
+ return VIRTUALKEYBOARD_ENTER_DEFAULT;
+ }
- virtualkeyboard_change_options(layout, VIRTUALKEYBOARD_ENTER_DEFAULT);
+ return VIRTUALKEYBOARD_ENTER_DEFAULT;
}
bool QQnxVirtualKeyboardBps::handleLocaleEvent(bps_event_t *event)
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h
index 43ecb4ecf8..5749deb4e0 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h
@@ -43,6 +43,7 @@
#define QQNXVIRTUALKEYBOARDBPS_H
#include "qqnxabstractvirtualkeyboard.h"
+#include <bps/virtualkeyboard.h>
struct bps_event_t;
@@ -60,11 +61,14 @@ public:
bool hideKeyboard();
protected:
- void applyKeyboardMode(KeyboardMode mode);
+ void applyKeyboardOptions();
private:
bool handleLocaleEvent(bps_event_t *event);
bool handleVirtualKeyboardEvent(bps_event_t *event);
+
+ virtualkeyboard_layout_t keyboardLayout() const;
+ virtualkeyboard_enter_t enterKey() const;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
index 20fce3da70..2b6ee3d1dc 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
@@ -67,9 +67,6 @@ QT_BEGIN_NAMESPACE
const char *QQnxVirtualKeyboardPps::ms_PPSPath = "/pps/services/input/control";
const size_t QQnxVirtualKeyboardPps::ms_bufferSize = 2048;
-// Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP.
-#define KEYBOARD_SHADOW_HEIGHT 8
-
QQnxVirtualKeyboardPps::QQnxVirtualKeyboardPps()
: m_encoder(0),
m_decoder(0),
@@ -91,11 +88,6 @@ void QQnxVirtualKeyboardPps::start()
return;
}
-void QQnxVirtualKeyboardPps::applyKeyboardMode(KeyboardMode mode)
-{
- applyKeyboardModeOptions(mode);
-}
-
void QQnxVirtualKeyboardPps::close()
{
delete m_readNotifier;
@@ -159,18 +151,14 @@ bool QQnxVirtualKeyboardPps::connect()
bool QQnxVirtualKeyboardPps::queryPPSInfo()
{
+ if (!prepareToSend())
+ return false;
+
// Request info, requires id to regenerate res message.
pps_encoder_add_string(m_encoder, "msg", "info");
pps_encoder_add_string(m_encoder, "id", "libWebView");
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
- close();
- return false;
- }
-
- pps_encoder_reset(m_encoder);
-
- return true;
+ return writeCurrentPPSEncoder();
}
void QQnxVirtualKeyboardPps::ppsDataReady()
@@ -257,9 +245,6 @@ void QQnxVirtualKeyboardPps::handleKeyboardInfoMessage()
}
const QString countryId = QString::fromLatin1(value);
- // HUGE hack, should be removed ASAP.
- newHeight -= KEYBOARD_SHADOW_HEIGHT; // We want to ignore the 8 pixel shadow above the keyboard. (PR 88400)
-
setHeight(newHeight);
const QLocale locale = QLocale(languageId + QLatin1Char('_') + countryId);
@@ -272,13 +257,12 @@ bool QQnxVirtualKeyboardPps::showKeyboard()
{
qVirtualKeyboardDebug() << Q_FUNC_INFO;
- // Try to connect.
- if (m_fd == -1 && !connect())
+ if (!prepareToSend())
return false;
// NOTE: This must be done everytime the keyboard is shown even if there is no change because
// hiding the keyboard wipes the setting.
- applyKeyboardModeOptions(keyboardMode());
+ applyKeyboardOptions();
if (isVisible())
return true;
@@ -288,140 +272,110 @@ bool QQnxVirtualKeyboardPps::showKeyboard()
// Send the show message.
pps_encoder_add_string(m_encoder, "msg", "show");
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
- close();
- return false;
- }
-
- pps_encoder_reset(m_encoder);
-
- // Return true if no error occurs. Sizing response will be triggered when confirmation of
- // the change arrives.
- return true;
+ return writeCurrentPPSEncoder();
}
bool QQnxVirtualKeyboardPps::hideKeyboard()
{
qVirtualKeyboardDebug() << Q_FUNC_INFO;
- if (m_fd == -1 && !connect())
+ if (!prepareToSend())
return false;
pps_encoder_add_string(m_encoder, "msg", "hide");
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
- close();
+ return writeCurrentPPSEncoder();
+}
- //Try again.
- if (connect()) {
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
- close();
- return false;
- }
- }
- else
- return false;
- }
+bool QQnxVirtualKeyboardPps::prepareToSend()
+{
+ if (m_fd == -1 && !connect())
+ return false;
pps_encoder_reset(m_encoder);
+ return true;
+}
- // Return true if no error occurs. Sizing response will be triggered when confirmation of
- // the change arrives.
+bool QQnxVirtualKeyboardPps::writeCurrentPPSEncoder()
+{
+ if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
+ close();
+ return false;
+ }
return true;
}
-void QQnxVirtualKeyboardPps::applyKeyboardModeOptions(KeyboardMode mode)
+void QQnxVirtualKeyboardPps::applyKeyboardOptions()
{
- // Try to connect.
- if (m_fd == -1 && !connect())
+ if (!prepareToSend())
return;
// Send the options message.
pps_encoder_add_string(m_encoder, "msg", "options");
-
pps_encoder_start_object(m_encoder, "dat");
- switch (mode) {
+
+ pps_encoder_add_string(m_encoder, "enter", enterKeyTypeStr());
+ pps_encoder_add_string(m_encoder, "type", keyboardModeStr());
+
+ pps_encoder_end_object(m_encoder);
+
+ writeCurrentPPSEncoder();
+}
+
+const char* QQnxVirtualKeyboardPps::keyboardModeStr() const
+{
+ switch (keyboardMode()) {
case Url:
- addUrlModeOptions();
- break;
+ return "url";
case Email:
- addEmailModeOptions();
- break;
+ return "email";
case Web:
- addWebModeOptions();
- break;
+ return "web";
case NumPunc:
- addNumPuncModeOptions();
- break;
+ return "num_punc";
+ case Number:
+ return "number";
case Symbol:
- addSymbolModeOptions();
- break;
+ return "symbol";
case Phone:
- addPhoneModeOptions();
- break;
+ return "phone";
case Pin:
- addPinModeOptions();
- break;
+ return "pin";
+ case Password:
+ return "password";
+ case Alphanumeric:
+ return "alphanumeric";
case Default:
- default:
- addDefaultModeOptions();
- break;
+ return "default";
}
- pps_encoder_end_object(m_encoder);
-
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1)
- close();
-
- pps_encoder_reset(m_encoder);
-}
-
-void QQnxVirtualKeyboardPps::addDefaultModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "default");
+ return "";
}
-void QQnxVirtualKeyboardPps::addUrlModeOptions()
+const char* QQnxVirtualKeyboardPps::enterKeyTypeStr() const
{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "url");
-}
-
-void QQnxVirtualKeyboardPps::addEmailModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "email");
-}
-
-void QQnxVirtualKeyboardPps::addWebModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "web");
-}
-
-void QQnxVirtualKeyboardPps::addNumPuncModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "numPunc");
-}
-
-void QQnxVirtualKeyboardPps::addPhoneModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "phone");
-}
-
-void QQnxVirtualKeyboardPps::addPinModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "pin");
-}
+ switch (enterKeyType()) {
+ case DefaultReturn:
+ return "enter.default";
+ case Connect:
+ return "enter.connect";
+ case Done:
+ return "enter.done";
+ case Go:
+ return "enter.go";
+ case Join:
+ return "enter.join";
+ case Next:
+ return "enter.next";
+ case Search:
+ return "enter.search";
+ case Send:
+ return "enter.send";
+ case Submit:
+ return "enter.submit";
+ }
-void QQnxVirtualKeyboardPps::addSymbolModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "symbol");
+ return "";
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
index 6048868b08..2b56d5afbe 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
@@ -48,6 +48,7 @@
QT_BEGIN_NAMESPACE
+
class QSocketNotifier;
class QQnxVirtualKeyboardPps : public QQnxAbstractVirtualKeyboard
@@ -64,7 +65,7 @@ public Q_SLOTS:
void start();
protected:
- void applyKeyboardMode(KeyboardMode mode);
+ void applyKeyboardOptions();
private Q_SLOTS:
void ppsDataReady();
@@ -76,15 +77,11 @@ private:
bool queryPPSInfo();
void handleKeyboardInfoMessage();
- void applyKeyboardModeOptions(KeyboardMode mode);
- void addDefaultModeOptions();
- void addUrlModeOptions();
- void addEmailModeOptions();
- void addWebModeOptions();
- void addNumPuncModeOptions();
- void addSymbolModeOptions();
- void addPhoneModeOptions();
- void addPinModeOptions();
+ const char* keyboardModeStr() const;
+ const char* enterKeyTypeStr() const;
+
+ bool prepareToSend();
+ bool writeCurrentPPSEncoder();
pps_encoder_t *m_encoder;
pps_decoder_t *m_decoder;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 99071cf4f2..bb76efea64 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxwindow.h"
#include "qqnxintegration.h"
#include "qqnxscreen.h"
@@ -73,36 +75,45 @@ QT_BEGIN_NAMESPACE
QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow)
: QPlatformWindow(window),
m_screenContext(context),
- m_parentWindow(0),
m_window(0),
m_screen(0),
+ m_parentWindow(0),
m_visible(false),
m_exposed(true),
m_windowState(Qt::WindowNoState),
m_mmRendererWindow(0)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
- int result;
QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window->screen()->handle());
- m_isTopLevel = ( needRootWindow && !platformScreen->rootWindow())
- || (!needRootWindow && !parent())
- || window->type() == Qt::CoverWindow;
+ if (window->type() == Qt::CoverWindow) {
+ // Cover windows have to be top level to be accessible to window delegate (i.e. navigator)
+ m_isTopLevel = true;
+ } else if (parent() || (window->type() & Qt::Dialog) == Qt::Dialog) {
+ // If we have a parent we are a child window. Sometimes we have to be a child even if we
+ // don't have a parent e.g. our parent might be in a different process.
+ m_isTopLevel = false;
+ } else {
+ // We're parentless. If we're not using a root window, we'll always be a top-level window
+ // otherwise only the first window is.
+ m_isTopLevel = !needRootWindow || !platformScreen->rootWindow();
+ }
- errno = 0;
if (m_isTopLevel) {
- result = screen_create_window(&m_window, m_screenContext); // Creates an application window
+ Q_SCREEN_CRITICALERROR(screen_create_window(&m_window, m_screenContext),
+ "Could not create top level window"); // Creates an application window
if (window->type() != Qt::CoverWindow) {
if (needRootWindow)
platformScreen->setRootWindow(this);
- createWindowGroup();
}
} else {
- result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
+ Q_SCREEN_CHECKERROR(
+ screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW),
+ "Could not create child window");
}
- if (result != 0)
- qFatal("QQnxWindow: failed to create window, errno=%d", errno);
+
+ createWindowGroup();
}
QQnxWindow::~QQnxWindow()
@@ -130,7 +141,7 @@ void QQnxWindow::setGeometry(const QRect &rect)
if (screen()->rootWindow() == this) //If this is the root window, it has to be shown fullscreen
newGeometry = screen()->geometry();
- const QRect oldGeometry = setGeometryHelper(newGeometry);
+ setGeometryHelper(newGeometry);
// Send a geometry change event to Qt (triggers resizeEvent() in QWindow/QWidget).
@@ -140,71 +151,34 @@ void QQnxWindow::setGeometry(const QRect &rect)
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
QWindowSystemInterface::setSynchronousWindowsSystemEvents(false);
-
- // Now move all children.
- if (!oldGeometry.isEmpty()) {
- const QPoint offset = newGeometry.topLeft() - oldGeometry.topLeft();
- Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
- childWindow->setOffset(offset);
- }
}
-QRect QQnxWindow::setGeometryHelper(const QRect &rect)
+void QQnxWindow::setGeometryHelper(const QRect &rect)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window()
<< ", (" << rect.x() << "," << rect.y()
<< "," << rect.width() << "," << rect.height() << ")";
// Call base class method
- QRect oldGeometry = QPlatformWindow::geometry();
QPlatformWindow::setGeometry(rect);
// Set window geometry equal to widget geometry
- errno = 0;
int val[2];
val[0] = rect.x();
val[1] = rect.y();
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
+ "Failed to set window position");
- errno = 0;
val[0] = rect.width();
val[1] = rect.height();
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window size, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val),
+ "Failed to set window size");
// Set viewport size equal to window size
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window source size, errno=%d", errno);
-
- return oldGeometry;
-}
-
-void QQnxWindow::setOffset(const QPoint &offset)
-{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
- // Move self and then children.
- QRect newGeometry = geometry();
- newGeometry.translate(offset);
-
- // Call the base class
- QPlatformWindow::setGeometry(newGeometry);
-
- int val[2];
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val),
+ "Failed to set window source size");
- errno = 0;
- val[0] = newGeometry.x();
- val[1] = newGeometry.y();
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window position, errno=%d", errno);
-
- Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
- childWindow->setOffset(offset);
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::setVisible(bool visible)
@@ -214,6 +188,12 @@ void QQnxWindow::setVisible(bool visible)
if (m_visible == visible)
return;
+ // The first time through we join a window group if appropriate.
+ if (m_parentGroupName.isNull() && !m_isTopLevel) {
+ joinWindowGroup(parent() ? static_cast<QQnxWindow*>(parent())->groupName()
+ : QByteArray(m_screen->windowGroupName()));
+ }
+
m_visible = visible;
QQnxWindow *root = this;
@@ -222,8 +202,6 @@ void QQnxWindow::setVisible(bool visible)
root->updateVisibility(root->m_visible);
- window()->requestActivate();
-
QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
if (visible) {
@@ -238,11 +216,9 @@ void QQnxWindow::updateVisibility(bool parentVisible)
{
qWindowDebug() << Q_FUNC_INFO << "parentVisible =" << parentVisible << "window =" << window();
// Set window visibility
- errno = 0;
int val = (m_visible && parentVisible) ? 1 : 0;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window visibility, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
+ "Failed to set window visibility");
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->updateVisibility(m_visible && parentVisible);
@@ -252,14 +228,11 @@ void QQnxWindow::setOpacity(qreal level)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "opacity =" << level;
// Set window global alpha
- errno = 0;
int val = (int)(level * 255);
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window global alpha, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val),
+ "Failed to set global alpha");
- // TODO: How to handle children of this window? If we change all the visibilities, then
- // the transparency will look wrong...
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::setExposed(bool exposed)
@@ -282,15 +255,12 @@ void QQnxWindow::setBufferSize(const QSize &size)
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size;
// Set window buffer size
- errno = 0;
-
// libscreen fails when creating empty buffers
const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window buffer size, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
+ "Failed to set window buffer size");
// Create window buffers if they do not exist
if (m_bufferSize.isEmpty()) {
@@ -298,24 +268,18 @@ void QQnxWindow::setBufferSize(const QSize &size)
if (val[0] == -1) // The platform GL context was not set yet on the window, so we can't procede
return;
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window pixel format, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val),
+ "Failed to set window format");
- errno = 0;
- result = screen_create_window_buffers(m_window, MAX_BUFFER_COUNT);
- if (result != 0) {
- qWarning() << "QQnxWindow: Buffer size was" << size;
- qFatal("QQnxWindow: failed to create window buffers, errno=%d", errno);
- }
+ Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
+ "Failed to create window buffers");
// check if there are any buffers available
int bufferCount = 0;
- result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount);
-
- if (result != 0)
- qFatal("QQnxWindow: failed to query window buffer count, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(
+ screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
+ "Failed to query render buffer count");
if (bufferCount != MAX_BUFFER_COUNT) {
qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d. You might experience problems.",
@@ -338,10 +302,8 @@ void QQnxWindow::setBufferSize(const QSize &size)
val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
}
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window transparency, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val),
+ "Failed to set window transparency");
// Cache new buffer size
m_bufferSize = nonEmptySize;
@@ -366,9 +328,8 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (m_screen) {
qWindowDebug() << Q_FUNC_INFO << "Moving window to different screen";
m_screen->removeWindow(this);
- QQnxIntegration *platformIntegration = static_cast<QQnxIntegration*>(QGuiApplicationPrivate::platformIntegration());
- if ((platformIntegration->options() & QQnxIntegration::RootWindow)) {
+ if ((QQnxIntegration::options() & QQnxIntegration::RootWindow)) {
screen_leave_window_group(m_window);
}
}
@@ -378,25 +339,12 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
platformScreen->addWindow(this);
}
if (m_isTopLevel) {
- // Move window to proper screen/display
- errno = 0;
+ // Move window to proper screen/display
screen_display_t display = platformScreen->nativeDisplay();
- int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window display, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display),
+ "Failed to set window display");
} else {
- errno = 0;
- int result;
- if (!parent()) {
- result = screen_join_window_group(m_window, platformScreen->windowGroupName());
- if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
- } else {
- result = screen_join_window_group(m_window, static_cast<QQnxWindow*>(parent())->groupName().constData());
- if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
- }
-
Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
// Only subwindows and tooltips need necessarily be moved to another display with the window.
if (window()->type() == Qt::SubWindow || window()->type() == Qt::ToolTip)
@@ -430,6 +378,11 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
if (newParent == m_parentWindow)
return;
+ if (screen()->rootWindow() == this) {
+ qWarning() << "Application window cannot be reparented";
+ return;
+ }
+
removeFromParent();
m_parentWindow = newParent;
@@ -439,12 +392,12 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
setScreen(m_parentWindow->m_screen);
m_parentWindow->m_childWindows.push_back(this);
+ joinWindowGroup(m_parentWindow->groupName());
} else {
m_screen->addWindow(this);
+ joinWindowGroup(QByteArray());
}
- adjustBufferSize();
-
m_screen->updateHierarchy();
}
@@ -478,14 +431,59 @@ void QQnxWindow::lower()
void QQnxWindow::requestActivateWindow()
{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
+ QQnxWindow *focusWindow = 0;
+ if (QGuiApplication::focusWindow())
+ focusWindow = static_cast<QQnxWindow*>(QGuiApplication::focusWindow()->handle());
+
+ if (focusWindow == this)
+ return;
+
+ if (screen()->rootWindow() == this ||
+ (focusWindow && findWindow(focusWindow->nativeHandle()))) {
+ // If the focus window is a child, we can just set the focus of our own window
+ // group to our window handle
+ setFocus(nativeHandle());
+ } else {
+ // In order to receive focus the parent's window group has to give focus to the
+ // child. If we have several hierarchy layers, we have to do that several times
+ QQnxWindow *currentWindow = this;
+ QList<QQnxWindow*> windowList;
+ while (currentWindow) {
+ windowList.prepend(currentWindow);
+ // If we find the focus window, we don't have to go further
+ if (currentWindow == focusWindow)
+ break;
+
+ if (currentWindow->parent()){
+ currentWindow = static_cast<QQnxWindow*>(currentWindow->parent());
+ } else if (screen()->rootWindow() &&
+ screen()->rootWindow()->m_windowGroupName == currentWindow->m_parentGroupName) {
+ currentWindow = screen()->rootWindow();
+ } else {
+ currentWindow = 0;
+ }
+ }
- // TODO: Tell screen to set keyboard focus to this window.
+ // We have to apply the focus from parent to child windows
+ for (int i = 1; i < windowList.size(); ++i)
+ windowList.at(i-1)->setFocus(windowList.at(i)->nativeHandle());
+
+ windowList.last()->setFocus(windowList.last()->nativeHandle());
+ }
- // Notify that we gained focus.
- gainedFocus();
+ screen_flush_context(m_screenContext, 0);
}
+void QQnxWindow::setFocus(screen_window_t newFocusWindow)
+{
+ screen_group_t screenGroup = 0;
+ screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP,
+ reinterpret_cast<void**>(&screenGroup));
+ if (screenGroup) {
+ screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_KEYBOARD_FOCUS,
+ reinterpret_cast<void**>(&newFocusWindow));
+ }
+}
void QQnxWindow::setWindowState(Qt::WindowState state)
{
@@ -507,14 +505,6 @@ void QQnxWindow::propagateSizeHints()
qWindowDebug() << Q_FUNC_INFO << ": ignored";
}
-void QQnxWindow::gainedFocus()
-{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
-
- // Got focus
- QWindowSystemInterface::handleWindowActivated(window());
-}
-
void QQnxWindow::setMMRendererWindowName(const QString &name)
{
m_mmRendererWindowName = name;
@@ -569,43 +559,43 @@ void QQnxWindow::minimize()
void QQnxWindow::setRotation(int rotation)
{
qWindowDebug() << Q_FUNC_INFO << "angle =" << rotation;
- errno = 0;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window rotation, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation),
+ "Failed to set window rotation");
}
void QQnxWindow::initWindow()
{
// Alpha channel is always pre-multiplied if present
- errno = 0;
int val = SCREEN_PRE_MULTIPLIED_ALPHA;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window alpha mode, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val),
+ "Failed to set alpha mode");
// Set the window swap interval
- errno = 0;
val = 1;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window swap interval, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val),
+ "Failed to set swap interval");
if (window()->flags() & Qt::WindowDoesNotAcceptFocus) {
- errno = 0;
val = SCREEN_SENSITIVITY_NO_FOCUS;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window sensitivity, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
+ "Failed to set window sensitivity");
}
- setScreen(static_cast<QQnxScreen *>(window()->screen()->handle()));
+ QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window()->screen()->handle());
+ setScreen(platformScreen);
if (window()->type() == Qt::CoverWindow) {
#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET)
- screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
- SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
- m_cover.reset(new QQnxNavigatorCover);
+ if (platformScreen->rootWindow()) {
+ screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
+ SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
+ m_cover.reset(new QQnxNavigatorCover);
+ } else {
+ qWarning("No root window for cover window");
+ }
#endif
m_exposed = false;
}
@@ -615,6 +605,8 @@ void QQnxWindow::initWindow()
// Qt never calls these setters after creating the window, so we need to do that ourselves here
setWindowState(window()->windowState());
+ setOpacity(window()->opacity());
+
if (window()->parent() && window()->parent()->handle())
setParent(window()->parent()->handle());
@@ -632,10 +624,36 @@ void QQnxWindow::createWindowGroup()
m_windowGroupName = QUuid::createUuid().toString().toLatin1();
// Create window group so child windows can be parented by container window
- errno = 0;
- int result = screen_create_window_group(m_window, m_windowGroupName.constData());
- if (result != 0)
- qFatal("QQnxRootWindow: failed to create app window group, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_create_window_group(m_window, m_windowGroupName.constData()),
+ "Failed to create window group");
+}
+
+void QQnxWindow::joinWindowGroup(const QByteArray &groupName)
+{
+ bool changed = false;
+
+ qWindowDebug() << Q_FUNC_INFO << "group:" << groupName;
+
+ if (!groupName.isEmpty()) {
+ if (groupName != m_parentGroupName) {
+ screen_join_window_group(m_window, groupName);
+ m_parentGroupName = groupName;
+ changed = true;
+ }
+ } else {
+ if (!m_parentGroupName.isEmpty()) {
+ screen_leave_window_group(m_window);
+ changed = true;
+ }
+ // By setting to an empty string we'll stop setVisible from trying to
+ // change our group, we want that to happen only if joinWindowGroup has
+ // never been called. This allows windows to be created that are not initially
+ // part of any group.
+ m_parentGroupName = "";
+ }
+
+ if (changed)
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::updateZorder(int &topZorder)
@@ -651,12 +669,9 @@ void QQnxWindow::updateZorder(int &topZorder)
void QQnxWindow::updateZorder(screen_window_t window, int &topZorder)
{
- errno = 0;
- int result = screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder),
+ "Failed to set window z-order");
topZorder++;
-
- if (result != 0)
- qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, window);
}
void QQnxWindow::applyWindowState()
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index 3c8070b0be..ea7b388e9f 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -78,7 +78,6 @@ public:
WId winId() const { return (WId)m_window; }
screen_window_t nativeHandle() const { return m_window; }
- virtual void adjustBufferSize() = 0;
void setBufferSize(const QSize &size);
QSize bufferSize() const { return m_bufferSize; }
@@ -93,7 +92,6 @@ public:
void propagateSizeHints();
- void gainedFocus();
void setMMRendererWindowName(const QString &name);
void setMMRendererWindow(screen_window_t handle);
void clearMMRendererWindow();
@@ -112,6 +110,7 @@ public:
void setRotation(int rotation);
QByteArray groupName() const { return m_windowGroupName; }
+ void joinWindowGroup(const QByteArray &groupName);
protected:
virtual int pixelFormat() const = 0;
@@ -122,22 +121,21 @@ protected:
screen_context_t m_screenContext;
QScopedPointer<QQnxAbstractCover> m_cover;
- QQnxWindow *m_parentWindow;
-
private:
void createWindowGroup();
- QRect setGeometryHelper(const QRect &rect);
+ void setGeometryHelper(const QRect &rect);
void removeFromParent();
- void setOffset(const QPoint &setOffset);
void updateVisibility(bool parentVisible);
void updateZorder(int &topZorder);
void updateZorder(screen_window_t window, int &zOrder);
void applyWindowState();
+ void setFocus(screen_window_t newFocusWindow);
screen_window_t m_window;
QSize m_bufferSize;
QQnxScreen *m_screen;
+ QQnxWindow *m_parentWindow;
QList<QQnxWindow*> m_childWindows;
bool m_visible;
bool m_exposed;
@@ -146,7 +144,10 @@ private:
QString m_mmRendererWindowName;
screen_window_t m_mmRendererWindow;
+ // Group name of window group headed by this window
QByteArray m_windowGroupName;
+ // Group name that we have joined or "" if we've not joined any group.
+ QByteArray m_parentGroupName;
bool m_isTopLevel;
};
diff --git a/src/plugins/platforms/windows/accessible/accessible.pri b/src/plugins/platforms/windows/accessible/accessible.pri
index 08a37a4733..e26c6614e2 100644
--- a/src/plugins/platforms/windows/accessible/accessible.pri
+++ b/src/plugins/platforms/windows/accessible/accessible.pri
@@ -8,10 +8,10 @@ HEADERS += \
$$PWD/qwindowsaccessibility.h \
$$PWD/comutils.h
-!win32-g++*: {
+!mingw: {
SOURCES += $$PWD/iaccessible2.cpp
HEADERS += $$PWD/iaccessible2.h
include(../../../../3rdparty/iaccessible2/iaccessible2.pri)
}
-win32-g++*: LIBS *= -luuid \ No newline at end of file
+mingw: LIBS *= -luuid \ No newline at end of file
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index 66ed9d85dc..7f2ed86404 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -59,10 +59,10 @@ HRESULT STDMETHODCALLTYPE AccessibleApplication::QueryInterface(REFIID id, LPVOI
{
*iface = 0;
if (id == IID_IUnknown) {
- accessibleDebug("AccessibleApplication::QI(): IID_IUnknown");
+ qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IUnknown";
*iface = (IUnknown*)this;
} else if (id == IID_IAccessibleApplication) {
- accessibleDebug("AccessibleApplication::QI(): IID_IAccessibleApplication");
+ qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IAccessibleApplication";
*iface = static_cast<IAccessibleApplication*>(this);
}
@@ -476,7 +476,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_uniqueID(long *outUniqueID)
if (!accessible)
return E_FAIL;
- accessibleDebug("uniqueID: %08x", id);
+ qCDebug(lcQpaAccessibility) << "uniqueID: " << showbase << hex << id;
*outUniqueID = (long)id;
return int(id) < 0 ? S_OK : S_FALSE;
@@ -841,7 +841,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_cellAt( long row, long colu
*cell = QWindowsAccessibility::wrap(qtCell);
}
}
- accessibleDebug("found cell? %p", *cell);
+ qCDebug(lcQpaAccessibility) << "found cell? " << *cell;
return *cell ? S_OK : S_FALSE;
}
@@ -1574,7 +1574,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryService(REFGUID guidServic
return E_POINTER;
Q_UNUSED(guidService);
*iface = 0;
- accessibleDebug("QWindowsIA2Accessible::QS(): %s", IIDToString(riid).constData());
+ qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QS(): " << IIDToString(riid);
if (guidService == IID_IAccessible) {
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
index 885bc37cff..307f2fc3bb 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
@@ -100,6 +100,25 @@ QWindowsAccessibility::QWindowsAccessibility()
{
}
+// Retrieve sound name by checking the icon property of a message box
+static inline QString messageBoxAlertSound(const QObject *messageBox)
+{
+ enum MessageBoxIcon { // Keep in sync with QMessageBox::Icon
+ Information = 1,
+ Warning = 2,
+ Critical = 3
+ };
+ switch (messageBox->property("icon").toInt()) {
+ case Information:
+ return QStringLiteral("SystemAsterisk");
+ case Warning:
+ return QStringLiteral("SystemExclamation");
+ case Critical:
+ return QStringLiteral("SystemHand");
+ }
+ return QString();
+}
+
void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
{
QString soundName;
@@ -113,32 +132,8 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
break;
case QAccessible::Alert:
- {
- /* ### FIXME
-#ifndef QT_NO_MESSAGEBOX
- QMessageBox *mb = qobject_cast<QMessageBox*>(o);
- if (mb) {
- switch (mb->icon()) {
- case QMessageBox::Warning:
- soundName = QLatin1String("SystemExclamation");
- break;
- case QMessageBox::Critical:
- soundName = QLatin1String("SystemHand");
- break;
- case QMessageBox::Information:
- soundName = QLatin1String("SystemAsterisk");
- break;
- default:
- break;
- }
- } else
-#endif // QT_NO_MESSAGEBOX
-*/
- {
- soundName = QLatin1String("SystemAsterisk");
- }
-
- }
+ soundName = event->object()->inherits("QMessageBox") ?
+ messageBoxAlertSound(event->object()) : QStringLiteral("SystemAsterisk");
break;
default:
break;
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 8bb7646258..49d4a712d8 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -185,23 +185,10 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Skip(unsigned long celt)
return S_OK;
}
-#ifndef QT_NO_DEBUG
-bool debug_accessibility()
-{
- static int debugging = -1;
- if (debugging == -1)
- debugging = qgetenv("QT_DEBUG_ACCESSIBILITY").toInt();
- return !!debugging;
-}
-#endif
-
#if defined(DEBUG_SHOW_ATCLIENT_COMMANDS)
void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleInterface *iface)
{
- QString str;
- QDebug dbg(&str);
- dbg << iface << QLatin1String(funcName);
- accessibleDebug("%s", qPrintable(str));
+ qCDebug(lcQpaAccessibility) << iface << funcName;
}
#endif
@@ -216,10 +203,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::QueryInterface(REFIID id, LPVO
QByteArray strIID = IIDToString(id);
if (!strIID.isEmpty()) {
- QString ss;
- QDebug dbg(&ss);
- dbg << accessibleInterface();
- accessibleDebug("QWindowsIA2Accessible::QI() - IID:%s, iface:%s ", strIID.constData(), qPrintable(ss));
+ qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QI() - IID:"
+ << strIID << ", iface:" << accessibleInterface();
}
if (id == IID_IUnknown) {
*iface = (IUnknown*)(IDispatch*)this;
@@ -1057,7 +1042,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accValue(VARIANT varID, BS
}
*pszValue = 0;
- accessibleDebug("return S_FALSE");
+ qCDebug(lcQpaAccessibility) << "return S_FALSE";
return S_FALSE;
}
@@ -1196,7 +1181,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetWindow(HWND *phwnd)
QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
Q_ASSERT(platform);
*phwnd = (HWND)platform->nativeResourceForWindow("handle", window);
- accessibleDebug("QWindowsAccessible::GetWindow(): %p", *phwnd);
+ qCDebug(lcQpaAccessibility) << "QWindowsAccessible::GetWindow(): " << *phwnd;
return S_OK;
}
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h
index 5b8d08d3c8..43482da4be 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h
@@ -59,13 +59,6 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_OUTPUT)
-bool debug_accessibility();
-# define accessibleDebug !debug_accessibility() ? (void)0 : qDebug
-#else
-# define accessibleDebug while (false) qDebug
-#endif
-
#ifndef QT_NO_DEBUG_OUTPUT
#define DEBUG_SHOW_ATCLIENT_COMMANDS
#endif
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp
index ffd87af193..a0057534b8 100644
--- a/src/plugins/platforms/windows/main.cpp
+++ b/src/plugins/platforms/windows/main.cpp
@@ -43,7 +43,7 @@
#include <qpa/qplatformintegrationplugin.h>
#include <QtCore/QStringList>
-#include "qwindowsintegration.h"
+#include "qwindowsgdiintegration.h"
QT_BEGIN_NAMESPACE
@@ -113,7 +113,7 @@ public:
QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList, int &, char **)
{
if (system.compare(system, QStringLiteral("windows"), Qt::CaseInsensitive) == 0)
- return new QWindowsIntegration(paramList);
+ return new QWindowsGdiIntegration(paramList);
return 0;
}
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 7b574b0a56..ee640224cf 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -73,6 +73,7 @@ enum WindowsEventType // Simplify event types
ExposeEvent = WindowEventFlag + 1,
ActivateWindowEvent = WindowEventFlag + 2,
DeactivateWindowEvent = WindowEventFlag + 3,
+ MouseActivateWindowEvent = WindowEventFlag + 4,
LeaveEvent = WindowEventFlag + 5,
CloseEvent = WindowEventFlag + 6,
ShowEvent = WindowEventFlag + 7,
@@ -131,6 +132,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
case WM_ACTIVATEAPP:
return (int)wParamIn ?
QtWindows::ActivateApplicationEvent : QtWindows::DeactivateApplicationEvent;
+ case WM_MOUSEACTIVATE:
+ return QtWindows::MouseActivateWindowEvent;
case WM_ACTIVATE:
return LOWORD(wParamIn) == WA_INACTIVE ?
QtWindows::DeactivateWindowEvent : QtWindows::ActivateWindowEvent;
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 55e7b85d96..f12c828d8a 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -61,14 +61,12 @@ QT_BEGIN_NAMESPACE
QWindowsBackingStore::QWindowsBackingStore(QWindow *window) :
QPlatformBackingStore(window)
{
- if (QWindowsContext::verboseBackingStore)
- qDebug() << __FUNCTION__ << this << window;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window;
}
QWindowsBackingStore::~QWindowsBackingStore()
{
- if (QWindowsContext::verboseBackingStore)
- qDebug() << __FUNCTION__ << this;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this;
}
QPaintDevice *QWindowsBackingStore::paintDevice()
@@ -83,8 +81,8 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
Q_ASSERT(window);
const QRect br = region.boundingRect();
- if (QWindowsContext::verboseBackingStore > 1)
- qDebug() << __FUNCTION__ << window << offset << br;
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << offset << br;
QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window);
#ifndef Q_OS_WINCE
@@ -117,20 +115,23 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
}
if (!BitBlt(dc, br.x(), br.y(), br.width(), br.height(),
- m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY))
- qErrnoWarning("%s: BitBlt failed", __FUNCTION__);
+ m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY)) {
+ const DWORD lastError = GetLastError(); // QTBUG-35926, QTBUG-29716: may fail after lock screen.
+ if (lastError != ERROR_SUCCESS && lastError != ERROR_INVALID_HANDLE)
+ qErrnoWarning(lastError, "%s: BitBlt failed", __FUNCTION__);
+ }
rw->releaseDC();
#ifndef Q_OS_WINCE
}
#endif
// Write image for debug purposes.
- if (QWindowsContext::verboseBackingStore > 2) {
+ if (QWindowsContext::verbose > 2 && lcQpaBackingStore().isDebugEnabled()) {
static int n = 0;
const QString fileName = QString::fromLatin1("win%1_%2.png").
arg(rw->winId()).arg(n++);
m_image->image().save(fileName);
- qDebug() << "Wrote " << m_image->image().size() << fileName;
+ qCDebug(lcQpaBackingStore) << "Wrote " << m_image->image().size() << fileName;
}
}
@@ -138,16 +139,14 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
{
if (m_image.isNull() || m_image->image().size() != size) {
#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verboseBackingStore) {
- QDebug nsp = qDebug().nospace();
- nsp << __FUNCTION__ << ' ' << rasterWindow()->window()
- << ' ' << size << ' ' << region;
- if (!m_image.isNull())
- nsp << " from: " << m_image->image().size();
+ if (QWindowsContext::verbose && lcQpaBackingStore().isDebugEnabled()) {
+ qCDebug(lcQpaBackingStore)
+ << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << region
+ << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
}
#endif
QImage::Format format = QWindowsNativeImage::systemFormat();
- if (format == QImage::Format_RGB32 && rasterWindow()->window()->format().hasAlpha())
+ if (format == QImage::Format_RGB32 && window()->format().hasAlpha())
format = QImage::Format_ARGB32_Premultiplied;
QWindowsNativeImage *oldwni = m_image.data();
@@ -185,8 +184,8 @@ bool QWindowsBackingStore::scroll(const QRegion &area, int dx, int dy)
void QWindowsBackingStore::beginPaint(const QRegion &region)
{
- if (QWindowsContext::verboseBackingStore > 1)
- qDebug() << __FUNCTION__;
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaBackingStore) <<__FUNCTION__ << region;
if (m_image->image().hasAlphaChannel()) {
QPainter p(&m_image->image());
@@ -197,14 +196,6 @@ void QWindowsBackingStore::beginPaint(const QRegion &region)
}
}
-QWindowsWindow *QWindowsBackingStore::rasterWindow() const
-{
- if (const QWindow *w = window())
- if (QPlatformWindow *pw = w->handle())
- return static_cast<QWindowsWindow *>(pw);
- return 0;
-}
-
HDC QWindowsBackingStore::getDC() const
{
if (!m_image.isNull())
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
index d50570dd2c..b655aca835 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.h
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -68,8 +68,6 @@ public:
HDC getDC() const;
private:
- QWindowsWindow *rasterWindow() const;
-
QScopedPointer<QWindowsNativeImage> m_image;
};
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 51e0d0e803..5370d556fd 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -164,9 +164,7 @@ void QWindowsClipboard::registerViewer()
qClipboardViewerWndProc, WS_OVERLAPPED);
m_nextClipboardViewer = SetClipboardViewer(m_clipboardViewer);
- if (QWindowsContext::verboseOLE)
- qDebug("%s m_clipboardViewer: %p next=%p", __FUNCTION__,
- m_clipboardViewer, m_nextClipboardViewer);
+ qCDebug(lcQpaMime) << __FUNCTION__ << "m_clipboardViewer: " << m_clipboardViewer << "next: " << m_nextClipboardViewer;
}
void QWindowsClipboard::unregisterViewer()
@@ -219,9 +217,8 @@ void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, L
bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
{
*result = 0;
- if (QWindowsContext::verboseOLE)
- qDebug("%s HWND=%p 0x%x %s", __FUNCTION__, hwnd, message,
- QWindowsGuiEventDispatcher::windowsMessageName(message));
+ if (QWindowsContext::verbose)
+ qCDebug(lcQpaMime) << __FUNCTION__ << hwnd << message << QWindowsGuiEventDispatcher::windowsMessageName(message);
switch (message) {
case WM_CHANGECBCHAIN: {
@@ -235,8 +232,7 @@ bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM w
return true;
case WM_DRAWCLIPBOARD: {
const bool owned = ownsClipboard();
- if (QWindowsContext::verboseOLE)
- qDebug("Clipboard changed owned %d", owned);
+ qCDebug(lcQpaMime) << "Clipboard changed owned " << owned;
emitChanged(QClipboard::Clipboard);
// clean up the clipboard object if we no longer own the clipboard
if (!owned && m_data)
@@ -247,8 +243,7 @@ bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM w
case WM_DESTROY:
// Recommended shutdown
if (ownsClipboard()) {
- if (QWindowsContext::verboseOLE)
- qDebug("Clipboard owner on shutdown, releasing.");
+ qCDebug(lcQpaMime) << "Clipboard owner on shutdown, releasing.";
OleFlushClipboard();
releaseIData();
}
@@ -259,8 +254,7 @@ bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM w
QMimeData *QWindowsClipboard::mimeData(QClipboard::Mode mode)
{
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << mode;
+ qCDebug(lcQpaMime) << __FUNCTION__ << mode;
if (mode != QClipboard::Clipboard)
return 0;
if (ownsClipboard())
@@ -270,8 +264,7 @@ QMimeData *QWindowsClipboard::mimeData(QClipboard::Mode mode)
void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
{
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << mode << *mimeData;
+ qCDebug(lcQpaMime) << __FUNCTION__ << mode << *mimeData;
if (mode != QClipboard::Clipboard)
return;
@@ -316,8 +309,7 @@ bool QWindowsClipboard::ownsMode(QClipboard::Mode mode) const
{
const bool result = mode == QClipboard::Clipboard ?
ownsClipboard() : false;
- if (QWindowsContext::verboseOLE)
- qDebug("%s %d returns %d", __FUNCTION__, mode, result);
+ qCDebug(lcQpaMime) << __FUNCTION__ << mode << result;
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 77cac647ba..8380aba13b 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -79,18 +79,18 @@
QT_BEGIN_NAMESPACE
-// Verbosity of components
-int QWindowsContext::verboseIntegration = 0;
-int QWindowsContext::verboseWindows = 0;
-int QWindowsContext::verboseEvents = 0;
-int QWindowsContext::verboseBackingStore = 0;
-int QWindowsContext::verboseFonts = 0;
-int QWindowsContext::verboseGL = 0;
-int QWindowsContext::verboseOLE = 0;
-int QWindowsContext::verboseInputMethods = 0;
-int QWindowsContext::verboseDialogs = 0;
-int QWindowsContext::verboseTheming = 0;
-int QWindowsContext::verboseTablet = 0;
+Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows")
+Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore")
+Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
+Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
+Q_LOGGING_CATEGORY(lcQpaGl, "qt.qpa.gl")
+Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime")
+Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.inputmethods")
+Q_LOGGING_CATEGORY(lcQpaDialogs, "qt.qpa.dialogs")
+Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.tabletsupport")
+Q_LOGGING_CATEGORY(lcQpaAccessibility, "qt.qpa.accessibility")
+
+int QWindowsContext::verbose = 0;
// Get verbosity of components from "foo:2,bar:3"
static inline int componentVerbose(const char *v, const char *keyWord)
@@ -318,25 +318,13 @@ QWindowsContext::QWindowsContext() :
# pragma warning( disable : 4996 )
#endif
m_instance = this;
+ // ### FIXME: Remove this once the logging system has other options of configurations.
const QByteArray bv = qgetenv("QT_QPA_VERBOSE");
- if (!bv.isEmpty()) {
- const char *v = bv.data();
- QWindowsContext::verboseIntegration = componentVerbose(v, "integration");
- QWindowsContext::verboseWindows = componentVerbose(v, "windows");
- QWindowsContext::verboseEvents = componentVerbose(v, "events");
- QWindowsContext::verboseBackingStore = componentVerbose(v, "backingstore");
- QWindowsContext::verboseFonts = componentVerbose(v, "fonts");
- QWindowsContext::verboseGL = componentVerbose(v, "gl");
- QWindowsContext::verboseOLE = componentVerbose(v, "ole");
- QWindowsContext::verboseInputMethods = componentVerbose(v, "im");
- QWindowsContext::verboseDialogs = componentVerbose(v, "dialogs");
- QWindowsContext::verboseTheming = componentVerbose(v, "theming");
- QWindowsContext::verboseTablet = componentVerbose(v, "tablet");
- }
+ if (!bv.isEmpty())
+ QLoggingCategory::setFilterRules(QString::fromLocal8Bit(bv));
#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
d->m_tabletSupport.reset(QWindowsTabletSupport::create());
- if (QWindowsContext::verboseTablet)
- qDebug() << "Tablet support: " << (d->m_tabletSupport.isNull() ? QStringLiteral("None") : d->m_tabletSupport->description());
+ qCDebug(lcQpaTablet) << "Tablet support: " << (d->m_tabletSupport.isNull() ? QStringLiteral("None") : d->m_tabletSupport->description());
#endif
}
@@ -407,7 +395,7 @@ QString QWindowsContext::registerWindowClass(const QWindow *w, bool isGL)
bool icon = true;
if (isGL || (flags & Qt::MSWindowsOwnDC))
style |= CS_OWNDC;
- if ((QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
+ if (!(flags & Qt::NoDropShadowWindowHint) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
&& (type == Qt::Popup || w->property("_q_windowsDropShadow").toBool())) {
style |= CS_DROPSHADOW;
}
@@ -519,8 +507,7 @@ QString QWindowsContext::registerWindowClass(QString cname,
qPrintable(cname));
d->m_registeredWindowClassNames.insert(cname);
- if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
- qDebug().nospace() << __FUNCTION__ << ' ' << cname
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << cname
<< " style=0x" << QString::number(style, 16)
<< " brush=" << brush << " icon=" << icon << " atom=" << atom;
return cname;
@@ -530,11 +517,8 @@ void QWindowsContext::unregisterWindowClasses()
{
const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0);
- foreach (const QString &name, d->m_registeredWindowClassNames) {
- if (QWindowsContext::verboseIntegration)
- qDebug() << __FUNCTION__ << name;
+ foreach (const QString &name, d->m_registeredWindowClassNames)
UnregisterClass((wchar_t*)name.utf16(), appInstance);
- }
d->m_registeredWindowClassNames.clear();
}
@@ -750,8 +734,20 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
msg.message = message; // time and pt fields ignored
msg.wParam = wParam;
msg.lParam = lParam;
- msg.pt.x = GET_X_LPARAM(lParam);
- msg.pt.y = GET_Y_LPARAM(lParam);
+ msg.pt.x = msg.pt.y = 0;
+ if (et != QtWindows::CursorEvent && (et & (QtWindows::MouseEventFlag | QtWindows::NonClientEventFlag))) {
+ msg.pt.x = GET_X_LPARAM(lParam);
+ msg.pt.y = GET_Y_LPARAM(lParam);
+ // For non-client-area messages, these are screen coordinates (as expected
+ // in the MSG structure), otherwise they are client coordinates.
+ if (!(et & QtWindows::NonClientEventFlag)) {
+ ClientToScreen(msg.hwnd, &msg.pt);
+ }
+ } else {
+#ifndef Q_OS_WINCE
+ GetCursorPos(&msg.pt);
+#endif
+ }
// Run the native event filters.
long filterResult = 0;
@@ -834,8 +830,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
// Suppress events sent during DestroyWindow() for native children.
if (platformWindow->testFlag(QWindowsWindow::WithinDestroy))
return false;
- if (QWindowsContext::verboseEvents > 1)
- qDebug().nospace() << "Event window: " << platformWindow->window();
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaEvents) << "Event window: " << platformWindow->window();
} else {
qWarning("%s: No Qt Window found for event 0x%x (%s), hwnd=0x%p.",
__FUNCTION__, message,
@@ -928,6 +924,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;
#ifndef Q_OS_WINCE
case QtWindows::ActivateWindowEvent:
+ if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
+ *result = LRESULT(MA_NOACTIVATE);
+ return true;
+ }
#ifndef QT_NO_TABLETEVENT
if (!d->m_tabletSupport.isNull())
d->m_tabletSupport->notifyActivate();
@@ -936,6 +936,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
if (const QWindow *modalWindow = QGuiApplication::modalWindow())
QWindowsWindow::baseWindowOf(modalWindow)->alertWindow();
break;
+ case QtWindows::MouseActivateWindowEvent:
+ if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
+ *result = LRESULT(MA_NOACTIVATE);
+ return true;
+ }
+ break;
#endif
#ifndef QT_NO_CONTEXTMENU
case QtWindows::ContextMenu:
@@ -1071,11 +1077,13 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR
LRESULT result;
const QtWindows::WindowsEventType et = windowsEventType(message, wParam);
const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result);
- if (QWindowsContext::verboseEvents > 1)
- if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message))
- qDebug("EVENT: hwd=%p %s msg=0x%x et=0x%x wp=%d at %d,%d handled=%d",
- hwnd, eventName, message, et, int(wParam),
- GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), handled);
+ if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
+ if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) {
+ qCDebug(lcQpaEvents) << "EVENT: hwd=" << hwnd << eventName << hex << "msg=0x" << message
+ << "et=0x" << et << dec << "wp=" << int(wParam) << "at"
+ << GET_X_LPARAM(lParam) << GET_Y_LPARAM(lParam) << "handled=" << handled;
+ }
+ }
if (!handled)
result = DefWindowProc(hwnd, message, wParam, lParam);
return result;
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 173df58570..1fea059ed9 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -47,12 +47,24 @@
#include <QtCore/QScopedPointer>
#include <QtCore/QSharedPointer>
+#include <QtCore/QLoggingCategory>
struct IBindCtx;
struct _SHSTOCKICONINFO;
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaWindows)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaGl)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaMime)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaDialogs)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaTablet)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaAccessibility)
+
class QWindow;
class QPlatformScreen;
class QWindowsScreenManager;
@@ -128,17 +140,7 @@ public:
};
// Verbose flag set by environment variable QT_QPA_VERBOSE
- static int verboseIntegration;
- static int verboseWindows;
- static int verboseBackingStore;
- static int verboseEvents;
- static int verboseFonts;
- static int verboseGL;
- static int verboseOLE;
- static int verboseInputMethods;
- static int verboseDialogs;
- static int verboseTheming;
- static int verboseTablet;
+ static int verbose;
explicit QWindowsContext();
~QWindowsContext();
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 5e7944a4cf..d8fb104b3c 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -186,32 +186,6 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar phand_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00,
- 0x80, 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00,
- 0x80, 0x1c, 0x00, 0x00, 0x80, 0xe4, 0x00, 0x00, 0x80, 0x24, 0x03, 0x00,
- 0x80, 0x24, 0x05, 0x00, 0xb8, 0x24, 0x09, 0x00, 0xc8, 0x00, 0x09, 0x00,
- 0x88, 0x00, 0x08, 0x00, 0x90, 0x00, 0x08, 0x00, 0xa0, 0x00, 0x08, 0x00,
- 0x20, 0x00, 0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 0x04, 0x00,
- 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x01, 0x02, 0x00,
- 0x00, 0x01, 0x02, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- static const uchar phandm_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00,
- 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00,
- 0x80, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00,
- 0x80, 0xff, 0x07, 0x00, 0xb8, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x0f, 0x00,
- 0xf8, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00,
- 0xe0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x07, 0x00,
- 0x80, 0xff, 0x07, 0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0xff, 0x03, 0x00,
- 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
static const uchar openhand_bits[] = {
0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
@@ -229,11 +203,6 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
- static const uchar * const cursor_bits32[] = {
- vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
- phand_bits, phandm_bits
- };
-
wchar_t *sh = 0;
switch (c.shape()) { // map to windows cursor
case Qt::ArrowCursor:
@@ -300,23 +269,18 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
mbits = cm.toImage().convertToFormat(QImage::Format_Mono);
hx = hy = 8;
invb = invm = false;
- } else if (cshape != Qt::BitmapCursor) {
- int i = cshape - Qt::SplitVCursor;
- QBitmap cb = QBitmap::fromData(QSize(32, 32), cursor_bits32[i * 2]);
- QBitmap cm = QBitmap::fromData(QSize(32, 32), cursor_bits32[i * 2 + 1]);
- bbits = cb.toImage().convertToFormat(QImage::Format_Mono);
- mbits = cm.toImage().convertToFormat(QImage::Format_Mono);
- if (cshape == Qt::PointingHandCursor) {
- hx = 7;
- hy = 0;
- } else
- hx = hy = 16;
- invb = invm = false;
- } else {
+ } else if (cshape == Qt::BitmapCursor) {
bbits = c.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
mbits = c.mask()->toImage().convertToFormat(QImage::Format_Mono);
invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
+ } else { // Qt::SplitVCursor, Qt::SplitHCursor
+ const QBitmap cb = QBitmap::fromData(QSize(32, 32), cshape == Qt::SplitVCursor ? vsplit_bits : hsplit_bits);
+ const QBitmap cm = QBitmap::fromData(QSize(32, 32), cshape == Qt::SplitVCursor ? vsplitm_bits : hsplitm_bits);
+ bbits = cb.toImage().convertToFormat(QImage::Format_Mono);
+ mbits = cm.toImage().convertToFormat(QImage::Format_Mono);
+ hx = hy = 16;
+ invb = invm = false;
}
const int n = qMax(1, bbits.width() / 8);
const int h = bbits.height();
@@ -441,9 +405,6 @@ QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c)
void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
{
-
- if (QWindowsContext::verboseWindows > 1)
- qDebug() << __FUNCTION__ << cursorIn << window;
if (!window)
return;
if (!cursorIn) {
@@ -468,10 +429,24 @@ QPoint QWindowsCursor::mousePosition()
return QPoint(p.x, p.y);
}
+QWindowsCursor::CursorState QWindowsCursor::cursorState()
+{
+#ifndef Q_OS_WINCE
+ enum { cursorShowing = 0x1, cursorSuppressed = 0x2 }; // Windows 8: CURSOR_SUPPRESSED
+ CURSORINFO cursorInfo;
+ cursorInfo.cbSize = sizeof(CURSORINFO);
+ if (GetCursorInfo(&cursorInfo)) {
+ if (cursorInfo.flags & CursorShowing)
+ return CursorShowing;
+ if (cursorInfo.flags & cursorSuppressed)
+ return CursorSuppressed;
+ }
+#endif // !Q_OS_WINCE
+ return CursorHidden;
+}
+
void QWindowsCursor::setPos(const QPoint &pos)
{
- if (QWindowsContext::verboseWindows)
- qDebug("%s %d,%d", __FUNCTION__, pos.x(), pos.y());
SetCursorPos(pos.x(), pos.y());
}
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index b366d9a06a..31da4e367d 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -93,6 +93,12 @@ private:
class QWindowsCursor : public QPlatformCursor
{
public:
+ enum CursorState {
+ CursorShowing,
+ CursorHidden,
+ CursorSuppressed // Cursor suppressed by touch interaction (Windows 8).
+ };
+
QWindowsCursor() {}
virtual void changeCursor(QCursor * widgetCursor, QWindow * widget);
@@ -102,6 +108,7 @@ public:
static HCURSOR createPixmapCursor(const QPixmap &pixmap, int hotX, int hotY);
static HCURSOR createSystemCursor(const QCursor &c);
static QPoint mousePosition();
+ static CursorState cursorState();
QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
QWindowsWindowCursor pixmapWindowCursor(const QCursor &c);
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 8ebfd018d0..2abfb426cc 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -422,8 +422,7 @@ void eatMouseMove()
;
if (msg.message == WM_MOUSEMOVE)
PostMessage(msg.hwnd, msg.message, 0, msg.lParam);
- if (QWindowsContext::verboseDialogs)
- qDebug("%s triggered=%d" , __FUNCTION__, msg.message == WM_MOUSEMOVE);
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << "triggered=" << (msg.message == WM_MOUSEMOVE);
}
} // namespace QWindowsDialogs
@@ -558,12 +557,10 @@ private:
void QWindowsDialogThread::run()
{
- if (QWindowsContext::verboseDialogs)
- qDebug(">%s" , __FUNCTION__);
+ qCDebug(lcQpaDialogs) << '>' << __FUNCTION__;
m_dialog->exec(m_owner);
deleteLater();
- if (QWindowsContext::verboseDialogs)
- qDebug("<%s" , __FUNCTION__);
+ qCDebug(lcQpaDialogs) << '<' << __FUNCTION__;
}
template <class BaseClass>
@@ -579,9 +576,9 @@ bool QWindowsDialogHelperBase<BaseClass>::show(Qt::WindowFlags,
} else {
m_ownerWindow = 0;
}
- if (QWindowsContext::verboseDialogs)
- qDebug("%s modal=%d modal supported? %d native=%p parent=%p" ,
- __FUNCTION__, modal, supportsNonModalDialog(parent), m_nativeDialog.data(), m_ownerWindow);
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << "modal=" << modal
+ << " modal supported? " << supportsNonModalDialog(parent)
+ << "native=" << m_nativeDialog.data() << "owner" << m_ownerWindow;
if (!modal && !supportsNonModalDialog(parent))
return false; // Was it changed in-between?
if (!ensureNativeDialog())
@@ -665,8 +662,7 @@ void QWindowsDialogHelperBase<BaseClass>::hide()
template <class BaseClass>
void QWindowsDialogHelperBase<BaseClass>::exec()
{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s" , __FUNCTION__);
+ qCDebug(lcQpaDialogs) << __FUNCTION__;
stopTimer();
if (QWindowsNativeDialogBase *nd = nativeDialog()) {
nd->exec(m_ownerWindow);
@@ -956,8 +952,7 @@ bool QWindowsNativeFileDialogBase::init(const CLSID &clsId, const IID &iid)
qErrnoWarning("IFileDialog::Advise failed");
return false;
}
- if (QWindowsContext::verboseDialogs)
- qDebug("%s %p %p cookie=%lu" , __FUNCTION__, m_fileDialog, m_dialogEvents, m_cookie);
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << m_fileDialog << m_dialogEvents << m_cookie;
return true;
}
@@ -1008,14 +1003,12 @@ QString QWindowsNativeFileDialogBase::directory() const
void QWindowsNativeFileDialogBase::doExec(HWND owner)
{
- if (QWindowsContext::verboseDialogs)
- qDebug(">%s on %p", __FUNCTION__, (void *)owner);
+ qCDebug(lcQpaDialogs) << '>' << __FUNCTION__;
// Show() blocks until the user closes the dialog, the dialog window
// gets a WM_CLOSE or the parent window is destroyed.
const HRESULT hr = m_fileDialog->Show(owner);
QWindowsDialogs::eatMouseMove();
- if (QWindowsContext::verboseDialogs)
- qDebug("<%s returns 0x%lx", __FUNCTION__, hr);
+ qCDebug(lcQpaDialogs) << '<' << __FUNCTION__ << " returns " << hex << hr;
if (hr == S_OK) {
emit accepted();
} else {
@@ -1045,10 +1038,8 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, QF
flags |= FOS_FILEMUSTEXIST | FOS_ALLOWMULTISELECT;
break;
}
- if (QWindowsContext::verboseDialogs)
- qDebug().nospace()
- << __FUNCTION__ << " mode=" << mode << " options"
- << options << " results in 0x" << flags;
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << " mode=" << mode << " options"
+ << options << " results in 0x" << flags;
if (FAILED(m_fileDialog->SetOptions(flags)))
qErrnoWarning("%s: SetOptions() failed", __FUNCTION__);
@@ -1352,8 +1343,7 @@ void QWindowsNativeFileDialogBase::close()
// IFileDialog::Close() does not work unless invoked from a callback.
// Try to find the window and send it a WM_CLOSE in addition.
const HWND hwnd = findDialogWindow(m_title);
- if (QWindowsContext::verboseDialogs)
- qDebug() << __FUNCTION__ << "closing" << hwnd;
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << "closing" << hwnd;
if (hwnd && IsWindowVisible(hwnd))
PostMessageW(hwnd, WM_CLOSE, 0, 0);
#endif // !Q_OS_WINCE
@@ -1617,8 +1607,7 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
void QWindowsFileDialogHelper::setDirectory(const QUrl &directory)
{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(directory.toString()));
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << directory.toString();
m_data.setDirectory(directory);
if (hasNativeDialog())
@@ -1632,8 +1621,7 @@ QUrl QWindowsFileDialogHelper::directory() const
void QWindowsFileDialogHelper::selectFile(const QUrl &fileName)
{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(fileName.toString()));
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << fileName.toString();
if (hasNativeDialog()) // Might be invoked from the QFileDialog constructor.
nativeFileDialog()->selectFile(fileName.toLocalFile()); // ## should use QUrl::fileName() once it exists
@@ -1646,8 +1634,7 @@ QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
void QWindowsFileDialogHelper::setFilter()
{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s" , __FUNCTION__);
+ qCDebug(lcQpaDialogs) << __FUNCTION__;
}
void QWindowsFileDialogHelper::selectNameFilter(const QString &filter)
@@ -2039,8 +2026,6 @@ void QWindowsNativeColorDialog::doExec(HWND owner)
typedef BOOL (WINAPI *ChooseColorWType)(LPCHOOSECOLORW);
CHOOSECOLOR chooseColor;
- if (QWindowsContext::verboseDialogs)
- qDebug() << '>' << __FUNCTION__ << " on " << owner;
ZeroMemory(&chooseColor, sizeof(chooseColor));
chooseColor.lStructSize = sizeof(chooseColor);
chooseColor.hwndOwner = owner;
@@ -2069,8 +2054,6 @@ void QWindowsNativeColorDialog::doExec(HWND owner)
for (int c= 0; c < customColorCount; ++c)
qCustomColors[c] = COLORREFToQColor(m_customColors[c]).rgb();
emit accepted();
- if (QWindowsContext::verboseDialogs)
- qDebug() << '<' << __FUNCTION__ << *m_color;
} else {
emit rejected();
}
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index fedda750d9..8f3ccdc0be 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -54,6 +54,9 @@
#include <QtGui/QMouseEvent>
#include <QtGui/QPixmap>
#include <QtGui/QPainter>
+#include <QtGui/QPaintDevice>
+#include <QtGui/QBackingStore>
+#include <QtGui/QWindow>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface_p.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -207,6 +210,77 @@ static const char * const ignoreDragCursorXpmC[] = {
"...............XXXX....."};
/*!
+ \class QWindowsDragCursorWindow
+ \brief A toplevel window showing the drag icon in case of touch drag.
+
+ \sa QWindowsOleDropSource
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsDragCursorWindow : public QWindow
+{
+public:
+ explicit QWindowsDragCursorWindow(QWindow *parent = 0);
+
+ void setPixmap(const QPixmap &p);
+
+protected:
+ void exposeEvent(QExposeEvent *);
+
+private:
+ void render();
+
+ QBackingStore m_backingStore;
+ QPixmap m_pixmap;
+};
+
+QWindowsDragCursorWindow::QWindowsDragCursorWindow(QWindow *parent)
+ : QWindow(parent)
+ , m_backingStore(this)
+{
+ QSurfaceFormat windowFormat = format();
+ windowFormat.setAlphaBufferSize(8);
+ setFormat(windowFormat);
+ setObjectName(QStringLiteral("QWindowsDragCursorWindow"));
+ setFlags(Qt::Popup | Qt::NoDropShadowWindowHint
+ | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
+ | Qt::WindowDoesNotAcceptFocus | Qt::WindowTransparentForInput);
+}
+
+void QWindowsDragCursorWindow::setPixmap(const QPixmap &p)
+{
+ if (p.cacheKey() == m_pixmap.cacheKey())
+ return;
+ const QSize oldSize = m_pixmap.size();
+ const QSize newSize = p.size();
+ qCDebug(lcQpaMime) << __FUNCTION__ << p.cacheKey() << newSize;
+ m_pixmap = p;
+ if (oldSize != newSize) {
+ resize(newSize);
+ m_backingStore.resize(newSize);
+ }
+ if (isVisible())
+ render();
+}
+
+void QWindowsDragCursorWindow::exposeEvent(QExposeEvent *)
+{
+ Q_ASSERT(!m_pixmap.isNull());
+ render();
+}
+
+void QWindowsDragCursorWindow::render()
+{
+ const QRect rect(QPoint(0, 0), m_pixmap.size());
+ m_backingStore.beginPaint(rect);
+ QPainter painter(m_backingStore.paintDevice());
+ painter.drawPixmap(0, 0, m_pixmap);
+ m_backingStore.endPaint();
+ m_backingStore.flush(rect);
+}
+
+/*!
\class QWindowsDropMimeData
\brief Special mime data class for data retrieval from Drag operations.
@@ -286,6 +360,11 @@ static inline Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
class QWindowsOleDropSource : public IDropSource
{
public:
+ enum Mode {
+ MouseDrag,
+ TouchDrag // Mouse cursor suppressed, use window as cursor.
+ };
+
explicit QWindowsOleDropSource(QWindowsDrag *drag);
virtual ~QWindowsOleDropSource();
@@ -304,34 +383,64 @@ private:
class DragCursorHandle {
Q_DISABLE_COPY(DragCursorHandle)
public:
- DragCursorHandle(HCURSOR c, qint64 k) : cursor(c), cacheKey(k) {}
+ DragCursorHandle(HCURSOR c) : cursor(c) {}
~DragCursorHandle() { DestroyCursor(cursor); }
- HCURSOR cursor;
- qint64 cacheKey;
+ const HCURSOR cursor;
+ };
+ typedef QSharedPointer<DragCursorHandle> DragCursorHandlePtr;
+
+ struct CursorEntry {
+ CursorEntry() : cacheKey(0) {}
+ CursorEntry(const QPixmap &p, qint64 cK, const DragCursorHandlePtr &c, const QPoint &h) :
+ pixmap(p), cacheKey(cK), cursor(c), hotSpot(h) {}
+
+ QPixmap pixmap;
+ qint64 cacheKey; // Cache key of cursor
+ DragCursorHandlePtr cursor;
+ QPoint hotSpot;
};
- typedef QMap <Qt::DropAction, QSharedPointer<DragCursorHandle> > ActionCursorMap;
+ typedef QMap<Qt::DropAction, CursorEntry> ActionCursorMap;
+ typedef ActionCursorMap::Iterator ActionCursorMapIt;
+ typedef ActionCursorMap::ConstIterator ActionCursorMapConstIt;
+
+ const Mode m_mode;
QWindowsDrag *m_drag;
Qt::MouseButtons m_currentButtons;
ActionCursorMap m_cursors;
+ QWindowsDragCursorWindow *m_touchDragWindow;
ULONG m_refs;
+#ifndef QT_NO_DEBUG_OUTPUT
+ friend QDebug operator<<(QDebug, const QWindowsOleDropSource::CursorEntry &);
+#endif
};
-QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag) :
- m_drag(drag), m_currentButtons(Qt::NoButton),
- m_refs(1)
+QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag)
+ : m_mode(QWindowsCursor::cursorState() != QWindowsCursor::CursorSuppressed ? MouseDrag : TouchDrag)
+ , m_drag(drag)
+ , m_currentButtons(Qt::NoButton)
+ , m_touchDragWindow(0)
+ , m_refs(1)
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s", __FUNCTION__);
+ qCDebug(lcQpaMime) << __FUNCTION__ << m_mode;
}
QWindowsOleDropSource::~QWindowsOleDropSource()
{
m_cursors.clear();
- if (QWindowsContext::verboseOLE)
- qDebug("%s", __FUNCTION__);
+ delete m_touchDragWindow;
+ qCDebug(lcQpaMime) << __FUNCTION__;
+}
+
+#ifndef QT_NO_DEBUG_OUTPUT
+QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
+{
+ d << "CursorEntry:" << e.pixmap.size() << '#' << e.cacheKey
+ << "HCURSOR" << e.cursor->cursor << "hotspot:" << e.hotSpot;
+ return d;
}
+#endif // !QT_NO_DEBUG_OUTPUT
/*!
\brief Blend custom pixmap with cursors.
@@ -343,59 +452,56 @@ void QWindowsOleDropSource::createCursors()
const QPixmap pixmap = drag->pixmap();
const bool hasPixmap = !pixmap.isNull();
- QList<Qt::DropAction> actions;
- actions << Qt::MoveAction << Qt::CopyAction << Qt::LinkAction;
- if (hasPixmap)
- actions << Qt::IgnoreAction;
+ 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();
- for (int cnum = 0; cnum < actions.size(); ++cnum) {
- const Qt::DropAction action = actions.at(cnum);
- QPixmap cpm = drag->dragCursor(action);
- if (cpm.isNull())
- cpm = m_drag->defaultCursor(action);
- QSharedPointer<DragCursorHandle> cursorHandler = m_cursors.value(action);
- if (!cursorHandler.isNull() && cpm.cacheKey() == cursorHandler->cacheKey)
+ for (int cnum = 0; cnum < actionCount; ++cnum) {
+ const Qt::DropAction action = actions[cnum];
+ QPixmap cursorPixmap = drag->dragCursor(action);
+ if (cursorPixmap.isNull())
+ cursorPixmap = m_drag->defaultCursor(action);
+ const qint64 cacheKey = cursorPixmap.cacheKey();
+ const ActionCursorMapIt it = m_cursors.find(action);
+ if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
continue;
- if (cpm.isNull()) {
+ if (cursorPixmap.isNull()) {
qWarning("%s: Unable to obtain drag cursor for %d.", __FUNCTION__, action);
continue;
}
- int w = cpm.width();
- int h = cpm.height();
+ QPoint newHotSpot(0, 0);
+ QPixmap newPixmap = cursorPixmap;
if (hasPixmap) {
const int x1 = qMin(-hotSpot.x(), 0);
- const int x2 = qMax(pixmap.width() - hotSpot.x(), cpm.width());
+ const int x2 = qMax(pixmap.width() - hotSpot.x(), cursorPixmap.width());
const int y1 = qMin(-hotSpot.y(), 0);
- const int y2 = qMax(pixmap.height() - hotSpot.y(), cpm.height());
-
- w = x2 - x1 + 1;
- h = y2 - y1 + 1;
- }
-
- const QPoint newHotSpot = hotSpot;
- QPixmap newCursor(w, h);
- if (hasPixmap) {
+ const int y2 = qMax(pixmap.height() - hotSpot.y(), cursorPixmap.height());
+ QPixmap newCursor(x2 - x1 + 1, y2 - y1 + 1);
newCursor.fill(Qt::transparent);
QPainter p(&newCursor);
const QRect srcRect = pixmap.rect();
const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
p.drawPixmap(pmDest, pixmap, srcRect);
- p.drawPixmap(qMax(0,newHotSpot.x()),qMax(0,newHotSpot.y()),cpm);
- } else {
- newCursor = cpm;
+ p.drawPixmap(qMax(0, hotSpot.x()),qMax(0, hotSpot.y()), cursorPixmap);
+ newPixmap = newCursor;
+ newHotSpot = QPoint(qMax(0, hotSpot.x()), qMax(0, hotSpot.y()));
}
- const int hotX = hasPixmap ? qMax(0,newHotSpot.x()) : 0;
- const int hotY = hasPixmap ? qMax(0,newHotSpot.y()) : 0;
-
- if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY)) {
- m_cursors.insert(action, QSharedPointer<DragCursorHandle>(new DragCursorHandle(sysCursor, cpm.cacheKey())));
+ if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newPixmap, newHotSpot.x(), newHotSpot.y())) {
+ const CursorEntry entry(newPixmap, cacheKey, DragCursorHandlePtr(new DragCursorHandle(sysCursor)), newHotSpot);
+ if (it == m_cursors.end())
+ m_cursors.insert(action, entry);
+ else
+ it.value() = entry;
}
}
- if (QWindowsContext::verboseOLE)
- qDebug("%s %d cursors", __FUNCTION__, m_cursors.size());
+#ifndef QT_NO_DEBUG_OUTPUT
+ if (lcQpaMime().isDebugEnabled())
+ qCDebug(lcQpaMime) << __FUNCTION__ << "pixmap" << pixmap.size() << m_cursors.size() << "cursors:\n" << m_cursors;
+#endif // !QT_NO_DEBUG_OUTPUT
}
//---------------------------------------------------------------------
@@ -468,11 +574,11 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
} while (false);
- if (QWindowsContext::verboseOLE
- && (QWindowsContext::verboseOLE > 1 || hr != S_OK))
- qDebug("%s fEscapePressed=%d, grfKeyState=%lu buttons=%d returns 0x%x",
- __FUNCTION__, fEscapePressed,grfKeyState, int(m_currentButtons),
- int(hr));
+ if (QWindowsContext::verbose > 1 || hr != S_OK) {
+ qCDebug(lcQpaMime) << __FUNCTION__ << "fEscapePressed=" << fEscapePressed
+ << "grfKeyState=" << grfKeyState << "buttons" << m_currentButtons
+ << "returns 0x" << hex <<int(hr) << dec;
+ }
return hr;
}
@@ -486,17 +592,29 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
const Qt::DropAction action = translateToQDragDropAction(dwEffect);
m_drag->updateAction(action);
- if (QWindowsContext::verboseOLE > 2)
- qDebug("%s dwEffect=%lu, action=%d", __FUNCTION__, dwEffect, action);
-
- QSharedPointer<DragCursorHandle> cursorHandler = m_cursors.value(action);
- qint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey();
- if (cursorHandler.isNull() || currentCacheKey != cursorHandler->cacheKey)
+ const qint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey();
+ ActionCursorMapConstIt it = m_cursors.constFind(action);
+ // If a custom drag cursor is set, check its cache key to detect changes.
+ if (it == m_cursors.constEnd() || (currentCacheKey && currentCacheKey != it.value().cacheKey)) {
createCursors();
+ it = m_cursors.constFind(action);
+ }
- const ActionCursorMap::const_iterator it = m_cursors.constFind(action);
if (it != m_cursors.constEnd()) {
- SetCursor(it.value()->cursor);
+ const CursorEntry &e = it.value();
+ switch (m_mode) {
+ case MouseDrag:
+ SetCursor(e.cursor->cursor);
+ break;
+ case TouchDrag:
+ if (!m_touchDragWindow)
+ m_touchDragWindow = new QWindowsDragCursorWindow;
+ m_touchDragWindow->setPixmap(e.pixmap);
+ m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot);
+ if (!m_touchDragWindow->isVisible())
+ m_touchDragWindow->show();
+ break;
+ }
return ResultFromScode(S_OK);
}
@@ -519,14 +637,12 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) :
m_refs(1), m_window(w), m_chosenEffect(0), m_lastKeyState(0)
{
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << this << w;
+ qCDebug(lcQpaMime) << __FUNCTION__ << this << w;
}
QWindowsOleDropTarget::~QWindowsOleDropTarget()
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s %p", __FUNCTION__, this);
+ qCDebug(lcQpaMime) << __FUNCTION__ << this;
}
STDMETHODIMP
@@ -588,13 +704,12 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
m_chosenEffect = DROPEFFECT_NONE;
}
*pdwEffect = m_chosenEffect;
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << m_window
- << windowsDrag->dropData() << " supported actions=" << actions
- << " mods=" << QGuiApplicationPrivate::modifier_buttons
- << " mouse=" << QGuiApplicationPrivate::mouse_buttons
- << " accepted: " << response.isAccepted() << action
- << m_answerRect << " effect" << *pdwEffect;
+ qCDebug(lcQpaMime) << __FUNCTION__ << m_window
+ << windowsDrag->dropData() << " supported actions=" << actions
+ << " mods=" << QGuiApplicationPrivate::modifier_buttons
+ << " mouse=" << QGuiApplicationPrivate::mouse_buttons
+ << " accepted: " << response.isAccepted() << action
+ << m_answerRect << " effect" << *pdwEffect;
}
QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
@@ -604,8 +719,8 @@ QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
dh->DragEnter(reinterpret_cast<HWND>(m_window->winId()), pDataObj, reinterpret_cast<POINT*>(&pt), *pdwEffect);
- if (QWindowsContext::verboseOLE)
- qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, m_window, grfKeyState, pt.x, pt.y);
+ qCDebug(lcQpaMime) << __FUNCTION__ << "widget=" << m_window << " key=" << grfKeyState
+ << "pt=" << pt.x << pt.y;
QWindowsDrag::instance()->setDropDataObject(pDataObj);
pDataObj->AddRef();
@@ -621,15 +736,14 @@ QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
dh->DragOver(reinterpret_cast<POINT*>(&pt), *pdwEffect);
QWindow *dragOverWindow = findDragOverWindow(pt);
- if (QWindowsContext::verboseOLE)
- qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, dragOverWindow, grfKeyState, pt.x, pt.y);
+ qCDebug(lcQpaMime) << __FUNCTION__ << "widget=" << dragOverWindow << " key=" << grfKeyState
+ << "pt=" << pt.x << pt.y;
const QPoint tmpPoint = QWindowsGeometryHint::mapFromGlobal(dragOverWindow, QPoint(pt.x,pt.y));
// see if we should compress this event
if ((tmpPoint == m_lastPoint || m_answerRect.contains(tmpPoint))
&& m_lastKeyState == grfKeyState) {
*pdwEffect = m_chosenEffect;
- if (QWindowsContext::verboseOLE)
- qDebug("%s: compressed event", __FUNCTION__);
+ qCDebug(lcQpaMime) << __FUNCTION__ << "compressed event";
return NOERROR;
}
@@ -643,8 +757,7 @@ QWindowsOleDropTarget::DragLeave()
if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
dh->DragLeave();
- if (QWindowsContext::verboseOLE)
- qDebug().nospace() <<__FUNCTION__ << ' ' << m_window;
+ qCDebug(lcQpaMime) << __FUNCTION__ << ' ' << m_window;
QWindowSystemInterface::handleDrag(m_window, 0, QPoint(), Qt::IgnoreAction);
QWindowsDrag::instance()->releaseDropDataObject();
@@ -663,11 +776,8 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
QWindow *dropWindow = findDragOverWindow(pt);
- if (QWindowsContext::verboseOLE)
- qDebug().nospace() << __FUNCTION__ << ' ' << m_window
- << " on " << dropWindow
- << " keys=" << grfKeyState << " pt="
- << pt.x << ',' << pt.y;
+ qCDebug(lcQpaMime) << __FUNCTION__ << ' ' << m_window
+ << " on " << dropWindow << " keys=" << grfKeyState << " pt=" << pt.x << ',' << pt.y;
m_lastPoint = QWindowsGeometryHint::mapFromGlobal(dropWindow, QPoint(pt.x,pt.y));
// grfKeyState does not all ways contain button state in the drop so if
@@ -796,9 +906,8 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag)
QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
const Qt::DropActions possibleActions = drag->supportedActions();
const DWORD allowedEffects = translateToWinDragEffects(possibleActions);
- if (QWindowsContext::verboseOLE)
- qDebug(">%s possible Actions=%x, effects=0x%lx", __FUNCTION__,
- int(possibleActions), allowedEffects);
+ qCDebug(lcQpaMime) << '>' << __FUNCTION__ << "possible Actions=0x"
+ << hex << int(possibleActions) << "effects=0x" << allowedEffects << dec;
const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect);
const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect();
if (r == DRAGDROP_S_DROP) {
@@ -819,10 +928,9 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag)
dropDataObject->releaseQt();
dropDataObject->Release(); // Will delete obj if refcount becomes 0
windowDropSource->Release(); // Will delete src if refcount becomes 0
- if (QWindowsContext::verboseOLE)
- qDebug("<%s allowedEffects=0x%lx, reportedPerformedEffect=0x%lx, resultEffect=0x%lx, hr=0x%x, dropAction=%d",
- __FUNCTION__, allowedEffects, reportedPerformedEffect,
- resultEffect, int(r), dragResult);
+ qCDebug(lcQpaMime) << '<' << __FUNCTION__ << hex << "allowedEffects=0x" << allowedEffects
+ << "reportedPerformedEffect=0x" << reportedPerformedEffect
+ << " resultEffect=0x" << resultEffect << "hr=0x" << int(r) << dec << "dropAction=" << dragResult;
return dragResult;
}
@@ -833,8 +941,7 @@ QWindowsDrag *QWindowsDrag::instance()
void QWindowsDrag::releaseDropDataObject()
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s %p", __FUNCTION__, m_dropDataObject);
+ qCDebug(lcQpaMime) << __FUNCTION__ << m_dropDataObject;
if (m_dropDataObject) {
m_dropDataObject->Release();
m_dropDataObject = 0;
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index d029249eeb..a8617b2c2b 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -89,16 +89,14 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
Q_FUNC_INFO, eglGetError());
return 0;
}
- if (QWindowsContext::verboseGL)
- qDebug("%s: Created EGL display %p v%d.%d",
- __FUNCTION__, display, major, minor);
+
+ qCDebug(lcQpaGl) << __FUNCTION__ << "Created EGL display" << display << 'v' <<major << '.' << minor;
return new QWindowsEGLStaticContext(display, (major << 8) | minor);
}
QWindowsEGLStaticContext::~QWindowsEGLStaticContext()
{
- if (QWindowsContext::verboseGL)
- qDebug("%s: Releasing EGL display %p", __FUNCTION__, m_display);
+ qCDebug(lcQpaGl) << __FUNCTION__ << "Releasing EGL display " << m_display;
eglTerminate(m_display);
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 3a6f9f72e3..c273219181 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -857,19 +857,20 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
const QFont::Stretch stretch = QFont::Unstretched;
#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verboseFonts > 2) {
- QDebug nospace = qDebug().nospace();
- nospace << __FUNCTION__ << familyName << charSet
- << "TTF=" << ttf;
+ if (QWindowsContext::verbose > 2) {
+ QString message;
+ QTextStream str(&message);
+ str << __FUNCTION__ << ' ' << familyName << ' ' << charSet << " TTF=" << ttf;
if (type & DEVICE_FONTTYPE)
- nospace << " DEVICE";
+ str << " DEVICE";
if (type & RASTER_FONTTYPE)
- nospace << " RASTER";
+ str << " RASTER";
if (type & TRUETYPE_FONTTYPE)
- nospace << " TRUETYPE";
- nospace << " scalable=" << scalable << " Size=" << size
+ str << " TRUETYPE";
+ str << " scalable=" << scalable << " Size=" << size
<< " Style=" << style << " Weight=" << weight
<< " stretch=" << stretch;
+ qCDebug(lcQpaFonts) << message;
}
#endif
@@ -973,8 +974,7 @@ void QWindowsFontDatabase::populateFontDatabase()
void QWindowsFontDatabase::populate(const QString &family)
{
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << m_families.size() << family;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << m_families.size() << family;
HDC dummy = GetDC(0);
LOGFONT lf;
@@ -1026,11 +1026,10 @@ QWindowsFontDatabase::QWindowsFontDatabase()
Q_UNUSED(hfontMetaTypeId)
Q_UNUSED(logFontMetaTypeId)
- if (QWindowsContext::verboseFonts) {
+ if (lcQpaFonts().isDebugEnabled()) {
const QWindowsFontEngineDataPtr data = sharedFontData();
- qDebug() << __FUNCTION__ << "Clear type: "
- << data->clearTypeEnabled << "gamma: "
- << data->fontSmoothingGamma;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "Clear type: "
+ << data->clearTypeEnabled << "gamma: " << data->fontSmoothingGamma;
}
}
@@ -1044,8 +1043,7 @@ QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, QChar::S
QFontEngine *fe = QWindowsFontDatabase::createEngine(script, fontDef,
0, QWindowsContext::instance()->defaultDPI(), false,
QStringList(), sharedFontData());
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << "FONTDEF" << fontDef << script << fe << handle;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << script << fe << handle;
return fe;
}
@@ -1200,8 +1198,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal
}
}
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fontEngine;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fontEngine;
return fontEngine;
}
@@ -1361,17 +1358,14 @@ void QWindowsFontDatabase::removeApplicationFonts()
m_applicationFonts.clear();
}
-void QWindowsFontDatabase::releaseHandle(void *handle)
+void QWindowsFontDatabase::releaseHandle(void * /* handle */)
{
- if (handle && QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << handle;
}
QString QWindowsFontDatabase::fontDir() const
{
const QString result = QPlatformFontDatabase::fontDir();
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << result;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << result;
return result;
}
@@ -1550,7 +1544,7 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request)
return lf;
}
-static QStringList extraTryFontsForFamily(const QString& family)
+QStringList QWindowsFontDatabase::extraTryFontsForFamily(const QString &family)
{
QStringList result;
QFontDatabase db;
@@ -1620,11 +1614,11 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFon
result << QString::fromLatin1("Arial");
}
- result.append(extraTryFontsForFamily(family));
+ if (script == QChar::Script_Common || script == QChar::Script_Han)
+ result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << family << style << styleHint
- << script << result << m_families.size();
+ qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
+ << script << result << m_families.size();
return result;
}
@@ -1785,7 +1779,7 @@ QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &requ
if ((script == QChar::Script_Common || script == QChar::Script_Han)
&& !(request.styleStrategy & QFont::NoFontMerging)) {
- QStringList extraFonts = extraTryFontsForFamily(request.family);
+ const QStringList extraFonts = QWindowsFontDatabase::extraTryFontsForFamily(request.family);
if (extraFonts.size()) {
QStringList list = family_list;
list.append(extraFonts);
@@ -1810,8 +1804,7 @@ QFont QWindowsFontDatabase::systemDefaultFont()
// "MS Shell Dlg 2" is the correct system font >= Win2k
if (systemFont.family() == QStringLiteral("MS Shell Dlg"))
systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << systemFont;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
return systemFont;
}
@@ -1825,9 +1818,9 @@ QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int vertica
qFont.setWeight(weightFromInteger(logFont.lfWeight));
const qreal logFontHeight = qAbs(logFont.lfHeight);
qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
- qFont.setUnderline(false);
+ qFont.setUnderline(logFont.lfUnderline);
qFont.setOverline(false);
- qFont.setStrikeOut(false);
+ qFont.setStrikeOut(logFont.lfStrikeOut);
return qFont;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h
index b9e6c38eaa..7dfcfbc2b5 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.h
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h
@@ -103,6 +103,8 @@ public:
static qreal fontSmoothingGamma();
static LOGFONT fontDefToLOGFONT(const QFontDef &fontDef);
+ static QStringList extraTryFontsForFamily(const QString &family);
+
private:
void populate(const QString &family = QString());
void removeApplicationFonts();
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 51f79736f2..c4fc2f4759 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -151,19 +151,20 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
const QFont::Stretch stretch = QFont::Unstretched;
#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verboseFonts > 2) {
- QDebug nospace = qDebug().nospace();
- nospace << __FUNCTION__ << familyName << faceName << fullName << charSet
- << "TTF=" << ttf;
+ if (QWindowsContext::verbose > 2) {
+ QString message;
+ QTextStream str(&message);
+ str << __FUNCTION__ << ' ' << familyName << ' ' << charSet << " TTF=" << ttf;
if (type & DEVICE_FONTTYPE)
- nospace << " DEVICE";
+ str << " DEVICE";
if (type & RASTER_FONTTYPE)
- nospace << " RASTER";
+ str << " RASTER";
if (type & TRUETYPE_FONTTYPE)
- nospace << " TRUETYPE";
- nospace << " scalable=" << scalable << " Size=" << size
+ str << " TRUETYPE";
+ str << " scalable=" << scalable << " Size=" << size
<< " Style=" << style << " Weight=" << weight
<< " stretch=" << stretch;
+ qCDebug(lcQpaFonts) << message;
}
#endif
@@ -403,8 +404,7 @@ void QWindowsFontDatabaseFT::populateFontDatabase()
void QWindowsFontDatabaseFT::populate(const QString &family)
{
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << m_families.size() << family;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << m_families.size() << family;
HDC dummy = GetDC(0);
LOGFONT lf;
@@ -425,108 +425,19 @@ void QWindowsFontDatabaseFT::populate(const QString &family)
QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle)
{
QFontEngine *fe = QBasicFontDatabase::fontEngine(fontDef, script, handle);
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << "FONTDEF" << /*fontDef <<*/ script << fe << handle;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef.family << script << fe << handle;
return fe;
}
QFontEngine *QWindowsFontDatabaseFT::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
{
QFontEngine *fe = QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference);
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe;
return fe;
}
-static const char *other_tryFonts[] = {
- "Arial",
- "MS UI Gothic",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *jp_tryFonts [] = {
- "MS UI Gothic",
- "Arial",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_CN_tryFonts [] = {
- "SimSun",
- "Arial",
- "PMingLiU",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_TW_tryFonts [] = {
- "PMingLiU",
- "Arial",
- "SimSun",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *kr_tryFonts[] = {
- "Gulim",
- "Arial",
- "PMingLiU",
- "SimSun",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char **tryFonts = 0;
-
QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
- if (script == QChar::Script_Common || script == QChar::Script_Han) {
-// && !(request.styleStrategy & QFont::NoFontMerging)) {
- QFontDatabase db;
- if (!db.writingSystems(family).contains(QFontDatabase::Symbol)) {
- if(!tryFonts) {
- LANGID lid = GetUserDefaultLangID();
- switch( lid&0xff ) {
- case LANG_CHINESE: // Chinese (Taiwan)
- if ( lid == 0x0804 ) // Taiwan
- tryFonts = ch_TW_tryFonts;
- else
- tryFonts = ch_CN_tryFonts;
- break;
- case LANG_JAPANESE:
- tryFonts = jp_tryFonts;
- break;
- case LANG_KOREAN:
- tryFonts = kr_tryFonts;
- break;
- default:
- tryFonts = other_tryFonts;
- break;
- }
- }
- QStringList list;
- const char **tf = tryFonts;
- while(tf && *tf) {
- if(m_families.contains(QLatin1String(*tf)))
- list << QLatin1String(*tf);
- ++tf;
- }
- if (!list.isEmpty())
- return list;
- }
- }
QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script);
if (!result.isEmpty())
return result;
@@ -566,51 +477,24 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QF
}
#endif
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << family << style << styleHint
- << script << result << m_families;
+ if (script == QChar::Script_Common || script == QChar::Script_Han)
+ result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
+
+ qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
+ << script << result << m_families;
+
return result;
}
QString QWindowsFontDatabaseFT::fontDir() const
{
const QString result = QLatin1String(qgetenv("windir")) + QLatin1String("/Fonts");//QPlatformFontDatabase::fontDir();
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << result;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << result;
return result;
}
-HFONT QWindowsFontDatabaseFT::systemFont()
-{
- static const HFONT stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT);
- return stock_sysfont;
-}
-
-// Creation functions
-
-static inline int verticalDPI()
-{
- return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY);
-}
-
QFont QWindowsFontDatabaseFT::defaultFont() const
{
return QWindowsFontDatabase::systemDefaultFont();
}
-QFont QWindowsFontDatabaseFT::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
-{
- if (verticalDPI_In <= 0)
- verticalDPI_In = verticalDPI();
- QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
- qFont.setItalic(logFont.lfItalic);
- if (logFont.lfWeight != FW_DONTCARE)
- qFont.setWeight(weightFromInteger(logFont.lfWeight));
- const qreal logFontHeight = qAbs(logFont.lfHeight);
- qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
- qFont.setUnderline(logFont.lfUnderline);
- qFont.setOverline(false);
- qFont.setStrikeOut(logFont.lfStrikeOut);
- return qFont;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
index d3cbc0210a..9544974ad1 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
@@ -60,9 +60,6 @@ public:
virtual QString fontDir() const;
virtual QFont defaultFont() const;
- static HFONT systemFont();
- static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
-
private:
void populate(const QString &family = QString());
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 6c928119b3..1676b73658 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -219,44 +219,11 @@ inline unsigned int getChar(const QChar *str, int &i, const int len)
return uc;
}
-int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
+int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs) const
{
int i = 0;
int glyph_pos = 0;
- if (mirrored) {
-#if defined(Q_OS_WINCE)
- {
-#else
- if (symbol) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
- if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
- }
- } else if (ttf) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc));
- }
- } else {
-#endif
- wchar_t first = tm.tmFirstChar;
- wchar_t last = tm.tmLastChar;
-
- for (; i < numChars; ++i, ++glyph_pos) {
- uint ucs = QChar::mirroredChar(getChar(str, i, numChars));
- if (
-#ifdef Q_WS_WINCE
- tm.tmFirstChar > 60000 ||
-#endif
- ucs >= first && ucs <= last)
- glyphs->glyphs[glyph_pos] = ucs;
- else
- glyphs->glyphs[glyph_pos] = 0;
- }
- }
- } else {
+ {
#if defined(Q_OS_WINCE)
{
#else
@@ -325,8 +292,7 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name,
designAdvances(0),
designAdvancesSize(0)
{
- if (QWindowsContext::verboseFonts)
- qDebug("%s: font='%s', size=%ld", __FUNCTION__, qPrintable(name), lf.lfHeight);
+ qCDebug(lcQpaFonts) << __FUNCTION__ << name << lf.lfHeight;
HDC hdc = m_fontEngineData->hdc;
SelectObject(hdc, hfont);
fontDef.pixelSize = -lf.lfHeight;
@@ -366,9 +332,7 @@ QWindowsFontEngine::~QWindowsFontEngine()
if (!DeleteObject(hfont))
qErrnoWarning("%s: QFontEngineWin: failed to delete non-stock font... failed", __FUNCTION__);
}
- if (QWindowsContext::verboseFonts)
- if (QWindowsContext::verboseFonts)
- qDebug("%s: font='%s", __FUNCTION__, qPrintable(_name));
+ qCDebug(lcQpaFonts) << __FUNCTION__ << _name;
if (!uniqueFamilyName.isEmpty()) {
QPlatformFontDatabase *pfdb = QWindowsIntegration::instance()->fontDatabase();
@@ -393,7 +357,7 @@ bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *g
}
glyphs->numGlyphs = *nglyphs;
- *nglyphs = getGlyphIndexes(str, len, glyphs, flags & RightToLeft);
+ *nglyphs = getGlyphIndexes(str, len, glyphs);
if (!(flags & GlyphIndicesOnly))
recalcAdvances(glyphs, flags);
@@ -434,8 +398,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
calculateTTFGlyphWidth(hdc, glyph, width);
designAdvances[glyph] = QFixed(width) / designToDevice;
}
- glyphs->advances_x[i] = designAdvances[glyph];
- glyphs->advances_y[i] = 0;
+ glyphs->advances[i] = designAdvances[glyph];
}
if(oldFont)
DeleteObject(SelectObject(hdc, oldFont));
@@ -443,8 +406,6 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
for(int i = 0; i < glyphs->numGlyphs; i++) {
unsigned int glyph = glyphs->glyphs[i];
- glyphs->advances_y[i] = 0;
-
if (glyph >= widthCacheSize) {
int newSize = (glyph + 256) >> 8 << 8;
widthCache = q_check_ptr((unsigned char *)realloc(widthCache,
@@ -452,9 +413,9 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
widthCacheSize = newSize;
}
- glyphs->advances_x[i] = widthCache[glyph];
+ glyphs->advances[i] = widthCache[glyph];
// font-width cache failed
- if (glyphs->advances_x[i] == 0) {
+ if (glyphs->advances[i].value() == 0) {
int width = 0;
if (!oldFont)
oldFont = SelectObject(hdc, hfont);
@@ -473,7 +434,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
} else {
calculateTTFGlyphWidth(hdc, glyph, width);
}
- glyphs->advances_x[i] = width;
+ glyphs->advances[i] = width;
// if glyph's within cache range, store it for later
if (width > 0 && width < 0x100)
widthCache[glyph] = width;
@@ -1347,8 +1308,7 @@ QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStri
: QFontEngineMulti(fallbacks.size()+1),
fallbacks(fallbacks)
{
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << engines.size() << first << first->fontDef.family << fallbacks;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << engines.size() << first << first->fontDef.family << fallbacks;
engines[0] = first;
first->ref.ref();
fontDef = engines[0]->fontDef;
@@ -1357,8 +1317,7 @@ QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStri
QWindowsMultiFontEngine::~QWindowsMultiFontEngine()
{
- if (QWindowsContext::verboseFonts)
- qDebug("%s", __FUNCTION__);
+ qCDebug(lcQpaFonts) << __FUNCTION__;
}
void QWindowsMultiFontEngine::loadEngine(int at)
@@ -1409,9 +1368,7 @@ void QWindowsMultiFontEngine::loadEngine(int at)
fedw->ref.ref();
engines[at] = fedw;
- if (QWindowsContext::verboseFonts)
- qDebug("%s %d %s", __FUNCTION__, at, qPrintable(fam));
-
+ qCDebug(lcQpaFonts) << __FUNCTION__ << at << fam;
return;
} else {
qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__);
@@ -1433,9 +1390,7 @@ void QWindowsMultiFontEngine::loadEngine(int at)
engines[at] = new QWindowsFontEngine(fam, hfont, stockFont, lf, data);
engines[at]->ref.ref();
engines[at]->fontDef = fontDef;
- if (QWindowsContext::verboseFonts)
- qDebug("%s %d %s", __FUNCTION__, at, qPrintable(fam));
-
+ qCDebug(lcQpaFonts) << __FUNCTION__ << at << fam;
// TODO: increase cost in QFontCache for the font engine loaded here
}
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index acf84d270c..e3fb3281a3 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -127,7 +127,7 @@ public:
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
#endif
- int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
+ int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs) const;
void getCMap();
bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const;
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index d81848fcc7..ce5ea8167f 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -212,8 +212,7 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
, m_xHeight(-1)
, m_lineGap(-1)
{
- if (QWindowsContext::verboseFonts)
- qDebug("%s %g", __FUNCTION__, pixelSize);
+ qCDebug(lcQpaFonts) << __FUNCTION__ << pixelSize;
Q_ASSERT(m_directWriteFontFace);
@@ -227,8 +226,7 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
{
- if (QWindowsContext::verboseFonts)
- qDebug("%s", __FUNCTION__);
+ qCDebug(lcQpaFonts) << __FUNCTION__;
m_fontEngineData->directWriteFactory->Release();
m_directWriteFontFace->Release();
@@ -327,13 +325,8 @@ bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGly
QVarLengthArray<UINT32> codePoints(len);
int actualLength = 0;
- if (flags & QFontEngine::RightToLeft) {
- for (int i = 0; i < len; ++i)
- codePoints[actualLength++] = QChar::mirroredChar(getChar(str, i, len));
- } else {
- for (int i = 0; i < len; ++i)
- codePoints[actualLength++] = getChar(str, i, len);
- }
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = getChar(str, i, len);
QVarLengthArray<UINT16> glyphIndices(actualLength);
HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,
@@ -368,13 +361,11 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
glyphIndices.size(),
glyphMetrics.data());
if (SUCCEEDED(hr)) {
- for (int i=0; i<glyphs->numGlyphs; ++i) {
- glyphs->advances_x[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth);
- glyphs->advances_y[i] = 0;
- }
+ for (int i = 0; i < glyphs->numGlyphs; ++i)
+ glyphs->advances[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth);
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < glyphs->numGlyphs; ++i)
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances[i] = glyphs->advances[i].round();
}
} else {
qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
index 57a6a3ba1d..399bb5f5ad 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -105,6 +105,8 @@ public:
static QString fontNameSubstitute(const QString &familyName);
+ IDWriteFontFace *directWriteFontFace() const { return m_directWriteFontFace; }
+
private:
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();
diff --git a/src/plugins/platforms/windows/qwindowsgdiintegration.cpp b/src/plugins/platforms/windows/qwindowsgdiintegration.cpp
new file mode 100644
index 0000000000..9c8b5ed620
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsgdiintegration.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsgdiintegration.h"
+#include "qwindowscontext.h"
+#include "qwindowsbackingstore.h"
+#include "qwindowsgdinativeinterface.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/private/qpixmap_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsGdiIntegrationPrivate
+{
+public:
+ QWindowsGdiNativeInterface m_nativeInterface;
+};
+
+QWindowsGdiIntegration::QWindowsGdiIntegration(const QStringList &paramList)
+ : QWindowsIntegration(paramList)
+ , d(new QWindowsGdiIntegrationPrivate)
+{}
+
+QWindowsGdiIntegration::~QWindowsGdiIntegration()
+{}
+
+QPlatformNativeInterface *QWindowsGdiIntegration::nativeInterface() const
+{
+ return &d->m_nativeInterface;
+}
+
+QPlatformPixmap *QWindowsGdiIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+{
+ return new QRasterPlatformPixmap(type);
+}
+
+QPlatformBackingStore *QWindowsGdiIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QWindowsBackingStore(window);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsgdiintegration.h b/src/plugins/platforms/windows/qwindowsgdiintegration.h
new file mode 100644
index 0000000000..0bf44d5439
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsgdiintegration.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSGDIINTEGRATION_H
+#define QWINDOWSGDIINTEGRATION_H
+
+#include "qwindowsintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsGdiIntegrationPrivate;
+class QWindowsGdiIntegration : public QWindowsIntegration
+{
+public:
+ explicit QWindowsGdiIntegration(const QStringList &paramList);
+ virtual ~QWindowsGdiIntegration();
+
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWindowsGdiIntegrationPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSGDIINTEGRATION_H
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp b/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp
index de4075feff..c1b0c139c9 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp
@@ -39,23 +39,24 @@
**
****************************************************************************/
-#include "qandroidopenglplatformscreen.h"
-#include "qandroidopenglplatformwindow.h"
-#include "androidjnimenu.h"
+#include "qwindowsgdinativeinterface.h"
+#include "qwindowsbackingstore.h"
-QT_BEGIN_NAMESPACE
+#include <QtGui/QBackingStore>
-QAndroidOpenGLPlatformScreen::QAndroidOpenGLPlatformScreen(EGLDisplay display)
- : QEglFSScreen(display)
-{
-}
+QT_BEGIN_NAMESPACE
-void QAndroidOpenGLPlatformScreen::topWindowChanged(QPlatformWindow *window)
+void *QWindowsGdiNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
{
- QtAndroidMenu::setActiveTopLevelWindow(window->window());
- QAndroidOpenGLPlatformWindow *platformWindow = static_cast<QAndroidOpenGLPlatformWindow *>(window);
- if (platformWindow != 0)
- platformWindow->updateStatusBarVisibility();
+ if (!bs || !bs->handle()) {
+ qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+ QWindowsBackingStore *wbs = static_cast<QWindowsBackingStore *>(bs->handle());
+ if (resource == "getDC")
+ return wbs->getDC();
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsvthandler.h b/src/plugins/platforms/windows/qwindowsgdinativeinterface.h
index 8c4f511bc8..3aa3a0b175 100644
--- a/src/plugins/platforms/kms/qkmsvthandler.h
+++ b/src/plugins/platforms/windows/qwindowsgdinativeinterface.h
@@ -39,30 +39,20 @@
**
****************************************************************************/
-#ifndef QKMSVTHANDLER_H
-#define QKMSVTHANDLER_H
+#ifndef QWINDOWSGDINATIVEINTERFACE_H
+#define QWINDOWSGDINATIVEINTERFACE_H
-#include <QObject>
+#include "qwindowsnativeinterface.h"
QT_BEGIN_NAMESPACE
-class QKmsVTHandler : public QObject
+class QWindowsGdiNativeInterface : public QWindowsNativeInterface
{
Q_OBJECT
-
public:
- QKmsVTHandler(QObject *parent = 0);
- ~QKmsVTHandler();
-
-private:
- void cleanup();
- static void crashHandler();
-
- static QKmsVTHandler *self;
- int m_tty;
- int m_oldKbdMode;
+ void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
-#endif
+#endif // QWINDOWSGDINATIVEINTERFACE_H
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index 82deb0f473..b046879314 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -223,7 +223,7 @@ static void describeFormats(HDC hdc)
PIXELFORMATDESCRIPTOR pfd;
initPixelFormatDescriptor(&pfd);
DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- qDebug() << '#' << i << '/' << pfiMax << ':' << pfd;
+ qCDebug(lcQpaGl) << '#' << i << '/' << pfiMax << ':' << pfd;
}
}
@@ -341,10 +341,8 @@ static int choosePixelFormat(HDC hdc, const QSurfaceFormat &format,
bestPfi = pfi;
*obtainedPfd = checkPfd;
}
- if (QWindowsContext::verboseGL)
- qDebug() << __FUNCTION__ << " checking " << pfi << '/' << pfiMax
- << " score=" << score << " (best " << bestPfi << '/' << bestScore
- << ") " << checkPfd;
+ qCDebug(lcQpaGl) << __FUNCTION__ << " checking " << pfi << '/' << pfiMax
+ << " score=" << score << " (best " << bestPfi << '/' << bestScore << ") " << checkPfd;
}
} // for
if (bestPfi > 0)
@@ -471,15 +469,15 @@ static int choosePixelFormat(HDC hdc,
initPixelFormatDescriptor(obtainedPfd);
DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
- if (QWindowsContext::verboseGL)
- qDebug() << __FUNCTION__ << " obtained px #" << pixelFormat
- << " not acceptable=" << *obtainedPfd;
+ qCDebug(lcQpaGl) << __FUNCTION__ << " obtained px #" << pixelFormat
+ << " not acceptable=" << *obtainedPfd;
pixelFormat = 0;
}
#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verboseGL) {
- QDebug nsp = qDebug().nospace();
+ if (lcQpaGl().isDebugEnabled()) {
+ QString message;
+ QDebug nsp(&message);
nsp << __FUNCTION__;
if (sampleBuffersRequested)
nsp << " samples=" << iAttributes[samplesValuePosition];
@@ -488,6 +486,7 @@ static int choosePixelFormat(HDC hdc,
nsp << iAttributes[ii] << ',';
nsp << noshowbase << dec << "\n obtained px #" << pixelFormat
<< " of " << numFormats << "\n " << *obtainedPfd;
+ qCDebug(lcQpaGl) << message;
} // Debug
#endif
@@ -611,9 +610,8 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
break;
}
}
- if (QWindowsContext::verboseGL)
- qDebug("%s: Creating context version %d.%d with %d attributes",
- __FUNCTION__, majorVersion, minorVersion, attribIndex / 2);
+ qCDebug(lcQpaGl) << __FUNCTION__ << "Creating context version"
+ << majorVersion << '.' << minorVersion << attribIndex / 2 << "attributes";
const HGLRC result =
staticContext.wglCreateContextAttribsARB(hdc, shared, attributes);
@@ -842,8 +840,7 @@ QOpenGLStaticContext *QOpenGLStaticContext::create()
if (!wglGetCurrentContext())
temporaryContext.reset(new QOpenGLTemporaryContext);
QOpenGLStaticContext *result = new QOpenGLStaticContext;
- if (QWindowsContext::verboseGL)
- qDebug() << __FUNCTION__ << *result;
+ qCDebug(lcQpaGl) << __FUNCTION__ << *result;
return result;
}
@@ -857,7 +854,7 @@ QDebug operator<<(QDebug d, const QOpenGLStaticContext &s)
if (s.hasExtensions())
nsp << ", Extension-API present";
nsp << "\nExtensions: " << (s.extensionNames.count(' ') + 1);
- if (QWindowsContext::verboseGL > 1)
+ if (QWindowsContext::verbose > 1)
nsp << s.extensionNames;
return d;
}
@@ -882,7 +879,9 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
m_staticContext(staticContext),
m_context(context),
m_renderingContext(0),
- m_pixelFormat(0), m_extensionsUsed(false)
+ m_pixelFormat(0),
+ m_extensionsUsed(false),
+ m_swapInterval(-1)
{
QSurfaceFormat format = context->format();
if (format.renderableType() == QSurfaceFormat::DefaultRenderableType)
@@ -915,7 +914,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
if (!hdc)
break;
- if (QWindowsContext::verboseGL > 1)
+ if (QWindowsContext::verbose > 1)
describeFormats(hdc);
// Preferably use direct rendering and ARB extensions (unless pixmap
// or explicitly turned off on command line).
@@ -979,11 +978,9 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
QWindowsOpenGLContextFormat::current().apply(&m_obtainedFormat);
- if (requestedAdditional.swapInterval != -1 && m_staticContext->wglSwapInternalExt) {
- m_staticContext->wglSwapInternalExt(requestedAdditional.swapInterval);
- if (m_staticContext->wglGetSwapInternalExt)
- obtainedSwapInternal = m_staticContext->wglGetSwapInternalExt();
- }
+ if (m_staticContext->wglGetSwapInternalExt)
+ obtainedSwapInternal = m_staticContext->wglGetSwapInternalExt();
+
wglMakeCurrent(0, 0);
} while (false);
if (hdc)
@@ -991,14 +988,12 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
if (dummyWindow)
DestroyWindow(dummyWindow);
- if (QWindowsContext::verboseGL)
- qDebug() << __FUNCTION__ << this << (tryExtensions ? "ARB" : "GDI")
- << " requested: " << context->format()
- << "\n obtained #" << m_pixelFormat << (m_extensionsUsed ? "ARB" : "GDI")
- << m_obtainedFormat << "\n " << m_obtainedPixelFormatDescriptor
- << " swap interval: " << obtainedSwapInternal
- << "\n default: " << m_staticContext->defaultFormat
- << "\n HGLRC=" << m_renderingContext;
+ qCDebug(lcQpaGl()) << __FUNCTION__ << this << (tryExtensions ? "ARB" : "GDI")
+ << " requested: " << context->format()
+ << "\n obtained #" << m_pixelFormat << (m_extensionsUsed ? "ARB" : "GDI") << m_obtainedFormat
+ << "\n " << m_obtainedPixelFormatDescriptor << " swap interval: " << obtainedSwapInternal
+ << "\n default: " << m_staticContext->defaultFormat
+ << "\n HGLRC=" << m_renderingContext;
}
QWindowsGLContext::~QWindowsGLContext()
@@ -1039,8 +1034,8 @@ static inline const QOpenGLContextData *
void QWindowsGLContext::swapBuffers(QPlatformSurface *surface)
{
- if (QWindowsContext::verboseGL > 1)
- qDebug() << __FUNCTION__ << surface;
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << surface;
if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, handleOf(surface))) {
SwapBuffers(contextData->hdc);
} else {
@@ -1051,8 +1046,8 @@ void QWindowsGLContext::swapBuffers(QPlatformSurface *surface)
bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
{
#ifdef DEBUG_GL
- if (QWindowsContext::verboseGL > 1)
- qDebug("%s context=%p contexts=%d", __FUNCTION__, this, m_windowContexts.size());
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << this << m_windowContexts.size() << "contexts";
#endif // DEBUG_GL
Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
@@ -1087,14 +1082,26 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
window->setFlag(QWindowsWindow::OpenGLDoubleBuffered);
}
m_windowContexts.append(newContext);
- return wglMakeCurrent(newContext.hdc, newContext.renderingContext);
+
+ bool success = wglMakeCurrent(newContext.hdc, newContext.renderingContext);
+
+ // Set the swap interval
+ if (m_staticContext->wglSwapInternalExt) {
+ const int interval = surface->format().swapInterval();
+ if (interval >= 0 && m_swapInterval != interval) {
+ m_swapInterval = interval;
+ m_staticContext->wglSwapInternalExt(interval);
+ }
+ }
+
+ return success;
}
void QWindowsGLContext::doneCurrent()
{
#ifdef DEBUG_GL
- if (QWindowsContext::verboseGL > 1)
- qDebug("%s context=%p %d contexts", __FUNCTION__, this, m_windowContexts.size());
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << this << m_windowContexts.size() << "contexts";
#endif // DEBUG_GL
wglMakeCurrent(0, 0);
releaseDCs();
@@ -1104,10 +1111,8 @@ QWindowsGLContext::GL_Proc QWindowsGLContext::getProcAddress(const QByteArray &p
{
// TODO: Will that work with the calling conventions?
GL_Proc procAddress = reinterpret_cast<GL_Proc>(wglGetProcAddress(procName.constData()));
- if (QWindowsContext::verboseGL > 1)
- qDebug("%s('%s') with current_hglrc=%p returns %p",
- __FUNCTION__, procName.constData(),
- wglGetCurrentContext(), procAddress);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << procName << wglGetCurrentContext() << "returns" << procAddress;
if (!procAddress)
qWarning("%s: Unable to resolve '%s'", __FUNCTION__, procName.constData());
return procAddress;
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 730e90bf70..c6b477128a 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -64,11 +64,10 @@ enum QWindowsGLFormatFlags
// Additional format information for Windows.
struct QWindowsOpenGLAdditionalFormat
{
- QWindowsOpenGLAdditionalFormat(unsigned formatFlagsIn = 0, unsigned pixmapDepthIn = 0, unsigned swapIntervalIn = -1) :
- formatFlags(formatFlagsIn), pixmapDepth(pixmapDepthIn), swapInterval(swapIntervalIn) {}
+ QWindowsOpenGLAdditionalFormat(unsigned formatFlagsIn = 0, unsigned pixmapDepthIn = 0) :
+ formatFlags(formatFlagsIn), pixmapDepth(pixmapDepthIn) { }
unsigned formatFlags; // QWindowsGLFormatFlags.
unsigned pixmapDepth; // for QWindowsGLRenderToPixmap
- int swapInterval;
};
// Per-window data for active OpenGL contexts.
@@ -178,6 +177,7 @@ private:
PIXELFORMATDESCRIPTOR m_obtainedPixelFormatDescriptor;
int m_pixelFormat;
bool m_extensionsUsed;
+ int m_swapInterval;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
index e7cd0bc6c8..878db7185d 100644
--- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
+++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
@@ -75,11 +75,11 @@ QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) :
bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
{
m_flags = flags;
- if (QWindowsContext::verboseEvents > 2)
- qDebug(">%s %s %d", __FUNCTION__, qPrintable(objectName()), int(flags));
+ if (QWindowsContext::verbose > 2 && lcQpaEvents().isDebugEnabled())
+ qCDebug(lcQpaEvents) << '>' << __FUNCTION__ << objectName() << flags;
const bool rc = QEventDispatcherWin32::processEvents(flags);
- if (QWindowsContext::verboseEvents > 2)
- qDebug("<%s %s returns %d", __FUNCTION__, qPrintable(objectName()), rc);
+ if (QWindowsContext::verbose > 2 && lcQpaEvents().isDebugEnabled())
+ qCDebug(lcQpaEvents) << '<' << __FUNCTION__ << "returns" << rc;
return rc;
}
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index a84d30de0f..2429e8a4fa 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -188,8 +188,7 @@ void QWindowsInputContext::reset()
if (!m_compositionContext.hwnd)
return;
QObject *fo = qApp->focusObject();
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__<< fo;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__<< fo;
if (!fo)
return;
if (m_compositionContext.isComposing) {
@@ -221,8 +220,7 @@ void QWindowsInputContext::cursorRectChanged()
if (!cursorRectangle.isValid())
return;
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__<< cursorRectangle;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__<< cursorRectangle;
const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
if (!himc)
@@ -259,8 +257,7 @@ void QWindowsInputContext::invokeAction(QInputMethod::Action action, int cursorP
return;
}
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << cursorPosition << action;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << cursorPosition << action;
if (cursorPosition < 0 || cursorPosition > m_compositionContext.composition.size())
reset();
@@ -339,8 +336,7 @@ bool QWindowsInputContext::startComposition(HWND hwnd)
QWindow *window = qApp->focusWindow();
if (!window)
return false;
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << fo << window;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window;
if (!fo || QWindowsWindow::handleOf(window) != hwnd)
return false;
initContext(hwnd);
@@ -402,9 +398,8 @@ bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
{
QObject *fo = qApp->focusObject();
const int lParam = int(lParamIn);
- if (QWindowsContext::verboseInputMethods)
- qDebug() << '>' << __FUNCTION__ << fo << debugComposition(lParam)
- << " composing=" << m_compositionContext.isComposing;
+ qCDebug(lcQpaInputMethods) << '>' << __FUNCTION__ << fo << debugComposition(lParam)
+ << " composing=" << m_compositionContext.isComposing;
if (!fo || m_compositionContext.hwnd != hwnd || !lParam)
return false;
const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
@@ -443,11 +438,9 @@ bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
endContextComposition();
}
const bool result = QCoreApplication::sendEvent(fo, event.data());
- if (QWindowsContext::verboseInputMethods)
- qDebug() << '<' << __FUNCTION__ << "sending markup="
- << event->attributes().size()
- << " commit=" << event->commitString()
- << " to " << fo << " returns " << result;
+ qCDebug(lcQpaInputMethods) << '<' << __FUNCTION__ << "sending markup="
+ << event->attributes().size() << " commit=" << event->commitString()
+ << " to " << fo << " returns " << result;
update(Qt::ImQueryAll);
ImmReleaseContext(m_compositionContext.hwnd, himc);
return result;
@@ -455,8 +448,7 @@ bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
bool QWindowsInputContext::endComposition(HWND hwnd)
{
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << m_endCompositionRecursionGuard << hwnd;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << m_endCompositionRecursionGuard << hwnd;
// Googles Pinyin Input Method likes to call endComposition again
// when we call notifyIME with CPS_CANCEL, so protect ourselves
// against that.
@@ -549,10 +541,8 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
return -1;
const DWORD memSize = sizeof(RECONVERTSTRING)
+ (surroundingText.length() + 1) * sizeof(ushort);
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << " reconv=" << reconv
- << " surroundingText=" << surroundingText
- << " size=" << memSize;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << " reconv=" << reconv
+ << " surroundingText=" << surroundingText << " size=" << memSize;
// If memory is not allocated, return the required size.
if (!reconv)
return surroundingText.isEmpty() ? -1 : int(memSize);
@@ -567,8 +557,7 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
const int startPos = bounds.position();
bounds.toNextBoundary();
const int endPos = bounds.position();
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << " boundary=" << startPos << endPos;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << " boundary=" << startPos << endPos;
// Select the text, this will be overwritten by following IME events.
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, startPos, endPos-startPos, QVariant());
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index b6e75929f8..8a91929733 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -41,7 +41,6 @@
****************************************************************************/
#include "qwindowsintegration.h"
-#include "qwindowsbackingstore.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#if defined(QT_OPENGL_ES_2)
@@ -75,8 +74,6 @@
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
# include "qwindowssessionmanager.h"
#endif
-#include <QtGui/QBackingStore>
-#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/private/qeventdispatcher_win_p.h>
@@ -86,174 +83,6 @@
QT_BEGIN_NAMESPACE
/*!
- \class QWindowsNativeInterface
- \brief Provides access to native handles.
-
- Currently implemented keys
- \list
- \li handle (HWND)
- \li getDC (DC)
- \li releaseDC Releases the previously acquired DC and returns 0.
- \endlist
-
- \internal
- \ingroup qt-lighthouse-win
-*/
-
-class QWindowsNativeInterface : public QPlatformNativeInterface
-{
- Q_OBJECT
- Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
-public:
-#ifndef QT_NO_OPENGL
- virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
-#endif
- virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
- virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs);
-
- Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
- const QString &windowName,
- void *eventProc) const;
-
- Q_INVOKABLE QString registerWindowClass(const QString &classNameIn, void *eventProc) const;
-
- Q_INVOKABLE void beep() { MessageBeep(MB_OK); } // For QApplication
-
- bool asyncExpose() const;
- void setAsyncExpose(bool value);
-
- QVariantMap windowProperties(QPlatformWindow *window) const;
- QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
- QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
- void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
-};
-
-void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
-{
- if (!window || !window->handle()) {
- qWarning("%s: '%s' requested for null window or window without handle.", __FUNCTION__, resource.constData());
- return 0;
- }
- QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle());
- if (resource == "handle")
- return bw->handle();
- if (window->surfaceType() == QWindow::RasterSurface) {
- if (resource == "getDC")
- return bw->getDC();
- if (resource == "releaseDC") {
- bw->releaseDC();
- return 0;
- }
- }
- qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
- return 0;
-}
-
-void *QWindowsNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
-{
- if (!bs || !bs->handle()) {
- qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
- return 0;
- }
- QWindowsBackingStore *wbs = static_cast<QWindowsBackingStore *>(bs->handle());
- if (resource == "getDC")
- return wbs->getDC();
- qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
- return 0;
-}
-
-static const char customMarginPropertyC[] = "WindowsCustomMargins";
-
-QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
-{
- QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window);
- if (name == QLatin1String(customMarginPropertyC))
- return qVariantFromValue(platformWindow->customMargins());
- return QVariant();
-}
-
-QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const
-{
- const QVariant result = windowProperty(window, name);
- return result.isValid() ? result : defaultValue;
-}
-
-void QWindowsNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
-{
- QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window);
- if (name == QLatin1String(customMarginPropertyC))
- platformWindow->setCustomMargins(qvariant_cast<QMargins>(value));
-}
-
-QVariantMap QWindowsNativeInterface::windowProperties(QPlatformWindow *window) const
-{
- QVariantMap result;
- const QString customMarginProperty = QLatin1String(customMarginPropertyC);
- result.insert(customMarginProperty, windowProperty(window, customMarginProperty));
- return result;
-}
-
-#ifndef QT_NO_OPENGL
-void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
-{
- if (!context || !context->handle()) {
- qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
- return 0;
- }
-#ifdef QT_OPENGL_ES_2
- QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
- if (resource == QByteArrayLiteral("eglDisplay"))
- return windowsEglContext->eglDisplay();
- if (resource == QByteArrayLiteral("eglContext"))
- return windowsEglContext->eglContext();
- if (resource == QByteArrayLiteral("eglConfig"))
- return windowsEglContext->eglConfig();
-#else // QT_OPENGL_ES_2
- QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
- if (resource == QByteArrayLiteral("renderingContext"))
- return windowsContext->renderingContext();
-#endif // !QT_OPENGL_ES_2
-
- qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
- return 0;
-}
-#endif // !QT_NO_OPENGL
-
-/*!
- \brief Creates a non-visible window handle for filtering messages.
-*/
-
-void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTemplate,
- const QString &windowName,
- void *eventProc) const
-{
- QWindowsContext *ctx = QWindowsContext::instance();
- const HWND hwnd = ctx->createDummyWindow(classNameTemplate,
- (wchar_t*)windowName.utf16(),
- (WNDPROC)eventProc);
- return hwnd;
-}
-
-/*!
- \brief Registers a unique window class with a callback function based on \a classNameIn.
-*/
-
-QString QWindowsNativeInterface::registerWindowClass(const QString &classNameIn, void *eventProc) const
-{
- return QWindowsContext::instance()->registerWindowClass(classNameIn, (WNDPROC)eventProc);
-}
-
-bool QWindowsNativeInterface::asyncExpose() const
-{
- return QWindowsContext::instance()->asyncExpose();
-}
-
-void QWindowsNativeInterface::setAsyncExpose(bool value)
-{
- QWindowsContext::instance()->setAsyncExpose(value);
-}
-
-/*!
\class QWindowsIntegration
\brief QPlatformIntegration implementation for Windows.
\internal
@@ -308,7 +137,6 @@ struct QWindowsIntegrationPrivate
const unsigned m_options;
QWindowsContext m_context;
QPlatformFontDatabase *m_fontDatabase;
- QWindowsNativeInterface m_nativeInterface;
#ifndef QT_NO_CLIPBOARD
QWindowsClipboard m_clipboard;
# ifndef QT_NO_DRAGANDDROP
@@ -345,8 +173,10 @@ static inline unsigned parseOptions(const QStringList &paramList)
}
} else if (param == QLatin1String("gl=gdi")) {
options |= QWindowsIntegration::DisableArb;
- } else if (param == QLatin1String("mousefromtouch")) {
- options |= QWindowsIntegration::PassOsMouseEventsSynthesizedFromTouch;
+ } else if (param == QLatin1String("nomousefromtouch")) {
+ options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch;
+ } else if (param.startsWith(QLatin1String("verbose="))) {
+ QWindowsContext::verbose = param.right(param.size() - 8).toInt();
}
}
return options;
@@ -375,8 +205,6 @@ QWindowsIntegration::QWindowsIntegration(const QStringList &paramList) :
QWindowsIntegration::~QWindowsIntegration()
{
- if (QWindowsContext::verboseIntegration)
- qDebug("%s", __FUNCTION__);
}
bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -406,14 +234,9 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
return false;
}
-QPlatformPixmap *QWindowsIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
{
- return new QRasterPlatformPixmap(type);
-}
-
-QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
-{
- QWindowsWindow::WindowData requested;
+ QWindowsWindowData requested;
requested.flags = window->flags();
requested.geometry = window->geometry();
// Apply custom margins (see QWindowsWindow::setCustomMargins())).
@@ -421,42 +244,40 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
if (customMarginsV.isValid())
requested.customMargins = qvariant_cast<QMargins>(customMarginsV);
- const QWindowsWindow::WindowData obtained
- = QWindowsWindow::WindowData::create(window, requested, window->title());
- if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
- qDebug().nospace()
- << __FUNCTION__ << '<' << window << '\n'
- << " Requested: " << requested.geometry << "frame incl.: "
- << QWindowsGeometryHint::positionIncludesFrame(window)
- << " Flags="
- << QWindowsWindow::debugWindowFlags(requested.flags) << '\n'
- << " Obtained : " << obtained.geometry << " Margins "
- << obtained.frame << " Flags="
- << QWindowsWindow::debugWindowFlags(obtained.flags)
- << " Handle=" << obtained.hwnd << '\n';
- if (!obtained.hwnd)
- return 0;
- if (requested.flags != obtained.flags)
- window->setFlags(obtained.flags);
- // Trigger geometry change signals of QWindow.
- if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry)
- QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
- return new QWindowsWindow(window, obtained);
+ const QWindowsWindowData obtained
+ = QWindowsWindowData::create(window, requested, window->title());
+ qCDebug(lcQpaWindows).nospace()
+ << __FUNCTION__ << '<' << window
+ << "\n Requested: " << requested.geometry << "frame incl.: "
+ << QWindowsGeometryHint::positionIncludesFrame(window)
+ << " Flags=" << QWindowsWindow::debugWindowFlags(requested.flags)
+ << "\n Obtained : " << obtained.geometry << " Margins "<< obtained.frame
+ << " Flags=" << QWindowsWindow::debugWindowFlags(obtained.flags)
+ << " Handle=" << obtained.hwnd << '\n';
+
+ if (obtained.hwnd) {
+ if (requested.flags != obtained.flags)
+ window->setFlags(obtained.flags);
+ // Trigger geometry change signals of QWindow.
+ if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry)
+ QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
+ }
+
+ return obtained;
}
-QPlatformBackingStore *QWindowsIntegration::createPlatformBackingStore(QWindow *window) const
+QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
{
- if (QWindowsContext::verboseIntegration)
- qDebug() << __FUNCTION__ << window;
- return new QWindowsBackingStore(window);
+ QWindowsWindowData data = createWindowData(window);
+ return data.hwnd ? new QWindowsWindow(window, data)
+ : Q_NULLPTR;
}
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext
*QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- if (QWindowsContext::verboseIntegration)
- qDebug() << __FUNCTION__ << context->format();
+ qCDebug(lcQpaGl) << __FUNCTION__ << context->format();
#ifdef QT_OPENGL_ES_2
if (d->m_staticEGLContext.isNull()) {
QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create();
@@ -510,9 +331,7 @@ QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const
d->m_fontDatabase = new QWindowsFontDatabase;
#else
if (isQMLApplication()) {
- if (QWindowsContext::verboseIntegration) {
- qDebug() << "QML application detected, using FreeType rendering";
- }
+ qCDebug(lcQpaFonts) << "QML application detected, using FreeType rendering";
d->m_fontDatabase = new QWindowsFontDatabaseFT;
}
else
@@ -563,11 +382,9 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co
case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
#ifdef Q_OS_WINCE
// We do not want Qt to synthesize mouse events as Windows also does that.
- // Alternatively, Windows-generated touch mouse events can be identified and
- // ignored by checking GetMessageExtraInfo() for MI_WP_SIGNATURE (0xFF515700).
return false;
#else // Q_OS_WINCE
- return QVariant(!(d->m_options & PassOsMouseEventsSynthesizedFromTouch));
+ return QVariant(bool(d->m_options & DontPassOsMouseEventsSynthesizedFromTouch));
#endif // !Q_OS_WINCE
default:
break;
@@ -585,11 +402,6 @@ QList<int> QWindowsIntegration::possibleKeys(const QKeyEvent *e) const
return d->m_context.possibleKeys(e);
}
-QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const
-{
- return &d->m_nativeInterface;
-}
-
#ifndef QT_NO_CLIPBOARD
QPlatformClipboard * QWindowsIntegration::clipboard() const
{
@@ -655,5 +467,3 @@ QPlatformServices *QWindowsIntegration::services() const
}
QT_END_NAMESPACE
-
-#include "qwindowsintegration.moc"
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 97916a479b..2202ebd39e 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -50,6 +50,8 @@
QT_BEGIN_NAMESPACE
struct QWindowsIntegrationPrivate;
+struct QWindowsWindowData;
+class QWindowsWindow;
class QWindowsIntegration : public QPlatformIntegration
{
@@ -60,7 +62,7 @@ public:
DisableArb = 0x4,
NoNativeDialogs = 0x8,
XpNativeDialogs = 0x10,
- PassOsMouseEventsSynthesizedFromTouch = 0x20 // Pass OS-generated mouse events from touch.
+ DontPassOsMouseEventsSynthesizedFromTouch = 0x20 // Do not pass OS-generated mouse events from touch.
};
explicit QWindowsIntegration(const QStringList &paramList);
@@ -68,9 +70,8 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
- virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
+ QWindowsWindowData createWindowData(QWindow *window) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
#ifndef QT_NO_OPENGL
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
#endif
@@ -85,7 +86,6 @@ public:
#ifndef QT_NO_ACCESSIBILITY
virtual QPlatformAccessibility *accessibility() const;
#endif
- virtual QPlatformNativeInterface *nativeInterface() const;
virtual QPlatformFontDatabase *fontDatabase() const;
virtual QStringList themeNames() const;
virtual QPlatformTheme *createPlatformTheme(const QString &name) const;
diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
index 5d22ea1a83..75686182cf 100644
--- a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
@@ -75,8 +75,7 @@ bool QWindowsInternalMimeData::hasFormat_sys(const QString &mime) const
const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
const bool has = mc.converterToMime(mime, pDataObj) != 0;
releaseDataObject(pDataObj);
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << mime << has;
+ qCDebug(lcQpaMime) << __FUNCTION__ << mime << has;
return has;
}
@@ -89,8 +88,7 @@ QStringList QWindowsInternalMimeData::formats_sys() const
const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
const QStringList fmts = mc.allMimesForFormats(pDataObj);
releaseDataObject(pDataObj);
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << fmts;
+ qCDebug(lcQpaMime) << __FUNCTION__ << fmts;
return fmts;
}
@@ -106,12 +104,10 @@ QVariant QWindowsInternalMimeData::retrieveData_sys(const QString &mimeType,
if (const QWindowsMime *converter = mc.converterToMime(mimeType, pDataObj))
result = converter->convertToMime(mimeType, pDataObj, type);
releaseDataObject(pDataObj);
- if (QWindowsContext::verboseOLE) {
- QDebug nospace = qDebug().nospace();
- nospace << __FUNCTION__ << ' ' << mimeType << ' ' << type
- << " returns " << result.type();
- if (result.type() != QVariant::ByteArray)
- nospace << ' ' << result;
+ if (QWindowsContext::verbose) {
+ qCDebug(lcQpaMime) <<__FUNCTION__ << ' ' << mimeType << ' ' << type
+ << " returns " << result.type()
+ << (result.type() != QVariant::ByteArray ? result.toString() : QStringLiteral("<data>"));
}
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 334df17026..0b257cc48f 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -653,16 +653,20 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32
::ToAscii(VK_SPACE, 0, emptyBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
}
-
- if (QWindowsContext::verboseEvents > 1) {
- qDebug("updatePossibleKeyCodes for virtual key = 0x%02x!", vk_key);
+ if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
+ QString message;
+ QDebug debug(&message);
+ debug <<__FUNCTION__ << " for virtual key = 0x" << hex << vk_key << dec<< '\n';
for (size_t i = 0; i < NumMods; ++i) {
- qDebug(" [%d] (%d,0x%02x,'%c') %s", int(i),
- keyLayout[vk_key].qtKey[i],
- keyLayout[vk_key].qtKey[i],
- keyLayout[vk_key].qtKey[i] ? keyLayout[vk_key].qtKey[i] : 0x03,
- keyLayout[vk_key].deadkeys & (1<<i) ? "deadkey" : "");
+ const quint32 qtKey = keyLayout[vk_key].qtKey[i];
+ debug << " [" << i << "] (" << qtKey << ','
+ << hex << showbase << qtKey << noshowbase << dec
+ << ",'" << char(qtKey ? qtKey : 0x03) << "')";
+ if (keyLayout[vk_key].deadkeys & (1<<i))
+ debug << " deadkey";
+ debug << '\n';
}
+ qCDebug(lcQpaEvents) << message;
}
}
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index f62b8a6139..3af2cff9a0 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -675,8 +675,7 @@ QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pData
else
ret = str.toUtf8();
}
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << ret;
+ qCDebug(lcQpaMime) << __FUNCTION__ << ret;
return ret;
}
@@ -1490,8 +1489,7 @@ QStringList QWindowsMimeConverter::allMimesForFormats(IDataObject *pDataObj) con
}
fmtenum->Release();
}
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << pDataObj << formats;
+ qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj << formats;
return formats;
}
@@ -1541,9 +1539,8 @@ QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
if (converter->canConvertToMime(format, pDataObj)) {
const QVariant dataV = converter->convertToMime(format, pDataObj, preferredType);
if (dataV.isValid()) {
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << mimeTypes << "\nFormat: "
- << format << pDataObj << " returns " << dataV;
+ qCDebug(lcQpaMime) << __FUNCTION__ << mimeTypes << "\nFormat: "
+ << format << pDataObj << " returns " << dataV;
if (formatIn)
*formatIn = format;
return dataV;
@@ -1551,8 +1548,7 @@ QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
}
}
}
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << "fails" << mimeTypes << pDataObj << preferredType;
+ qCDebug(lcQpaMime) << __FUNCTION__ << "fails" << mimeTypes << pDataObj << preferredType;
return QVariant();
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 3dd8c5a0cd..d8c0a9e426 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -167,8 +167,12 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
if (et == QtWindows::MouseWheelEvent)
return translateMouseWheelEvent(window, hwnd, msg, result);
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
+
#ifndef Q_OS_WINCE
- static const bool passSynthesizedMouseEvents = QWindowsIntegration::instance()->options() & QWindowsIntegration::PassOsMouseEventsSynthesizedFromTouch;
+ // Check for events synthesized from touch. Lower byte is touch index, 0 means pen.
+ static const bool passSynthesizedMouseEvents =
+ !(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch);
if (!passSynthesizedMouseEvents) {
// Check for events synthesized from touch. Lower 7 bits are touch/pen index, bit 8 indicates touch.
// However, when tablet support is active, extraInfo is a packet serial number. This is not a problem
@@ -177,6 +181,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
const bool fromTouch = (extraInfo & signatureMask) == miWpSignature && (extraInfo & 0x80);
if (fromTouch)
return false;
+ source = Qt::MouseEventSynthesizedBySystem;
}
#endif // !Q_OS_WINCE
@@ -187,22 +192,21 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
globalPosition, buttons,
- QWindowsKeyMapper::queryKeyboardModifiers());
+ QWindowsKeyMapper::queryKeyboardModifiers(),
+ source);
return false; // Allow further event processing (dragging of windows).
}
*result = 0;
if (msg.message == WM_MOUSELEAVE) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "WM_MOUSELEAVE for " << window << " previous window under mouse = " << m_windowUnderMouse << " tracked window =" << m_trackedWindow;
+ qCDebug(lcQpaEvents) << "WM_MOUSELEAVE for " << window << " previous window under mouse = " << m_windowUnderMouse << " tracked window =" << m_trackedWindow;
// When moving out of a window, WM_MOUSEMOVE within the moved-to window is received first,
// so if m_trackedWindow is not the window here, it means the cursor has left the
// application.
if (window == m_trackedWindow) {
QWindow *leaveTarget = m_windowUnderMouse ? m_windowUnderMouse : m_trackedWindow;
- if (QWindowsContext::verboseEvents)
- qDebug() << "Generating leave event for " << leaveTarget;
+ qCDebug(lcQpaEvents) << "Generating leave event for " << leaveTarget;
QWindowSystemInterface::handleLeaveEvent(leaveTarget);
m_trackedWindow = 0;
m_windowUnderMouse = 0;
@@ -231,8 +235,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
QWindowsWindow::baseWindowOf(window)->applyCursor();
platformWindow->setMouseGrabEnabled(true);
platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
- if (QWindowsContext::verboseEvents)
- qDebug() << "Automatic mouse capture for missing buttondown event" << window;
+ qCDebug(lcQpaEvents) << "Automatic mouse capture for missing buttondown event" << window;
}
m_previousCaptureWindow = window;
return true;
@@ -257,8 +260,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|| msg.message == WM_RBUTTONDBLCLK || msg.message == WM_XBUTTONDBLCLK)) {
platformWindow->setMouseGrabEnabled(true);
platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
- if (QWindowsContext::verboseEvents)
- qDebug() << "Automatic mouse capture " << window;
+ qCDebug(lcQpaEvents) << "Automatic mouse capture " << window;
// Implement "Click to focus" for native child windows (unless it is a native widget window).
if (!window->isTopLevel() && !window->inherits("QWidgetWindow") && QGuiApplication::focusWindow() != window)
window->requestActivate();
@@ -268,8 +270,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|| msg.message == WM_RBUTTONUP || msg.message == WM_XBUTTONUP)
&& !buttons) {
platformWindow->setMouseGrabEnabled(false);
- if (QWindowsContext::verboseEvents)
- qDebug() << "Releasing automatic mouse capture " << window;
+ qCDebug(lcQpaEvents) << "Releasing automatic mouse capture " << window;
}
const bool hasCapture = platformWindow->hasMouseCapture();
@@ -301,8 +302,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
&& (!hasCapture || window == m_windowUnderMouse))
|| (hasCapture && m_previousCaptureWindow != window && m_windowUnderMouse
&& m_windowUnderMouse != window)) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "Synthetic leave for " << m_windowUnderMouse;
+ qCDebug(lcQpaEvents) << "Synthetic leave for " << m_windowUnderMouse;
QWindowSystemInterface::handleLeaveEvent(m_windowUnderMouse);
if (currentNotCapturing) {
// Clear tracking if capturing and current window is not the capturing window
@@ -321,8 +321,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
&& (!hasCapture || currentWindowUnderMouse == window))
|| (m_previousCaptureWindow && window != m_previousCaptureWindow && currentWindowUnderMouse
&& currentWindowUnderMouse != m_previousCaptureWindow)) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "Entering " << currentWindowUnderMouse;
+ qCDebug(lcQpaEvents) << "Entering " << currentWindowUnderMouse;
QWindowsWindow::baseWindowOf(currentWindowUnderMouse)->applyCursor();
QWindowSystemInterface::handleEnterEvent(currentWindowUnderMouse,
currentWindowUnderMouse->mapFromGlobal(globalPosition),
@@ -335,7 +334,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
- QWindowsKeyMapper::queryKeyboardModifiers());
+ QWindowsKeyMapper::queryKeyboardModifiers(),
+ source);
m_previousCaptureWindow = hasCapture ? window : 0;
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
new file mode 100644
index 0000000000..9bf4b3240c
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsnativeinterface.h"
+#include "qwindowswindow.h"
+#include "qwindowscontext.h"
+
+#if defined(QT_OPENGL_ES_2)
+# include "qwindowseglcontext.h"
+# include <QtGui/QOpenGLContext>
+#elif !defined(QT_NO_OPENGL)
+# include "qwindowsglcontext.h"
+#endif
+
+#include <QtGui/QWindow>
+
+QT_BEGIN_NAMESPACE
+
+void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ if (!window || !window->handle()) {
+ qWarning("%s: '%s' requested for null window or window without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+ QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle());
+ if (resource == "handle")
+ return bw->handle();
+ if (window->surfaceType() == QWindow::RasterSurface) {
+ if (resource == "getDC")
+ return bw->getDC();
+ if (resource == "releaseDC") {
+ bw->releaseDC();
+ return 0;
+ }
+ }
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+}
+
+static const char customMarginPropertyC[] = "WindowsCustomMargins";
+
+QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
+{
+ QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window);
+ if (name == QLatin1String(customMarginPropertyC))
+ return qVariantFromValue(platformWindow->customMargins());
+ return QVariant();
+}
+
+QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const
+{
+ const QVariant result = windowProperty(window, name);
+ return result.isValid() ? result : defaultValue;
+}
+
+void QWindowsNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
+{
+ QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window);
+ if (name == QLatin1String(customMarginPropertyC))
+ platformWindow->setCustomMargins(qvariant_cast<QMargins>(value));
+}
+
+QVariantMap QWindowsNativeInterface::windowProperties(QPlatformWindow *window) const
+{
+ QVariantMap result;
+ const QString customMarginProperty = QLatin1String(customMarginPropertyC);
+ result.insert(customMarginProperty, windowProperty(window, customMarginProperty));
+ return result;
+}
+
+#ifndef QT_NO_OPENGL
+void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+{
+ if (!context || !context->handle()) {
+ qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+#ifdef QT_OPENGL_ES_2
+ QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
+ if (resource == QByteArrayLiteral("eglDisplay"))
+ return windowsEglContext->eglDisplay();
+ if (resource == QByteArrayLiteral("eglContext"))
+ return windowsEglContext->eglContext();
+ if (resource == QByteArrayLiteral("eglConfig"))
+ return windowsEglContext->eglConfig();
+#else // QT_OPENGL_ES_2
+ QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
+ if (resource == QByteArrayLiteral("renderingContext"))
+ return windowsContext->renderingContext();
+#endif // !QT_OPENGL_ES_2
+
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+}
+#endif // !QT_NO_OPENGL
+
+/*!
+ \brief Creates a non-visible window handle for filtering messages.
+*/
+
+void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTemplate,
+ const QString &windowName,
+ void *eventProc) const
+{
+ QWindowsContext *ctx = QWindowsContext::instance();
+ const HWND hwnd = ctx->createDummyWindow(classNameTemplate,
+ (wchar_t*)windowName.utf16(),
+ (WNDPROC)eventProc);
+ return hwnd;
+}
+
+/*!
+ \brief Registers a unique window class with a callback function based on \a classNameIn.
+*/
+
+QString QWindowsNativeInterface::registerWindowClass(const QString &classNameIn, void *eventProc) const
+{
+ return QWindowsContext::instance()->registerWindowClass(classNameIn, (WNDPROC)eventProc);
+}
+
+bool QWindowsNativeInterface::asyncExpose() const
+{
+ return QWindowsContext::instance()->asyncExpose();
+}
+
+void QWindowsNativeInterface::setAsyncExpose(bool value)
+{
+ QWindowsContext::instance()->setAsyncExpose(value);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h
new file mode 100644
index 0000000000..20100d0f49
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSNATIVEINTERFACE_H
+#define QWINDOWSNATIVEINTERFACE_H
+
+#include "qtwindows_additional.h"
+#include <QtGui/qpa/qplatformnativeinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsNativeInterface
+ \brief Provides access to native handles.
+
+ Currently implemented keys
+ \list
+ \li handle (HWND)
+ \li getDC (DC)
+ \li releaseDC Releases the previously acquired DC and returns 0.
+ \endlist
+
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsNativeInterface : public QPlatformNativeInterface
+{
+ Q_OBJECT
+ Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
+public:
+#ifndef QT_NO_OPENGL
+ virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+#endif
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
+
+ Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
+ const QString &windowName,
+ void *eventProc) const;
+
+ Q_INVOKABLE QString registerWindowClass(const QString &classNameIn, void *eventProc) const;
+
+ Q_INVOKABLE void beep() { MessageBeep(MB_OK); } // For QApplication
+
+ bool asyncExpose() const;
+ void setAsyncExpose(bool value);
+
+ QVariantMap windowProperties(QPlatformWindow *window) const;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
+ void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
index 0cea691f39..4f641d781d 100644
--- a/src/plugins/platforms/windows/qwindowsole.cpp
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -80,14 +80,11 @@ QWindowsOleDataObject::QWindowsOleDataObject(QMimeData *mimeData) :
CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)),
performedEffect(DROPEFFECT_NONE)
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s '%s'", __FUNCTION__, qPrintable(mimeData->formats().join(QStringLiteral(", "))));
+ qCDebug(lcQpaMime) << __FUNCTION__ << mimeData->formats();
}
QWindowsOleDataObject::~QWindowsOleDataObject()
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s", __FUNCTION__);
}
void QWindowsOleDataObject::releaseQt()
@@ -143,10 +140,10 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
{
HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
- if (QWindowsContext::verboseOLE) {
+ if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled()) {
wchar_t buf[256] = {0};
GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
- qDebug("%s CF = %d : %s", __FUNCTION__, pformatetc->cfFormat, qPrintable(QString::fromWCharArray(buf)));
+ qCDebug(lcQpaMime) <<__FUNCTION__ << "CF = " << pformatetc->cfFormat << QString::fromWCharArray(buf);
}
if (data) {
@@ -156,11 +153,10 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
hr = ResultFromScode(S_OK);
}
- if (QWindowsContext::verboseOLE) {
+ if (QWindowsContext::verbose > 1) {
wchar_t buf[256] = {0};
GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
- qDebug("%s CF = %d : %s returns 0x%x", __FUNCTION__, pformatetc->cfFormat,
- qPrintable(QString::fromWCharArray(buf)), int(hr));
+ qCDebug(lcQpaMime) <<__FUNCTION__ << "CF = " << pformatetc->cfFormat << " returns 0x" << int(hr) << dec;
}
return hr;
@@ -177,16 +173,16 @@ QWindowsOleDataObject::QueryGetData(LPFORMATETC pformatetc)
{
HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
if (data) {
const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
hr = mc.converterFromMime(*pformatetc, data) ?
ResultFromScode(S_OK) : ResultFromScode(S_FALSE);
}
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s returns 0x%x", __FUNCTION__, int(hr));
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << hex << int(hr);
return hr;
}
@@ -200,8 +196,8 @@ QWindowsOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetc
STDMETHODIMP
QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease)
{
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
HRESULT hr = ResultFromScode(E_NOTIMPL);
@@ -213,8 +209,8 @@ QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL
ReleaseStgMedium(pMedium);
hr = ResultFromScode(S_OK);
}
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s returns 0x%x", __FUNCTION__, int(hr));
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << hex << int(hr);
return hr;
}
@@ -222,8 +218,8 @@ QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL
STDMETHODIMP
QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
{
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
if (!data)
return ResultFromScode(DATA_E_FORMATETC);
@@ -285,8 +281,8 @@ QWindowsOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*)
QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) :
m_dwRefs(1), m_nIndex(0), m_isNull(false)
{
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
m_lpfmtetcs.reserve(fmtetcs.count());
for (int idx = 0; idx < fmtetcs.count(); ++idx) {
LPFORMATETC destetc = new FORMATETC();
@@ -303,8 +299,8 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs)
QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs) :
m_dwRefs(1), m_nIndex(0), m_isNull(false)
{
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
m_lpfmtetcs.reserve(lpfmtetcs.count());
for (int idx = 0; idx < lpfmtetcs.count(); ++idx) {
LPFORMATETC srcetc = lpfmtetcs.at(idx);
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 1fc1be53c7..a6e2aabaf0 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -201,8 +201,6 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat =
QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
- if (QWindowsContext::verboseIntegration)
- qDebug() << __FUNCTION__ << window << x << y << width << height;
RECT r;
HWND hwnd = window ? (HWND)window : GetDesktopWindow();
GetClientRect(hwnd, &r);
@@ -243,8 +241,7 @@ QWindow *QWindowsScreen::findTopLevelAt(const QPoint &point, unsigned flags)
if (QPlatformWindow *bw = QWindowsContext::instance()->
findPlatformWindowAt(GetDesktopWindow(), point, flags))
result = QWindowsWindow::topLevelOf(bw->window());
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << point << flags << result;
+ qCDebug(lcQpaWindows) <<__FUNCTION__ << point << flags << result;
return result;
}
@@ -254,8 +251,7 @@ QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags)
if (QPlatformWindow *bw = QWindowsContext::instance()->
findPlatformWindowAt(GetDesktopWindow(), screenPoint, flags))
result = bw->window();
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << screenPoint << " returns " << result;
+ qCDebug(lcQpaWindows) <<__FUNCTION__ << screenPoint << " returns " << result;
return result;
}
@@ -366,9 +362,8 @@ bool QWindowsScreenManager::handleDisplayChange(WPARAM wParam, LPARAM lParam)
m_lastDepth = newDepth;
m_lastHorizontalResolution = newHorizontalResolution;
m_lastVerticalResolution = newVerticalResolution;
- if (QWindowsContext::verboseWindows)
- qDebug("%s: Depth=%d, resolution=%hux%hu",
- __FUNCTION__, newDepth, newHorizontalResolution, newVerticalResolution);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << "Depth=" << newDepth
+ << ", resolution " << newHorizontalResolution << 'x' << newVerticalResolution;
handleScreenChanges();
}
return false;
@@ -410,8 +405,7 @@ bool QWindowsScreenManager::handleScreenChanges()
QWindowsScreen *newScreen = new QWindowsScreen(newData);
m_screens.push_back(newScreen);
QWindowsIntegration::instance()->emitScreenAdded(newScreen);
- if (QWindowsContext::verboseWindows)
- qDebug() << "New Monitor: " << newData;
+ qCDebug(lcQpaWindows) << "New Monitor: " << newData;
} // exists
} // for new screens.
// Remove deleted ones but keep main monitors if we get only the
@@ -419,8 +413,7 @@ bool QWindowsScreenManager::handleScreenChanges()
if (!lockScreen) {
for (int i = m_screens.size() - 1; i >= 0; --i) {
if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) {
- if (QWindowsContext::verboseWindows)
- qDebug() << "Removing Monitor: " << m_screens.at(i) ->data();
+ qCDebug(lcQpaWindows) << "Removing Monitor: " << m_screens.at(i) ->data();
delete m_screens.takeAt(i);
} // not found
} // for existing screens
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 1a5c1a2e0c..8b863ec43d 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -182,8 +182,7 @@ QWindowsTabletSupport *QWindowsTabletSupport::create()
L"TabletDummyWindow",
qWindowsTabletSupportWndProc);
if (!window) {
- if (QWindowsContext::verboseTablet)
- qWarning() << __FUNCTION__ << "Unable to create window for tablet.";
+ qCWarning(lcQpaTablet) << __FUNCTION__ << "Unable to create window for tablet.";
return 0;
}
LOGCONTEXT lcMine;
@@ -199,8 +198,7 @@ QWindowsTabletSupport *QWindowsTabletSupport::create()
lcMine.lcOutExtY = -lcMine.lcInExtY;
const HCTX context = QWindowsTabletSupport::m_winTab32DLL.wTOpen(window, &lcMine, true);
if (!context) {
- if (QWindowsContext::verboseTablet)
- qWarning() << __FUNCTION__ << "Unable to open tablet.";
+ qCDebug(lcQpaTablet) << __FUNCTION__ << "Unable to open tablet.";
DestroyWindow(window);
return 0;
@@ -217,9 +215,9 @@ QWindowsTabletSupport *QWindowsTabletSupport::create()
} // cannot restore old size
} // cannot set
} // mismatch
- if (QWindowsContext::verboseTablet)
- qDebug("Opened tablet context %p on window %p, changed packet queue size %d -> %d",
- context, window, currentQueueSize, TabletPacketQSize);
+ qCDebug(lcQpaTablet) << "Opened tablet context " << context << " on window "
+ << window << "changed packet queue size " << currentQueueSize
+ << "->" << TabletPacketQSize;
return new QWindowsTabletSupport(window, context);
}
@@ -261,8 +259,7 @@ void QWindowsTabletSupport::notifyActivate()
// Cooperate with other tablet applications, but when we get focus, I want to use the tablet.
const bool result = QWindowsTabletSupport::m_winTab32DLL.wTEnable(m_context, true)
&& QWindowsTabletSupport::m_winTab32DLL.wTOverlap(m_context, true);
- if (QWindowsContext::verboseTablet)
- qDebug() << __FUNCTION__ << result;
+ qCDebug(lcQpaTablet) << __FUNCTION__ << result;
}
static inline int indexOfDevice(const QVector<QWindowsTabletDeviceData> &devices, qint64 uniqueId)
@@ -369,10 +366,8 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
m_devices.push_back(tabletInit(uniqueId, cursorType));
}
m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
- if (QWindowsContext::verboseTablet)
- qDebug() << __FUNCTION__ << (enteredProximity ? "enter" : "leave")
- << " proximity for device #"
- << m_currentDevice << m_devices.at(m_currentDevice);
+ qCDebug(lcQpaTablet) << __FUNCTION__ << (enteredProximity ? "enter" : "leave")
+ << " proximity for device #" << m_currentDevice << m_devices.at(m_currentDevice);
if (enteredProximity) {
QWindowSystemInterface::handleTabletEnterProximityEvent(m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
@@ -410,9 +405,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
enum { absoluteRange = 20 };
const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
- if (QWindowsContext::verboseTablet)
- qDebug() << __FUNCTION__ << "processing " << packetCount
- << "target:" << QGuiApplicationPrivate::tabletPressTarget;
+ qCDebug(lcQpaTablet) << __FUNCTION__ << "processing " << packetCount
+ << "target:" << QGuiApplicationPrivate::tabletPressTarget;
const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
@@ -474,8 +468,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
rotation = packet.pkOrientation.orTwist;
}
- if (QWindowsContext::verboseTablet > 1) {
- qDebug()
+ if (QWindowsContext::verbose > 1) {
+ qCDebug(lcQpaTablet)
<< "Packet #" << i << '/' << packetCount << "button:" << packet.pkButtons
<< globalPosF << z << "to:" << target << localPos << "(packet" << packet.pkX
<< packet.pkY << ") dev:" << currentDevice << "pointer:"
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 00a5da8f44..988e34ea6d 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -406,10 +406,6 @@ void QWindowsTheme::refreshPalettes()
m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette]));
m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette]));
m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette]);
- if (QWindowsContext::verboseTheming)
- qDebug() << __FUNCTION__ << '\n'
- << " system=" << paletteToString(*m_palettes[SystemPalette])
- << " tooltip=" << paletteToString(*m_palettes[ToolTipPalette]);
}
void QWindowsTheme::clearFonts()
@@ -449,11 +445,6 @@ void QWindowsTheme::refreshFonts()
m_fonts[DockWidgetTitleFont] = new QFont(titleFont);
m_fonts[ItemViewFont] = new QFont(iconTitleFont);
m_fonts[FixedFont] = new QFont(fixedFont);
-
- if (QWindowsContext::verboseTheming)
- qDebug() << __FUNCTION__ << '\n'
- << " menuFont=" << menuFont
- << " messageBox=" << MessageBoxFont;
#endif // !Q_OS_WINCE
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 51902385e1..5b6fced031 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -358,7 +358,7 @@ static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bo
struct WindowCreationData
{
- typedef QWindowsWindow::WindowData WindowData;
+ typedef QWindowsWindowData WindowData;
enum Flags { ForceChild = 0x1, ForceTopLevel = 0x2 };
WindowCreationData() : parentHandle(0), type(Qt::Widget), style(0), exStyle(0),
@@ -534,7 +534,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
}
}
-QWindowsWindow::WindowData
+QWindowsWindowData
WindowCreationData::create(const QWindow *w, const WindowData &data, QString title) const
{
typedef QSharedPointer<QWindowCreationContext> QWindowCreationContextPtr;
@@ -546,8 +546,7 @@ QWindowsWindow::WindowData
result.hwnd = GetDesktopWindow();
result.geometry = frameGeometry(result.hwnd, true);
result.embedded = false;
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << "Created desktop window " << w << result.hwnd;
+ qCDebug(lcQpaWindows) << "Created desktop window " << w << result.hwnd;
return result;
}
if ((flags & Qt::WindowType_Mask) == Qt::ForeignWindow) {
@@ -558,8 +557,7 @@ QWindowsWindow::WindowData
result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd));
result.frame = QWindowsGeometryHint::frame(style, exStyle);
result.embedded = false;
- if (QWindowsContext::verboseWindows)
- qDebug() << "Foreign window: " << w << result.hwnd << result.geometry << result.frame;
+ qCDebug(lcQpaWindows) << "Foreign window: " << w << result.hwnd << result.geometry << result.frame;
return result;
}
@@ -580,24 +578,21 @@ QWindowsWindow::WindowData
const QWindowCreationContextPtr context(new QWindowCreationContext(w, rect, data.customMargins, style, exStyle));
QWindowsContext::instance()->setWindowCreationContext(context);
- if (QWindowsContext::verboseWindows)
- qDebug().nospace()
- << "CreateWindowEx: " << w << *this
- << " class=" <<windowClassName << " title=" << title
- << "\nrequested: " << rect << ": "
- << context->frameWidth << 'x' << context->frameHeight
- << '+' << context->frameX << '+' << context->frameY
- << " custom margins: " << context->customMargins;
+ qCDebug(lcQpaWindows).nospace()
+ << "CreateWindowEx: " << w << *this << " class=" <<windowClassName << " title=" << title
+ << "\nrequested: " << rect << ": "
+ << context->frameWidth << 'x' << context->frameHeight
+ << '+' << context->frameX << '+' << context->frameY
+ << " custom margins: " << context->customMargins;
result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
style,
context->frameX, context->frameY,
context->frameWidth, context->frameHeight,
parentHandle, NULL, appinst, NULL);
- if (QWindowsContext::verboseWindows)
- qDebug().nospace()
- << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
- << context->obtainedGeometry << context->margins;
+ qCDebug(lcQpaWindows).nospace()
+ << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
+ << context->obtainedGeometry << context->margins;
if (!result.hwnd) {
qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
@@ -627,8 +622,7 @@ void WindowCreationData::applyWindowFlags(HWND hwnd) const
const LONG_PTR newExStyle = exStyle;
if (newExStyle != oldExStyle)
SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << __FUNCTION__ << hwnd << *this
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << hwnd << *this
<< "\n Style from " << debugWinStyle(oldStyle) << "\n to "
<< debugWinStyle(newStyle) << "\n ExStyle from "
<< debugWinExStyle(oldExStyle) << " to "
@@ -705,10 +699,8 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle)
qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__);
const QMargins result(qAbs(rect.left), qAbs(rect.top),
qAbs(rect.right), qAbs(rect.bottom));
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << __FUNCTION__ << " style= 0x"
- << QString::number(style, 16)
- << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result;
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style= 0x"
+ << QString::number(style, 16) << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result;
return result;
}
@@ -727,10 +719,9 @@ bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, co
ncp->rgrc[0].right -= customMargins.right();
ncp->rgrc[0].bottom -= customMargins.bottom();
result = 0;
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << oldClientArea << '+' << customMargins << "-->"
- << ncp->rgrc[0] << ' ' << ncp->rgrc[1] << ' ' << ncp->rgrc[2]
- << ' ' << ncp->lppos->cx << ',' << ncp->lppos->cy;
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << oldClientArea << '+' << customMargins << "-->"
+ << ncp->rgrc[0] << ' ' << ncp->rgrc[1] << ' ' << ncp->rgrc[2]
+ << ' ' << ncp->lppos->cx << ',' << ncp->lppos->cy;
return true;
#else
Q_UNUSED(customMargins)
@@ -749,11 +740,10 @@ void QWindowsGeometryHint::applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const
void QWindowsGeometryHint::applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXINFO *mmi) const
{
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << '>' << __FUNCTION__ << '<' << " min="
- << minimumSize.width() << ',' << minimumSize.height()
- << " max=" << maximumSize.width() << ',' << maximumSize.height()
- << " in " << *mmi;
+ qCDebug(lcQpaWindows).nospace() << '>' << __FUNCTION__ << '<' << " min="
+ << minimumSize.width() << ',' << minimumSize.height()
+ << " max=" << maximumSize.width() << ',' << maximumSize.height()
+ << " in " << *mmi;
const QMargins margins = QWindowsGeometryHint::frame(style, exStyle);
const int frameWidth = margins.left() + margins.right() + customMargins.left() + customMargins.right();
@@ -770,10 +760,9 @@ void QWindowsGeometryHint::applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXI
// windows with title bar have an implicit size limit of 112 pixels
if (maximumHeight < QWINDOWSIZE_MAX)
mmi->ptMaxTrackSize.y = qMax(maximumHeight + frameHeight, 112);
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << '<' << __FUNCTION__
- << " frame=" << margins << ' ' << frameWidth << ',' << frameHeight
- << " out " << *mmi;
+ qCDebug(lcQpaWindows).nospace() << '<' << __FUNCTION__
+ << " frame=" << margins << ' ' << frameWidth << ',' << frameHeight
+ << " out " << *mmi;
}
#endif // !Q_OS_WINCE
@@ -831,15 +820,13 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
}
}
- if (QWindowsContext::verboseWindows)
- qDebug().nospace()
- << __FUNCTION__ << ' ' << w << geometry
- << " pos incl. frame" << QWindowsGeometryHint::positionIncludesFrame(w)
- << " frame: " << frameWidth << 'x' << frameHeight << '+'
- << frameX << '+' << frameY
- << " min" << geometryHint.minimumSize
- << " max" << geometryHint.maximumSize
- << " custom margins " << customMargins;
+ qCDebug(lcQpaWindows).nospace()
+ << __FUNCTION__ << ' ' << w << geometry
+ << " pos incl. frame" << QWindowsGeometryHint::positionIncludesFrame(w)
+ << " frame: " << frameWidth << 'x' << frameHeight << '+'
+ << frameX << '+' << frameY
+ << " min" << geometryHint.minimumSize << " max" << geometryHint.maximumSize
+ << " custom margins " << customMargins;
}
/*!
@@ -864,7 +851,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
\ingroup qt-lighthouse-win
*/
-QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
+QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) :
QPlatformWindow(aWindow),
m_data(data),
m_flags(WithinCreate),
@@ -949,8 +936,7 @@ void QWindowsWindow::fireExpose(const QRegion &region, bool force)
void QWindowsWindow::destroyWindow()
{
- if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << m_data.hwnd;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd;
if (m_data.hwnd) { // Stop event dispatching before Window is destroyed.
setFlag(WithinDestroy);
QWindowsContext *context = QWindowsContext::instance();
@@ -961,9 +947,7 @@ void QWindowsWindow::destroyWindow()
unregisterDropSite();
#ifdef QT_OPENGL_ES_2
if (m_eglSurface) {
- if (QWindowsContext::verboseGL)
- qDebug("%s: Freeing EGL surface %p, this = %p",
- __FUNCTION__, m_eglSurface, this);
+ qCDebug(lcQpaGl) << __FUNCTION__ << "Freeing EGL surface " << m_eglSurface << window();
eglDestroySurface(m_staticEglContext->display(), m_eglSurface);
m_eglSurface = 0;
}
@@ -1033,14 +1017,14 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w)
return w;
}
-QWindowsWindow::WindowData
- QWindowsWindow::WindowData::create(const QWindow *w,
- const WindowData &parameters,
+QWindowsWindowData
+ QWindowsWindowData::create(const QWindow *w,
+ const QWindowsWindowData &parameters,
const QString &title)
{
WindowCreationData creationData;
creationData.fromWindow(w, parameters.flags);
- WindowData result = creationData.create(w, parameters, title);
+ QWindowsWindowData result = creationData.create(w, parameters, title);
// Force WM_NCCALCSIZE (with wParam=1) via SWP_FRAMECHANGED for custom margin.
creationData.initialize(result.hwnd, !parameters.customMargins.isNull(), 1);
return result;
@@ -1048,8 +1032,7 @@ QWindowsWindow::WindowData
void QWindowsWindow::setVisible(bool visible)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << m_data.hwnd << visible;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd << visible;
if (m_data.hwnd) {
if (visible) {
show_sys();
@@ -1193,14 +1176,13 @@ void QWindowsWindow::hide_sys() const
if (flags & Qt::Popup)
ShowWindow(m_data.hwnd, SW_HIDE);
else
- SetWindowPos(m_data.hwnd,0, 0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
+ SetWindowPos(m_data.hwnd,0, 0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
}
}
void QWindowsWindow::setParent(const QPlatformWindow *newParent)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << window() << newParent;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window() << newParent;
if (m_data.hwnd)
setParent_sys(newParent);
@@ -1350,8 +1332,7 @@ void QWindowsWindow::handleGeometryChange()
if (testFlag(SynchronousGeometryChangeEvent))
QWindowSystemInterface::flushWindowSystemEvents();
- if (QWindowsContext::verboseEvents || QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << m_data.geometry;
+ qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry;
}
void QWindowsWindow::setGeometry_sys(const QRect &rect) const
@@ -1359,17 +1340,15 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
const QMargins margins = frameMargins();
const QRect frameGeometry = rect + margins;
- if (QWindowsContext::verboseWindows)
- qDebug() << '>' << __FUNCTION__ << this << window()
+ qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
<< " \n from " << geometry_sys() << " frame: "
<< margins << " to " <<rect
<< " new frame: " << frameGeometry;
const bool rc = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(),
frameGeometry.width(), frameGeometry.height(), true);
- if (QWindowsContext::verboseWindows)
- qDebug() << '<' << __FUNCTION__ << this << window()
- << " \n resulting " << rc << geometry_sys();
+ qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window()
+ << " \n resulting " << rc << geometry_sys();
}
QRect QWindowsWindow::frameGeometry_sys() const
@@ -1442,8 +1421,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
void QWindowsWindow::setWindowTitle(const QString &title)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() <<title;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() <<title;
if (m_data.hwnd) {
const QString fullTitle = formatWindowTitle(title, QStringLiteral(" - "));
SetWindowText(m_data.hwnd, (const wchar_t*)fullTitle.utf16());
@@ -1452,10 +1430,9 @@ void QWindowsWindow::setWindowTitle(const QString &title)
void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << '>' << __FUNCTION__ << this << window() << "\n from: "
- << QWindowsWindow::debugWindowFlags(m_data.flags)
- << "\n to: " << QWindowsWindow::debugWindowFlags(flags);
+ qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: "
+ << QWindowsWindow::debugWindowFlags(m_data.flags)
+ << "\n to: " << QWindowsWindow::debugWindowFlags(flags);
const QRect oldGeometry = geometry();
if (m_data.flags != flags) {
m_data.flags = flags;
@@ -1470,13 +1447,12 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
if (oldGeometry != newGeometry)
handleGeometryChange();
- if (QWindowsContext::verboseWindows)
- qDebug() << '<' << __FUNCTION__ << "\n returns: "
- << QWindowsWindow::debugWindowFlags(m_data.flags)
- << " geometry " << oldGeometry << "->" << newGeometry;
+ qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << "\n returns: "
+ << QWindowsWindow::debugWindowFlags(m_data.flags)
+ << " geometry " << oldGeometry << "->" << newGeometry;
}
-QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
+QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
unsigned flags) const
{
WindowCreationData creationData;
@@ -1484,7 +1460,7 @@ QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt
creationData.applyWindowFlags(m_data.hwnd);
creationData.initialize(m_data.hwnd, true, m_opacity);
- WindowData result = m_data;
+ QWindowsWindowData result = m_data;
result.flags = creationData.flags;
result.embedded = creationData.embedded;
setFlag(FrameDirty);
@@ -1493,8 +1469,7 @@ QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt
void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window()
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window()
<< "\n from " << debugWindowStates(m_windowState)
<< " to " << debugWindowStates(state);
setFlag(FrameDirty);
@@ -1577,10 +1552,8 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
const Qt::WindowState oldState = m_windowState;
if (oldState == newState)
return;
- if (QWindowsContext::verboseWindows)
- qDebug() << '>' << __FUNCTION__ << this << window()
- << " from " << debugWindowStates(oldState)
- << " to " << debugWindowStates(newState);
+ qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
+ << " from " << debugWindowStates(oldState) << " to " << debugWindowStates(newState);
const bool visible = isVisible();
@@ -1677,15 +1650,12 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
ShowWindow(m_data.hwnd, (newState == Qt::WindowMinimized) ? SW_MINIMIZE :
(newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
}
- if (QWindowsContext::verboseWindows)
- qDebug() << '<' << __FUNCTION__ << this << window()
- << debugWindowStates(newState);
+ qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() << debugWindowStates(newState);
}
void QWindowsWindow::setStyle(unsigned s) const
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << debugWinStyle(s);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << debugWinStyle(s);
setFlag(WithinSetStyle);
setFlag(FrameDirty);
SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
@@ -1694,8 +1664,7 @@ void QWindowsWindow::setStyle(unsigned s) const
void QWindowsWindow::setExStyle(unsigned s) const
{
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << __FUNCTION__ << ' ' << this << ' ' << window()
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << this << ' ' << window()
<< " 0x" << QByteArray::number(s, 16);
setFlag(FrameDirty);
SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
@@ -1703,15 +1672,13 @@ void QWindowsWindow::setExStyle(unsigned s) const
void QWindowsWindow::raise()
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
SetWindowPos(m_data.hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
void QWindowsWindow::lower()
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
if (m_data.hwnd)
SetWindowPos(m_data.hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
@@ -1734,8 +1701,7 @@ void QWindowsWindow::windowEvent(QEvent *event)
void QWindowsWindow::propagateSizeHints()
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
}
QMargins QWindowsWindow::frameMargins() const
@@ -1753,8 +1719,7 @@ QMargins QWindowsWindow::frameMargins() const
void QWindowsWindow::setOpacity(qreal level)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << level;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << level;
if (m_opacity != level) {
m_opacity = level;
if (m_data.hwnd)
@@ -1816,8 +1781,7 @@ void QWindowsWindow::setMask(const QRegion &region)
void QWindowsWindow::requestActivateWindow()
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
// 'Active' state handling is based in focus since it needs to work for
// child windows as well.
if (m_data.hwnd) {
@@ -1832,8 +1796,7 @@ bool QWindowsWindow::setKeyboardGrabEnabled(bool grab)
qWarning("%s: No handle", __FUNCTION__);
return false;
}
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << grab;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << grab;
QWindowsContext *context = QWindowsContext::instance();
if (grab) {
@@ -1847,8 +1810,7 @@ bool QWindowsWindow::setKeyboardGrabEnabled(bool grab)
bool QWindowsWindow::setMouseGrabEnabled(bool grab)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << window() << grab;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window() << grab;
if (!m_data.hwnd) {
qWarning("%s: No handle", __FUNCTION__);
return false;
@@ -1930,8 +1892,7 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
}
}
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << window() << *mmi;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window() << *mmi;
}
bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *result) const
@@ -2031,9 +1992,8 @@ void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
#ifndef QT_NO_CURSOR
if (c.handle() != m_cursor.handle()) {
const bool apply = applyNewCursor(window());
- if (QWindowsContext::verboseWindows)
- qDebug() << window() << __FUNCTION__ << "Shape=" << c.cursor().shape()
- << " doApply=" << apply;
+ qCDebug(lcQpaWindows) <<window() << __FUNCTION__
+ << "Shape=" << c.cursor().shape() << " doApply=" << apply;
m_cursor = c;
if (apply)
applyCursor();
@@ -2131,9 +2091,7 @@ EGLSurface QWindowsWindow::ensureEglSurfaceHandle(const QWindowsWindow::QWindows
Q_FUNC_INFO, window()->metaObject()->className(),
qPrintable(window()->objectName()), eglGetError());
- if (QWindowsContext::verboseGL)
- qDebug("%s: Created EGL surface %p, this = %p",
- __FUNCTION__, m_eglSurface, this);
+ qCDebug(lcQpaGl) << __FUNCTION__<<"Created EGL surface "<< m_eglSurface <<window();
}
return m_eglSurface;
}
@@ -2244,9 +2202,8 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
newFrame.moveTo(topLeft);
setFlag(FrameDirty);
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins
- << currentFrameGeometry << "->" << newFrame;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins
+ << currentFrameGeometry << "->" << newFrame;
SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED);
}
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 61dc3e2dc2..3a9516e0e5 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -111,6 +111,22 @@ struct QWindowCreationContext
int frameHeight;
};
+struct QWindowsWindowData
+{
+ QWindowsWindowData() : hwnd(0), embedded(false) {}
+
+ Qt::WindowFlags flags;
+ QRect geometry;
+ QMargins frame; // Do not use directly for windows, see FrameDirty.
+ QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
+ HWND hwnd;
+ bool embedded;
+
+ static QWindowsWindowData create(const QWindow *w,
+ const QWindowsWindowData &parameters,
+ const QString &title);
+};
+
class QWindowsWindow : public QPlatformWindow
{
public:
@@ -140,23 +156,7 @@ public:
WithinMaximize = 0x40000
};
- struct WindowData
- {
- WindowData() : hwnd(0) {}
-
- Qt::WindowFlags flags;
- QRect geometry;
- QMargins frame; // Do not use directly for windows, see FrameDirty.
- QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
- HWND hwnd;
- bool embedded;
-
- static WindowData create(const QWindow *w,
- const WindowData &parameters,
- const QString &title);
- };
-
- QWindowsWindow(QWindow *window, const WindowData &data);
+ QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
~QWindowsWindow();
virtual QSurfaceFormat format() const { return m_format; }
@@ -274,7 +274,7 @@ private:
inline void setGeometry_sys(const QRect &rect) const;
inline QRect frameGeometry_sys() const;
inline QRect geometry_sys() const;
- inline WindowData setWindowFlags_sys(Qt::WindowFlags wt, unsigned flags = 0) const;
+ inline QWindowsWindowData setWindowFlags_sys(Qt::WindowFlags wt, unsigned flags = 0) const;
inline bool isFullScreen_sys() const;
inline void setWindowState_sys(Qt::WindowState newState);
inline void setParent_sys(const QPlatformWindow *parent) const;
@@ -287,7 +287,7 @@ private:
inline void destroyIcon();
void fireExpose(const QRegion &region, bool force=false);
- mutable WindowData m_data;
+ mutable QWindowsWindowData m_data;
mutable unsigned m_flags;
HDC m_hdc;
Qt::WindowState m_windowState;
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
new file mode 100644
index 0000000000..c10d00c2ad
--- /dev/null
+++ b/src/plugins/platforms/windows/windows.pri
@@ -0,0 +1,180 @@
+# Note: OpenGL32 must precede Gdi32 as it overwrites some functions.
+LIBS *= -lole32
+!wince*:LIBS *= -luser32 -lwinspool -limm32 -lwinmm -loleaut32
+
+contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):LIBS *= -lopengl32
+
+mingw: LIBS *= -luuid
+# For the dialog helpers:
+!wince*:LIBS *= -lshlwapi -lshell32
+!wince*:LIBS *= -ladvapi32
+wince*:DEFINES *= QT_LIBINFIX=L"\"\\\"$${QT_LIBINFIX}\\\"\""
+
+DEFINES *= QT_NO_CAST_FROM_ASCII
+
+contains(QT_CONFIG, directwrite) {
+ LIBS *= -ldwrite
+ SOURCES += $$PWD/qwindowsfontenginedirectwrite.cpp
+ HEADERS += $$PWD/qwindowsfontenginedirectwrite.h
+} else {
+ DEFINES *= QT_NO_DIRECTWRITE
+}
+
+SOURCES += \
+ $$PWD/qwindowswindow.cpp \
+ $$PWD/qwindowsintegration.cpp \
+ $$PWD/qwindowscontext.cpp \
+ $$PWD/qwindowsscreen.cpp \
+ $$PWD/qwindowskeymapper.cpp \
+ $$PWD/qwindowsfontengine.cpp \
+ $$PWD/qwindowsfontdatabase.cpp \
+ $$PWD/qwindowsmousehandler.cpp \
+ $$PWD/qwindowsguieventdispatcher.cpp \
+ $$PWD/qwindowsole.cpp \
+ $$PWD/qwindowsmime.cpp \
+ $$PWD/qwindowsinternalmimedata.cpp \
+ $$PWD/qwindowscursor.cpp \
+ $$PWD/qwindowsinputcontext.cpp \
+ $$PWD/qwindowstheme.cpp \
+ $$PWD/qwindowsdialoghelpers.cpp \
+ $$PWD/qwindowsservices.cpp \
+ $$PWD/qwindowsnativeimage.cpp \
+ $$PWD/qwindowsnativeinterface.cpp
+
+HEADERS += \
+ $$PWD/qwindowswindow.h \
+ $$PWD/qwindowsintegration.h \
+ $$PWD/qwindowscontext.h \
+ $$PWD/qwindowsscreen.h \
+ $$PWD/qwindowskeymapper.h \
+ $$PWD/qwindowsfontengine.h \
+ $$PWD/qwindowsfontdatabase.h \
+ $$PWD/qwindowsmousehandler.h \
+ $$PWD/qwindowsguieventdispatcher.h \
+ $$PWD/qtwindowsglobal.h \
+ $$PWD/qtwindows_additional.h \
+ $$PWD/qwindowsole.h \
+ $$PWD/qwindowsmime.h \
+ $$PWD/qwindowsinternalmimedata.h \
+ $$PWD/qwindowscursor.h \
+ $$PWD/array.h \
+ $$PWD/qwindowsinputcontext.h \
+ $$PWD/qwindowstheme.h \
+ $$PWD/qwindowsdialoghelpers.h \
+ $$PWD/qwindowsservices.h \
+ $$PWD/qplatformfunctions_wince.h \
+ $$PWD/qwindowsnativeimage.h \
+ $$PWD/qwindowsnativeinterface.h
+
+INCLUDEPATH += $$PWD
+
+contains(QT_CONFIG, opengles2) {
+ SOURCES += $$PWD/qwindowseglcontext.cpp
+ HEADERS += $$PWD/qwindowseglcontext.h
+} else {
+ contains(QT_CONFIG, opengl) {
+ SOURCES += $$PWD/qwindowsglcontext.cpp
+ HEADERS += $$PWD/qwindowsglcontext.h
+ }
+}
+
+!contains( DEFINES, QT_NO_CLIPBOARD ) {
+ SOURCES += $$PWD/qwindowsclipboard.cpp
+ HEADERS += $$PWD/qwindowsclipboard.h
+}
+
+# drag and drop on windows only works if a clipboard is available
+!contains( DEFINES, QT_NO_DRAGANDDROP ) {
+ !win32:SOURCES += $$PWD/qwindowsdrag.cpp
+ !win32:HEADERS += $$PWD/qwindowsdrag.h
+ win32:!contains( DEFINES, QT_NO_CLIPBOARD ) {
+ HEADERS += $$PWD/qwindowsdrag.h
+ SOURCES += $$PWD/qwindowsdrag.cpp
+ }
+}
+
+!wince*:!contains( DEFINES, QT_NO_TABLETEVENT ) {
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/wintab
+ HEADERS += $$PWD/qwindowstabletsupport.h
+ SOURCES += $$PWD/qwindowstabletsupport.cpp
+}
+
+!wince*:!contains( DEFINES, QT_NO_SESSIONMANAGER ) {
+ SOURCES += $$PWD/qwindowssessionmanager.cpp
+ HEADERS += $$PWD/qwindowssessionmanager.h
+}
+
+contains(QT_CONFIG, freetype) {
+ DEFINES *= QT_NO_FONTCONFIG
+ QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
+
+ HEADERS += \
+ $$PWD/qwindowsfontdatabase_ft.h
+ SOURCES += \
+ $$PWD/qwindowsfontdatabase_ft.cpp \
+ $$QT_FREETYPE_DIR/src/base/ftbase.c \
+ $$QT_FREETYPE_DIR/src/base/ftbbox.c \
+ $$QT_FREETYPE_DIR/src/base/ftdebug.c \
+ $$QT_FREETYPE_DIR/src/base/ftglyph.c \
+ $$QT_FREETYPE_DIR/src/base/ftinit.c \
+ $$QT_FREETYPE_DIR/src/base/ftmm.c \
+ $$QT_FREETYPE_DIR/src/base/fttype1.c \
+ $$QT_FREETYPE_DIR/src/base/ftsynth.c \
+ $$QT_FREETYPE_DIR/src/base/ftbitmap.c \
+ $$QT_FREETYPE_DIR/src/bdf/bdf.c \
+ $$QT_FREETYPE_DIR/src/cache/ftcache.c \
+ $$QT_FREETYPE_DIR/src/cff/cff.c \
+ $$QT_FREETYPE_DIR/src/cid/type1cid.c \
+ $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \
+ $$QT_FREETYPE_DIR/src/pcf/pcf.c \
+ $$QT_FREETYPE_DIR/src/pfr/pfr.c \
+ $$QT_FREETYPE_DIR/src/psaux/psaux.c \
+ $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \
+ $$QT_FREETYPE_DIR/src/psnames/psmodule.c \
+ $$QT_FREETYPE_DIR/src/raster/raster.c \
+ $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \
+ $$QT_FREETYPE_DIR/src/smooth/smooth.c \
+ $$QT_FREETYPE_DIR/src/truetype/truetype.c \
+ $$QT_FREETYPE_DIR/src/type1/type1.c \
+ $$QT_FREETYPE_DIR/src/type42/type42.c \
+ $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \
+ $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\
+ $$QT_FREETYPE_DIR/src/autofit/afangles.c\
+ $$QT_FREETYPE_DIR/src/autofit/afglobal.c\
+ $$QT_FREETYPE_DIR/src/autofit/aflatin.c\
+ $$QT_FREETYPE_DIR/src/autofit/afmodule.c\
+ $$QT_FREETYPE_DIR/src/autofit/afdummy.c\
+ $$QT_FREETYPE_DIR/src/autofit/afhints.c\
+ $$QT_FREETYPE_DIR/src/autofit/afloader.c\
+ $$QT_FREETYPE_DIR/src/autofit/autofit.c
+
+ SOURCES += $$QT_FREETYPE_DIR/src/base/ftsystem.c
+
+
+ INCLUDEPATH += \
+ $$QT_FREETYPE_DIR/src \
+ $$QT_FREETYPE_DIR/include
+
+ TR_EXCLUDE += $$QT_FREETYPE_DIR/*
+
+ DEFINES += FT2_BUILD_LIBRARY
+ contains(QT_CONFIG, system-zlib) {
+ DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
+ }
+} else:contains(QT_CONFIG, system-freetype) {
+ include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri)
+ HEADERS += \
+ $$PWD/qwindowsfontdatabase_ft.h
+ SOURCES += \
+ $$PWD/qwindowsfontdatabase_ft.cpp
+}
+
+contains(QT_CONFIG, accessibility):include($$PWD/accessible/accessible.pri)
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
index 0249e156d9..188bd7917c 100644
--- a/src/plugins/platforms/windows/windows.pro
+++ b/src/plugins/platforms/windows/windows.pro
@@ -8,184 +8,19 @@ QT *= core-private
QT *= gui-private
QT *= platformsupport-private
-# Note: OpenGL32 must precede Gdi32 as it overwrites some functions.
-LIBS *= -lole32
-!wince*:LIBS *= -lgdi32 -luser32 -lwinspool -limm32 -lwinmm -loleaut32
+!wince:LIBS *= -lgdi32
-contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):LIBS *= -lopengl32
+include(windows.pri)
-win32-g++*: LIBS *= -luuid
-# For the dialog helpers:
-!wince*:LIBS *= -lshlwapi -lshell32
-!wince*:LIBS *= -ladvapi32
-wince*:DEFINES *= QT_LIBINFIX=L"\"\\\"$${QT_LIBINFIX}\\\"\""
-
-DEFINES *= QT_NO_CAST_FROM_ASCII
-
-contains(QT_CONFIG, directwrite) {
- LIBS *= -ldwrite
- SOURCES += qwindowsfontenginedirectwrite.cpp
- HEADERS += qwindowsfontenginedirectwrite.h
-} else {
- DEFINES *= QT_NO_DIRECTWRITE
-}
-
-SOURCES += \
+SOURCES += \
main.cpp \
- qwindowsnativeimage.cpp \
- qwindowswindow.cpp \
- qwindowsintegration.cpp \
- qwindowscontext.cpp \
qwindowsbackingstore.cpp \
- qwindowsscreen.cpp \
- qwindowskeymapper.cpp \
- qwindowsfontengine.cpp \
- qwindowsfontdatabase.cpp \
- qwindowsmousehandler.cpp \
- qwindowsguieventdispatcher.cpp \
- qwindowsole.cpp \
- qwindowsmime.cpp \
- qwindowsinternalmimedata.cpp \
- qwindowscursor.cpp \
- qwindowsinputcontext.cpp \
- qwindowstheme.cpp \
- qwindowsdialoghelpers.cpp \
- qwindowsservices.cpp
+ qwindowsgdiintegration.cpp \
+ qwindowsgdinativeinterface.cpp
-HEADERS += \
- qwindowsnativeimage.h \
- qwindowswindow.h \
- qwindowsintegration.h \
- qwindowscontext.h \
+HEADERS += \
qwindowsbackingstore.h \
- qwindowsscreen.h \
- qwindowskeymapper.h \
- qwindowsfontengine.h \
- qwindowsfontdatabase.h \
- qwindowsmousehandler.h \
- qwindowsguieventdispatcher.h \
- qtwindowsglobal.h \
- qtwindows_additional.h \
- qwindowsole.h \
- qwindowsmime.h \
- qwindowsinternalmimedata.h \
- qwindowscursor.h \
- array.h \
- qwindowsinputcontext.h \
- qwindowstheme.h \
- qwindowsdialoghelpers.h \
- qwindowsservices.h \
- qplatformfunctions_wince.h
-
-contains(QT_CONFIG, opengles2) {
- SOURCES += qwindowseglcontext.cpp
- HEADERS += qwindowseglcontext.h
-} else {
- contains(QT_CONFIG, opengl) {
- SOURCES += qwindowsglcontext.cpp
- HEADERS += qwindowsglcontext.h
- }
-}
-
-!contains( DEFINES, QT_NO_CLIPBOARD ) {
- SOURCES += qwindowsclipboard.cpp
- HEADERS += qwindowsclipboard.h
-}
-
-# drag and drop on windows only works if a clipboard is available
-!contains( DEFINES, QT_NO_DRAGANDDROP ) {
- !win32:SOURCES += qwindowsdrag.cpp
- !win32:HEADERS += qwindowsdrag.h
- win32:!contains( DEFINES, QT_NO_CLIPBOARD ) {
- HEADERS += qwindowsdrag.h
- SOURCES += qwindowsdrag.cpp
- }
-}
-
-!wince*:!contains( DEFINES, QT_NO_TABLETEVENT ) {
- INCLUDEPATH += ../../../3rdparty/wintab
- HEADERS += qwindowstabletsupport.h
- SOURCES += qwindowstabletsupport.cpp
-}
-
-!wince*:!contains( DEFINES, QT_NO_SESSIONMANAGER ) {
- SOURCES += qwindowssessionmanager.cpp
- HEADERS += qwindowssessionmanager.h
-}
-
-contains(QT_CONFIG, freetype) {
- DEFINES *= QT_NO_FONTCONFIG
- QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
-
- HEADERS += \
- qwindowsfontdatabase_ft.h
- SOURCES += \
- qwindowsfontdatabase_ft.cpp \
- $$QT_FREETYPE_DIR/src/base/ftbase.c \
- $$QT_FREETYPE_DIR/src/base/ftbbox.c \
- $$QT_FREETYPE_DIR/src/base/ftdebug.c \
- $$QT_FREETYPE_DIR/src/base/ftglyph.c \
- $$QT_FREETYPE_DIR/src/base/ftinit.c \
- $$QT_FREETYPE_DIR/src/base/ftmm.c \
- $$QT_FREETYPE_DIR/src/base/fttype1.c \
- $$QT_FREETYPE_DIR/src/base/ftsynth.c \
- $$QT_FREETYPE_DIR/src/base/ftbitmap.c \
- $$QT_FREETYPE_DIR/src/bdf/bdf.c \
- $$QT_FREETYPE_DIR/src/cache/ftcache.c \
- $$QT_FREETYPE_DIR/src/cff/cff.c \
- $$QT_FREETYPE_DIR/src/cid/type1cid.c \
- $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \
- $$QT_FREETYPE_DIR/src/pcf/pcf.c \
- $$QT_FREETYPE_DIR/src/pfr/pfr.c \
- $$QT_FREETYPE_DIR/src/psaux/psaux.c \
- $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \
- $$QT_FREETYPE_DIR/src/psnames/psmodule.c \
- $$QT_FREETYPE_DIR/src/raster/raster.c \
- $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \
- $$QT_FREETYPE_DIR/src/smooth/smooth.c \
- $$QT_FREETYPE_DIR/src/truetype/truetype.c \
- $$QT_FREETYPE_DIR/src/type1/type1.c \
- $$QT_FREETYPE_DIR/src/type42/type42.c \
- $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \
- $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\
- $$QT_FREETYPE_DIR/src/autofit/afangles.c\
- $$QT_FREETYPE_DIR/src/autofit/afglobal.c\
- $$QT_FREETYPE_DIR/src/autofit/aflatin.c\
- $$QT_FREETYPE_DIR/src/autofit/afmodule.c\
- $$QT_FREETYPE_DIR/src/autofit/afdummy.c\
- $$QT_FREETYPE_DIR/src/autofit/afhints.c\
- $$QT_FREETYPE_DIR/src/autofit/afloader.c\
- $$QT_FREETYPE_DIR/src/autofit/autofit.c
-
- SOURCES += $$QT_FREETYPE_DIR/src/base/ftsystem.c
-
-
- INCLUDEPATH += \
- $$QT_FREETYPE_DIR/src \
- $$QT_FREETYPE_DIR/include
-
- TR_EXCLUDE += $$QT_FREETYPE_DIR/*
-
- DEFINES += FT2_BUILD_LIBRARY
- contains(QT_CONFIG, system-zlib) {
- DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
- }
-} else:contains(QT_CONFIG, system-freetype) {
- include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri)
- HEADERS += \
- qwindowsfontdatabase_ft.h
- SOURCES += \
- qwindowsfontdatabase_ft.cpp
-}
+ qwindowsgdiintegration.h \
+ qwindowsgdinativeinterface.h
OTHER_FILES += windows.json
-
-contains(QT_CONFIG, accessibility):include(accessible/accessible.pri)
diff --git a/src/plugins/platforms/winrt/blit.hlsl b/src/plugins/platforms/winrt/blit.hlsl
new file mode 100644
index 0000000000..170e7f40ca
--- /dev/null
+++ b/src/plugins/platforms/winrt/blit.hlsl
@@ -0,0 +1,14 @@
+uniform SamplerState Sampler : register(s0);
+uniform Texture2D Texture : register(t0);
+
+void blitvs(in float4 pos0 : TEXCOORD0, in float2 tex0 : TEXCOORD1,
+ out float4 gl_Position : SV_POSITION, out float2 coord : TEXCOORD0)
+{
+ coord = tex0;
+ gl_Position = pos0 * float4(1.0, -1.0, 1.0, 1.0);
+}
+
+float4 blitps(in float4 gl_Position : SV_POSITION, in float2 coord : TEXCOORD0) : SV_TARGET0
+{
+ return Texture.Sample(Sampler, coord);
+}
diff --git a/src/plugins/platforms/winrt/main.cpp b/src/plugins/platforms/winrt/main.cpp
new file mode 100644
index 0000000000..89d560dbe3
--- /dev/null
+++ b/src/plugins/platforms/winrt/main.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtintegration.h"
+
+#include <qpa/qplatformintegrationplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "winrt.json")
+
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QWinRTIntegrationPlugin::keys() const
+{
+ return QStringList(QStringLiteral("WinRT"));
+}
+
+QPlatformIntegration *QWinRTIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (!system.compare(QLatin1String("winrt"), Qt::CaseInsensitive))
+ return QWinRTIntegration::create();
+
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
new file mode 100644
index 0000000000..b219548788
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtbackingstore.h"
+
+#include "qwinrtscreen.h"
+#include "qwinrtwindow.h"
+#include "qwinrteglcontext.h"
+#include <QtGui/QOpenGLContext>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <dxgi.h>
+
+// Generated shader headers
+#include "blitps.h"
+#include "blitvs.h"
+
+namespace { // Utility namespace for writing out an ANGLE-compatible binary blob
+
+// Must match packaged ANGLE
+enum : quint32 {
+ AngleMajorVersion = 1,
+ AngleMinorVersion = 2,
+ AngleBuildRevision = 2446,
+ AngleVersion = ((AngleMajorVersion << 24) | (AngleMinorVersion << 16) | AngleBuildRevision),
+ AngleOptimizationLevel = (1 << 14)
+};
+
+struct ShaderString
+{
+ ShaderString(const char *data = 0) : data(data) { }
+ const char *data;
+};
+
+// ANGLE stream compatibility - when size_t is 32-bit, QDataStream::writeBytes() also works
+QDataStream &operator<<(QDataStream &stream, const ShaderString &shaderString)
+{
+ if (!shaderString.data)
+ return stream << size_t(0);
+
+ size_t len = strlen(shaderString.data);
+ stream << len;
+ stream.writeRawData(shaderString.data, int(len));
+ return stream;
+}
+
+struct Attribute
+{
+ Attribute(GLenum type = 0, const char *name = 0, quint32 index = 0)
+ : type(type), name(name), index(index) { }
+ GLenum type;
+ ShaderString name;
+ quint32 index;
+};
+
+struct Sampler
+{
+ enum TextureType { Texture2D, TextureCube };
+ Sampler(bool active = false, GLint unit = 0, TextureType type = Texture2D)
+ : active(active), unit(unit), type(type) { }
+ bool active;
+ GLint unit;
+ TextureType type;
+};
+
+struct Uniform
+{
+ Uniform() { }
+ Uniform(GLenum type, quint32 precision, const char *name, quint32 arraySize,
+ quint32 psRegisterIndex, quint32 vsRegisterIndex, quint32 registerCount)
+ : type(type), precision(precision), name(name), arraySize(arraySize)
+ , psRegisterIndex(psRegisterIndex), vsRegisterIndex(vsRegisterIndex), registerCount(registerCount) { }
+ GLenum type;
+ quint32 precision;
+ ShaderString name;
+ quint32 arraySize;
+ quint32 psRegisterIndex;
+ quint32 vsRegisterIndex;
+ quint32 registerCount;
+};
+
+struct UniformIndex
+{
+ UniformIndex(const char *name = 0, quint32 element = 0, quint32 index = 0)
+ : name(name), element(element), index(index) { }
+ ShaderString name;
+ quint32 element;
+ quint32 index;
+};
+
+static const QByteArray createAngleBinary(
+ const QVector<Attribute> &attributes,
+ const QVector<Sampler> &textureSamplers,
+ const QVector<Sampler> &vertexSamplers,
+ const QVector<Uniform> &uniforms,
+ const QVector<UniformIndex> &uniformIndex,
+ const QByteArray &pixelShader,
+ const QByteArray &vertexShader,
+ const QByteArray &geometryShader = QByteArray(),
+ bool usesPointSize = false)
+{
+ QByteArray binary;
+
+ QDataStream stream(&binary, QIODevice::WriteOnly);
+ stream.setByteOrder(QDataStream::LittleEndian);
+
+ stream << quint32(GL_PROGRAM_BINARY_ANGLE)
+ << quint32(AngleVersion)
+ << quint32(AngleOptimizationLevel);
+
+ // Vertex attributes
+ for (int i = 0; i < 16; ++i) {
+ if (i < attributes.size())
+ stream << quint32(attributes[i].type) << attributes[i].name << attributes[i].index;
+ else
+ stream << quint32(GL_NONE) << ShaderString() << qint32(-1);
+ }
+
+ // Texture units
+ for (int i = 0; i < 16; ++i) {
+ if (i < textureSamplers.size())
+ stream << textureSamplers[i].active << textureSamplers[i].unit << qint32(textureSamplers[i].type);
+ else
+ stream << false << qint32(0) << qint32(Sampler::Texture2D);
+ }
+
+ // Vertex texture units
+ for (int i = 0; i < 16; ++i) {
+ if (i < vertexSamplers.size())
+ stream << vertexSamplers[i].active << vertexSamplers[i].unit << qint32(vertexSamplers[i].type);
+ else
+ stream << false << qint32(0) << qint32(Sampler::Texture2D);
+ }
+
+ stream << vertexSamplers.size()
+ << textureSamplers.size()
+ << usesPointSize;
+
+ stream << size_t(uniforms.size());
+ foreach (const Uniform &uniform, uniforms) {
+ stream << uniform.type << uniform.precision << uniform.name << uniform.arraySize
+ << uniform.psRegisterIndex << uniform.vsRegisterIndex << uniform.registerCount;
+ }
+
+ stream << size_t(uniformIndex.size());
+ foreach (const UniformIndex &index, uniformIndex)
+ stream << index.name << index.element << index.index;
+
+ stream << quint32(pixelShader.size())
+ << quint32(vertexShader.size())
+ << quint32(geometryShader.size());
+
+ // ANGLE requires that we query the adapter for its LUID. Later on, it may be useful
+ // for checking feature level support, picking the best adapter on the system, etc.
+ IDXGIFactory1 *dxgiFactory;
+ if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)))) {
+ qCritical("QWinRTBackingStore: failed to create DXGI factory.");
+ return QByteArray();
+ }
+ IDXGIAdapter *dxgiAdapter;
+ if (FAILED(dxgiFactory->EnumAdapters(0, &dxgiAdapter))) {
+ qCritical("QWinRTBackingStore:: failed to enumerate adapter.");
+ dxgiFactory->Release();
+ return QByteArray();
+ }
+ DXGI_ADAPTER_DESC desc;
+ dxgiAdapter->GetDesc(&desc);
+ dxgiAdapter->Release();
+ QByteArray guid(sizeof(GUID), '\0');
+ memcpy(guid.data(), &desc.AdapterLuid, sizeof(LUID));
+ stream.writeRawData(guid.constData(), guid.size());
+ stream.writeRawData(pixelShader.constData(), pixelShader.size());
+ stream.writeRawData(vertexShader.constData(), vertexShader.size());
+ if (!geometryShader.isEmpty())
+ stream.writeRawData(geometryShader.constData(), geometryShader.size());
+
+ return binary;
+}
+
+} // namespace
+
+QT_BEGIN_NAMESPACE
+
+static const GLfloat normCoords[] = { -1, 1, 1, 1, 1, -1, -1, -1 };
+static const GLfloat quadCoords[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
+
+QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+ , m_context(new QOpenGLContext)
+ , m_shaderProgram(0)
+ , m_fbo(0)
+ , m_texture(0)
+ , m_screen(static_cast<QWinRTScreen*>(window->screen()->handle()))
+{
+ window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap
+
+ m_context->setFormat(window->requestedFormat());
+ m_context->setScreen(window->screen());
+ m_context->create();
+
+ m_context->makeCurrent(window);
+ glGenFramebuffers(1, &m_fbo);
+ glGenRenderbuffers(1, &m_rbo);
+ glGenTextures(1, &m_texture);
+ m_shaderProgram = glCreateProgram();
+
+#if 0 // Standard GLES passthrough shader program
+ static const char *vertexShaderSource =
+ "attribute vec4 pos0;\n"
+ "attribute vec2 tex0;\n"
+ "varying vec2 coord;\n"
+ "void main() {\n"
+ " coord = tex0;\n"
+ " gl_Position = pos0;\n"
+ "}\n";
+ static const char *fragmentShaderSource =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 coord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texture, coord);\n"
+ "}\n";
+ GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
+ glCompileShader(vertexShader);
+ GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
+ glCompileShader(fragmentShader);
+ glAttachShader(m_shaderProgram, vertexShader);
+ glAttachShader(m_shaderProgram, fragmentShader);
+ glLinkProgram(m_shaderProgram);
+#else // Precompiled passthrough shader
+ QVector<Attribute> attributes = QVector<Attribute>() << Attribute(GL_FLOAT_VEC4, "pos0", 0)
+ << Attribute(GL_FLOAT_VEC2, "tex0", 1);
+ QVector<Sampler> textureSamplers = QVector<Sampler>() << Sampler(true, 0, Sampler::Texture2D);
+ QVector<Sampler> vertexSamplers;
+ QVector<Uniform> uniforms = QVector<Uniform>() << Uniform(GL_SAMPLER_2D, 0, "texture", 0, 0, -1, 1);
+ QVector<UniformIndex> uniformsIndex = QVector<UniformIndex>() << UniformIndex("texture", 0, 0);
+ QByteArray pixelShader(reinterpret_cast<const char *>(q_blitps), sizeof(q_blitps));
+ QByteArray vertexShader(reinterpret_cast<const char *>(q_blitvs), sizeof(q_blitvs));
+ QByteArray binary = createAngleBinary(attributes, textureSamplers, vertexSamplers,
+ uniforms, uniformsIndex, pixelShader, vertexShader);
+ glProgramBinaryOES(m_shaderProgram, GL_PROGRAM_BINARY_ANGLE, binary.constData(), binary.size());
+#endif
+ m_context->doneCurrent();
+ resize(window->size(), QRegion());
+}
+
+QWinRTBackingStore::~QWinRTBackingStore()
+{
+ glDeleteBuffers(1, &m_fbo);
+ glDeleteRenderbuffers(1, &m_rbo);
+ glDeleteTextures(1, &m_texture);
+ glDeleteProgram(m_shaderProgram);
+}
+
+QPaintDevice *QWinRTBackingStore::paintDevice()
+{
+ return m_paintDevice.data();
+}
+
+void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(offset)
+
+ const QImage *image = static_cast<QImage *>(m_paintDevice.data());
+
+ m_context->makeCurrent(window);
+
+ // Blitting the entire image width trades zero image copy/relayout for a larger texture upload.
+ // Since we're blitting the whole width anyway, the boundingRect() is used in the assumption that
+ // we don't repeat upload. This is of course dependent on the distance between update regions.
+ // Ideally, we would use the GL_EXT_unpack_subimage extension, which should be possible to implement
+ // since D3D11_MAPPED_SUBRESOURCE supports RowPitch (see below).
+ // Note that single-line blits in a loop are *very* slow, so reducing calls to glTexSubImage2D
+ // is probably a good idea anyway.
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ QRect bounds = region.boundingRect();
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), m_size.width(), bounds.height(),
+ GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()));
+ // TODO: Implement GL_EXT_unpack_subimage in ANGLE for more minimal uploads
+ //glPixelStorei(GL_UNPACK_ROW_LENGTH, image->bytesPerLine());
+ //glTexSubImage2D(GL_TEXTURE_2D, 0, bounds.x(), bounds.y(), bounds.width(), bounds.height(),
+ // GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()) + bounds.x() * 4);
+
+ // Bind render buffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
+
+ // Bind position
+ glUseProgram(m_shaderProgram);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, normCoords);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, quadCoords);
+
+ // Render
+ glViewport(0, 0, m_size.width(), m_size.height());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // Unbind
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ glUseProgram(0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ // fast blit - TODO: perform the blit inside swap buffers instead
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0);
+ glBlitFramebufferANGLE(0, 0, m_size.width(), m_size.height(), // TODO: blit only the changed rectangle
+ 0, 0, m_size.width(), m_size.height(),
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ m_context->swapBuffers(window);
+ m_context->doneCurrent();
+}
+
+void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents)
+ if (m_size == size)
+ return;
+
+ m_size = size;
+ m_paintDevice.reset(new QImage(m_size, QImage::Format_ARGB32_Premultiplied));
+
+ m_context->makeCurrent(window());
+ // Input texture
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_size.width(), m_size.height(),
+ 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
+ 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);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ // Render buffer
+ glBindRenderbuffer(GL_RENDERBUFFER, m_rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, m_size.width(), m_size.height());
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ m_context->doneCurrent();
+}
+
+void QWinRTBackingStore::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region)
+}
+
+void QWinRTBackingStore::endPaint()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h
index 9af856e8e7..8be549b441 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.h
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h
@@ -39,43 +39,39 @@
**
****************************************************************************/
-#ifndef QEGLFSBACKINGSTORE_H
-#define QEGLFSBACKINGSTORE_H
+#ifndef QWINRTBACKINGSTORE_H
+#define QWINRTBACKINGSTORE_H
#include <qpa/qplatformbackingstore.h>
-#include <QtGui/QOpenGLFunctions>
-
-#include <QImage>
-#include <QRegion>
+#include <QtCore/QScopedPointer>
QT_BEGIN_NAMESPACE
-class QOpenGLPaintDevice;
-class QEglFSWindow;
+class QWinRTScreen;
+class QOpenGLContext;
-class QEglFSBackingStore : public QPlatformBackingStore, public QOpenGLFunctions
+class QWinRTBackingStore : public QPlatformBackingStore
{
public:
- QEglFSBackingStore(QWindow *window);
-
+ explicit QWinRTBackingStore(QWindow *window);
+ ~QWinRTBackingStore();
QPaintDevice *paintDevice();
-
void beginPaint(const QRegion &);
-
+ void endPaint();
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
void resize(const QSize &size, const QRegion &staticContents);
- uint texture() const { return m_texture; }
-
private:
- void updateTexture();
-
- QEglFSWindow *m_window;
- QImage m_image;
- uint m_texture;
- QRegion m_dirty;
+ QSize m_size;
+ QScopedPointer<QPaintDevice> m_paintDevice;
+ QScopedPointer<QOpenGLContext> m_context;
+ quint32 m_shaderProgram;
+ quint32 m_fbo;
+ quint32 m_rbo;
+ quint32 m_texture;
+ QWinRTScreen *m_screen;
};
QT_END_NAMESPACE
-#endif // QEGLFSBACKINGSTORE_H
+#endif // QWINRTBACKINGSTORE_H
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
new file mode 100644
index 0000000000..8241560cef
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcursor.h"
+
+#include <wrl.h>
+#include <windows.ui.core.h>
+#include <windows.foundation.h>
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::Foundation;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTCursor::QWinRTCursor(ICoreWindow *window) : m_window(window), m_cursorFactory(nullptr)
+{
+#ifndef Q_OS_WINPHONE
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(), &m_cursorFactory);
+#endif
+}
+
+QWinRTCursor::~QWinRTCursor()
+{
+ if (m_cursorFactory)
+ m_cursorFactory->Release();
+}
+
+#ifndef QT_NO_CURSOR
+void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *)
+{
+#ifndef Q_OS_WINPHONE
+ if (!m_cursorFactory)
+ return;
+
+ CoreCursorType type;
+ switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) {
+ case Qt::BlankCursor:
+ m_window->put_PointerCursor(nullptr);
+ return;
+ default:
+ case Qt::OpenHandCursor:
+ case Qt::ClosedHandCursor:
+ case Qt::DragCopyCursor:
+ case Qt::DragMoveCursor:
+ case Qt::DragLinkCursor:
+ // (unavailable)
+ case Qt::ArrowCursor:
+ type = CoreCursorType_Arrow;
+ break;
+ case Qt::UpArrowCursor:
+ type = CoreCursorType_UpArrow;
+ break;
+ case Qt::CrossCursor:
+ type = CoreCursorType_Cross;
+ break;
+ case Qt::WaitCursor:
+ case Qt::BusyCursor:
+ type = CoreCursorType_Wait;
+ break;
+ case Qt::IBeamCursor:
+ type = CoreCursorType_IBeam;
+ break;
+ case Qt::SizeVerCursor:
+ case Qt::SplitVCursor:
+ type = CoreCursorType_SizeNorthSouth;
+ break;
+ case Qt::SizeHorCursor:
+ case Qt::SplitHCursor:
+ type = CoreCursorType_SizeWestEast;
+ break;
+ case Qt::SizeBDiagCursor:
+ type = CoreCursorType_SizeNortheastSouthwest;
+ break;
+ case Qt::SizeFDiagCursor:
+ type = CoreCursorType_SizeNorthwestSoutheast;
+ break;
+ case Qt::SizeAllCursor:
+ type = CoreCursorType_SizeAll;
+ break;
+ case Qt::PointingHandCursor:
+ type = CoreCursorType_Hand;
+ break;
+ case Qt::ForbiddenCursor:
+ type = CoreCursorType_UniversalNo;
+ break;
+ case Qt::WhatsThisCursor:
+ type = CoreCursorType_Help;
+ break;
+ case Qt::BitmapCursor:
+ case Qt::CustomCursor:
+ // TODO: figure out if arbitrary bitmaps can be made into resource IDs
+ // For now, we don't get enough info from QCursor to set a custom cursor
+ type = CoreCursorType_Custom;
+ break;
+ }
+
+ ICoreCursor *cursor;
+ if (SUCCEEDED(m_cursorFactory->CreateCursor(type, 0, &cursor)))
+ m_window->put_PointerCursor(cursor);
+#endif // Q_OS_WINPHONE
+}
+#endif // QT_NO_CURSOR
+
+QPoint QWinRTCursor::pos() const
+{
+#ifdef Q_OS_WINPHONE
+ return QPlatformCursor::pos();
+#else
+ Point point;
+ m_window->get_PointerPosition(&point);
+ return QPoint(point.X, point.Y);
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.h b/src/plugins/platforms/winrt/qwinrtcursor.h
new file mode 100644
index 0000000000..f7b301a98b
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcursor.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTCURSOR_H
+#define QWINRTCURSOR_H
+
+#include <qpa/qplatformcursor.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct ICoreWindow;
+ struct ICoreCursorFactory;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTCursor : public QPlatformCursor
+{
+public:
+ explicit QWinRTCursor(ABI::Windows::UI::Core::ICoreWindow *window);
+ ~QWinRTCursor();
+#ifndef QT_NO_CURSOR
+ void changeCursor(QCursor * windowCursor, QWindow *);
+#endif
+ QPoint pos() const;
+
+private:
+ ABI::Windows::UI::Core::ICoreWindow *m_window;
+ ABI::Windows::UI::Core::ICoreCursorFactory *m_cursorFactory;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCURSOR_H
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
new file mode 100644
index 0000000000..014378f896
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrteglcontext.h"
+
+QT_BEGIN_NAMESPACE
+
+QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface)
+ : QEGLPlatformContext(format, share, display, EGL_OPENGL_ES_API), m_eglSurface(surface)
+{
+}
+
+EGLSurface QWinRTEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+{
+ 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;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h
new file mode 100644
index 0000000000..c065847374
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSEGLCONTEXT_H
+#define QWINDOWSEGLCONTEXT_H
+
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTEGLContext : public QEGLPlatformContext
+{
+public:
+ explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface);
+
+protected:
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
+
+private:
+ EGLSurface m_eglSurface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSEGLCONTEXT_H
diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
new file mode 100644
index 0000000000..baa8b5c636
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrteventdispatcher.h"
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformscreen.h>
+#include <qpa/qplatformscreenpageflipper.h>
+#include <QtCore/QThread>
+#include <QtGui/QGuiApplication>
+
+#include <Windows.ui.core.h>
+#include <Windows.ApplicationModel.core.h>
+
+using namespace ABI::Windows::ApplicationModel::Core;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::Foundation;
+using namespace Microsoft::WRL;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTEventDispatcher::QWinRTEventDispatcher(ICoreDispatcher *dispatcher, QObject *parent)
+ : QEventDispatcherWinRT(parent)
+ , m_dispatcher(dispatcher)
+ , m_interrupt(false)
+{
+}
+
+bool QWinRTEventDispatcher::hasPendingEvents()
+{
+ return QEventDispatcherWinRT::hasPendingEvents() || QWindowSystemInterface::windowSystemEventsQueued();
+}
+
+void QWinRTEventDispatcher::interrupt()
+{
+ m_interrupt = true;
+}
+
+bool QWinRTEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ bool canWait = flags & QEventLoop::WaitForMoreEvents;
+ bool didProcess;
+ m_interrupt = false;
+ do {
+ // Send Qt events
+ didProcess = QEventDispatcherWinRT::processEvents(flags);
+
+ // Process system events
+ emit aboutToBlock();
+ if (m_dispatcher)
+ m_dispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
+ emit awake();
+
+ // Dispatch accumulated user events
+ didProcess |= QWindowSystemInterface::sendWindowSystemEvents(flags);
+ canWait = canWait && !didProcess && !m_interrupt;
+
+ // Short sleep if there is nothing to do
+ if (canWait) {
+ emit aboutToBlock();
+ WaitForSingleObjectEx(GetCurrentThread(), 1, true);
+ emit awake();
+ }
+ } while (canWait);
+ return didProcess;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.h b/src/plugins/platforms/winrt/qwinrteventdispatcher.h
index 0d5daafa2c..741007c7fa 100644
--- a/src/plugins/platforms/eglfs/qeglfscompositor.h
+++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.h
@@ -39,47 +39,43 @@
**
****************************************************************************/
-#ifndef QEGLFSCOMPOSITOR_H
-#define QEGLFSCOMPOSITOR_H
+#ifndef QWINRTEVENTDISPATCHER_H
+#define QWINRTEVENTDISPATCHER_H
-#include <QtCore/QTimer>
-#include <QtGui/QOpenGLFunctions>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
-QT_BEGIN_NAMESPACE
+#include <wrl.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct ICoreDispatcher;
+ }
+ }
+ }
+}
-class QEglFSScreen;
-class QEglFSWindow;
-class QOpenGLShaderProgram;
+QT_BEGIN_NAMESPACE
-class QEglFSCompositor : public QObject, public QOpenGLFunctions
+class QWinRTEventDispatcher : public QEventDispatcherWinRT
{
Q_OBJECT
-
public:
- void schedule(QEglFSScreen *screen);
-
- static QEglFSCompositor *instance();
- static void destroy();
+ explicit QWinRTEventDispatcher(ABI::Windows::UI::Core::ICoreDispatcher *dispatcher, QObject *parent = 0);
-private slots:
- void renderAll();
+protected:
+ void interrupt();
+ bool hasPendingEvents();
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
private:
- QEglFSCompositor();
- ~QEglFSCompositor();
-
- void render(QEglFSWindow *window, uint texture, bool raster);
- void ensureProgram();
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> m_dispatcher;
+ bool m_interrupt;
- QEglFSScreen *m_screen;
- QTimer m_updateTimer;
- QOpenGLShaderProgram *m_program;
- int m_vertexCoordEntry;
- int m_textureCoordEntry;
- int m_isRasterEntry;
- bool m_initialized;
+ friend class QWinRTIntegration;
};
QT_END_NAMESPACE
-#endif // QEGLFSCOMPOSITOR_H
+#endif // QWINRTEVENTDISPATCHER_H
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
new file mode 100644
index 0000000000..c7fa339fad
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtfontdatabase.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+
+QT_BEGIN_NAMESPACE
+
+QString QWinRTFontDatabase::fontDir() const
+{
+ QString fontDirectory = QBasicFontDatabase::fontDir();
+ if (!QFile::exists(fontDirectory)) {
+ // Fall back to app directory + fonts, and just app directory after that
+ const QString applicationDirPath = QCoreApplication::applicationDirPath();
+ fontDirectory = applicationDirPath + QLatin1String("/fonts");
+ if (!QFile::exists(fontDirectory)) {
+ qWarning("No fonts directory found in application package.");
+ fontDirectory = applicationDirPath;
+ }
+ }
+ return fontDirectory;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
index e9251592aa..49e32470c2 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -39,22 +39,19 @@
**
****************************************************************************/
-#ifndef QANDROIDOPENGLPLATFORMSCREEN_H
-#define QANDROIDOPENGLPLATFORMSCREEN_H
+#ifndef QWINRTFONTDATABASE_H
+#define QWINRTFONTDATABASE_H
-#include "qeglfsscreen.h"
+#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
QT_BEGIN_NAMESPACE
-class QAndroidOpenGLPlatformScreen : public QEglFSScreen
+class QWinRTFontDatabase : public QBasicFontDatabase
{
public:
- QAndroidOpenGLPlatformScreen(EGLDisplay display);
-
-protected:
- void topWindowChanged(QPlatformWindow *window);
+ QString fontDir() const;
};
QT_END_NAMESPACE
-#endif // QANDROIDOPENGLPLATFORMSCREEN_H
+#endif // QWINRTFONTDATABASE_H
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
new file mode 100644
index 0000000000..bc15f1e448
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtinputcontext.h"
+#include <QtGui/QWindow>
+
+#include <wrl.h>
+#include <roapi.h>
+#include <windows.ui.viewmanagement.h>
+#include <windows.ui.core.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::UI::Core;
+
+#ifdef Q_OS_WINPHONE
+#include <windows.phone.ui.core.h>
+using namespace ABI::Windows::Phone::UI::Core;
+#endif
+
+typedef ITypedEventHandler<InputPane*, InputPaneVisibilityEventArgs*> InputPaneVisibilityHandler;
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWinRTInputContext
+ \brief Manages Input Method visibility
+ \internal
+ \ingroup qt-qpa-winrt
+
+ Listens to the native virtual keyboard for hide/show events and provides
+ hints to the OS for showing/hiding. On WinRT, showInputPanel()/hideInputPanel()
+ have no effect because WinRT dictates that keyboard presence is user-driven:
+ (http://msdn.microsoft.com/en-us/library/windows/apps/hh465404.aspx)
+ Windows Phone, however, supports direct hiding/showing of the keyboard.
+*/
+
+QWinRTInputContext::QWinRTInputContext(ICoreWindow *window)
+ : m_window(window)
+{
+ IInputPaneStatics *statics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
+ &statics))) {
+ qWarning(Q_FUNC_INFO ": failed to retrieve input pane statics.");
+ return;
+ }
+
+ IInputPane *inputPane;
+ statics->GetForCurrentView(&inputPane);
+ statics->Release();
+ if (inputPane) {
+ EventRegistrationToken showToken, hideToken;
+ inputPane->add_Showing(Callback<InputPaneVisibilityHandler>(
+ this, &QWinRTInputContext::onShowing).Get(), &showToken);
+ inputPane->add_Hiding(Callback<InputPaneVisibilityHandler>(
+ this, &QWinRTInputContext::onHiding).Get(), &hideToken);
+
+ Rect rect;
+ inputPane->get_OccludedRect(&rect);
+ m_keyboardRect = QRectF(rect.X, rect.Y, rect.Width, rect.Height);
+ m_isInputPanelVisible = !m_keyboardRect.isEmpty();
+ } else {
+ qWarning(Q_FUNC_INFO ": failed to retrieve InputPane.");
+ }
+}
+
+QRectF QWinRTInputContext::keyboardRect() const
+{
+ return m_keyboardRect;
+}
+
+bool QWinRTInputContext::isInputPanelVisible() const
+{
+ return m_isInputPanelVisible;
+}
+
+HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEventArgs *)
+{
+ m_isInputPanelVisible = true;
+ emitInputPanelVisibleChanged();
+
+ Rect rect;
+ pane->get_OccludedRect(&rect);
+ setKeyboardRect(QRectF(rect.X, rect.Y, rect.Width, rect.Height));
+
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEventArgs *)
+{
+ m_isInputPanelVisible = false;
+ emitInputPanelVisibleChanged();
+
+ Rect rect;
+ pane->get_OccludedRect(&rect);
+ setKeyboardRect(QRectF(rect.X, rect.Y, rect.Width, rect.Height));
+
+ return S_OK;
+}
+
+void QWinRTInputContext::setKeyboardRect(const QRectF rect)
+{
+ if (m_keyboardRect == rect)
+ return;
+
+ m_keyboardRect = rect;
+ emitKeyboardRectChanged();
+}
+
+#ifdef Q_OS_WINPHONE
+
+void QWinRTInputContext::showInputPanel()
+{
+ ICoreWindowKeyboardInput *input;
+ if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) {
+ input->put_IsKeyboardInputEnabled(true);
+ input->Release();
+ }
+}
+
+void QWinRTInputContext::hideInputPanel()
+{
+ ICoreWindowKeyboardInput *input;
+ if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) {
+ input->put_IsKeyboardInputEnabled(false);
+ input->Release();
+ }
+}
+
+#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_window;
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_HostRawElementProvider(IRawElementProviderSimple **retVal)
+{
+ // Return the window's element provider
+ IInspectable *hostProvider;
+ HRESULT hr = m_window->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;
+}
+
+#endif // !Q_OS_WINPHONE
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h
new file mode 100644
index 0000000000..0a35f9b6e1
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTINPUTCONTEXT_H
+#define QWINRTINPUTCONTEXT_H
+
+#include <qpa/qplatforminputcontext.h>
+#include <QtCore/QRectF>
+
+#include <wrl.h>
+#ifndef Q_OS_WINPHONE
+# include <UIAutomationCore.h>
+#endif
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct ICoreWindow;
+ }
+ namespace ViewManagement {
+ struct IInputPane;
+ struct IInputPaneVisibilityEventArgs;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+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(ABI::Windows::UI::Core::ICoreWindow *window);
+
+ QRectF keyboardRect() const;
+
+ bool isInputPanelVisible() const;
+
+#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
+
+private:
+ HRESULT onShowing(ABI::Windows::UI::ViewManagement::IInputPane *,
+ ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *);
+ HRESULT onHiding(ABI::Windows::UI::ViewManagement::IInputPane *,
+ ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *);
+ void setKeyboardRect(const QRectF rect);
+
+ ABI::Windows::UI::Core::ICoreWindow *m_window;
+ QRectF m_keyboardRect;
+ bool m_isInputPanelVisible;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTINPUTCONTEXT_H
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
new file mode 100644
index 0000000000..22c50e67f3
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtintegration.h"
+#include "qwinrtwindow.h"
+#include "qwinrteventdispatcher.h"
+#include "qwinrtbackingstore.h"
+#include "qwinrtscreen.h"
+#include "qwinrtinputcontext.h"
+#include "qwinrtservices.h"
+#include "qwinrteglcontext.h"
+#include "qwinrtfontdatabase.h"
+
+#include <QtGui/QOpenGLContext>
+
+#include <wrl.h>
+#include <windows.ui.core.h>
+#include <windows.ui.viewmanagement.h>
+#include <Windows.ApplicationModel.core.h>
+
+using namespace Microsoft::WRL;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::ApplicationModel::Core;
+
+static IUISettings *getSettings()
+{
+ static IUISettings *settings = 0;
+ if (!settings) {
+ if (FAILED(RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(),
+ reinterpret_cast<IInspectable **>(&settings)))) {
+ qWarning("Could not activate UISettings.");
+ }
+ }
+ return settings;
+}
+
+QT_BEGIN_NAMESPACE
+
+QWinRTIntegration::QWinRTIntegration()
+ : m_success(false)
+ , m_fontDatabase(new QWinRTFontDatabase)
+ , m_services(new QWinRTServices)
+{
+ // Obtain the WinRT Application, view, and window
+ ICoreApplication *application;
+ if (FAILED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&application))))
+ qCritical("Could not attach to the application factory.");
+
+ ICoreApplicationView *view;
+ if (FAILED(application->GetCurrentView(&view))) {
+ qCritical("Could not obtain the application view - have you started outside of WinRT?");
+ return;
+ }
+
+ // Get core window (will act as our screen)
+ ICoreWindow *window;
+ if (FAILED(view->get_CoreWindow(&window))) {
+ qCritical("Could not obtain the application window - have you started outside of WinRT?");
+ return;
+ }
+ window->Activate();
+ m_screen = new QWinRTScreen(window);
+ screenAdded(m_screen);
+
+ m_success = true;
+}
+
+QWinRTIntegration::~QWinRTIntegration()
+{
+ Windows::Foundation::Uninitialize();
+}
+
+QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const
+{
+ ICoreDispatcher *dispatcher;
+ if (FAILED(m_screen->coreWindow()->get_Dispatcher(&dispatcher)))
+ qCritical("Could not capture UI Dispatcher");
+ return new QWinRTEventDispatcher(dispatcher);
+}
+
+bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps:
+ case OpenGL:
+ case ApplicationState:
+ return true;
+ default:
+ return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QVariant QWinRTIntegration::styleHint(StyleHint hint) const
+{
+ switch (hint) {
+ case CursorFlashTime:
+ if (IUISettings *settings = getSettings()) {
+ quint32 blinkRate;
+ settings->get_CaretBlinkRate(&blinkRate);
+ return blinkRate;
+ }
+ break;
+ case MouseDoubleClickInterval:
+ if (IUISettings *settings = getSettings()) {
+ quint32 doubleClickTime;
+ settings->get_DoubleClickTime(&doubleClickTime);
+ return doubleClickTime;
+ }
+ case ShowIsFullScreen:
+ return true;
+ default:
+ break;
+ }
+ return QPlatformIntegration::styleHint(hint);
+}
+
+QPlatformWindow *QWinRTIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QWinRTWindow(window);
+}
+
+QPlatformBackingStore *QWinRTIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QWinRTBackingStore(window);
+}
+
+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());
+}
+
+QPlatformFontDatabase *QWinRTIntegration::fontDatabase() const
+{
+ return m_fontDatabase;
+}
+
+QPlatformInputContext *QWinRTIntegration::inputContext() const
+{
+ return m_screen->inputContext();
+}
+
+QPlatformServices *QWinRTIntegration::services() const
+{
+ return m_services;
+}
+
+Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
+{
+ return m_screen->keyboardModifiers();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h
new file mode 100644
index 0000000000..d9438bcb3a
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTINTEGRATION_H
+#define QWINRTINTEGRATION_H
+
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractEventDispatcher;
+class QWinRTScreen;
+
+class QWinRTIntegration : public QPlatformIntegration
+{
+private:
+ explicit QWinRTIntegration();
+public:
+ ~QWinRTIntegration();
+
+ static QWinRTIntegration *create()
+ {
+ QWinRTIntegration *integration = new QWinRTIntegration;
+ return integration->m_success ? integration : 0;
+ }
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+ QVariant styleHint(StyleHint hint) const;
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QAbstractEventDispatcher *createEventDispatcher() const;
+ QPlatformFontDatabase *fontDatabase() const;
+ QPlatformInputContext *inputContext() const;
+ QPlatformServices *services() const;
+ Qt::KeyboardModifiers queryKeyboardModifiers() const;
+
+private:
+ bool m_success;
+ QWinRTScreen *m_screen;
+ QPlatformFontDatabase *m_fontDatabase;
+ QPlatformServices *m_services;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTINTEGRATION_H
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
new file mode 100644
index 0000000000..5bbf73a945
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -0,0 +1,1003 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtscreen.h"
+
+#include "qwinrtbackingstore.h"
+#include "qwinrtinputcontext.h"
+#include "qwinrtcursor.h"
+#include "qwinrteglcontext.h"
+
+#include <QtGui/QSurfaceFormat>
+#include <QtGui/QGuiApplication>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/qt_windows.h>
+
+#include <wrl.h>
+#include <windows.system.h>
+#include <Windows.Applicationmodel.h>
+#include <Windows.ApplicationModel.core.h>
+#include <windows.devices.input.h>
+#include <windows.ui.h>
+#include <windows.ui.core.h>
+#include <windows.ui.input.h>
+#include <windows.ui.viewmanagement.h>
+#include <windows.graphics.display.h>
+#include <windows.foundation.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+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::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;
+
+typedef IEventHandler<IInspectable*> ResumeHandler;
+typedef IEventHandler<SuspendingEventArgs*> SuspendHandler;
+typedef ITypedEventHandler<CoreWindow*, WindowActivatedEventArgs*> ActivatedHandler;
+typedef ITypedEventHandler<CoreWindow*, CoreWindowEventArgs*> ClosedHandler;
+typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterReceivedHandler;
+typedef ITypedEventHandler<CoreWindow*, InputEnabledEventArgs*> InputEnabledHandler;
+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;
+
+QT_BEGIN_NAMESPACE
+
+static inline Qt::ScreenOrientations qtOrientationsFromNative(DisplayOrientations native)
+{
+ Qt::ScreenOrientations orientations = Qt::PrimaryOrientation;
+ if (native & DisplayOrientations_Portrait)
+ orientations |= Qt::PortraitOrientation;
+ if (native & DisplayOrientations_PortraitFlipped)
+ orientations |= Qt::InvertedPortraitOrientation;
+ if (native & DisplayOrientations_Landscape)
+ orientations |= Qt::LandscapeOrientation;
+ if (native & DisplayOrientations_LandscapeFlipped)
+ orientations |= Qt::InvertedLandscapeOrientation;
+ return orientations;
+}
+
+static inline DisplayOrientations nativeOrientationsFromQt(Qt::ScreenOrientations orientation)
+{
+ DisplayOrientations native = DisplayOrientations_None;
+ if (orientation & Qt::PortraitOrientation)
+ native |= DisplayOrientations_Portrait;
+ if (orientation & Qt::InvertedPortraitOrientation)
+ native |= DisplayOrientations_PortraitFlipped;
+ if (orientation & Qt::LandscapeOrientation)
+ native |= DisplayOrientations_Landscape;
+ if (orientation & Qt::InvertedLandscapeOrientation)
+ native |= DisplayOrientations_LandscapeFlipped;
+ return native;
+}
+
+static inline bool qIsNonPrintable(quint32 keyCode)
+{
+ switch (keyCode) {
+ case '\b':
+ case '\n':
+ case '\t':
+ case '\r':
+ case '\v':
+ case '\f':
+ return true;
+ default:
+ return false;
+ }
+}
+
+// Return Qt meta key from VirtualKey
+static inline Qt::Key qKeyFromVirtual(VirtualKey key)
+{
+ switch (key) {
+
+ default:
+ return Qt::Key_unknown;
+
+ // Non-printable characters
+ case VirtualKey_Enter:
+ return Qt::Key_Enter;
+ case VirtualKey_Tab:
+ return Qt::Key_Tab;
+ case VirtualKey_Back:
+ return Qt::Key_Backspace;
+
+ // Modifiers
+ case VirtualKey_Shift:
+ case VirtualKey_LeftShift:
+ case VirtualKey_RightShift:
+ return Qt::Key_Shift;
+ case VirtualKey_Control:
+ case VirtualKey_LeftControl:
+ case VirtualKey_RightControl:
+ return Qt::Key_Control;
+ case VirtualKey_Menu:
+ case VirtualKey_LeftMenu:
+ case VirtualKey_RightMenu:
+ return Qt::Key_Alt;
+ case VirtualKey_LeftWindows:
+ case VirtualKey_RightWindows:
+ return Qt::Key_Meta;
+
+ // Toggle keys
+ case VirtualKey_CapitalLock:
+ return Qt::Key_CapsLock;
+ case VirtualKey_NumberKeyLock:
+ return Qt::Key_NumLock;
+ case VirtualKey_Scroll:
+ return Qt::Key_ScrollLock;
+
+ // East-Asian language keys
+ case VirtualKey_Kana:
+ //case VirtualKey_Hangul: // Same enum as Kana
+ return Qt::Key_Kana_Shift;
+ case VirtualKey_Junja:
+ return Qt::Key_Hangul_Jeonja;
+ case VirtualKey_Kanji:
+ //case VirtualKey_Hanja: // Same enum as Kanji
+ return Qt::Key_Kanji;
+ case VirtualKey_ModeChange:
+ return Qt::Key_Mode_switch;
+ case VirtualKey_Convert:
+ return Qt::Key_Henkan;
+ case VirtualKey_NonConvert:
+ return Qt::Key_Muhenkan;
+
+ // Misc. keys
+ case VirtualKey_Cancel:
+ return Qt::Key_Cancel;
+ case VirtualKey_Clear:
+ return Qt::Key_Clear;
+ case VirtualKey_Application:
+ return Qt::Key_ApplicationLeft;
+ case VirtualKey_Sleep:
+ return Qt::Key_Sleep;
+ case VirtualKey_Pause:
+ return Qt::Key_Pause;
+ case VirtualKey_PageUp:
+ return Qt::Key_PageUp;
+ case VirtualKey_PageDown:
+ return Qt::Key_PageDown;
+ case VirtualKey_End:
+ return Qt::Key_End;
+ case VirtualKey_Home:
+ return Qt::Key_Home;
+ case VirtualKey_Left:
+ return Qt::Key_Left;
+ case VirtualKey_Up:
+ return Qt::Key_Up;
+ case VirtualKey_Right:
+ return Qt::Key_Right;
+ case VirtualKey_Down:
+ return Qt::Key_Down;
+ case VirtualKey_Select:
+ return Qt::Key_Select;
+ case VirtualKey_Print:
+ return Qt::Key_Print;
+ case VirtualKey_Execute:
+ return Qt::Key_Execute;
+ case VirtualKey_Insert:
+ return Qt::Key_Insert;
+ case VirtualKey_Delete:
+ return Qt::Key_Delete;
+ case VirtualKey_Help:
+ return Qt::Key_Help;
+ case VirtualKey_Snapshot:
+ return Qt::Key_Camera;
+ case VirtualKey_Escape:
+ return Qt::Key_Escape;
+
+ // Function Keys
+ case VirtualKey_F1:
+ return Qt::Key_F1;
+ case VirtualKey_F2:
+ return Qt::Key_F2;
+ case VirtualKey_F3:
+ return Qt::Key_F3;
+ case VirtualKey_F4:
+ return Qt::Key_F4;
+ case VirtualKey_F5:
+ return Qt::Key_F5;
+ case VirtualKey_F6:
+ return Qt::Key_F6;
+ case VirtualKey_F7:
+ return Qt::Key_F7;
+ case VirtualKey_F8:
+ return Qt::Key_F8;
+ case VirtualKey_F9:
+ return Qt::Key_F9;
+ case VirtualKey_F10:
+ return Qt::Key_F10;
+ case VirtualKey_F11:
+ return Qt::Key_F11;
+ case VirtualKey_F12:
+ return Qt::Key_F12;
+ case VirtualKey_F13:
+ return Qt::Key_F13;
+ case VirtualKey_F14:
+ return Qt::Key_F14;
+ case VirtualKey_F15:
+ return Qt::Key_F15;
+ case VirtualKey_F16:
+ return Qt::Key_F16;
+ case VirtualKey_F17:
+ return Qt::Key_F17;
+ case VirtualKey_F18:
+ return Qt::Key_F18;
+ case VirtualKey_F19:
+ return Qt::Key_F19;
+ case VirtualKey_F20:
+ return Qt::Key_F20;
+ case VirtualKey_F21:
+ return Qt::Key_F21;
+ case VirtualKey_F22:
+ return Qt::Key_F22;
+ case VirtualKey_F23:
+ return Qt::Key_F23;
+ case VirtualKey_F24:
+ return Qt::Key_F24;
+
+ // Character keys
+ case VirtualKey_Space:
+ return Qt::Key_Space;
+ case VirtualKey_Number0:
+ case VirtualKey_NumberPad0:
+ return Qt::Key_0;
+ case VirtualKey_Number1:
+ case VirtualKey_NumberPad1:
+ return Qt::Key_1;
+ case VirtualKey_Number2:
+ case VirtualKey_NumberPad2:
+ return Qt::Key_2;
+ case VirtualKey_Number3:
+ case VirtualKey_NumberPad3:
+ return Qt::Key_3;
+ case VirtualKey_Number4:
+ case VirtualKey_NumberPad4:
+ return Qt::Key_4;
+ case VirtualKey_Number5:
+ case VirtualKey_NumberPad5:
+ return Qt::Key_5;
+ case VirtualKey_Number6:
+ case VirtualKey_NumberPad6:
+ return Qt::Key_6;
+ case VirtualKey_Number7:
+ case VirtualKey_NumberPad7:
+ return Qt::Key_7;
+ case VirtualKey_Number8:
+ case VirtualKey_NumberPad8:
+ return Qt::Key_8;
+ case VirtualKey_Number9:
+ case VirtualKey_NumberPad9:
+ return Qt::Key_9;
+ case VirtualKey_A:
+ return Qt::Key_A;
+ case VirtualKey_B:
+ return Qt::Key_B;
+ case VirtualKey_C:
+ return Qt::Key_C;
+ case VirtualKey_D:
+ return Qt::Key_D;
+ case VirtualKey_E:
+ return Qt::Key_E;
+ case VirtualKey_F:
+ return Qt::Key_F;
+ case VirtualKey_G:
+ return Qt::Key_G;
+ case VirtualKey_H:
+ return Qt::Key_H;
+ case VirtualKey_I:
+ return Qt::Key_I;
+ case VirtualKey_J:
+ return Qt::Key_J;
+ case VirtualKey_K:
+ return Qt::Key_K;
+ case VirtualKey_L:
+ return Qt::Key_L;
+ case VirtualKey_M:
+ return Qt::Key_M;
+ case VirtualKey_N:
+ return Qt::Key_N;
+ case VirtualKey_O:
+ return Qt::Key_O;
+ case VirtualKey_P:
+ return Qt::Key_P;
+ case VirtualKey_Q:
+ return Qt::Key_Q;
+ case VirtualKey_R:
+ return Qt::Key_R;
+ case VirtualKey_S:
+ return Qt::Key_S;
+ case VirtualKey_T:
+ return Qt::Key_T;
+ case VirtualKey_U:
+ return Qt::Key_U;
+ case VirtualKey_V:
+ return Qt::Key_V;
+ case VirtualKey_W:
+ return Qt::Key_W;
+ case VirtualKey_X:
+ return Qt::Key_X;
+ case VirtualKey_Y:
+ return Qt::Key_Y;
+ case VirtualKey_Z:
+ return Qt::Key_Z;
+ case VirtualKey_Multiply:
+ return Qt::Key_9;
+ case VirtualKey_Add:
+ return Qt::Key_9;
+ case VirtualKey_Separator:
+ return Qt::Key_9;
+ case VirtualKey_Subtract:
+ return Qt::Key_9;
+ case VirtualKey_Decimal:
+ return Qt::Key_9;
+ case VirtualKey_Divide:
+ return Qt::Key_9;
+
+ /* Keys with no matching Qt enum (?)
+ case VirtualKey_None:
+ case VirtualKey_LeftButton:
+ case VirtualKey_RightButton:
+ case VirtualKey_MiddleButton:
+ case VirtualKey_XButton1:
+ case VirtualKey_XButton2:
+ case VirtualKey_Final:
+ case VirtualKey_Accept:*/
+ }
+}
+
+static inline Qt::Key qKeyFromCode(quint32 code, int mods)
+{
+ if (code >= 'a' && code <= 'z')
+ code = toupper(code);
+ if ((mods & Qt::ControlModifier) != 0) {
+ if (code >= 0 && code <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
+ code += '@'; // to @..A..Z.._
+ }
+ return static_cast<Qt::Key>(code & 0xff);
+}
+
+QWinRTScreen::QWinRTScreen(ICoreWindow *window)
+ : m_coreWindow(window)
+ , m_depth(32)
+ , m_format(QImage::Format_ARGB32_Premultiplied)
+#ifdef Q_OS_WINPHONE
+ , m_inputContext(new QWinRTInputContext(m_coreWindow))
+#else
+ , m_inputContext(Make<QWinRTInputContext>(m_coreWindow).Detach())
+#endif
+ , m_cursor(new QWinRTCursor(window))
+ , m_orientation(Qt::PrimaryOrientation)
+{
+#ifdef Q_OS_WINPHONE // On phone, there can be only one touch device
+ QTouchDevice *touchDevice = new QTouchDevice;
+ touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure);
+ touchDevice->setType(QTouchDevice::TouchScreen);
+ touchDevice->setName(QStringLiteral("WinPhoneTouchScreen"));
+ Pointer pointer = { Pointer::TouchScreen, touchDevice };
+ m_pointers.insert(0, pointer);
+ QWindowSystemInterface::registerTouchDevice(touchDevice);
+#endif
+
+ Rect rect;
+ window->get_Bounds(&rect);
+ m_geometry = QRect(0, 0, rect.Width, rect.Height);
+
+ m_surfaceFormat.setAlphaBufferSize(0);
+ m_surfaceFormat.setRedBufferSize(8);
+ m_surfaceFormat.setGreenBufferSize(8);
+ m_surfaceFormat.setBlueBufferSize(8);
+
+ m_surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
+ m_surfaceFormat.setSamples(1);
+ m_surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ m_surfaceFormat.setDepthBufferSize(24);
+ m_surfaceFormat.setStencilBufferSize(8);
+
+ m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (m_eglDisplay == EGL_NO_DISPLAY)
+ qFatal("Qt WinRT platform plugin: failed to initialize EGL display.");
+
+ if (!eglInitialize(m_eglDisplay, NULL, NULL))
+ qFatal("Qt WinRT platform plugin: failed to initialize EGL. This can happen if you haven't included the D3D compiler DLL in your application package.");
+
+ // TODO: move this to Window
+ m_eglSurface = eglCreateWindowSurface(m_eglDisplay, q_configFromGLFormat(m_eglDisplay, m_surfaceFormat), window, NULL);
+ if (m_eglSurface == EGL_NO_SURFACE)
+ qFatal("Could not create EGL surface, error 0x%X", eglGetError());
+
+ // Event handlers mapped to QEvents
+ m_coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &m_tokens[QEvent::KeyPress]);
+ m_coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &m_tokens[QEvent::KeyRelease]);
+ m_coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &m_tokens[QEvent::User]);
+ m_coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &m_tokens[QEvent::Enter]);
+ m_coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &m_tokens[QEvent::Leave]);
+ m_coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseMove]);
+ m_coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonPress]);
+ m_coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonRelease]);
+ m_coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::Wheel]);
+ m_coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &m_tokens[QEvent::Resize]);
+
+ // Window event handlers
+ m_coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &m_tokens[QEvent::WindowActivate]);
+ m_coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &m_tokens[QEvent::WindowDeactivate]);
+ m_coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &m_tokens[QEvent::Show]);
+ m_coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &m_tokens[QEvent::InputMethodQuery]);
+
+ // Orientation handling
+ if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(),
+ &m_displayProperties))) {
+ // Set native orientation
+ DisplayOrientations displayOrientation;
+ m_displayProperties->get_NativeOrientation(&displayOrientation);
+ m_nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+
+ // Set initial orientation
+ onOrientationChanged(0);
+
+ m_displayProperties->add_OrientationChanged(Callback<IDisplayPropertiesEventHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
+ &m_tokens[QEvent::OrientationChange]);
+ }
+
+#ifndef Q_OS_WINPHONE
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
+ &m_applicationView);
+#endif
+
+
+ if (SUCCEEDED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&m_application)))) {
+ m_application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &m_suspendTokens[Qt::ApplicationSuspended]);
+ m_application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &m_suspendTokens[Qt::ApplicationHidden]);
+ }
+}
+
+QRect QWinRTScreen::geometry() const
+{
+ return m_geometry;
+}
+
+int QWinRTScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QWinRTScreen::format() const
+{
+ return m_format;
+}
+
+QSurfaceFormat QWinRTScreen::surfaceFormat() const
+{
+ return m_surfaceFormat;
+}
+
+QWinRTInputContext *QWinRTScreen::inputContext() const
+{
+ return m_inputContext;
+}
+
+QPlatformCursor *QWinRTScreen::cursor() const
+{
+ return m_cursor;
+}
+
+Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const
+{
+ Qt::KeyboardModifiers mods;
+ CoreVirtualKeyStates mod;
+ m_coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::ShiftModifier;
+ m_coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::AltModifier;
+ m_coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::ControlModifier;
+ m_coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod);
+ if (mod == CoreVirtualKeyStates_Down) {
+ mods |= Qt::MetaModifier;
+ } else {
+ m_coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::MetaModifier;
+ }
+ return mods;
+}
+
+Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const
+{
+ return m_nativeOrientation;
+}
+
+Qt::ScreenOrientation QWinRTScreen::orientation() const
+{
+ return m_orientation;
+}
+
+void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
+{
+ m_displayProperties->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
+}
+
+ICoreWindow *QWinRTScreen::coreWindow() const
+{
+ return m_coreWindow;
+}
+
+EGLDisplay QWinRTScreen::eglDisplay() const
+{
+ return m_eglDisplay;
+}
+
+EGLSurface QWinRTScreen::eglSurface() const
+{
+ return m_eglSurface;
+}
+
+QWindow *QWinRTScreen::topWindow() const
+{
+ return m_visibleWindows.isEmpty() ? 0 : m_visibleWindows.first();
+}
+
+void QWinRTScreen::addWindow(QWindow *window)
+{
+ if (window == topWindow())
+ return;
+ m_visibleWindows.prepend(window);
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::removeWindow(QWindow *window)
+{
+ const bool wasTopWindow = window == topWindow();
+ if (!m_visibleWindows.removeAll(window))
+ return;
+ if (wasTopWindow)
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::raise(QWindow *window)
+{
+ m_visibleWindows.removeAll(window);
+ addWindow(window);
+}
+
+void QWinRTScreen::lower(QWindow *window)
+{
+ const bool wasTopWindow = window == topWindow();
+ if (wasTopWindow && m_visibleWindows.size() == 1)
+ return;
+ m_visibleWindows.removeAll(window);
+ m_visibleWindows.append(window);
+ if (wasTopWindow)
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::handleExpose()
+{
+ if (m_visibleWindows.isEmpty())
+ return;
+ QList<QWindow *>::const_iterator it = m_visibleWindows.constBegin();
+ QWindowSystemInterface::handleExposeEvent(*it, m_geometry);
+ while (++it != m_visibleWindows.constEnd())
+ QWindowSystemInterface::handleExposeEvent(*it, QRegion());
+ QWindowSystemInterface::flushWindowSystemEvents();
+}
+
+HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args)
+{
+ Q_UNUSED(window);
+ VirtualKey virtualKey;
+ args->get_VirtualKey(&virtualKey);
+ Qt::Key key = qKeyFromVirtual(virtualKey);
+ // Defer character key presses to onCharacterReceived
+ if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis))
+ return S_OK;
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, keyboardModifiers());
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args)
+{
+ Q_UNUSED(window);
+ Qt::KeyboardModifiers mods = keyboardModifiers();
+#ifndef Q_OS_WINPHONE
+ CorePhysicalKeyStatus status; // Look for a pressed character key
+ if (SUCCEEDED(args->get_KeyStatus(&status)) && m_activeKeys.contains(status.ScanCode)) {
+ QPair<Qt::Key, QString> keyStatus = m_activeKeys.take(status.ScanCode);
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease,
+ keyStatus.first, mods, keyStatus.second);
+ return S_OK;
+ }
+#endif // !Q_OS_WINPHONE
+ VirtualKey virtualKey;
+ args->get_VirtualKey(&virtualKey);
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease,
+ qKeyFromVirtual(virtualKey), mods);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceivedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ quint32 keyCode;
+ args->get_KeyCode(&keyCode);
+ // Don't generate character events for non-printables; the meta key stage is enough
+ if (qIsNonPrintable(keyCode))
+ return S_OK;
+
+ Qt::KeyboardModifiers mods = keyboardModifiers();
+ Qt::Key key = qKeyFromCode(keyCode, mods);
+ QString text = QChar(keyCode);
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text);
+#ifndef Q_OS_WINPHONE
+ CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys
+ if (SUCCEEDED(args->get_KeyStatus(&status)) && !status.IsKeyReleased) {
+ m_activeKeys.insert(status.ScanCode, qMakePair(key, text));
+ return S_OK;
+ }
+#endif // !Q_OS_WINPHONE
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, key, mods, text);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+ IPointerPoint *pointerPoint;
+ if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) {
+ // Assumes full-screen window
+ Point point;
+ pointerPoint->get_Position(&point);
+ QPoint pos(point.X, point.Y);
+
+ QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos);
+ pointerPoint->Release();
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerExited(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+ QWindowSystemInterface::handleLeaveEvent(0);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ IPointerPoint *pointerPoint;
+ if (FAILED(args->get_CurrentPoint(&pointerPoint)))
+ return E_INVALIDARG;
+
+ // Common traits - point, modifiers, properties
+ Point point;
+ pointerPoint->get_Position(&point);
+ QPointF pos(point.X, point.Y);
+
+ VirtualKeyModifiers modifiers;
+ args->get_KeyModifiers(&modifiers);
+ Qt::KeyboardModifiers mods;
+ if (modifiers & VirtualKeyModifiers_Control)
+ mods |= Qt::ControlModifier;
+ if (modifiers & VirtualKeyModifiers_Menu)
+ mods |= Qt::AltModifier;
+ if (modifiers & VirtualKeyModifiers_Shift)
+ mods |= Qt::ShiftModifier;
+ if (modifiers & VirtualKeyModifiers_Windows)
+ mods |= Qt::MetaModifier;
+
+ IPointerPointProperties *properties;
+ if (FAILED(pointerPoint->get_Properties(&properties)))
+ return E_INVALIDARG;
+
+#ifdef Q_OS_WINPHONE
+ quint32 pointerId = 0;
+ Pointer pointer = m_pointers.value(pointerId);
+#else
+ Pointer pointer = { Pointer::Unknown, 0 };
+ quint32 pointerId;
+ pointerPoint->get_PointerId(&pointerId);
+ if (m_pointers.contains(pointerId)) {
+ pointer = m_pointers.value(pointerId);
+ } else { // We have not yet enumerated this device. Do so now...
+ IPointerDevice *device;
+ if (SUCCEEDED(pointerPoint->get_PointerDevice(&device))) {
+ PointerDeviceType type;
+ device->get_PointerDeviceType(&type);
+ switch (type) {
+ case PointerDeviceType_Touch:
+ pointer.type = Pointer::TouchScreen;
+ pointer.device = new QTouchDevice;
+ pointer.device->setName(QStringLiteral("WinRT TouchScreen ") + QString::number(pointerId));
+ // TODO: We may want to probe the device usage flags for more accurate values for these next two
+ pointer.device->setType(QTouchDevice::TouchScreen);
+ pointer.device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure);
+ QWindowSystemInterface::registerTouchDevice(pointer.device);
+ break;
+
+ case PointerDeviceType_Pen:
+ pointer.type = Pointer::Tablet;
+ break;
+
+ case PointerDeviceType_Mouse:
+ pointer.type = Pointer::Mouse;
+ break;
+ }
+
+ m_pointers.insert(pointerId, pointer);
+ device->Release();
+ }
+ }
+#endif
+ switch (pointer.type) {
+ case Pointer::Mouse: {
+ qint32 delta;
+ properties->get_MouseWheelDelta(&delta);
+ if (delta) {
+ boolean isHorizontal;
+ properties->get_IsHorizontalMouseWheel(&isHorizontal);
+ QPoint angleDelta(isHorizontal ? delta : 0, isHorizontal ? 0 : delta);
+ QWindowSystemInterface::handleWheelEvent(topWindow(), pos, pos, QPoint(), angleDelta, mods);
+ break;
+ }
+
+ boolean isPressed;
+ Qt::MouseButtons buttons = Qt::NoButton;
+ properties->get_IsLeftButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::LeftButton;
+
+ properties->get_IsMiddleButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::MiddleButton;
+
+ properties->get_IsRightButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::RightButton;
+
+ properties->get_IsXButton1Pressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::XButton1;
+
+ properties->get_IsXButton2Pressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::XButton2;
+
+ QWindowSystemInterface::handleMouseEvent(topWindow(), pos, pos, buttons, mods);
+
+ break;
+ }
+ case Pointer::TouchScreen: {
+ quint32 id;
+ pointerPoint->get_PointerId(&id);
+
+ Rect area;
+ properties->get_ContactRect(&area);
+
+ float pressure;
+ properties->get_Pressure(&pressure);
+
+ QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = m_touchPoints.find(id);
+ if (it != m_touchPoints.end()) {
+ boolean isPressed;
+#ifndef Q_OS_WINPHONE
+ pointerPoint->get_IsInContact(&isPressed);
+#else
+ properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
+#endif
+ it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased;
+ } else {
+ it = m_touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
+ it.value().state = Qt::TouchPointPressed;
+ it.value().id = id;
+ }
+ it.value().area = QRectF(area.X, area.Y, area.Width, area.Height);
+ it.value().normalPosition = QPointF(pos.x()/m_geometry.width(), pos.y()/m_geometry.height());
+ it.value().pressure = pressure;
+
+ QWindowSystemInterface::handleTouchEvent(topWindow(), pointer.device, m_touchPoints.values(), mods);
+
+ // Remove released points, station others
+ for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = m_touchPoints.begin(); i != m_touchPoints.end();) {
+ if (i.value().state == Qt::TouchPointReleased)
+ i = m_touchPoints.erase(i);
+ else
+ (i++).value().state = Qt::TouchPointStationary;
+ }
+
+ break;
+ }
+ case Pointer::Tablet: {
+ quint32 id;
+ pointerPoint->get_PointerId(&id);
+
+ boolean isPressed;
+ pointerPoint->get_IsInContact(&isPressed);
+
+ boolean isEraser;
+ properties->get_IsEraser(&isEraser);
+ int pointerType = isEraser ? 3 : 1;
+
+ float pressure;
+ properties->get_Pressure(&pressure);
+
+ float xTilt;
+ properties->get_XTilt(&xTilt);
+
+ float yTilt;
+ properties->get_YTilt(&yTilt);
+
+ float rotation;
+ properties->get_Twist(&rotation);
+
+ QWindowSystemInterface::handleTabletEvent(topWindow(), isPressed, pos, pos, pointerId,
+ pointerType, pressure, xTilt, yTilt,
+ 0, rotation, 0, id, mods);
+
+ break;
+ }
+ }
+
+ properties->Release();
+ pointerPoint->Release();
+
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args)
+{
+#ifndef Q_OS_WINPHONE
+ args->put_AutomationProvider(m_inputContext);
+#endif
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *window, IWindowSizeChangedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ Size size;
+ if (FAILED(args->get_Size(&size))) {
+ qWarning(Q_FUNC_INFO ": failed to get size");
+ return S_OK;
+ }
+
+ // Regardless of state, all top-level windows are viewport-sized - this might change if
+ // a more advanced compositor is written.
+ m_geometry.setSize(QSize(size.Width, size.Height));
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry);
+ QPlatformScreen::resizeMaximizedWindows();
+ handleExpose();
+
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ CoreWindowActivationState activationState;
+ args->get_WindowActivationState(&activationState);
+ if (activationState == CoreWindowActivationState_Deactivated) {
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
+ return S_OK;
+ }
+
+ // Activate topWindow
+ if (!m_visibleWindows.isEmpty()) {
+ Qt::FocusReason focusReason = activationState == CoreWindowActivationState_PointerActivated
+ ? Qt::MouseFocusReason : Qt::ActiveWindowFocusReason;
+ QWindowSystemInterface::handleWindowActivated(topWindow(), focusReason);
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onSuspended(IInspectable *, ISuspendingEventArgs *)
+{
+ 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 *window, ICoreWindowEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+
+ foreach (QWindow *w, QGuiApplication::topLevelWindows())
+ QWindowSystemInterface::handleCloseEvent(w);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChangedEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+
+ boolean visible;
+ args->get_Visible(&visible);
+ QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onOrientationChanged(IInspectable *)
+{
+ DisplayOrientations displayOrientation;
+ m_displayProperties->get_CurrentOrientation(&displayOrientation);
+ Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+ if (m_orientation != newOrientation) {
+ m_orientation = newOrientation;
+ QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
+ }
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
new file mode 100644
index 0000000000..3131f879b5
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTSCREEN_H
+#define QWINRTSCREEN_H
+
+#include <qpa/qplatformscreen.h>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <QtCore/QHash>
+#include <QtGui/QSurfaceFormat>
+#include <EGL/egl.h>
+
+#include <EventToken.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace ApplicationModel {
+ struct ISuspendingEventArgs;
+ namespace Core {
+ struct ICoreApplication;
+ }
+ }
+ namespace UI {
+ namespace Core {
+ struct IAutomationProviderRequestedEventArgs;
+ struct ICharacterReceivedEventArgs;
+ struct ICoreWindow;
+ struct ICoreWindowEventArgs;
+ struct IKeyEventArgs;
+ struct IPointerEventArgs;
+ struct IVisibilityChangedEventArgs;
+ struct IWindowActivatedEventArgs;
+ struct IWindowSizeChangedEventArgs;
+ }
+ namespace ViewManagement {
+ struct IApplicationViewStatics;
+ }
+ }
+ namespace Graphics {
+ namespace Display {
+ struct IDisplayPropertiesStatics;
+ }
+ }
+ }
+}
+struct IInspectable;
+
+QT_BEGIN_NAMESPACE
+
+class QTouchDevice;
+class QWinRTEGLContext;
+class QWinRTPageFlipper;
+class QWinRTCursor;
+class QWinRTInputContext;
+
+struct Pointer {
+ enum Type { Unknown, Mouse, TouchScreen, Tablet };
+ Type type;
+ QTouchDevice *device;
+};
+
+class QWinRTScreen : public QPlatformScreen
+{
+public:
+ explicit QWinRTScreen(ABI::Windows::UI::Core::ICoreWindow *window);
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSurfaceFormat surfaceFormat() const;
+ QWinRTInputContext *inputContext() const;
+ QPlatformCursor *cursor() const;
+ Qt::KeyboardModifiers keyboardModifiers() const;
+
+ Qt::ScreenOrientation nativeOrientation() const;
+ Qt::ScreenOrientation orientation() const;
+ void setOrientationUpdateMask(Qt::ScreenOrientations mask);
+
+ QWindow *topWindow() const;
+ void addWindow(QWindow *window);
+ void removeWindow(QWindow *window);
+ void raise(QWindow *window);
+ void lower(QWindow *window);
+
+ ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
+ EGLDisplay eglDisplay() const; // To opengl context
+ EGLSurface eglSurface() const; // To window
+
+private:
+ void handleExpose();
+
+ // Event handlers
+ QHash<QEvent::Type, EventRegistrationToken> m_tokens;
+ QHash<Qt::ApplicationState, EventRegistrationToken> m_suspendTokens;
+
+ HRESULT onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args);
+ HRESULT onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args);
+ HRESULT onCharacterReceived(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::ICharacterReceivedEventArgs *args);
+ HRESULT onPointerEntered(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onPointerExited(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onPointerUpdated(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *args);
+
+ HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *args);
+ HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
+ HRESULT onResume(IInspectable *, IInspectable *);
+
+ HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *args);
+ HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *args);
+ HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *args);
+
+ HRESULT onOrientationChanged(IInspectable *);
+
+ ABI::Windows::UI::Core::ICoreWindow *m_coreWindow;
+ ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView;
+ ABI::Windows::ApplicationModel::Core::ICoreApplication *m_application;
+ QRect m_geometry;
+ QImage::Format m_format;
+ QSurfaceFormat m_surfaceFormat;
+ int m_depth;
+ QWinRTInputContext *m_inputContext;
+ QWinRTCursor *m_cursor;
+ QList<QWindow *> m_visibleWindows;
+
+ EGLDisplay m_eglDisplay;
+ EGLSurface m_eglSurface;
+
+ ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayProperties;
+ Qt::ScreenOrientation m_nativeOrientation;
+ Qt::ScreenOrientation m_orientation;
+
+#ifndef Q_OS_WINPHONE
+ QHash<quint32, QPair<Qt::Key, QString> > m_activeKeys;
+#endif
+ QHash<quint32, Pointer> m_pointers;
+ QHash<quint32, QWindowSystemInterface::TouchPoint> m_touchPoints;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTSCREEN_H
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
new file mode 100644
index 0000000000..8f0a1d55bb
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtservices.h"
+#include <QtCore/QUrl>
+#include <QtCore/QDir>
+#include <QtCore/QCoreApplication>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+#include <windows.system.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::System;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTServices::QWinRTServices()
+{
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Uri).Get(), &m_uriFactory);
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFile).Get(), &m_fileFactory);
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Launcher).Get(), &m_launcher);
+}
+
+QWinRTServices::~QWinRTServices()
+{
+ if (m_uriFactory)
+ m_uriFactory->Release();
+
+ if (m_fileFactory)
+ m_fileFactory->Release();
+
+ if (m_launcher)
+ m_launcher->Release();
+}
+
+bool QWinRTServices::openUrl(const QUrl &url)
+{
+ if (!(m_uriFactory && m_launcher))
+ return QPlatformServices::openUrl(url);
+
+ IUriRuntimeClass *uri;
+ QString urlString = url.toString(); HSTRING uriString; HSTRING_HEADER header;
+ WindowsCreateStringReference((const wchar_t*)urlString.utf16(), urlString.length(), &header, &uriString);
+ m_uriFactory->CreateUri(uriString, &uri);
+ if (!uri)
+ return false;
+
+ IAsyncOperation<bool> *launchOp;
+ m_launcher->LaunchUriAsync(uri, &launchOp);
+ uri->Release();
+ if (!launchOp)
+ return false;
+
+ boolean result = false;
+ while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ launchOp->Release();
+
+ return result;
+}
+
+bool QWinRTServices::openDocument(const QUrl &url)
+{
+ if (!(m_fileFactory && m_launcher))
+ return QPlatformServices::openDocument(url);
+
+ QString pathString = QDir::toNativeSeparators(
+ QDir::cleanPath(qApp->applicationDirPath().append(url.toString(QUrl::RemoveScheme))));
+ HSTRING_HEADER header; HSTRING path;
+ WindowsCreateStringReference((const wchar_t*)pathString.utf16(), pathString.length(), &header, &path);
+ IAsyncOperation<StorageFile*> *fileOp;
+ m_fileFactory->GetFileFromPathAsync(path, &fileOp);
+ if (!fileOp)
+ return false;
+
+ IStorageFile *file = nullptr;
+ while (fileOp->GetResults(&file) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ fileOp->Release();
+ if (!file)
+ return false;
+
+ IAsyncOperation<bool> *launchOp;
+ m_launcher->LaunchFileAsync(file, &launchOp);
+ if (!launchOp)
+ return false;
+
+ boolean result = false;
+ while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ launchOp->Release();
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtservices.h b/src/plugins/platforms/winrt/qwinrtservices.h
new file mode 100644
index 0000000000..9cc917030a
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtservices.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTSERVICES_H
+#define QWINRTSERVICES_H
+
+#include <qpa/qplatformservices.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace Foundation {
+ struct IUriRuntimeClassFactory;
+ }
+ namespace Storage {
+ struct IStorageFileStatics;
+ }
+ namespace System {
+ struct ILauncherStatics;
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTServices : public QPlatformServices
+{
+public:
+ explicit QWinRTServices();
+ ~QWinRTServices();
+
+ bool openUrl(const QUrl &url);
+ bool openDocument(const QUrl &url);
+
+private:
+ ABI::Windows::Foundation::IUriRuntimeClassFactory *m_uriFactory;
+ ABI::Windows::Storage::IStorageFileStatics *m_fileFactory;
+ ABI::Windows::System::ILauncherStatics *m_launcher;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTSERVICES_H
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
new file mode 100644
index 0000000000..88b753b463
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtwindow.h"
+#include "qwinrtscreen.h"
+
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformscreen.h>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLContext>
+
+QT_BEGIN_NAMESPACE
+
+QWinRTWindow::QWinRTWindow(QWindow *window)
+ : QPlatformWindow(window)
+ , m_screen(static_cast<QWinRTScreen*>(screen()))
+{
+ setWindowFlags(window->flags());
+ setWindowState(window->windowState());
+ handleContentOrientationChange(window->contentOrientation());
+ setGeometry(window->geometry());
+}
+
+QWinRTWindow::~QWinRTWindow()
+{
+ m_screen->removeWindow(window());
+}
+
+QSurfaceFormat QWinRTWindow::format() const
+{
+ return m_screen->surfaceFormat();
+}
+
+bool QWinRTWindow::isActive() const
+{
+ return m_screen->topWindow() == window();
+}
+
+bool QWinRTWindow::isExposed() const
+{
+ const bool exposed = isActive();
+ return exposed;
+}
+
+void QWinRTWindow::setGeometry(const QRect &rect)
+{
+ if (window()->isTopLevel()) {
+ QPlatformWindow::setGeometry(m_screen->geometry());
+ QWindowSystemInterface::handleGeometryChange(window(), geometry());
+ } else {
+ QPlatformWindow::setGeometry(rect);
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
+ }
+}
+
+void QWinRTWindow::setVisible(bool visible)
+{
+ if (!window()->isTopLevel())
+ return;
+ if (visible)
+ m_screen->addWindow(window());
+ else
+ m_screen->removeWindow(window());
+}
+
+void QWinRTWindow::raise()
+{
+ if (!window()->isTopLevel())
+ return;
+ m_screen->raise(window());
+}
+
+void QWinRTWindow::lower()
+{
+ if (!window()->isTopLevel())
+ return;
+ m_screen->lower(window());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 9e3f203201..1f19b4f2d5 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,26 +39,34 @@
**
****************************************************************************/
-#ifndef ANDROIDPLATFORMWINDOW_H
-#define ANDROIDPLATFORMWINDOW_H
-#include <qobject.h>
-#include <QtPlatformSupport/private/qfbwindow_p.h>
+#ifndef QWINRTWINDOW_H
+#define QWINRTWINDOW_H
-class QAndroidPlatformWindow: public QObject, public QFbWindow
+#include <qpa/qplatformwindow.h>
+#include <qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTScreen;
+
+class QWinRTWindow : public QPlatformWindow
{
- Q_OBJECT
public:
- explicit QAndroidPlatformWindow(QWindow *window);
+ QWinRTWindow(QWindow *window);
+ ~QWinRTWindow();
- void propagateSizeHints();
-
- void raise();
- void setWindowState(Qt::WindowState state);
+ QSurfaceFormat format() const;
+ bool isActive() const;
+ bool isExposed() const;
+ void setGeometry(const QRect &rect);
void setVisible(bool visible);
- void updateStatusBarVisibility();
+ void raise();
+ void lower();
-public slots:
- void setGeometry(const QRect &rect);
+private:
+ QWinRTScreen *m_screen;
};
-#endif // ANDROIDPLATFORMWINDOW_H
+QT_END_NAMESPACE
+
+#endif // QWINRTWINDOW_H
diff --git a/src/plugins/platforms/winrt/winrt.json b/src/plugins/platforms/winrt/winrt.json
new file mode 100644
index 0000000000..962747b697
--- /dev/null
+++ b/src/plugins/platforms/winrt/winrt.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "winrt" ]
+}
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
new file mode 100644
index 0000000000..ea5ff93d00
--- /dev/null
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -0,0 +1,55 @@
+TARGET = qwinrt
+CONFIG -= precompile_header
+
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin
+load(qt_plugin)
+
+QT += core-private gui-private platformsupport-private
+
+DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES
+
+LIBS += $$QMAKE_LIBS_CORE -ldxgi
+
+SOURCES = \
+ main.cpp \
+ qwinrtbackingstore.cpp \
+ qwinrtcursor.cpp \
+ qwinrteglcontext.cpp \
+ qwinrteventdispatcher.cpp \
+ qwinrtfontdatabase.cpp \
+ qwinrtinputcontext.cpp \
+ qwinrtintegration.cpp \
+ qwinrtscreen.cpp \
+ qwinrtservices.cpp \
+ qwinrtwindow.cpp
+
+HEADERS = \
+ qwinrtbackingstore.h \
+ qwinrtcursor.h \
+ qwinrteglcontext.h \
+ qwinrteventdispatcher.h \
+ qwinrtfontdatabase.h \
+ qwinrtinputcontext.h \
+ qwinrtintegration.h \
+ qwinrtscreen.h \
+ qwinrtservices.h \
+ qwinrtwindow.h
+
+BLIT_INPUT = $$PWD/blit.hlsl
+fxc_blitps.commands = fxc.exe /nologo /T ps_4_0_level_9_1 /E blitps /Vn q_blitps /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+fxc_blitps.output = $$OUT_PWD/blitps.h
+fxc_blitps.input = BLIT_INPUT
+fxc_blitps.dependency_type = TYPE_C
+fxc_blitps.variable_out = HEADERS
+fxc_blitps.CONFIG += target_predeps
+fxc_blitvs.commands = fxc.exe /nologo /T vs_4_0_level_9_1 /E blitvs /Vn q_blitvs /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+fxc_blitvs.output = $$OUT_PWD/blitvs.h
+fxc_blitvs.input = BLIT_INPUT
+fxc_blitvs.dependency_type = TYPE_C
+fxc_blitvs.variable_out = HEADERS
+fxc_blitvs.CONFIG += target_predeps
+QMAKE_EXTRA_COMPILERS += fxc_blitps fxc_blitvs
+
+OTHER_FILES += winrt.json \
+ blit.hlsl
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index e504d93fba..3f1c53b122 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -167,6 +167,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
, m_shareContext(0)
, m_format(format)
, m_isPBufferCurrent(false)
+ , m_swapInterval(-1)
{
if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType)
m_format.setRenderableType(QSurfaceFormat::OpenGL);
@@ -326,19 +327,50 @@ QGLXContext::~QGLXContext()
bool QGLXContext::makeCurrent(QPlatformSurface *surface)
{
+ bool success = false;
Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Display *dpy = DISPLAY_FROM_XCB(m_screen);
+ GLXDrawable glxDrawable = 0;
QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass();
if (surfaceClass == QSurface::Window) {
m_isPBufferCurrent = false;
QXcbWindow *window = static_cast<QXcbWindow *>(surface);
- return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), window->xcb_window(), m_context);
+ glxDrawable = window->xcb_window();
+ success = glXMakeCurrent(dpy, glxDrawable, m_context);
} else if (surfaceClass == QSurface::Offscreen) {
m_isPBufferCurrent = true;
QGLXPbuffer *pbuffer = static_cast<QGLXPbuffer *>(surface);
- return glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), pbuffer->pbuffer(), pbuffer->pbuffer(), m_context);
+ glxDrawable = pbuffer->pbuffer();
+ success = glXMakeContextCurrent(dpy, glxDrawable, glxDrawable, m_context);
+ }
+
+ if (success) {
+ int interval = surface->format().swapInterval();
+ if (interval >= 0 && m_swapInterval != interval) {
+ m_swapInterval = interval;
+ typedef void (*qt_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
+ typedef void (*qt_glXSwapIntervalMESA)(unsigned int);
+ static qt_glXSwapIntervalEXT glXSwapIntervalEXT = 0;
+ static qt_glXSwapIntervalMESA glXSwapIntervalMESA = 0;
+ static bool resolved = false;
+ if (!resolved) {
+ resolved = true;
+ QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(dpy,
+ m_screen->screenNumber())).split(' ');
+ if (glxExt.contains("GLX_EXT_swap_control"))
+ glXSwapIntervalEXT = (qt_glXSwapIntervalEXT) getProcAddress("glXSwapIntervalEXT");
+ if (glxExt.contains("GLX_MESA_swap_control"))
+ glXSwapIntervalMESA = (qt_glXSwapIntervalMESA) getProcAddress("glXSwapIntervalMESA");
+ }
+ if (glXSwapIntervalEXT)
+ glXSwapIntervalEXT(dpy, glxDrawable, interval);
+ else if (glXSwapIntervalMESA)
+ glXSwapIntervalMESA(interval);
+ }
}
- return false;
+
+ return success;
}
void QGLXContext::doneCurrent()
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index dcc7fe8855..00bba94ab3 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -81,7 +81,7 @@ private:
GLXContext m_shareContext;
QSurfaceFormat m_format;
bool m_isPBufferCurrent;
-
+ int m_swapInterval;
static bool m_queriedDummyContext;
static bool m_supportsThreading;
};
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index e93b36cb99..366e043e98 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -232,9 +232,6 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
Q_XCB_NOOP(connection());
m_dirty = m_dirty | source;
-
- xcb_flush(xcb_connection());
- Q_XCB_NOOP(connection());
}
void QXcbShmImage::preparePaint(const QRegion &region)
@@ -314,10 +311,11 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
Q_XCB_NOOP(connection());
if (m_syncingResize) {
- xcb_flush(xcb_connection());
connection()->sync();
m_syncingResize = false;
platformWindow->updateSyncRequestCounter();
+ } else {
+ xcb_flush(xcb_connection());
}
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 3c4ab8d3e2..030090d98d 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -326,23 +326,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeXRandr();
updateScreens();
- m_connectionEventListener = xcb_generate_id(m_connection);
- xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
- m_connectionEventListener, m_screens.at(0)->root(),
- 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
- m_screens.at(0)->screen()->root_visual, 0, 0);
-#ifndef QT_NO_DEBUG
- QByteArray ba("Qt xcb connection listener window");
- Q_XCB_CALL(xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_connectionEventListener,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData()));
-#endif
-
initializeGLX();
initializeXFixes();
initializeXRender();
@@ -379,9 +362,6 @@ QXcbConnection::~QXcbConnection()
#ifndef QT_NO_DRAGANDDROP
delete m_drag;
#endif
- // Delete screens in reverse order to avoid crash in case of multiple screens
- while (!m_screens.isEmpty())
- delete m_screens.takeLast();
#ifdef XCB_USE_XINPUT2_MAEMO
finalizeXInput2Maemo();
@@ -396,6 +376,10 @@ QXcbConnection::~QXcbConnection()
delete m_reader;
+ // Delete screens in reverse order to avoid crash in case of multiple screens
+ while (!m_screens.isEmpty())
+ delete m_screens.takeLast();
+
#ifdef XCB_USE_EGL
if (m_has_egl)
eglTerminate(m_egl_display);
@@ -1081,14 +1065,21 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
xcb_client_message_event_t event;
memset(&event, 0, sizeof(event));
+ const xcb_window_t eventListener = xcb_generate_id(m_connection);
+ Q_XCB_CALL(xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
+ eventListener, m_screens.at(0)->root(),
+ 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
+ m_screens.at(0)->screen()->root_visual, 0, 0));
+
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.sequence = 0;
- event.window = m_connectionEventListener;
+ event.window = eventListener;
event.type = atom(a);
event.data.data32[0] = id;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_connectionEventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_destroy_window(m_connection, eventListener));
xcb_flush(xcb_connection());
}
@@ -1163,6 +1154,7 @@ void QXcbConnection::processXcbEvents()
xcb_generic_event_t *event = eventqueue->at(i);
if (!event)
continue;
+ QScopedPointer<xcb_generic_event_t, QScopedPointerPodDeleter> eventGuard(event);
(*eventqueue)[i] = 0;
uint response_type = event->response_type & ~0x80;
@@ -1213,8 +1205,6 @@ void QXcbConnection::processXcbEvents()
handleXcbEvent(event);
m_reader->lock();
}
-
- free(event);
}
eventqueue->clear();
@@ -1450,6 +1440,10 @@ static const char * xcb_atomnames = {
"Abs Distance\0"
"Wacom Serial IDs\0"
"INTEGER\0"
+ "Rel Horiz Wheel\0"
+ "Rel Vert Wheel\0"
+ "Rel Horiz Scroll\0"
+ "Rel Vert Scroll\0"
#if XCB_USE_MAEMO_WINDOW_PROPERTIES
"_MEEGOTOUCH_ORIENTATION_ANGLE\0"
#endif
@@ -1731,21 +1725,23 @@ bool QXcbConnection::hasEgl() const
#endif // defined(XCB_USE_EGL)
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
-// Borrowed from libXi.
-int QXcbConnection::xi2CountBits(unsigned char *ptr, int len)
+static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number)
{
- int bits = 0;
- int i;
- unsigned char x;
-
- for (i = 0; i < len; i++) {
- x = ptr[i];
- while (x > 0) {
- bits += (x & 0x1);
- x >>= 1;
+ int offset = 0;
+ for (int i = 0; i < maskLen; i++) {
+ if (number < 8) {
+ if ((maskPtr[i] & (1 << number)) == 0)
+ return -1;
}
+ for (int j = 0; j < 8; j++) {
+ if (j == number)
+ return offset;
+ if (maskPtr[i] & (1 << j))
+ offset++;
+ }
+ number -= 8;
}
- return bits;
+ return -1;
}
bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value)
@@ -1754,13 +1750,13 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub
unsigned char *buttonsMaskAddr = (unsigned char*)&xideviceevent[1];
unsigned char *valuatorsMaskAddr = buttonsMaskAddr + xideviceevent->buttons_len * 4;
FP3232 *valuatorsValuesAddr = (FP3232*)(valuatorsMaskAddr + xideviceevent->valuators_len * 4);
- int numValuatorValues = xi2CountBits(valuatorsMaskAddr, xideviceevent->valuators_len * 4);
- // This relies on all bit being set until a certain number i.e. it doesn't support only bit 0 and 5 being set in the mask.
- // Just like the original code, works for now.
- if (valuatorNum >= numValuatorValues)
+
+ int valuatorOffset = xi2ValuatorOffset(valuatorsMaskAddr, xideviceevent->valuators_len, valuatorNum);
+ if (valuatorOffset < 0)
return false;
- *value = valuatorsValuesAddr[valuatorNum].integral;
- *value += ((double)valuatorsValuesAddr[valuatorNum].frac / (1 << 16) / (1 << 16));
+
+ *value = valuatorsValuesAddr[valuatorOffset].integral;
+ *value += ((double)valuatorsValuesAddr[valuatorOffset].frac / (1 << 16) / (1 << 16));
return true;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index ba056a8006..71f5ce13fb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -69,9 +69,12 @@
struct XInput2MaemoData;
#elif XCB_USE_XINPUT2
#include <X11/extensions/XI2.h>
+#ifdef XIScrollClass
+#define XCB_USE_XINPUT21 // XI 2.1 adds smooth scrolling support
#ifdef XI_TouchBeginMask
#define XCB_USE_XINPUT22 // XI 2.2 adds multi-point touch support
#endif
+#endif
struct XInput2DeviceData;
#endif
struct xcb_randr_get_output_info_reply_t;
@@ -271,6 +274,10 @@ namespace QXcbAtom {
AbsDistance,
WacomSerialIDs,
INTEGER,
+ RelHorizWheel,
+ RelVertWheel,
+ RelHorizScroll,
+ RelVertScroll,
#if XCB_USE_MAEMO_WINDOW_PROPERTIES
MeegoTouchOrientationAngle,
@@ -499,10 +506,19 @@ private:
void xi2ReportTabletEvent(const TabletData &tabletData, void *event);
QVector<TabletData> m_tabletData;
#endif
+ struct ScrollingDevice {
+ ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0) { }
+ int deviceId;
+ int verticalIndex, horizontalIndex;
+ double verticalIncrement, horizontalIncrement;
+ Qt::Orientations orientations;
+ QPointF lastScrollPosition;
+ };
+ void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
+ QHash<int, ScrollingDevice> m_scrollingDevices;
#endif // XCB_USE_XINPUT2
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
- static int xi2CountBits(unsigned char *ptr, int len);
static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value);
static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode);
#endif
@@ -521,8 +537,6 @@ private:
QByteArray m_displayName;
- xcb_window_t m_connectionEventListener;
-
QXcbKeyboard *m_keyboard;
#ifndef QT_NO_CLIPBOARD
QXcbClipboard *m_clipboard;
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index a2ef8bf20f..d80b49ccbb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qxcbconnection.h"
+#include "qxcbkeyboard.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
#include "qtouchdevice.h"
@@ -75,16 +76,20 @@ void QXcbConnection::initializeXInput2()
#ifndef QT_NO_TABLETEVENT
m_tabletData.clear();
#endif
+ m_scrollingDevices.clear();
Display *xDisplay = static_cast<Display *>(m_xlib_display);
if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
int xiMajor = 2;
m_xi2Minor = 2; // try 2.2 first, needed for TouchBegin/Update/End
if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
- m_xi2Minor = 0; // for tablet support 2.0 is enough
- m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
- } else {
+ m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
+ m_xi2Minor = 0; // for tablet support 2.0 is enough
+ m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
+ } else
+ m_xi2Enabled = true;
+ } else
m_xi2Enabled = true;
- }
if (m_xi2Enabled) {
if (Q_UNLIKELY(debug_xinput_devices))
#ifdef XCB_USE_XINPUT22
@@ -103,6 +108,7 @@ void QXcbConnection::initializeXInput2()
#ifndef QT_NO_TABLETEVENT
TabletData tabletData;
#endif
+ ScrollingDevice scrollingDevice;
for (int c = 0; c < devices[i].num_classes; ++c) {
switch (devices[i].classes[c]->type) {
case XIValuatorClass: {
@@ -119,7 +125,29 @@ void QXcbConnection::initializeXInput2()
tabletData.valuatorInfo[valuatorAtom] = info;
}
#endif // QT_NO_TABLETEVENT
- } break;
+ if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
+ scrollingDevice.lastScrollPosition.setX(vci->value);
+ else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
+ scrollingDevice.lastScrollPosition.setY(vci->value);
+ break;
+ }
+#ifdef XCB_USE_XINPUT21
+ case XIScrollClass: {
+ XIScrollClassInfo *sci = reinterpret_cast<XIScrollClassInfo *>(devices[i].classes[c]);
+ scrollingDevice.deviceId = devices[i].deviceid;
+ if (sci->scroll_type == XIScrollTypeVertical) {
+ scrollingDevice.orientations |= Qt::Vertical;
+ scrollingDevice.verticalIndex = sci->number;
+ scrollingDevice.verticalIncrement = sci->increment;
+ }
+ else if (sci->scroll_type == XIScrollTypeHorizontal) {
+ scrollingDevice.orientations |= Qt::Horizontal;
+ scrollingDevice.horizontalIndex = sci->number;
+ scrollingDevice.horizontalIncrement = sci->increment;
+ }
+ break;
+ }
+#endif
default:
break;
}
@@ -140,6 +168,15 @@ void QXcbConnection::initializeXInput2()
qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
}
#endif // QT_NO_TABLETEVENT
+
+#ifdef XCB_USE_XINPUT21
+ if (scrollingDevice.orientations) {
+ m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice);
+ if (Q_UNLIKELY(debug_xinput_devices))
+ qDebug() << " it's a scrolling device";
+ }
+#endif
+
if (!isTablet) {
XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
if (Q_UNLIKELY(debug_xinput_devices)) {
@@ -181,7 +218,7 @@ void QXcbConnection::xi2Select(xcb_window_t window)
mask.mask_len = sizeof(bitMask);
mask.mask = xiBitMask;
// Enable each touchscreen
- foreach (XInput2DeviceData *dev, m_touchDevices.values()) {
+ foreach (XInput2DeviceData *dev, m_touchDevices) {
mask.deviceid = dev->xiDeviceInfo->deviceid;
Status result = XISelectEvents(xDisplay, window, &mask, 1);
// If we have XInput >= 2.2 and successfully enable a touchscreen, then
@@ -213,6 +250,22 @@ void QXcbConnection::xi2Select(xcb_window_t window)
XISelectEvents(xDisplay, window, xiEventMask.data(), m_tabletData.count());
}
#endif // QT_NO_TABLETEVENT
+
+#ifdef XCB_USE_XINPUT21
+ // Enable each scroll device
+ if (!m_scrollingDevices.isEmpty()) {
+ QVector<XIEventMask> xiEventMask(m_scrollingDevices.size());
+ bitMask = XI_MotionMask;
+ int i=0;
+ Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) {
+ xiEventMask[i].deviceid = scrollingDevice.deviceId;
+ xiEventMask[i].mask_len = sizeof(bitMask);
+ xiEventMask[i].mask = xiBitMask;
+ i++;
+ }
+ XISelectEvents(xDisplay, window, xiEventMask.data(), m_scrollingDevices.size());
+ }
+#endif
}
XInput2DeviceData *QXcbConnection::deviceForId(int id)
@@ -243,7 +296,8 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
type = QTouchDevice::TouchScreen;
break;
}
- } break;
+ break;
+ }
#endif // XCB_USE_XINPUT22
case XIValuatorClass: {
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo);
@@ -260,7 +314,8 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
hasRelativeCoords = true;
dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution);
}
- } break;
+ break;
+ }
}
}
if (type < 0 && caps && hasRelativeCoords) {
@@ -287,14 +342,14 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
return dev;
}
-#if defined(XCB_USE_XINPUT22) || !defined(QT_NO_TABLETEVENT)
+#if defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT)
static qreal fixed1616ToReal(FP1616 val)
{
return (qreal(val >> 16)) + (val & 0xFF) / (qreal)0xFF;
}
-#endif
+#endif // defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT)
-#ifdef XCB_USE_XINPUT22
+#if defined(XCB_USE_XINPUT21)
static qreal valuatorNormalized(double value, XIValuatorClassInfo *vci)
{
if (value > vci->max)
@@ -303,7 +358,7 @@ static qreal valuatorNormalized(double value, XIValuatorClassInfo *vci)
value = vci->min;
return (value - vci->min) / (vci->max - vci->min);
}
-#endif // XCB_USE_XINPUT22
+#endif // XCB_USE_XINPUT21
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
@@ -319,6 +374,12 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
#endif // QT_NO_TABLETEVENT
+#ifdef XCB_USE_XINPUT21
+ QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(xiEvent->deviceid);
+ if (device != m_scrollingDevices.end())
+ xi2HandleScrollEvent(xiEvent, device.value());
+#endif // XCB_USE_XINPUT21
+
#ifdef XCB_USE_XINPUT22
if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
@@ -463,6 +524,55 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
}
+void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice)
+{
+#ifdef XCB_USE_XINPUT21
+ xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
+
+ if (xiEvent->evtype == XI_Motion) {
+ xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
+ QPoint rawDelta;
+ QPoint angleDelta;
+ double value;
+ if (scrollingDevice.orientations & Qt::Vertical) {
+ if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice.verticalIndex, &value)) {
+ double delta = scrollingDevice.lastScrollPosition.y() - value;
+ scrollingDevice.lastScrollPosition.setY(value);
+ angleDelta.setY((delta / scrollingDevice.verticalIncrement) * 120);
+ // We do not set "pixel" delta if it is only measured in ticks.
+ if (scrollingDevice.verticalIncrement > 1)
+ rawDelta.setY(delta);
+ }
+ }
+ if (scrollingDevice.orientations & Qt::Horizontal) {
+ if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice.horizontalIndex, &value)) {
+ double delta = scrollingDevice.lastScrollPosition.x() - value;
+ scrollingDevice.lastScrollPosition.setX(value);
+ angleDelta.setX((delta / scrollingDevice.horizontalIncrement) * 120);
+ // We do not set "pixel" delta if it is only measured in ticks.
+ if (scrollingDevice.horizontalIncrement > 1)
+ rawDelta.setX(delta);
+ }
+ }
+ if (!angleDelta.isNull()) {
+ 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());
+ std::swap(rawDelta.rx(), rawDelta.ry());
+ }
+ QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers);
+ }
+ }
+ }
+#else
+ Q_UNUSED(event);
+ Q_UNUSED(scrollingDevice);
+#endif // XCB_USE_XINPUT21
+}
+
#ifndef QT_NO_TABLETEVENT
bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
{
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 15e5bf27f1..ce9e445ba2 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -549,7 +549,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
void *dpy = connection()->xlib_display();
// special case for non-standard dnd-* cursors
cursor = loadCursor(dpy, cshape);
- if (!cursor && !m_gtkCursorThemeInitialized) {
+ if (!cursor && !m_gtkCursorThemeInitialized && m_screen->xSettings()->initialized()) {
QByteArray gtkCursorTheme = m_screen->xSettings()->setting("Gtk/CursorThemeName").toByteArray();
m_screen->xSettings()->registerCallbackForProperty("Gtk/CursorThemeName",cursorThemePropertyChanged,this);
if (updateCursorTheme(dpy,gtkCursorTheme)) {
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index d18693f6b8..61dfe8ac17 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -593,9 +593,9 @@ static Window findXdndAwareParent(Window window)
unsigned char *data = 0;
if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
- if (data)
+ if (data)
XFree(data);
- if (type) {
+ if (type) {
target = window;
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 2529fb8a83..966090dbd5 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -117,7 +117,7 @@
#define XF86XK_KbdBrightnessUp 0x1008FF05
#define XF86XK_KbdBrightnessDown 0x1008FF06
#define XF86XK_Standby 0x1008FF10
-#define XF86XK_AudioLowerVolume 0x1008FF11
+#define XF86XK_AudioLowerVolume 0x1008FF11
#define XF86XK_AudioMute 0x1008FF12
#define XF86XK_AudioRaiseVolume 0x1008FF13
#define XF86XK_AudioPlay 0x1008FF14
@@ -344,65 +344,65 @@ static const unsigned int KeyTbl[] = {
// International & multi-key character composition
XK_ISO_Level3_Shift, Qt::Key_AltGr,
- XK_Multi_key, Qt::Key_Multi_key,
- XK_Codeinput, Qt::Key_Codeinput,
- XK_SingleCandidate, Qt::Key_SingleCandidate,
- XK_MultipleCandidate, Qt::Key_MultipleCandidate,
- XK_PreviousCandidate, Qt::Key_PreviousCandidate,
+ XK_Multi_key, Qt::Key_Multi_key,
+ XK_Codeinput, Qt::Key_Codeinput,
+ XK_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_MultipleCandidate, Qt::Key_MultipleCandidate,
+ XK_PreviousCandidate, Qt::Key_PreviousCandidate,
// Misc Functions
- XK_Mode_switch, Qt::Key_Mode_switch,
- XK_script_switch, Qt::Key_Mode_switch,
+ XK_Mode_switch, Qt::Key_Mode_switch,
+ XK_script_switch, Qt::Key_Mode_switch,
// Japanese keyboard support
- XK_Kanji, Qt::Key_Kanji,
- XK_Muhenkan, Qt::Key_Muhenkan,
- //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
- XK_Henkan_Mode, Qt::Key_Henkan,
- XK_Henkan, Qt::Key_Henkan,
- XK_Romaji, Qt::Key_Romaji,
- XK_Hiragana, Qt::Key_Hiragana,
- XK_Katakana, Qt::Key_Katakana,
- XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
- XK_Zenkaku, Qt::Key_Zenkaku,
- XK_Hankaku, Qt::Key_Hankaku,
- XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
- XK_Touroku, Qt::Key_Touroku,
- XK_Massyo, Qt::Key_Massyo,
- XK_Kana_Lock, Qt::Key_Kana_Lock,
- XK_Kana_Shift, Qt::Key_Kana_Shift,
- XK_Eisu_Shift, Qt::Key_Eisu_Shift,
- XK_Eisu_toggle, Qt::Key_Eisu_toggle,
- //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
- //XK_Zen_Koho, Qt::Key_Zen_Koho,
- //XK_Mae_Koho, Qt::Key_Mae_Koho,
- XK_Kanji_Bangou, Qt::Key_Codeinput,
- XK_Zen_Koho, Qt::Key_MultipleCandidate,
- XK_Mae_Koho, Qt::Key_PreviousCandidate,
+ XK_Kanji, Qt::Key_Kanji,
+ XK_Muhenkan, Qt::Key_Muhenkan,
+ //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
+ XK_Henkan_Mode, Qt::Key_Henkan,
+ XK_Henkan, Qt::Key_Henkan,
+ XK_Romaji, Qt::Key_Romaji,
+ XK_Hiragana, Qt::Key_Hiragana,
+ XK_Katakana, Qt::Key_Katakana,
+ XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
+ XK_Zenkaku, Qt::Key_Zenkaku,
+ XK_Hankaku, Qt::Key_Hankaku,
+ XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
+ XK_Touroku, Qt::Key_Touroku,
+ XK_Massyo, Qt::Key_Massyo,
+ XK_Kana_Lock, Qt::Key_Kana_Lock,
+ XK_Kana_Shift, Qt::Key_Kana_Shift,
+ XK_Eisu_Shift, Qt::Key_Eisu_Shift,
+ XK_Eisu_toggle, Qt::Key_Eisu_toggle,
+ //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
+ //XK_Zen_Koho, Qt::Key_Zen_Koho,
+ //XK_Mae_Koho, Qt::Key_Mae_Koho,
+ XK_Kanji_Bangou, Qt::Key_Codeinput,
+ XK_Zen_Koho, Qt::Key_MultipleCandidate,
+ XK_Mae_Koho, Qt::Key_PreviousCandidate,
#ifdef XK_KOREAN
// Korean keyboard support
- XK_Hangul, Qt::Key_Hangul,
- XK_Hangul_Start, Qt::Key_Hangul_Start,
- XK_Hangul_End, Qt::Key_Hangul_End,
- XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
- XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
- XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
- //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
- XK_Hangul_Codeinput, Qt::Key_Codeinput,
- XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
- XK_Hangul_Banja, Qt::Key_Hangul_Banja,
- XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
- XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
+ XK_Hangul, Qt::Key_Hangul,
+ XK_Hangul_Start, Qt::Key_Hangul_Start,
+ XK_Hangul_End, Qt::Key_Hangul_End,
+ XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
+ XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
+ XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
+ //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
+ XK_Hangul_Codeinput, Qt::Key_Codeinput,
+ XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
+ XK_Hangul_Banja, Qt::Key_Hangul_Banja,
+ XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
+ XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
//XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
//XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
//XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
- XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
- XK_Hangul_Special, Qt::Key_Hangul_Special,
- //XK_Hangul_switch, Qt::Key_Hangul_switch,
- XK_Hangul_switch, Qt::Key_Mode_switch,
+ XK_Hangul_Special, Qt::Key_Hangul_Special,
+ //XK_Hangul_switch, Qt::Key_Hangul_switch,
+ XK_Hangul_switch, Qt::Key_Mode_switch,
#endif // XK_KOREAN
// dead keys
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index 9d81c8e224..0098f47e33 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -50,6 +50,7 @@
#include <X11/SM/SMlib.h>
#include <errno.h> // ERANGE
+#include <cerrno> // ERANGE
class QSmSocketReceiver : public QObject
{
@@ -390,16 +391,6 @@ void* QXcbSessionManager::handle() const
return (void*) smcConnection;
}
-void QXcbSessionManager::setSessionId(const QString &id)
-{
- m_sessionId = id;
-}
-
-void QXcbSessionManager::setSessionKey(const QString &key)
-{
- m_sessionKey = key;
-}
-
bool QXcbSessionManager::allowsInteraction()
{
if (sm_interactionActive)
@@ -495,16 +486,6 @@ void QXcbSessionManager::requestPhase2()
sm_phase2 = true;
}
-void QXcbSessionManager::appCommitData()
-{
- QPlatformSessionManager::appCommitData();
-}
-
-void QXcbSessionManager::appSaveState()
-{
- QPlatformSessionManager::appSaveState();
-}
-
void QXcbSessionManager::exitEventLoop()
{
m_eventLoop->exit();
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.h b/src/plugins/platforms/xcb/qxcbsessionmanager.h
index 28eb287097..3c7c968890 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.h
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.h
@@ -66,8 +66,8 @@ public:
void *handle() const;
- void setSessionId(const QString &id);
- void setSessionKey(const QString &key);
+ void setSessionId(const QString &id) { m_sessionId = id; }
+ void setSessionKey(const QString &key) { m_sessionKey = key; }
bool allowsInteraction() Q_DECL_OVERRIDE;
bool allowsErrorInteraction() Q_DECL_OVERRIDE;
@@ -81,9 +81,6 @@ public:
bool isPhase2() const Q_DECL_OVERRIDE;
void requestPhase2() Q_DECL_OVERRIDE;
- void appCommitData() Q_DECL_OVERRIDE;
- void appSaveState() Q_DECL_OVERRIDE;
-
void exitEventLoop();
private:
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 3d8f91649a..3d79f742b3 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -297,7 +297,7 @@ void QXcbWindow::create()
#elif defined(XCB_USE_EGL)
EGLDisplay eglDisplay = connection()->egl_display();
EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, m_format, true);
- m_format = q_glFormatFromConfig(eglDisplay, eglConfig);
+ m_format = q_glFormatFromConfig(eglDisplay, eglConfig, m_format);
VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
@@ -672,8 +672,6 @@ void QXcbWindow::show()
m_screen->windowShown(this);
- xcb_flush(xcb_connection());
-
connection()->sync();
}
@@ -1586,6 +1584,16 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(window(), rect);
+ if (!m_screen->availableGeometry().intersects(rect)) {
+ Q_FOREACH (QPlatformScreen* screen, m_screen->virtualSiblings()) {
+ if (screen->availableGeometry().intersects(rect)) {
+ m_screen = static_cast<QXcbScreen*>(screen);
+ QWindowSystemInterface::handleWindowScreenChanged(window(), m_screen->QPlatformScreen::screen());
+ break;
+ }
+ }
+ }
+
m_configureNotifyPending = false;
if (m_deferredExpose) {
@@ -1695,6 +1703,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
if (isWheel) {
+#ifndef XCB_USE_XINPUT21
// Logic borrowed from qapplication_x11.cpp
int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1);
bool hor = (((event->detail == 4 || event->detail == 5)
@@ -1703,6 +1712,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
QWindowSystemInterface::handleWheelEvent(window(), event->time,
local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers);
+#endif
return;
}
@@ -1893,7 +1903,6 @@ void QXcbWindow::updateSyncRequestCounter()
{
if (m_usingSyncProtocol && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
- xcb_flush(xcb_connection());
connection()->sync();
m_syncValue.lo = 0;
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index 8679d502d9..141a6cc0cb 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -99,6 +99,7 @@ class QXcbXSettingsPrivate
public:
QXcbXSettingsPrivate(QXcbScreen *screen)
: screen(screen)
+ , initialized(false)
{
}
@@ -202,6 +203,7 @@ public:
QXcbScreen *screen;
xcb_window_t x_settings_window;
QMap<QByteArray, QXcbXSettingsPropertyValue> settings;
+ bool initialized;
};
@@ -217,7 +219,6 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
xcb_generic_error_t *error = 0;
xcb_intern_atom_reply_t *atom_reply = xcb_intern_atom_reply(screen->xcb_connection(),atom_cookie,&error);
if (error) {
- qWarning() << Q_FUNC_INFO << "Failed to find XSETTINGS_S atom";
free(error);
return;
}
@@ -230,7 +231,6 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
xcb_get_selection_owner_reply_t *selection_result =
xcb_get_selection_owner_reply(screen->xcb_connection(), selection_cookie, &error);
if (error) {
- qWarning() << Q_FUNC_INFO << "Failed to get selection owner for XSETTINGS_S atom";
free(error);
return;
}
@@ -246,6 +246,13 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
xcb_change_window_attributes(screen->xcb_connection(),d_ptr->x_settings_window,event,event_mask);
d_ptr->populateSettings(d_ptr->getSettings());
+ d_ptr->initialized = true;
+}
+
+bool QXcbXSettings::initialized() const
+{
+ Q_D(const QXcbXSettings);
+ return d->initialized;
}
void QXcbXSettings::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.h b/src/plugins/platforms/xcb/qxcbxsettings.h
index 16fed862bc..f6a07a6091 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.h
+++ b/src/plugins/platforms/xcb/qxcbxsettings.h
@@ -53,6 +53,7 @@ class QXcbXSettings : public QXcbWindowEventListener
Q_DECLARE_PRIVATE(QXcbXSettings)
public:
QXcbXSettings(QXcbScreen *screen);
+ bool initialized() const;
QVariant setting(const QByteArray &property) const;
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index 8968d020c4..67f2d8a911 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -42,7 +42,7 @@ HEADERS = \
qxcbxsettings.h \
qxcbsystemtraytracker.h
-LIBS += -ldl
+LIBS += $$QMAKE_LIBS_DYNLOAD
# needed by GLX, Xcursor ...
contains(QT_CONFIG, xcb-xlib) {
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 6f4bca63be..942db329ca 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -1,7 +1,7 @@
TEMPLATE = subdirs
SUBDIRS *= sqldrivers
-qtHaveModule(network): SUBDIRS += bearer
+!winrt:qtHaveModule(network): SUBDIRS += bearer
qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts platformthemes generic
qtHaveModule(widgets): SUBDIRS += accessible
diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp
index 1c86420cb2..2fecdc00e9 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp
@@ -221,7 +221,7 @@ void QCupsPrintEnginePrivate::closePrintDevice()
if (copies > 1)
options.append(QPair<QByteArray, QByteArray>("copies", QString::number(copies).toLocal8Bit()));
- if (collate)
+ if (copies > 1 && collate)
options.append(QPair<QByteArray, QByteArray>("Collate", "True"));
switch (duplex) {