summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-09-13 08:54:45 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-09-13 08:54:45 +0200
commitb62bd0584a7872b6917917009b707785b3abd077 (patch)
tree9981f274712c098cabbff0c4667672a3934e5393 /src/plugins
parent5e10745dca1d10025404a9f268f03ae697fb10cc (diff)
parent97baad65f65783d2b5ff938f6217aec9434f2e5f (diff)
Merge branch 'refactor'
Conflicts: mkspecs/qws/linux-lsb-g++/qmake.conf src/gui/image/qpixmap_mac.cpp src/gui/painting/qpaintengine_x11.cpp src/gui/painting/qtessellator.cpp src/gui/text/qfontengine_qws.cpp src/gui/text/qfontengine_x11.cpp src/gui/widgets/qlinecontrol.cpp src/opengl/qgl.h src/opengl/qgl_x11egl.cpp src/plugins/plugins.pro Change-Id: If52dcd55cd55f2983a756c2f843967702b60a310
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/accessible/widgets/complexwidgets.h6
-rw-r--r--src/plugins/accessible/widgets/itemviews.h10
-rw-r--r--src/plugins/accessible/widgets/qaccessiblemenu.cpp2
-rw-r--r--src/plugins/accessible/widgets/qaccessiblemenu.h2
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp2
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.h4
-rw-r--r--src/plugins/accessible/widgets/rangecontrols.h4
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h4
-rw-r--r--src/plugins/accessible/widgets/widgets.pro2
-rw-r--r--src/plugins/decorations/decorations.pro4
-rw-r--r--src/plugins/decorations/default/default.pro10
-rw-r--r--src/plugins/decorations/styled/styled.pro13
-rw-r--r--src/plugins/decorations/windows/windows.pro10
-rw-r--r--src/plugins/generic/linuxinput/linuxinput.pro6
-rw-r--r--src/plugins/generic/linuxinput/main.cpp5
-rw-r--r--src/plugins/generic/linuxinput/qlinuxinput.cpp192
-rw-r--r--src/plugins/generic/linuxinput/qlinuxinput.h25
-rw-r--r--src/plugins/gfxdrivers/ahi/ahi.pro14
-rw-r--r--src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp598
-rw-r--r--src/plugins/gfxdrivers/directfb/directfb.pro15
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp436
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp294
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp221
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h108
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp1430
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h123
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp588
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h105
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp1819
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h303
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp506
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h129
-rw-r--r--src/plugins/gfxdrivers/eglnullws/README48
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullws.pro18
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp181
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h69
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp66
-rw-r--r--src/plugins/gfxdrivers/gfxdrivers.pro10
-rw-r--r--src/plugins/gfxdrivers/linuxfb/linuxfb.pro14
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro26
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c830
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h169
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h132
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c402
-rw-r--r--src/plugins/gfxdrivers/powervr/README66
-rw-r--r--src/plugins/gfxdrivers/powervr/powervr.pri2
-rw-r--r--src/plugins/gfxdrivers/powervr/powervr.pro3
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp351
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro27
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreenplugin.cpp74
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp273
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h85
-rw-r--r--src/plugins/gfxdrivers/qvfb/main.cpp82
-rw-r--r--src/plugins/gfxdrivers/qvfb/qvfb.pro19
-rw-r--r--src/plugins/gfxdrivers/transformed/main.cpp84
-rw-r--r--src/plugins/gfxdrivers/transformed/transformed.pro13
-rw-r--r--src/plugins/gfxdrivers/vnc/main.cpp86
-rw-r--r--src/plugins/gfxdrivers/vnc/qscreenvnc_p.h524
-rw-r--r--src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp2338
-rw-r--r--src/plugins/gfxdrivers/vnc/vnc.pro16
-rw-r--r--src/plugins/graphicssystems/graphicssystems.pro15
-rw-r--r--src/plugins/graphicssystems/meego/dithering.cpp266
-rw-r--r--src/plugins/graphicssystems/meego/meego.pro13
-rw-r--r--src/plugins/graphicssystems/meego/qmeegoextensions.cpp213
-rw-r--r--src/plugins/graphicssystems/meego/qmeegoextensions.h125
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.cpp534
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.h127
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp323
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h78
-rw-r--r--src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp224
-rw-r--r--src/plugins/graphicssystems/meego/qmeegopixmapdata.h74
-rw-r--r--src/plugins/graphicssystems/opengl/opengl.pro13
-rw-r--r--src/plugins/graphicssystems/openvg/openvg.pro14
-rw-r--r--src/plugins/graphicssystems/shivavg/README8
-rw-r--r--src/plugins/graphicssystems/shivavg/shivavg.pro12
-rw-r--r--src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp358
-rw-r--r--src/plugins/graphicssystems/trace/main.cpp69
-rw-r--r--src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp153
-rw-r--r--src/plugins/graphicssystems/trace/trace.pro13
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp1
-rw-r--r--src/plugins/inputmethods/imsw-multi/imsw-multi.pro13
-rw-r--r--src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp212
-rw-r--r--src/plugins/inputmethods/imsw-multi/qmultiinputcontext.h117
-rw-r--r--src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp111
-rw-r--r--src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.h85
-rw-r--r--src/plugins/inputmethods/inputmethods.pro3
-rw-r--r--src/plugins/kbddrivers/kbddrivers.pro2
-rw-r--r--src/plugins/kbddrivers/linuxinput/linuxinput.pro14
-rw-r--r--src/plugins/kbddrivers/linuxinput/main.cpp77
-rw-r--r--src/plugins/mousedrivers/linuxtp/linuxtp.pro14
-rw-r--r--src/plugins/mousedrivers/linuxtp/main.cpp76
-rw-r--r--src/plugins/mousedrivers/mousedrivers.pro5
-rw-r--r--src/plugins/mousedrivers/pc/main.cpp81
-rw-r--r--src/plugins/mousedrivers/pc/pc.pro14
-rw-r--r--src/plugins/mousedrivers/tslib/main.cpp77
-rw-r--r--src/plugins/mousedrivers/tslib/tslib.pro16
-rw-r--r--src/plugins/platforminputcontexts/ibus/ibus.pro19
-rw-r--r--src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.InputContext.xml80
-rw-r--r--src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.xml30
-rw-r--r--src/plugins/platforminputcontexts/ibus/main.cpp (renamed from src/plugins/gfxdrivers/linuxfb/main.cpp)34
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.cpp26
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h144
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp329
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h74
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusproxy.cpp26
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusproxy.h88
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibustypes.cpp209
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibustypes.h (renamed from src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h)93
-rw-r--r--src/plugins/platforminputcontexts/platforminputcontexts.pro4
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro42
-rw-r--r--src/plugins/platforms/cocoa/images/copyarrowcursor.pngbin0 -> 1976 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/forbiddencursor.pngbin0 -> 1745 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.pngbin0 -> 356 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/pluscursor.pngbin0 -> 688 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/spincursor.pngbin0 -> 748 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/waitcursor.pngbin0 -> 724 bytes
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.h116
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm227
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h127
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm354
-rw-r--r--src/plugins/platforms/cocoa/qcocoaautoreleasepool.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h (renamed from src/plugins/platforms/cocoa/qcocoawindowsurface.h)18
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm (renamed from src/plugins/platforms/cocoa/qcocoawindowsurface.mm)27
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h220
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm1123
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm112
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h43
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm99
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h90
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm448
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h16
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm92
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h (renamed from src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp)60
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm267
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h (renamed from src/plugins/decorations/styled/main.cpp)76
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm314
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h (renamed from src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h)16
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm (renamed from src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp)29
-rw-r--r--src/plugins/platforms/cocoa/qcocoaresources.qrc17
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h37
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm318
-rw-r--r--src/plugins/platforms/cocoa/qmenu_mac.h85
-rw-r--r--src/plugins/platforms/cocoa/qmenu_mac.mm1274
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h11
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm193
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h21
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm12
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/classes.nib59
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/info.nib18
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nibbin0 -> 5560 bytes
-rw-r--r--src/plugins/platforms/directfb/directfb.pro10
-rw-r--r--src/plugins/platforms/directfb/qdirectfbblitter.cpp6
-rw-r--r--src/plugins/platforms/directfb/qdirectfbblitter.h2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp4
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.h2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbcursor.cpp21
-rw-r--r--src/plugins/platforms/directfb/qdirectfbcursor.h8
-rw-r--r--src/plugins/platforms/directfb/qdirectfbglcontext.cpp4
-rw-r--r--src/plugins/platforms/directfb/qdirectfbglcontext.h4
-rw-r--r--src/plugins/platforms/directfb/qdirectfbinput.cpp13
-rw-r--r--src/plugins/platforms/directfb/qdirectfbinput.h4
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.cpp66
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.h22
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.cpp48
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.h6
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp17
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindowsurface.h12
-rw-r--r--src/plugins/platforms/eglconvenience/eglconvenience.pri7
-rw-r--r--src/plugins/platforms/eglconvenience/qeglconvenience.cpp324
-rw-r--r--src/plugins/platforms/eglconvenience/qeglconvenience.h60
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp157
-rw-r--r--src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp184
-rw-r--r--src/plugins/platforms/eglconvenience/xlibeglintegration.pri7
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pro12
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.cpp (renamed from src/plugins/platforms/eglfs/qeglfswindowsurface.cpp)31
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.h (renamed from src/plugins/platforms/eglfs/qeglfswindowsurface.h)13
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp44
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h11
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp50
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h8
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp30
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h7
-rw-r--r--src/plugins/platforms/externalplugin.pri29
-rw-r--r--src/plugins/platforms/fb_base/fb_base.cpp507
-rw-r--r--src/plugins/platforms/fb_base/fb_base.h210
-rw-r--r--src/plugins/platforms/fb_base/fb_base.pri2
-rw-r--r--src/plugins/platforms/fb_base/fb_base.pro23
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/basicunix.pri88
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp355
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h67
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri12
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp604
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h56
-rw-r--r--src/plugins/platforms/fontdatabases/genericunix/genericunix.pri10
-rw-r--r--src/plugins/platforms/glxconvenience/glxconvenience.pri15
-rw-r--r--src/plugins/platforms/glxconvenience/qglxconvenience.cpp257
-rw-r--r--src/plugins/platforms/glxconvenience/qglxconvenience.h56
-rw-r--r--src/plugins/platforms/kms/kms.pro42
-rw-r--r--src/plugins/platforms/kms/main.cpp (renamed from src/plugins/graphicssystems/openvg/main.cpp)21
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.cpp (renamed from src/plugins/decorations/windows/main.cpp)36
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.h (renamed from src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h)19
-rw-r--r--src/plugins/platforms/kms/qkmsbuffermanager.cpp198
-rw-r--r--src/plugins/platforms/kms/qkmsbuffermanager.h105
-rw-r--r--src/plugins/platforms/kms/qkmscontext.cpp113
-rw-r--r--src/plugins/platforms/kms/qkmscontext.h75
-rw-r--r--src/plugins/platforms/kms/qkmscursor.cpp131
-rw-r--r--src/plugins/platforms/kms/qkmscursor.h (renamed from src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h)36
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.cpp163
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.h (renamed from src/plugins/platforms/eglconvenience/qeglplatformcontext.h)52
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp139
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h82
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.cpp224
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.h97
-rw-r--r--src/plugins/platforms/kms/qkmswindow.cpp (renamed from src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp)22
-rw-r--r--src/plugins/platforms/kms/qkmswindow.h (renamed from src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h)22
-rw-r--r--src/plugins/platforms/linuxfb/linuxfb.pro2
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp10
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h4
-rw-r--r--src/plugins/platforms/minimal/minimal.pro6
-rw-r--r--src/plugins/platforms/minimal/qminimalbackingstore.cpp (renamed from src/plugins/platforms/minimal/qminimalwindowsurface.cpp)30
-rw-r--r--src/plugins/platforms/minimal/qminimalbackingstore.h (renamed from src/plugins/platforms/minimal/qminimalwindowsurface.h)18
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.cpp37
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.h10
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.cpp6
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.h4
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindow.cpp4
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindow.h2
-rw-r--r--src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp14
-rw-r--r--src/plugins/platforms/openvglite/qgraphicssystem_vglite.h2
-rw-r--r--src/plugins/platforms/openwfd/main.cpp (renamed from src/plugins/graphicssystems/shivavg/main.cpp)21
-rw-r--r--src/plugins/platforms/openwfd/openwf.pro41
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdbackingstore.cpp25
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdbackingstore.h (renamed from src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h)30
-rw-r--r--src/plugins/platforms/openwfd/qopenwfddevice.cpp317
-rw-r--r--src/plugins/platforms/openwfd/qopenwfddevice.h113
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdevent.cpp (renamed from src/plugins/platforms/eglconvenience/qxlibeglintegration.h)13
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdevent.h (renamed from src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h)12
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdglcontext.cpp (renamed from src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp)73
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdglcontext.h (renamed from src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h)31
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdintegration.cpp145
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdintegration.h86
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdnativeinterface.cpp141
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdnativeinterface.h (renamed from src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h)47
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdoutputbuffer.cpp (renamed from src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h)61
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdoutputbuffer.h69
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdport.cpp212
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdport.h89
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdportmode.cpp (renamed from src/plugins/gfxdrivers/ahi/qscreenahiplugin.cpp)39
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdportmode.h74
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdscreen.cpp192
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdscreen.h91
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdwindow.cpp (renamed from src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp)23
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdwindow.h61
-rw-r--r--src/plugins/platforms/platforms.pro6
-rw-r--r--src/plugins/platforms/qvfb/qvfb.pro1
-rw-r--r--src/plugins/platforms/qvfb/qvfbintegration.cpp10
-rw-r--r--src/plugins/platforms/qvfb/qvfbintegration.h4
-rw-r--r--src/plugins/platforms/uikit/quikitintegration.h2
-rw-r--r--src/plugins/platforms/uikit/quikitintegration.mm4
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.h2
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.mm10
-rw-r--r--src/plugins/platforms/uikit/uikit.pro4
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.cpp8
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h5
-rw-r--r--src/plugins/platforms/vnc/qvncserver.cpp2
-rw-r--r--src/plugins/platforms/vnc/vnc.pro2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/gl_integration.pri13
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h8
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp184
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp106
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h72
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp (renamed from src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp)44
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h (renamed from src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h)42
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp (renamed from src/plugins/graphicssystems/opengl/main.cpp)87
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h (renamed from src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h)42
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri10
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp18
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h7
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h6
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp101
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h31
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h18
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp25
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h11
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp81
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h22
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp74
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h32
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp123
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h32
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h7
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp100
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h22
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp110
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h37
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp23
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp95
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h24
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h4
-rw-r--r--src/plugins/platforms/wayland/main.cpp7
-rw-r--r--src/plugins/platforms/wayland/qwaylandclipboard.cpp2
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.cpp73
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.h14
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp20
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylanddnd.cpp423
-rw-r--r--src/plugins/platforms/wayland/qwaylanddnd.h86
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp12
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.h1
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp87
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h17
-rw-r--r--src/plugins/platforms/wayland/qwaylandnativeinterface.cpp19
-rw-r--r--src/plugins/platforms/wayland/qwaylandnativeinterface.h6
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.cpp5
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp (renamed from src/plugins/platforms/wayland/qwaylandshmsurface.cpp)30
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmbackingstore.h (renamed from src/plugins/platforms/wayland/qwaylandshmsurface.h)18
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.cpp10
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.h4
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp12
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h2
-rw-r--r--src/plugins/platforms/wayland/wayland.pro27
-rw-r--r--src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp17
-rw-r--r--src/plugins/platforms/windows/array.h103
-rw-r--r--src/plugins/platforms/windows/main.cpp (renamed from src/plugins/decorations/default/main.cpp)74
-rw-r--r--src/plugins/platforms/windows/pixmaputils.cpp316
-rw-r--r--src/plugins/platforms/windows/pixmaputils.h71
-rw-r--r--src/plugins/platforms/windows/qtwindows_additional.h121
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h182
-rw-r--r--src/plugins/platforms/windows/qwindows.qdocconf27
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp143
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h77
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp366
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.h94
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp750
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h172
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp451
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h93
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp721
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h116
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp950
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.h107
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp1223
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h186
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp737
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h133
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp971
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h165
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp215
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.h (renamed from src/plugins/gfxdrivers/ahi/qscreenahi_qws.h)45
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp598
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.h98
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp271
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h80
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.h (renamed from src/plugins/gfxdrivers/directfb/qdirectfbmouse.h)39
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp1075
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.h114
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp1557
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.h102
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp288
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h115
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.cpp151
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.h82
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp476
-rw-r--r--src/plugins/platforms/windows/qwindowsole.h127
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp230
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h100
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp1317
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h284
-rw-r--r--src/plugins/platforms/windows/windows.pro70
-rw-r--r--src/plugins/platforms/xcb/README2
-rw-r--r--src/plugins/platforms/xcb/main.cpp5
-rw-r--r--src/plugins/platforms/xcb/qdri2context.cpp8
-rw-r--r--src/plugins/platforms/xcb/qdri2context.h4
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp61
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h26
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp (renamed from src/plugins/platforms/xcb/qxcbwindowsurface.cpp)121
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.h (renamed from src/plugins/platforms/xcb/qxcbwindowsurface.h)16
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp848
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.h108
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp474
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h109
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp546
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h71
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp1332
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h158
-rw-r--r--src/plugins/platforms/xcb/qxcbeglsurface.h68
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.cpp266
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.h (renamed from src/plugins/gfxdrivers/vnc/qscreenvnc_qws.h)56
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp177
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h28
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp219
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h13
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.cpp288
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.h68
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp95
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h18
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp220
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h14
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp950
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h62
-rw-r--r--src/plugins/platforms/xcb/qxcbwmsupport.cpp136
-rw-r--r--src/plugins/platforms/xcb/qxcbwmsupport.h (renamed from src/plugins/platforms/cocoa/qcocoaeventloopintegration.h)34
-rw-r--r--src/plugins/platforms/xcb/xcb.pro103
-rw-r--r--src/plugins/platforms/xlib/main.cpp9
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.cpp51
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.h24
-rw-r--r--src/plugins/platforms/xlib/qxlibbackingstore.cpp (renamed from src/plugins/platforms/xlib/qxlibwindowsurface.cpp)58
-rw-r--r--src/plugins/platforms/xlib/qxlibbackingstore.h (renamed from src/plugins/platforms/xlib/qxlibwindowsurface.h)17
-rw-r--r--src/plugins/platforms/xlib/qxlibclipboard.cpp4
-rw-r--r--src/plugins/platforms/xlib/qxlibcursor.cpp7
-rw-r--r--src/plugins/platforms/xlib/qxlibcursor.h2
-rw-r--r--src/plugins/platforms/xlib/qxlibintegration.cpp103
-rw-r--r--src/plugins/platforms/xlib/qxlibintegration.h15
-rw-r--r--src/plugins/platforms/xlib/qxlibkeyboard.cpp2
-rw-r--r--src/plugins/platforms/xlib/qxlibkeyboard.h2
-rw-r--r--src/plugins/platforms/xlib/qxlibnativeinterface.cpp48
-rw-r--r--src/plugins/platforms/xlib/qxlibnativeinterface.h16
-rw-r--r--src/plugins/platforms/xlib/qxlibscreen.cpp54
-rw-r--r--src/plugins/platforms/xlib/qxlibscreen.h4
-rw-r--r--src/plugins/platforms/xlib/qxlibstatic.cpp5
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.cpp141
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.h20
-rw-r--r--src/plugins/platforms/xlib/xlib.pro24
-rw-r--r--src/plugins/plugins.pro15
439 files changed, 34097 insertions, 22583 deletions
diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h
index c6453f19c4..3c01445091 100644
--- a/src/plugins/accessible/widgets/complexwidgets.h
+++ b/src/plugins/accessible/widgets/complexwidgets.h
@@ -43,9 +43,9 @@
#define COMPLEXWIDGETS_H
#include <QtCore/qpointer.h>
-#include <QtGui/qaccessiblewidget.h>
-#include <QtGui/qabstractitemview.h>
-#include <QtGui/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
+#include <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qaccessible2.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h
index c8492e3c89..2c981ef0e8 100644
--- a/src/plugins/accessible/widgets/itemviews.h
+++ b/src/plugins/accessible/widgets/itemviews.h
@@ -42,11 +42,11 @@
#ifndef ACCESSIBLE_ITEMVIEWS_H
#define ACCESSIBLE_ITEMVIEWS_H
-#include <QtGui/qabstractitemview.h>
-#include <QtGui/qheaderview.h>
-#include <QtGui/qaccessible.h>
-#include <QtGui/qaccessible2.h>
-#include <QtGui/qaccessiblewidget.h>
+#include <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qheaderview.h>
+#include <QtWidgets/qaccessible.h>
+#include <QtWidgets/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp
index 1454c7c80b..8e72910b45 100644
--- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp
@@ -43,7 +43,7 @@
#include <qmenu.h>
#include <qmenubar.h>
-#include <QtGui/QAction>
+#include <QtWidgets/QAction>
#include <qstyle.h>
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h
index 680594d667..1ee6d5436f 100644
--- a/src/plugins/accessible/widgets/qaccessiblemenu.h
+++ b/src/plugins/accessible/widgets/qaccessiblemenu.h
@@ -42,7 +42,7 @@
#ifndef QACCESSIBLEMENU_H
#define QACCESSIBLEMENU_H
-#include <QtGui/qaccessiblewidget.h>
+#include <QtWidgets/qaccessiblewidget.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index a0dde37ed6..a8f38b61a3 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -65,7 +65,7 @@
#include <QMainWindow>
#include <QAbstractButton>
#include <private/qdockwidget_p.h>
-#include <QtGui/QFocusFrame>
+#include <QFocusFrame>
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h
index 242f8c1610..942012896b 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.h
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h
@@ -42,8 +42,8 @@
#ifndef QACCESSIBLEWIDGETS_H
#define QACCESSIBLEWIDGETS_H
-#include <QtGui/qaccessible2.h>
-#include <QtGui/qaccessiblewidget.h>
+#include <QtWidgets/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/rangecontrols.h b/src/plugins/accessible/widgets/rangecontrols.h
index 0f21a5a119..529a331c94 100644
--- a/src/plugins/accessible/widgets/rangecontrols.h
+++ b/src/plugins/accessible/widgets/rangecontrols.h
@@ -42,8 +42,8 @@
#ifndef RANGECONTROLS_H
#define RANGECONTROLS_H
-#include <QtGui/qaccessiblewidget.h>
-#include <QtGui/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
+#include <QtWidgets/qaccessible2.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h
index d5144caebd..7cc14410cf 100644
--- a/src/plugins/accessible/widgets/simplewidgets.h
+++ b/src/plugins/accessible/widgets/simplewidgets.h
@@ -43,8 +43,8 @@
#define SIMPLEWIDGETS_H
#include <QtCore/qcoreapplication.h>
-#include <QtGui/qaccessible2.h>
-#include <QtGui/qaccessiblewidget.h>
+#include <QtWidgets/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro
index d1a121ec94..3bf7dede56 100644
--- a/src/plugins/accessible/widgets/widgets.pro
+++ b/src/plugins/accessible/widgets/widgets.pro
@@ -2,7 +2,7 @@ TARGET = qtaccessiblewidgets
load(qt_plugin)
include (../qaccessiblebase.pri)
-QT += core-private gui-private
+QT += core-private gui-private widgets-private
DESTDIR = $$QT.gui.plugins/accessible
QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)"
diff --git a/src/plugins/decorations/decorations.pro b/src/plugins/decorations/decorations.pro
deleted file mode 100644
index 3d6912e77c..0000000000
--- a/src/plugins/decorations/decorations.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-TEMPLATE = subdirs
-contains(decoration-plugins, default) :SUBDIRS += default
-contains(decoration-plugins, styled) :SUBDIRS += styled
-contains(decoration-plugins, windows) :SUBDIRS += windows
diff --git a/src/plugins/decorations/default/default.pro b/src/plugins/decorations/default/default.pro
deleted file mode 100644
index c323d10930..0000000000
--- a/src/plugins/decorations/default/default.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-TARGET = qdecorationdefault
-load(qt_plugin)
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qdecorationdefault_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qdecorationdefault_qws.cpp
-
-DESTDIR = $$QT.gui.plugins/decorations
-target.path += $$[QT_INSTALL_PLUGINS]/decorations
-INSTALLS += target
diff --git a/src/plugins/decorations/styled/styled.pro b/src/plugins/decorations/styled/styled.pro
deleted file mode 100644
index c5329aea29..0000000000
--- a/src/plugins/decorations/styled/styled.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qdecorationstyled
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/decorations
-target.path += $$[QT_INSTALL_PLUGINS]/decorations
-INSTALLS += target
-
-DEFINES += QT_QWS_DECORATION_STYLED
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qdecorationstyled_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qdecorationstyled_qws.cpp
-
diff --git a/src/plugins/decorations/windows/windows.pro b/src/plugins/decorations/windows/windows.pro
deleted file mode 100644
index f27adb908b..0000000000
--- a/src/plugins/decorations/windows/windows.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-TARGET = qdecorationwindows
-load(qt_plugin)
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qdecorationwindows_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qdecorationwindows_qws.cpp
-
-DESTDIR = $$QT.gui.plugins/decorations
-target.path += $$[QT_INSTALL_PLUGINS]/decorations
-INSTALLS += target
diff --git a/src/plugins/generic/linuxinput/linuxinput.pro b/src/plugins/generic/linuxinput/linuxinput.pro
index 18cb04e973..6ef5f0fb3a 100644
--- a/src/plugins/generic/linuxinput/linuxinput.pro
+++ b/src/plugins/generic/linuxinput/linuxinput.pro
@@ -5,8 +5,6 @@ DESTDIR = $$QT.gui.plugins/generic
target.path = $$[QT_INSTALL_PLUGINS]/generic
INSTALLS += target
-DEFINES += QT_QWS_KBD_LINUXINPUT
-
HEADERS = qlinuxinput.h
QT += core-private
@@ -14,7 +12,3 @@ QT += core-private
SOURCES = main.cpp \
qlinuxinput.cpp
-HEADERS += $$QT_SOURCE_TREE/src/gui/embedded/qkbd_qws.h \
- $$QT_SOURCE_TREE/src/gui/embedded/qkbd_qws_p.h
-
-SOURCES += $$QT_SOURCE_TREE/src/gui/embedded/qkbd_qws.cpp
diff --git a/src/plugins/generic/linuxinput/main.cpp b/src/plugins/generic/linuxinput/main.cpp
index 9c38dba199..20391901bf 100644
--- a/src/plugins/generic/linuxinput/main.cpp
+++ b/src/plugins/generic/linuxinput/main.cpp
@@ -61,8 +61,7 @@ QLinuxInputPlugin::QLinuxInputPlugin()
QStringList QLinuxInputPlugin::keys() const
{
return (QStringList()
- << QLatin1String("LinuxInputMouse")
- << QLatin1String("LinuxInputKeyboard"));
+ << QLatin1String("LinuxInputMouse"));
}
QObject* QLinuxInputPlugin::create(const QString &key,
@@ -70,8 +69,6 @@ QObject* QLinuxInputPlugin::create(const QString &key,
{
if (!key.compare(QLatin1String("LinuxInputMouse"), Qt::CaseInsensitive))
return new QLinuxInputMouseHandler(key, specification);
- if (!key.compare(QLatin1String("LinuxInputKeyboard"), Qt::CaseInsensitive))
- return new QLinuxInputKeyboardHandler(key, specification);
return 0;
}
diff --git a/src/plugins/generic/linuxinput/qlinuxinput.cpp b/src/plugins/generic/linuxinput/qlinuxinput.cpp
index 2316f089cc..943b213ce0 100644
--- a/src/plugins/generic/linuxinput/qlinuxinput.cpp
+++ b/src/plugins/generic/linuxinput/qlinuxinput.cpp
@@ -48,9 +48,6 @@
#include <QPoint>
#include <QWindowSystemInterface>
-#include <qkbd_qws.h>
-
-
#include <qplatformdefs.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
@@ -361,195 +358,6 @@ void QLinuxInputMouseHandler::readMouseData()
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//Keyboard handler
-
-
-
-
-class QWSLinuxInputKeyboardHandler : public QWSKeyboardHandler
-{
-public:
- QWSLinuxInputKeyboardHandler(const QString&);
- ~QWSLinuxInputKeyboardHandler();
-
- virtual bool filterInputEvent(quint16 &input_code, qint32 &input_value);
-
-//private:
-// QWSLinuxInputKbPrivate *d;
-};
-
-
-QWSLinuxInputKeyboardHandler::QWSLinuxInputKeyboardHandler(const QString &device)
- : QWSKeyboardHandler(device)
-{
-}
-
-QWSLinuxInputKeyboardHandler::~QWSLinuxInputKeyboardHandler()
-{
-}
-
-bool QWSLinuxInputKeyboardHandler::filterInputEvent(quint16 &, qint32 &)
-{
- return false;
-}
-
-
-QLinuxInputKeyboardHandler::QLinuxInputKeyboardHandler(const QString &key, const QString &specification)
- : m_handler(0), m_fd(-1), m_tty_fd(-1), m_orig_kbmode(K_XLATE)
-{
- setObjectName(QLatin1String("LinuxInputSubsystem Keyboard Handler"));
-
- QString dev = QLatin1String("/dev/input/event1");
- int repeat_delay = -1;
- int repeat_rate = -1;
-
- bool ttymode = false;
-
- QStringList args = specification.split(QLatin1Char(':'));
- foreach (const QString &arg, args) {
- if (arg.startsWith(QLatin1String("repeat-delay=")))
- repeat_delay = arg.mid(13).toInt();
- else if (arg.startsWith(QLatin1String("repeat-rate=")))
- repeat_rate = arg.mid(12).toInt();
- else if (arg.startsWith(QLatin1String("ttymode")))
- ttymode = true;
- else if (arg.startsWith(QLatin1String("/dev/")))
- dev = arg;
- }
-
- m_handler = new QWSLinuxInputKeyboardHandler(dev); //This is a hack to avoid copying all the QWS code
-
- m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDWR, 0);
- if (m_fd >= 0) {
- if (repeat_delay > 0 && repeat_rate > 0) {
- int kbdrep[2] = { repeat_delay, repeat_rate };
- ::ioctl(m_fd, EVIOCSREP, kbdrep);
- }
-
- QSocketNotifier *notifier;
- notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode()));
-
- if (ttymode) {
- // play nice in case we are started from a shell (e.g. for debugging)
- m_tty_fd = isatty(0) ? 0 : -1;
-
- if (m_tty_fd >= 0) {
- // save tty config for restore.
- tcgetattr(m_tty_fd, &m_tty_attr);
-
- struct ::termios termdata;
- tcgetattr(m_tty_fd, &termdata);
-
- // record the original mode so we can restore it again in the destructor.
- ::ioctl(m_tty_fd, KDGKBMODE, &m_orig_kbmode);
-
- // setting this translation mode is even needed in INPUT mode to prevent
- // the shell from also interpreting codes, if the process has a tty
- // attached: e.g. Ctrl+C wouldn't copy, but kill the application.
- ::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW);
-
- // set the tty layer to pass-through
- termdata.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
- termdata.c_oflag = 0;
- termdata.c_cflag = CREAD | CS8;
- termdata.c_lflag = 0;
- termdata.c_cc[VTIME]=0;
- termdata.c_cc[VMIN]=1;
- cfsetispeed(&termdata, 9600);
- cfsetospeed(&termdata, 9600);
- tcsetattr(m_tty_fd, TCSANOW, &termdata);
- }
- }
- } else {
- qWarning("Cannot open keyboard input device '%s': %s", qPrintable(dev), strerror(errno));
- return;
- }
-}
-
-QLinuxInputKeyboardHandler::~QLinuxInputKeyboardHandler()
-{
- if (m_tty_fd >= 0) {
- ::ioctl(m_tty_fd, KDSKBMODE, m_orig_kbmode);
- tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr);
- }
- if (m_fd >= 0)
- QT_CLOSE(m_fd);
- delete m_handler;
-}
-
-void QLinuxInputKeyboardHandler::switchLed(int led, bool state)
-{
- struct ::input_event led_ie;
- ::gettimeofday(&led_ie.time, 0);
- led_ie.type = EV_LED;
- led_ie.code = led;
- led_ie.value = state;
-
- QT_WRITE(m_fd, &led_ie, sizeof(led_ie));
-}
-
-
-
-void QLinuxInputKeyboardHandler::readKeycode()
-{
- struct ::input_event buffer[32];
- int n = 0;
-
- forever {
- n = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
-
- if (n == 0) {
- qWarning("Got EOF from the input device.");
- return;
- } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) {
- qWarning("Could not read from input device: %s", strerror(errno));
- return;
- } else if (n % sizeof(buffer[0]) == 0) {
- break;
- }
- }
-
- n /= sizeof(buffer[0]);
-
- for (int i = 0; i < n; ++i) {
- if (buffer[i].type != EV_KEY)
- continue;
-
- quint16 code = buffer[i].code;
- qint32 value = buffer[i].value;
-
- if (m_handler->filterInputEvent(code, value))
- continue;
-
- QWSKeyboardHandler::KeycodeAction ka;
- ka = m_handler->processKeycode(code, value != 0, value == 2);
-
- switch (ka) {
- case QWSKeyboardHandler::CapsLockOn:
- case QWSKeyboardHandler::CapsLockOff:
- switchLed(LED_CAPSL, ka == QWSKeyboardHandler::CapsLockOn);
- break;
-
- case QWSKeyboardHandler::NumLockOn:
- case QWSKeyboardHandler::NumLockOff:
- switchLed(LED_NUML, ka == QWSKeyboardHandler::NumLockOn);
- break;
-
- case QWSKeyboardHandler::ScrollLockOn:
- case QWSKeyboardHandler::ScrollLockOff:
- switchLed(LED_SCROLLL, ka == QWSKeyboardHandler::ScrollLockOn);
- break;
-
- default:
- // ignore console switching and reboot
- break;
- }
- }
-}
-
-
diff --git a/src/plugins/generic/linuxinput/qlinuxinput.h b/src/plugins/generic/linuxinput/qlinuxinput.h
index 83b91d095d..b9475a1bf5 100644
--- a/src/plugins/generic/linuxinput/qlinuxinput.h
+++ b/src/plugins/generic/linuxinput/qlinuxinput.h
@@ -79,31 +79,6 @@ private:
QLinuxInputMouseHandlerData *d;
};
-
-class QWSLinuxInputKeyboardHandler;
-
-class QLinuxInputKeyboardHandler : public QObject
-{
- Q_OBJECT
-public:
- QLinuxInputKeyboardHandler(const QString &key, const QString &specification);
- ~QLinuxInputKeyboardHandler();
-
-
-private:
- void switchLed(int, bool);
-
-private slots:
- void readKeycode();
-
-private:
- QWSLinuxInputKeyboardHandler *m_handler;
- int m_fd;
- int m_tty_fd;
- struct termios m_tty_attr;
- int m_orig_kbmode;
-};
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/plugins/gfxdrivers/ahi/ahi.pro b/src/plugins/gfxdrivers/ahi/ahi.pro
deleted file mode 100644
index fd078421f9..0000000000
--- a/src/plugins/gfxdrivers/ahi/ahi.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qahiscreen
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-HEADERS = qscreenahi_qws.h
-
-SOURCES = qscreenahi_qws.cpp \
- qscreenahiplugin.cpp
-
-LIBS += -lahi
diff --git a/src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp b/src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp
deleted file mode 100644
index 320aff9811..0000000000
--- a/src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp
+++ /dev/null
@@ -1,598 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreenahi_qws.h"
-
-#ifndef QT_NO_QWS_AHI
-
-#include <QtGui/qcolor.h>
-#include <QtGui/qapplication.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qvarlengtharray.h>
-#include <private/qwssignalhandler_p.h>
-
-#include <ahi.h>
-
-//#define QAHISCREEN_DEBUG
-
-static int depthForPixelFormat(const AhiPixelFormat_t format)
-{
- switch (format) {
- case AhiPix1bpp:
- return 1;
- case AhiPix2bpp:
- return 2;
- case AhiPix4bpp:
- return 4;
- case AhiPix8bpp_332RGB:
- case AhiPix8bpp:
- return 8;
- case AhiPix16bpp_444RGB:
- return 12;
- case AhiPix16bpp_555RGB:
- return 15;
- case AhiPix16bpp_565RGB:
- return 16;
- case AhiPix32bpp_8888ARGB:
- case AhiPix32bpp_8888BGRA:
- return 32;
- default:
- return 0;
- }
-}
-
-static AhiPixelFormat_t pixelFormatForImageFormat(const QImage::Format format)
-{
- switch (format) {
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- return AhiPix1bpp;
- case QImage::Format_Indexed8:
- return AhiPix8bpp;
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- return AhiPix32bpp_8888ARGB;
- case QImage::Format_RGB16:
- return AhiPix16bpp_565RGB;
- case QImage::Format_RGB555:
- return AhiPix16bpp_555RGB;
- case QImage::Format_ARGB4444_Premultiplied:
- case QImage::Format_RGB444:
- return AhiPix16bpp_444RGB;
- default:
- return AhiPixelFormatMax;
- }
-}
-
-class QAhiScreenCursor : public QScreenCursor
-{
-public:
- QAhiScreenCursor(QScreen *screen, AhiDevCtx_t context);
-
- void set(const QImage &image, int hotx, int hoty);
- void move(int x, int y);
- void show();
- void hide();
-
-private:
- QScreen *screen;
- AhiDevCtx_t context;
-};
-
-QAhiScreenCursor::QAhiScreenCursor(QScreen *s, AhiDevCtx_t c)
- : QScreenCursor(), screen(s), context(c)
-{
- hwaccel = true;
- supportsAlpha = true;
-
- if (enable)
- show();
- else
- hide();
-}
-
-void QAhiScreenCursor::set(const QImage &image, int hotx, int hoty)
-{
- if (image.isNull()) {
- QScreenCursor::set(image, hotx, hoty);
- return;
- }
-
- if (image.format() != QImage::Format_MonoLSB) {
- set(image.convertToFormat(QImage::Format_MonoLSB), hotx, hoty);
- return;
- }
-
- AhiPixelFormat_t pixFmt = pixelFormatForImageFormat(image.format());
-
- if (pixFmt >= AhiPixelFormatMax) { // generic fallback
- QImage::Format toFormat = screen->pixelFormat();
- if (toFormat == QImage::Format_Invalid)
- toFormat = QImage::Format_ARGB32;
- set(image.convertToFormat(toFormat), hotx, hoty);
- return;
- }
-
- AhiPoint_t hotSpot = { hotx, hoty };
- AhiSize_t bitmapSize = { image.width(), image.height() };
- AhiBitmap_t bitmap = { bitmapSize, (void*)(image.bits()),
- image.bytesPerLine(), pixFmt };
-
- AhiSts_t status;
- status = AhiDispCursorSet(context, AhiCursor1, &bitmap, &hotSpot,
- image.serialNumber(), 0);
- if (status != AhiStsOk)
- qWarning("QAhiScreenCursor::set(): AhiDispCursorSet failed: %x",
- status);
-
- QScreenCursor::set(image, hotx, hoty);
-}
-
-void QAhiScreenCursor::move(int x, int y)
-{
- AhiPoint_t pos = { x, y };
- AhiSts_t status = AhiDispCursorPos(context, AhiCursor1, &pos, 0);
- if (status != AhiStsOk)
- qWarning("QAhiScreenCursor::move(): error setting mouse position: %x",
- status);
- QScreenCursor::move(x, y);
-}
-
-void QAhiScreenCursor::show()
-{
- AhiSts_t status;
- status = AhiDispCursorState(context, AhiCursor1, AhiCursorStateOn, 0);
- if (status != AhiStsOk)
- qWarning("QAhiScreenCursor::show(): error setting state: %x", status);
- QScreenCursor::show();
-}
-
-void QAhiScreenCursor::hide()
-{
- AhiDispCursorState(context, AhiCursor1, AhiCursorStateOff, 0);
- QScreenCursor::hide();
-}
-
-class QAhiScreenPrivate : public QObject
-{
-public:
- QAhiScreenPrivate();
- ~QAhiScreenPrivate();
-
- bool setMode(AhiDispMode_t mode);
-
- AhiDevCtx_t context;
- AhiSurf_t surface;
- QAhiScreenCursor *cursor;
-};
-
-QT_BEGIN_NAMESPACE
-
-QAhiScreenPrivate::QAhiScreenPrivate()
- : context(0), surface(0), cursor(0)
-{
-#ifndef QT_NO_QWS_SIGNALHANDLER
- QWSSignalHandler::instance()->addObject(this);
-#endif
-}
-
-QAhiScreenPrivate::~QAhiScreenPrivate()
-{
- delete cursor;
-
- if (surface) {
- AhiSurfFree(context, surface);
- surface = 0;
- }
- if (context) {
- AhiDevClose(context);
- context = 0;
- }
- AhiTerm();
-}
-
-bool QAhiScreenPrivate::setMode(AhiDispMode_t mode)
-{
- AhiSts_t status;
-
- status = AhiDispModeSet(context, &mode, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreenPrivate::setMode(): AhiDispModeSet failed: %x",
- status);
- return false;
- }
-
- if (surface) {
- AhiSurfFree(context, surface);
- surface = 0;
- }
- status = AhiSurfAlloc(context, &surface, &mode.size, mode.pixFmt,
- AHIFLAG_SURFFIXED);
- if (status != AhiStsOk) {
- qCritical("QAhiScreenPrivate::setMode(): AhisurfAlloc failed: %x",
- status);
- return false;
- }
-
- status = AhiDispSurfSet(context, surface, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreenPrivate::setMode(): AhiDispSurfSet failed: %x",
- status);
- return false;
- }
-
- return true;
-}
-
-QAhiScreen::QAhiScreen(int displayId)
- : QScreen(displayId), d_ptr(new QAhiScreenPrivate)
-{
-}
-
-QAhiScreen::~QAhiScreen()
-{
- delete d_ptr;
-}
-
-bool QAhiScreen::configure()
-{
- AhiSurfInfo_t surfaceInfo;
- AhiSts_t status;
-
- status = AhiSurfInfo(d_ptr->context, d_ptr->surface, &surfaceInfo);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::configure(): AhiSurfInfo failed: %x", status);
- return false;
- }
-
- QScreen::data = 0;
- QScreen::w = QScreen::dw = surfaceInfo.size.cx;
- QScreen::h = QScreen::dh = surfaceInfo.size.cy;
- QScreen::lstep = surfaceInfo.stride;
- QScreen::size = surfaceInfo.sizeInBytes;
-
- switch (surfaceInfo.pixFmt) {
- case AhiPix1bpp:
- setPixelFormat(QImage::Format_Mono);
- QScreen::d = 1;
- break;
- case AhiPix4bpp:
- QScreen::d = 4;
- break;
- case AhiPix8bpp_332RGB:
- case AhiPix8bpp:
- QScreen::d = 8;
- break;
- case AhiPix16bpp_444RGB:
- setPixelFormat(QImage::Format_RGB444);
- QScreen::d = 12;
- break;
- case AhiPix16bpp_555RGB:
- setPixelFormat(QImage::Format_RGB555);
- QScreen::d = 15;
- break;
- case AhiPix16bpp_565RGB:
- setPixelFormat(QImage::Format_RGB16);
- QScreen::d = 16;
- break;
- case AhiPix2bpp:
- QScreen::d = 2;
- break;
- case AhiPix32bpp_8888ARGB:
- setPixelFormat(QImage::Format_ARGB32);
- // fallthrough
- case AhiPix32bpp_8888BGRA:
- QScreen::d = 32;
- break;
- default:
- qCritical("QAhiScreen::configure(): Unknown pixel format: %x",
- surfaceInfo.pixFmt);
- return false;
- }
-
- const int dpi = 72;
- QScreen::physWidth = qRound(QScreen::dw * 25.4 / dpi);
- QScreen::physHeight = qRound(QScreen::dh * 25.4 / dpi);
-
- return true;
-}
-
-bool QAhiScreen::connect(const QString &displaySpec)
-{
- Q_UNUSED(displaySpec);
-
- AhiSts_t status;
-
- status = AhiInit(0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiInit failed: %x", status);
- return false;
- }
-
- AhiDev_t device;
- AhiDevInfo_t info;
-
- status = AhiDevEnum(&device, &info, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDevEnum failed: %x", status);
- return false;
- }
-#ifdef QAHISCREEN_DEBUG
- {
- int displayNo = 0;
- AhiDevInfo_t dispInfo = info;
- qDebug("AHI supported devices:");
- do {
- qDebug(" %2i: %s, sw version: %s (rev %u)\n"
- " chip: 0x%x (rev %u), mem: %i (%i/%i), bus: 0x%x",
- displayNo, dispInfo.name,
- dispInfo.swVersion, uint(dispInfo.swRevision),
- uint(dispInfo.chipId), uint(dispInfo.revisionId),
- uint(dispInfo.totalMemory),
- uint(dispInfo.internalMemSize),
- uint(dispInfo.externalMemSize),
- uint(dispInfo.cpuBusInterfaceMode));
- status = AhiDevEnum(&device, &info, ++displayNo);
- } while (status == AhiStsOk);
- }
-#endif
-
- status = AhiDevOpen(&d_ptr->context, device, "qscreenahi",
- AHIFLAG_USERLEVEL);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDevOpen failed: %x", status);
- return false;
- }
-
- AhiDispMode_t mode;
-
- status = AhiDispModeEnum(d_ptr->context, &mode, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDispModeEnum failed: %x", status);
- return false;
- }
-
-#ifdef QAHISCREEN_DEBUG
- {
- int modeNo = 0;
- AhiDispMode_t modeInfo = mode;
- qDebug("AHI supported modes:");
- do {
- qDebug(" %2i: %ux%u, fmt: %i, %u Hz, rot: %i, mirror: %i",
- modeNo, uint(modeInfo.size.cx), uint(modeInfo.size.cy),
- modeInfo.pixFmt, uint(modeInfo.frequency),
- modeInfo.rotation, modeInfo.mirror);
- status = AhiDispModeEnum(d_ptr->context, &modeInfo, ++modeNo);
- } while (status == AhiStsOk);
- }
-#endif
-
- if (QApplication::type() == QApplication::GuiServer) {
- if (!d_ptr->setMode(mode))
- return false;
- } else {
- status = AhiDispSurfGet(d_ptr->context, &d_ptr->surface);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDispSurfGet failed: %x",
- status);
- return false;
- }
-
- status = AhiDispModeGet(d_ptr->context, &mode);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::context(): AhiDispModeGet failed: %x",
- status);
- return false;
- }
- }
-
- return configure();
-}
-
-void QAhiScreen::disconnect()
-{
- AhiSurfFree(d_ptr->context, d_ptr->surface);
- d_ptr->surface = 0;
- AhiDevClose(d_ptr->context);
- d_ptr->context = 0;
- AhiTerm();
-}
-
-bool QAhiScreen::initDevice()
-{
- QScreenCursor::initSoftwareCursor();
-
- AhiSts_t status = AhiDispState(d_ptr->context, AhiDispStateOn, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDispState failed: %x", status);
- return false;
- }
-
- return true;
-}
-
-void QAhiScreen::shutdownDevice()
-{
- AhiDispState(d_ptr->context, AhiDispStateOff, 0);
-}
-
-void QAhiScreen::setMode(int width, int height, int depth)
-{
- int modeNo = 0;
- AhiDispMode_t mode;
- AhiSts_t status = AhiStsOk;
-
- while (status == AhiStsOk) {
- status = AhiDispModeEnum(d_ptr->context, &mode, modeNo);
- if (mode.size.cx == uint(width) &&
- mode.size.cy == uint(height) &&
- depthForPixelFormat(mode.pixFmt) == depth)
- {
- d_ptr->setMode(mode);
- configure();
- return;
- }
- }
-}
-
-void QAhiScreen::blit(const QImage &image, const QPoint &topLeft,
- const QRegion &reg)
-{
- AhiPixelFormat_t pixFmt = pixelFormatForImageFormat(image.format());
-
- if (pixFmt >= AhiPixelFormatMax) { // generic fallback
- QImage::Format toFormat = pixelFormat();
- if (toFormat == QImage::Format_Invalid)
- toFormat = QImage::Format_ARGB32;
- blit(image.convertToFormat(toFormat), topLeft, reg);
- return;
- }
-
- AhiSts_t status;
-
- status = AhiDrawSurfDstSet(d_ptr->context, d_ptr->surface, 0);
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::blit(): AhiDrawSurfDstSet failed: %x", status);
- return;
- }
-
- const QVector<QRect> rects = (reg & region()).rects();
- const int numRects = rects.size();
- QVarLengthArray<AhiPoint_t, 8> src(numRects);
- QVarLengthArray<AhiRect_t, 8> dest(numRects);
-
- for (int i = 0; i < numRects; ++i) {
- const QRect rect = rects.at(i);
-
- src[i].x = rect.x() - topLeft.x();
- src[i].y = rect.y() - topLeft.y();
- dest[i].left = rect.left();
- dest[i].top = rect.top();
- dest[i].right = rect.x() + rect.width();
- dest[i].bottom = rect.y() + rect.height();
- }
-
- AhiSize_t bitmapSize = { image.width(), image.height() };
- AhiBitmap_t bitmap = { bitmapSize, (void*)(image.bits()),
- image.bytesPerLine(), pixFmt };
-
- status = AhiDrawRopSet(d_ptr->context, AHIMAKEROP3(AHIROPSRCCOPY));
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::blit(): AhiDrawRopSet failed: %x", status);
- return;
- }
-
- for (int i = 0; i < numRects; ++i) {
- status = AhiDrawBitmapBlt(d_ptr->context, &dest[i], &src[i],
- &bitmap, 0, 0);
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::blit(): AhiDrawBitmapBlt failed: %x",
- status);
- break;
- }
- }
-}
-
-void QAhiScreen::solidFill(const QColor &color, const QRegion &reg)
-{
- AhiSts_t status = AhiStsOk;
-
- switch (pixelFormat()) {
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB32:
- case QImage::Format_RGB32:
- status = AhiDrawBrushFgColorSet(d_ptr->context, color.rgba());
- break;
- case QImage::Format_RGB16:
- status = AhiDrawBrushFgColorSet(d_ptr->context, qt_convRgbTo16(color.rgb()));
- break;
- default:
- qFatal("QAhiScreen::solidFill(): Not implemented for pixel format %d",
- int(pixelFormat()));
- break;
- }
-
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::solidFill(): AhiDrawBrushFgColorSet failed: %x",
- status);
- return;
- }
-
- status = AhiDrawBrushSet(d_ptr->context, 0, 0, 0, AHIFLAG_BRUSHSOLID);
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::solidFill(): AhiDrawBrushSet failed: %x",
- status);
- return;
- }
-
- status = AhiDrawRopSet(d_ptr->context, AHIMAKEROP3(AHIROPPATCOPY));
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::solidFill(): AhiDrawRopSet failed: %x", status);
- return;
- }
-
- status = AhiDrawSurfDstSet(d_ptr->context, d_ptr->surface, 0);
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::solidFill(): AhiDrawSurfDst failed: %x", status);
- return;
- }
-
- const QVector<QRect> rects = (reg & region()).rects();
- QVarLengthArray<AhiRect_t> ahiRects(rects.size());
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect rect = rects.at(i);
- ahiRects[i].left = rect.left();
- ahiRects[i].top = rect.top();
- ahiRects[i].right = rect.x() + rect.width();
- ahiRects[i].bottom = rect.y() + rect.height();
- }
-
- status = AhiDrawBitBltMulti(d_ptr->context, ahiRects.data(),
- 0, ahiRects.size());
- if (status != AhiStsOk)
- qWarning("QAhiScreen::solidFill(): AhiDrawBitBlt failed: %x", status);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_AHI
diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro
deleted file mode 100644
index 6fb2a0f9aa..0000000000
--- a/src/plugins/gfxdrivers/directfb/directfb.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-TARGET = qdirectfbscreen
-load(qt_plugin)
-include($$QT_SOURCE_TREE/src/gui/embedded/directfb.pri)
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-SOURCES += qdirectfbscreenplugin.cpp
-
-QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB
-LIBS += $$QT_LIBS_DIRECTFB
-DEFINES += $$QT_DEFINES_DIRECTFB
-contains(gfx-plugins, directfb):DEFINES += QT_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp
deleted file mode 100644
index 9ec3f71c7c..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbkeyboard.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include "qdirectfbscreen.h"
-#include <qobject.h>
-#include <qsocketnotifier.h>
-#include <qhash.h>
-
-#include <directfb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-class KeyMap : public QHash<DFBInputDeviceKeySymbol, Qt::Key>
-{
-public:
- KeyMap();
-};
-
-Q_GLOBAL_STATIC(KeyMap, keymap);
-
-class QDirectFBKeyboardHandlerPrivate : public QObject
-{
- Q_OBJECT
-public:
- QDirectFBKeyboardHandlerPrivate(QDirectFBKeyboardHandler *handler);
- ~QDirectFBKeyboardHandlerPrivate();
-
- void suspend();
- void resume();
-
-private:
- QDirectFBKeyboardHandler *handler;
- IDirectFBEventBuffer *eventBuffer;
- QSocketNotifier *keyboardNotifier;
- DFBEvent event;
- int bytesRead;
- int lastUnicode, lastKeycode;
- Qt::KeyboardModifiers lastModifiers;
-private Q_SLOTS:
- void readKeyboardData();
-};
-
-QDirectFBKeyboardHandlerPrivate::QDirectFBKeyboardHandlerPrivate(QDirectFBKeyboardHandler *h)
- : handler(h), eventBuffer(0), keyboardNotifier(0), bytesRead(0),
- lastUnicode(0), lastKeycode(0), lastModifiers(0)
-{
- Q_ASSERT(qt_screen);
-
- IDirectFB *fb = QDirectFBScreen::instance()->dfb();
- if (!fb) {
- qCritical("QDirectFBKeyboardHandler: DirectFB not initialized");
- return;
- }
-
- DFBResult result;
- result = fb->CreateInputEventBuffer(fb, DICAPS_KEYS, DFB_TRUE,
- &eventBuffer);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBKeyboardHandler: "
- "Unable to create input event buffer", result);
- return;
- }
-
- int fd;
- result = eventBuffer->CreateFileDescriptor(eventBuffer, &fd);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBKeyboardHandler: "
- "Unable to create file descriptor", result);
- return;
- }
-
- int flags = ::fcntl(fd, F_GETFL, 0);
- ::fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
- memset(&event, 0, sizeof(event));
-
- keyboardNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(keyboardNotifier, SIGNAL(activated(int)),
- this, SLOT(readKeyboardData()));
- resume();
-}
-
-void QDirectFBKeyboardHandlerPrivate::suspend()
-{
- keyboardNotifier->setEnabled(false);
-}
-
-void QDirectFBKeyboardHandlerPrivate::resume()
-{
- eventBuffer->Reset(eventBuffer);
- keyboardNotifier->setEnabled(true);
-}
-
-QDirectFBKeyboardHandlerPrivate::~QDirectFBKeyboardHandlerPrivate()
-{
- if (eventBuffer)
- eventBuffer->Release(eventBuffer);
-}
-
-void QDirectFBKeyboardHandlerPrivate::readKeyboardData()
-{
- if(!qt_screen)
- return;
-
- for (;;) {
- // GetEvent returns DFB_UNSUPPORTED after CreateFileDescriptor().
- // This seems stupid and I really hope it's a bug which will be fixed.
-
- // DFBResult ret = eventBuffer->GetEvent(eventBuffer, &event);
-
- char *buf = reinterpret_cast<char*>(&event);
- int ret = ::read(keyboardNotifier->socket(),
- buf + bytesRead, sizeof(DFBEvent) - bytesRead);
- if (ret == -1) {
- if (errno != EAGAIN)
- qWarning("QDirectFBKeyboardHandlerPrivate::readKeyboardData(): %s",
- strerror(errno));
- return;
- }
-
- Q_ASSERT(ret >= 0);
- bytesRead += ret;
- if (bytesRead < int(sizeof(DFBEvent)))
- break;
- bytesRead = 0;
-
- Q_ASSERT(event.clazz == DFEC_INPUT);
-
- const DFBInputEvent input = event.input;
-
- Qt::KeyboardModifiers modifiers = Qt::NoModifier;
-
- // Not implemented:
- // if (input.modifiers & DIMM_SUPER)
- // if (input.modifiers & DIMM_HYPER)
-
- if (!(input.flags & DIEF_KEYSYMBOL) ||
- !(input.flags & DIEF_KEYID) ||
- !(input.type & (DIET_KEYPRESS|DIET_KEYRELEASE)))
- {
- static bool first = true;
- if (first) {
- qWarning("QDirectFBKeyboardHandler - Getting unexpected non-keyboard related events");
- first = false;
- }
- break;
- }
-
- if (input.flags & DIEF_MODIFIERS) {
- if (input.modifiers & DIMM_SHIFT)
- modifiers |= Qt::ShiftModifier;
- if (input.modifiers & DIMM_CONTROL)
- modifiers |= Qt::ControlModifier;
- if (input.modifiers & DIMM_ALT)
- modifiers |= Qt::AltModifier;
- if (input.modifiers & DIMM_ALTGR)
- modifiers |= Qt::AltModifier;
- if (input.modifiers & DIMM_META)
- modifiers |= Qt::MetaModifier;
- }
-
-
- const bool press = input.type & DIET_KEYPRESS;
- DFBInputDeviceKeySymbol symbol = input.key_symbol;
- int unicode = -1;
- int keycode = 0;
-
- keycode = keymap()->value(symbol);
- if (DFB_KEY_TYPE(symbol) == DIKT_UNICODE)
- unicode = symbol;
-
- if (unicode != -1 || keycode != 0) {
- bool autoRepeat = false;
- if (press) {
- if (unicode == lastUnicode && keycode == lastKeycode && modifiers == lastModifiers) {
- autoRepeat = true;
- } else {
- lastUnicode = unicode;
- lastKeycode = keycode;
- lastModifiers = modifiers;
- }
- } else {
- lastUnicode = lastKeycode = -1;
- lastModifiers = 0;
- }
- if (autoRepeat) {
- handler->processKeyEvent(unicode, keycode,
- modifiers, false, autoRepeat);
-
- }
-
- handler->processKeyEvent(unicode, keycode,
- modifiers, press, autoRepeat);
- }
- }
-}
-
-QDirectFBKeyboardHandler::QDirectFBKeyboardHandler(const QString &device)
- : QWSKeyboardHandler()
-{
- Q_UNUSED(device);
- d = new QDirectFBKeyboardHandlerPrivate(this);
-}
-
-QDirectFBKeyboardHandler::~QDirectFBKeyboardHandler()
-{
- delete d;
-}
-
-KeyMap::KeyMap()
-{
- insert(DIKS_BACKSPACE , Qt::Key_Backspace);
- insert(DIKS_TAB , Qt::Key_Tab);
- insert(DIKS_RETURN , Qt::Key_Return);
- insert(DIKS_ESCAPE , Qt::Key_Escape);
- insert(DIKS_DELETE , Qt::Key_Delete);
-
- insert(DIKS_CURSOR_LEFT , Qt::Key_Left);
- insert(DIKS_CURSOR_RIGHT , Qt::Key_Right);
- insert(DIKS_CURSOR_UP , Qt::Key_Up);
- insert(DIKS_CURSOR_DOWN , Qt::Key_Down);
- insert(DIKS_INSERT , Qt::Key_Insert);
- insert(DIKS_HOME , Qt::Key_Home);
- insert(DIKS_END , Qt::Key_End);
- insert(DIKS_PAGE_UP , Qt::Key_PageUp);
- insert(DIKS_PAGE_DOWN , Qt::Key_PageDown);
- insert(DIKS_PRINT , Qt::Key_Print);
- insert(DIKS_PAUSE , Qt::Key_Pause);
- insert(DIKS_SELECT , Qt::Key_Select);
- insert(DIKS_GOTO , Qt::Key_OpenUrl);
- insert(DIKS_CLEAR , Qt::Key_Clear);
- insert(DIKS_MENU , Qt::Key_Menu);
- insert(DIKS_HELP , Qt::Key_Help);
-
- insert(DIKS_INTERNET , Qt::Key_HomePage);
- insert(DIKS_MAIL , Qt::Key_LaunchMail);
- insert(DIKS_FAVORITES , Qt::Key_Favorites);
-
- insert(DIKS_BACK , Qt::Key_Back);
- insert(DIKS_FORWARD , Qt::Key_Forward);
- insert(DIKS_VOLUME_UP , Qt::Key_VolumeUp);
- insert(DIKS_VOLUME_DOWN , Qt::Key_VolumeDown);
- insert(DIKS_MUTE , Qt::Key_VolumeMute);
- insert(DIKS_PLAYPAUSE , Qt::Key_Pause);
- insert(DIKS_PLAY , Qt::Key_MediaPlay);
- insert(DIKS_STOP , Qt::Key_MediaStop);
- insert(DIKS_RECORD , Qt::Key_MediaRecord);
- insert(DIKS_PREVIOUS , Qt::Key_MediaPrevious);
- insert(DIKS_NEXT , Qt::Key_MediaNext);
-
- insert(DIKS_F1 , Qt::Key_F1);
- insert(DIKS_F2 , Qt::Key_F2);
- insert(DIKS_F3 , Qt::Key_F3);
- insert(DIKS_F4 , Qt::Key_F4);
- insert(DIKS_F5 , Qt::Key_F5);
- insert(DIKS_F6 , Qt::Key_F6);
- insert(DIKS_F7 , Qt::Key_F7);
- insert(DIKS_F8 , Qt::Key_F8);
- insert(DIKS_F9 , Qt::Key_F9);
- insert(DIKS_F10 , Qt::Key_F10);
- insert(DIKS_F11 , Qt::Key_F11);
- insert(DIKS_F12 , Qt::Key_F12);
-
- insert(DIKS_SHIFT , Qt::Key_Shift);
- insert(DIKS_CONTROL , Qt::Key_Control);
- insert(DIKS_ALT , Qt::Key_Alt);
- insert(DIKS_ALTGR , Qt::Key_AltGr);
-
- insert(DIKS_META , Qt::Key_Meta);
- insert(DIKS_SUPER , Qt::Key_Super_L); // ???
- insert(DIKS_HYPER , Qt::Key_Hyper_L); // ???
-
- insert(DIKS_CAPS_LOCK , Qt::Key_CapsLock);
- insert(DIKS_NUM_LOCK , Qt::Key_NumLock);
- insert(DIKS_SCROLL_LOCK , Qt::Key_ScrollLock);
-
- insert(DIKS_DEAD_ABOVEDOT , Qt::Key_Dead_Abovedot);
- insert(DIKS_DEAD_ABOVERING , Qt::Key_Dead_Abovering);
- insert(DIKS_DEAD_ACUTE , Qt::Key_Dead_Acute);
- insert(DIKS_DEAD_BREVE , Qt::Key_Dead_Breve);
- insert(DIKS_DEAD_CARON , Qt::Key_Dead_Caron);
- insert(DIKS_DEAD_CEDILLA , Qt::Key_Dead_Cedilla);
- insert(DIKS_DEAD_CIRCUMFLEX , Qt::Key_Dead_Circumflex);
- insert(DIKS_DEAD_DIAERESIS , Qt::Key_Dead_Diaeresis);
- insert(DIKS_DEAD_DOUBLEACUTE , Qt::Key_Dead_Doubleacute);
- insert(DIKS_DEAD_GRAVE , Qt::Key_Dead_Grave);
- insert(DIKS_DEAD_IOTA , Qt::Key_Dead_Iota);
- insert(DIKS_DEAD_MACRON , Qt::Key_Dead_Macron);
- insert(DIKS_DEAD_OGONEK , Qt::Key_Dead_Ogonek);
- insert(DIKS_DEAD_SEMIVOICED_SOUND , Qt::Key_Dead_Semivoiced_Sound);
- insert(DIKS_DEAD_TILDE , Qt::Key_Dead_Tilde);
- insert(DIKS_DEAD_VOICED_SOUND , Qt::Key_Dead_Voiced_Sound);
- insert(DIKS_SPACE , Qt::Key_Space);
- insert(DIKS_EXCLAMATION_MARK , Qt::Key_Exclam);
- insert(DIKS_QUOTATION , Qt::Key_QuoteDbl);
- insert(DIKS_NUMBER_SIGN , Qt::Key_NumberSign);
- insert(DIKS_DOLLAR_SIGN , Qt::Key_Dollar);
- insert(DIKS_PERCENT_SIGN , Qt::Key_Percent);
- insert(DIKS_AMPERSAND , Qt::Key_Ampersand);
- insert(DIKS_APOSTROPHE , Qt::Key_Apostrophe);
- insert(DIKS_PARENTHESIS_LEFT , Qt::Key_ParenLeft);
- insert(DIKS_PARENTHESIS_RIGHT , Qt::Key_ParenRight);
- insert(DIKS_ASTERISK , Qt::Key_Asterisk);
- insert(DIKS_PLUS_SIGN , Qt::Key_Plus);
- insert(DIKS_COMMA , Qt::Key_Comma);
- insert(DIKS_MINUS_SIGN , Qt::Key_Minus);
- insert(DIKS_PERIOD , Qt::Key_Period);
- insert(DIKS_SLASH , Qt::Key_Slash);
- insert(DIKS_0 , Qt::Key_0);
- insert(DIKS_1 , Qt::Key_1);
- insert(DIKS_2 , Qt::Key_2);
- insert(DIKS_3 , Qt::Key_3);
- insert(DIKS_4 , Qt::Key_4);
- insert(DIKS_5 , Qt::Key_5);
- insert(DIKS_6 , Qt::Key_6);
- insert(DIKS_7 , Qt::Key_7);
- insert(DIKS_8 , Qt::Key_8);
- insert(DIKS_9 , Qt::Key_9);
- insert(DIKS_COLON , Qt::Key_Colon);
- insert(DIKS_SEMICOLON , Qt::Key_Semicolon);
- insert(DIKS_LESS_THAN_SIGN , Qt::Key_Less);
- insert(DIKS_EQUALS_SIGN , Qt::Key_Equal);
- insert(DIKS_GREATER_THAN_SIGN , Qt::Key_Greater);
- insert(DIKS_QUESTION_MARK , Qt::Key_Question);
- insert(DIKS_AT , Qt::Key_At);
- insert(DIKS_CAPITAL_A , Qt::Key_A);
- insert(DIKS_CAPITAL_B , Qt::Key_B);
- insert(DIKS_CAPITAL_C , Qt::Key_C);
- insert(DIKS_CAPITAL_D , Qt::Key_D);
- insert(DIKS_CAPITAL_E , Qt::Key_E);
- insert(DIKS_CAPITAL_F , Qt::Key_F);
- insert(DIKS_CAPITAL_G , Qt::Key_G);
- insert(DIKS_CAPITAL_H , Qt::Key_H);
- insert(DIKS_CAPITAL_I , Qt::Key_I);
- insert(DIKS_CAPITAL_J , Qt::Key_J);
- insert(DIKS_CAPITAL_K , Qt::Key_K);
- insert(DIKS_CAPITAL_L , Qt::Key_L);
- insert(DIKS_CAPITAL_M , Qt::Key_M);
- insert(DIKS_CAPITAL_N , Qt::Key_N);
- insert(DIKS_CAPITAL_O , Qt::Key_O);
- insert(DIKS_CAPITAL_P , Qt::Key_P);
- insert(DIKS_CAPITAL_Q , Qt::Key_Q);
- insert(DIKS_CAPITAL_R , Qt::Key_R);
- insert(DIKS_CAPITAL_S , Qt::Key_S);
- insert(DIKS_CAPITAL_T , Qt::Key_T);
- insert(DIKS_CAPITAL_U , Qt::Key_U);
- insert(DIKS_CAPITAL_V , Qt::Key_V);
- insert(DIKS_CAPITAL_W , Qt::Key_W);
- insert(DIKS_CAPITAL_X , Qt::Key_X);
- insert(DIKS_CAPITAL_Y , Qt::Key_Y);
- insert(DIKS_CAPITAL_Z , Qt::Key_Z);
- insert(DIKS_SQUARE_BRACKET_LEFT , Qt::Key_BracketLeft);
- insert(DIKS_BACKSLASH , Qt::Key_Backslash);
- insert(DIKS_SQUARE_BRACKET_RIGHT , Qt::Key_BracketRight);
- insert(DIKS_CIRCUMFLEX_ACCENT , Qt::Key_AsciiCircum);
- insert(DIKS_UNDERSCORE , Qt::Key_Underscore);
- insert(DIKS_SMALL_A , Qt::Key_A);
- insert(DIKS_SMALL_B , Qt::Key_B);
- insert(DIKS_SMALL_C , Qt::Key_C);
- insert(DIKS_SMALL_D , Qt::Key_D);
- insert(DIKS_SMALL_E , Qt::Key_E);
- insert(DIKS_SMALL_F , Qt::Key_F);
- insert(DIKS_SMALL_G , Qt::Key_G);
- insert(DIKS_SMALL_H , Qt::Key_H);
- insert(DIKS_SMALL_I , Qt::Key_I);
- insert(DIKS_SMALL_J , Qt::Key_J);
- insert(DIKS_SMALL_K , Qt::Key_K);
- insert(DIKS_SMALL_L , Qt::Key_L);
- insert(DIKS_SMALL_M , Qt::Key_M);
- insert(DIKS_SMALL_N , Qt::Key_N);
- insert(DIKS_SMALL_O , Qt::Key_O);
- insert(DIKS_SMALL_P , Qt::Key_P);
- insert(DIKS_SMALL_Q , Qt::Key_Q);
- insert(DIKS_SMALL_R , Qt::Key_R);
- insert(DIKS_SMALL_S , Qt::Key_S);
- insert(DIKS_SMALL_T , Qt::Key_T);
- insert(DIKS_SMALL_U , Qt::Key_U);
- insert(DIKS_SMALL_V , Qt::Key_V);
- insert(DIKS_SMALL_W , Qt::Key_W);
- insert(DIKS_SMALL_X , Qt::Key_X);
- insert(DIKS_SMALL_Y , Qt::Key_Y);
- insert(DIKS_SMALL_Z , Qt::Key_Z);
- insert(DIKS_CURLY_BRACKET_LEFT , Qt::Key_BraceLeft);
- insert(DIKS_VERTICAL_BAR , Qt::Key_Bar);
- insert(DIKS_CURLY_BRACKET_RIGHT , Qt::Key_BraceRight);
- insert(DIKS_TILDE , Qt::Key_AsciiTilde);
-}
-
-QT_END_NAMESPACE
-#include "qdirectfbkeyboard.moc"
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp
deleted file mode 100644
index f5f03e72eb..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbmouse.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include "qdirectfbscreen.h"
-#include <qsocketnotifier.h>
-
-#include <directfb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDirectFBMouseHandlerPrivate : public QObject
-{
- Q_OBJECT
-public:
- QDirectFBMouseHandlerPrivate(QDirectFBMouseHandler *h);
- ~QDirectFBMouseHandlerPrivate();
-
- void setEnabled(bool on);
-private:
- QDirectFBMouseHandler *handler;
- IDirectFBEventBuffer *eventBuffer;
-#ifndef QT_NO_DIRECTFB_LAYER
- IDirectFBDisplayLayer *layer;
-#endif
- QSocketNotifier *mouseNotifier;
-
- QPoint prevPoint;
- Qt::MouseButtons prevbuttons;
-
- DFBEvent event;
- uint bytesRead;
-
-private Q_SLOTS:
- void readMouseData();
-};
-
-QDirectFBMouseHandlerPrivate::QDirectFBMouseHandlerPrivate(QDirectFBMouseHandler *h)
- : handler(h), eventBuffer(0)
-{
- DFBResult result;
-
- QScreen *screen = QScreen::instance();
- if (!screen) {
- qCritical("QDirectFBMouseHandler: no screen instance found");
- return;
- }
-
- IDirectFB *fb = QDirectFBScreen::instance()->dfb();
- if (!fb) {
- qCritical("QDirectFBMouseHandler: DirectFB not initialized");
- return;
- }
-
-#ifndef QT_NO_DIRECTFB_LAYER
- layer = QDirectFBScreen::instance()->dfbDisplayLayer();
- if (!layer) {
- qCritical("QDirectFBMouseHandler: Unable to get primary display layer");
- return;
- }
-#endif
-
- DFBInputDeviceCapabilities caps;
- caps = DICAPS_BUTTONS | DICAPS_AXES;
- result = fb->CreateInputEventBuffer(fb, caps, DFB_TRUE, &eventBuffer);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBMouseHandler: "
- "Unable to create input event buffer", result);
- return;
- }
-
- int fd;
- result = eventBuffer->CreateFileDescriptor(eventBuffer, &fd);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBMouseHandler: "
- "Unable to create file descriptor", result);
- return;
- }
-
- int flags = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
- // DirectFB seems to assume that the mouse always starts centered
- prevPoint = QPoint(screen->deviceWidth() / 2, screen->deviceHeight() / 2);
- prevbuttons = Qt::NoButton;
- memset(&event, 0, sizeof(event));
- bytesRead = 0;
-
- mouseNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
- setEnabled(true);
-}
-
-QDirectFBMouseHandlerPrivate::~QDirectFBMouseHandlerPrivate()
-{
- if (eventBuffer)
- eventBuffer->Release(eventBuffer);
-}
-
-void QDirectFBMouseHandlerPrivate::setEnabled(bool on)
-{
- if (mouseNotifier->isEnabled() != on) {
-#ifndef QT_NO_DIRECTFB_LAYER
- DFBResult result;
- result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::QDirectFBScreenCursor: "
- "Unable to set cooperative level", result);
- }
- result = layer->EnableCursor(layer, on ? 1 : 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::QDirectFBScreenCursor: "
- "Unable to enable cursor", result);
- }
-
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
-
- layer->SetCooperativeLevel(layer, DLSCL_SHARED);
-#endif
- mouseNotifier->setEnabled(on);
- }
-}
-
-void QDirectFBMouseHandlerPrivate::readMouseData()
-{
- if (!QScreen::instance())
- return;
-
- for (;;) {
- // GetEvent returns DFB_UNSUPPORTED after CreateFileDescriptor().
- // This seems stupid and I really hope it's a bug which will be fixed.
-
- // DFBResult ret = eventBuffer->GetEvent(eventBuffer, &event);
-
- char *buf = reinterpret_cast<char*>(&event);
- int ret = ::read(mouseNotifier->socket(),
- buf + bytesRead, sizeof(DFBEvent) - bytesRead);
- if (ret == -1) {
- if (errno == EINTR)
- continue;
- if (errno == EAGAIN)
- return;
- qWarning("QDirectFBMouseHandlerPrivate::readMouseData(): %s",
- strerror(errno));
- return;
- }
-
- Q_ASSERT(ret >= 0);
- bytesRead += ret;
- if (bytesRead < sizeof(DFBEvent))
- break;
- bytesRead = 0;
-
- Q_ASSERT(event.clazz == DFEC_INPUT);
-
- const DFBInputEvent input = event.input;
- int x = prevPoint.x();
- int y = prevPoint.y();
- int wheel = 0;
-
- if (input.type == DIET_AXISMOTION) {
-#if defined(QT_NO_DIRECTFB_LAYER) || defined(QT_DIRECTFB_WINDOW_AS_CURSOR)
- if (input.flags & DIEF_AXISABS) {
- switch (input.axis) {
- case DIAI_X: x = input.axisabs; break;
- case DIAI_Y: y = input.axisabs; break;
- default:
- qWarning("QDirectFBMouseHandlerPrivate::readMouseData: "
- "unknown axis (absolute) %d", input.axis);
- break;
- }
- } else if (input.flags & DIEF_AXISREL) {
- switch (input.axis) {
- case DIAI_X: x += input.axisrel; break;
- case DIAI_Y: y += input.axisrel; break;
- case DIAI_Z: wheel = -120 * input.axisrel; break;
- default:
- qWarning("QDirectFBMouseHandlerPrivate::readMouseData: "
- "unknown axis (releative) %d", input.axis);
- }
- }
-#else
- if (input.axis == DIAI_X || input.axis == DIAI_Y) {
- DFBResult result = layer->GetCursorPosition(layer, &x, &y);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBMouseHandler::readMouseData",
- result);
- }
- } else if (input.axis == DIAI_Z) {
- Q_ASSERT(input.flags & DIEF_AXISREL);
- wheel = input.axisrel;
- wheel *= -120;
- }
-#endif
- }
-
- Qt::MouseButtons buttons = Qt::NoButton;
- if (input.flags & DIEF_BUTTONS) {
- if (input.buttons & DIBM_LEFT)
- buttons |= Qt::LeftButton;
- if (input.buttons & DIBM_MIDDLE)
- buttons |= Qt::MidButton;
- if (input.buttons & DIBM_RIGHT)
- buttons |= Qt::RightButton;
- }
-
- QPoint p = QPoint(x, y);
- handler->limitToScreen(p);
-
- if (p == prevPoint && wheel == 0 && buttons == prevbuttons)
- continue;
-
- prevPoint = p;
- prevbuttons = buttons;
-
- handler->mouseChanged(p, buttons, wheel);
- }
-}
-
-QDirectFBMouseHandler::QDirectFBMouseHandler(const QString &driver,
- const QString &device)
- : QWSMouseHandler(driver, device)
-{
- d = new QDirectFBMouseHandlerPrivate(this);
-}
-
-QDirectFBMouseHandler::~QDirectFBMouseHandler()
-{
- delete d;
-}
-
-void QDirectFBMouseHandler::suspend()
-{
- d->setEnabled(false);
-}
-
-void QDirectFBMouseHandler::resume()
-{
- d->setEnabled(true);
-}
-
-QT_END_NAMESPACE
-#include "qdirectfbmouse.moc"
-#endif // QT_NO_QWS_DIRECTFB
-
-
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
deleted file mode 100644
index 90d0090790..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbscreen.h"
-#include "qdirectfbpaintdevice.h"
-#include "qdirectfbpaintengine.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_NAMESPACE
-
-QDirectFBPaintDevice::QDirectFBPaintDevice(QDirectFBScreen *scr)
- : QCustomRasterPaintDevice(0), dfbSurface(0), screen(scr),
- bpl(-1), lockFlgs(DFBSurfaceLockFlags(0)), mem(0), engine(0), imageFormat(QImage::Format_Invalid)
-{
-#ifdef QT_DIRECTFB_SUBSURFACE
- subSurface = 0;
- syncPending = false;
-#endif
-}
-
-QDirectFBPaintDevice::~QDirectFBPaintDevice()
-{
- if (QDirectFBScreen::instance()) {
- unlockSurface();
-#ifdef QT_DIRECTFB_SUBSURFACE
- releaseSubSurface();
-#endif
- if (dfbSurface) {
- screen->releaseDFBSurface(dfbSurface);
- }
- }
- delete engine;
-}
-
-IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const
-{
- return dfbSurface;
-}
-
-bool QDirectFBPaintDevice::lockSurface(DFBSurfaceLockFlags lockFlags)
-{
- if (lockFlgs && (lockFlags & ~lockFlgs))
- unlockSurface();
- if (!mem) {
- Q_ASSERT(dfbSurface);
-#ifdef QT_DIRECTFB_SUBSURFACE
- if (!subSurface) {
- DFBResult result;
- subSurface = screen->getSubSurface(dfbSurface, QRect(), QDirectFBScreen::TrackSurface, &result);
- if (result != DFB_OK || !subSurface) {
- DirectFBError("Couldn't create sub surface", result);
- return false;
- }
- }
- IDirectFBSurface *surface = subSurface;
-#else
- IDirectFBSurface *surface = dfbSurface;
-#endif
- Q_ASSERT(surface);
- mem = QDirectFBScreen::lockSurface(surface, lockFlags, &bpl);
- lockFlgs = lockFlags;
- Q_ASSERT(mem);
- Q_ASSERT(bpl > 0);
- const QSize s = size();
- lockedImage = QImage(mem, s.width(), s.height(), bpl,
- QDirectFBScreen::getImageFormat(dfbSurface));
- return true;
- }
-#ifdef QT_DIRECTFB_SUBSURFACE
- if (syncPending) {
- syncPending = false;
- screen->waitIdle();
- }
-#endif
- return false;
-}
-
-void QDirectFBPaintDevice::unlockSurface()
-{
- if (QDirectFBScreen::instance() && lockFlgs) {
-#ifdef QT_DIRECTFB_SUBSURFACE
- IDirectFBSurface *surface = subSurface;
-#else
- IDirectFBSurface *surface = dfbSurface;
-#endif
- if (surface) {
- surface->Unlock(surface);
- lockFlgs = static_cast<DFBSurfaceLockFlags>(0);
- mem = 0;
- }
- }
-}
-
-void *QDirectFBPaintDevice::memory() const
-{
- return mem;
-}
-
-QImage::Format QDirectFBPaintDevice::format() const
-{
- return imageFormat;
-}
-
-int QDirectFBPaintDevice::bytesPerLine() const
-{
- Q_ASSERT(!mem || bpl != -1);
- return bpl;
-}
-
-QSize QDirectFBPaintDevice::size() const
-{
- int w, h;
- dfbSurface->GetSize(dfbSurface, &w, &h);
- return QSize(w, h);
-}
-
-int QDirectFBPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- if (!dfbSurface)
- return 0;
-
- switch (metric) {
- case QPaintDevice::PdmWidth:
- case QPaintDevice::PdmHeight:
- return (metric == PdmWidth ? size().width() : size().height());
- case QPaintDevice::PdmWidthMM:
- return (size().width() * 1000) / dotsPerMeterX();
- case QPaintDevice::PdmHeightMM:
- return (size().height() * 1000) / dotsPerMeterY();
- case QPaintDevice::PdmPhysicalDpiX:
- case QPaintDevice::PdmDpiX:
- return (dotsPerMeterX() * 254) / 10000; // 0.0254 meters-per-inch
- case QPaintDevice::PdmPhysicalDpiY:
- case QPaintDevice::PdmDpiY:
- return (dotsPerMeterY() * 254) / 10000; // 0.0254 meters-per-inch
- case QPaintDevice::PdmDepth:
- return QDirectFBScreen::depth(imageFormat);
- case QPaintDevice::PdmNumColors: {
- if (!lockedImage.isNull())
- return lockedImage.colorCount();
-
- DFBResult result;
- IDirectFBPalette *palette = 0;
- unsigned int numColors = 0;
-
- result = dfbSurface->GetPalette(dfbSurface, &palette);
- if ((result != DFB_OK) || !palette)
- return 0;
-
- result = palette->GetSize(palette, &numColors);
- palette->Release(palette);
- if (result != DFB_OK)
- return 0;
-
- return numColors;
- }
- default:
- qCritical("QDirectFBPaintDevice::metric(): Unhandled metric!");
- return 0;
- }
-}
-
-QPaintEngine *QDirectFBPaintDevice::paintEngine() const
-{
- return engine;
-}
-
-#ifdef QT_DIRECTFB_SUBSURFACE
-void QDirectFBPaintDevice::releaseSubSurface()
-{
- Q_ASSERT(QDirectFBScreen::instance());
- if (subSurface) {
- unlockSurface();
- screen->releaseDFBSurface(subSurface);
- subSurface = 0;
- }
-}
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
deleted file mode 100644
index 975954a496..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTFBPAINTDEVICE_H
-#define QDIRECTFBPAINTDEVICE_H
-
-#include <private/qpaintengine_raster_p.h>
-#include "qdirectfbscreen.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-// Inherited by both window surface and pixmap
-class QDirectFBPaintEngine;
-class QDirectFBPaintDevice : public QCustomRasterPaintDevice
-{
-public:
- ~QDirectFBPaintDevice();
-
- virtual IDirectFBSurface *directFBSurface() const;
-
- bool lockSurface(DFBSurfaceLockFlags lockFlags);
- void unlockSurface();
-
- // Reimplemented from QCustomRasterPaintDevice:
- void *memory() const;
- QImage::Format format() const;
- int bytesPerLine() const;
- QSize size() const;
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
- DFBSurfaceLockFlags lockFlags() const { return lockFlgs; }
- QPaintEngine *paintEngine() const;
-protected:
- QDirectFBPaintDevice(QDirectFBScreen *scr);
- inline int dotsPerMeterX() const
- {
- return (screen->deviceWidth() * 1000) / screen->physicalWidth();
- }
- inline int dotsPerMeterY() const
- {
- return (screen->deviceHeight() * 1000) / screen->physicalHeight();
- }
-
- IDirectFBSurface *dfbSurface;
-#ifdef QT_DIRECTFB_SUBSURFACE
- void releaseSubSurface();
- IDirectFBSurface *subSurface;
- friend class QDirectFBPaintEnginePrivate;
- bool syncPending;
-#endif
- QImage lockedImage;
- QDirectFBScreen *screen;
- int bpl;
- DFBSurfaceLockFlags lockFlgs;
- uchar *mem;
- QDirectFBPaintEngine *engine;
- QImage::Format imageFormat;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-#endif //QDIRECTFBPAINTDEVICE_H
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
deleted file mode 100644
index 18861cfac1..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ /dev/null
@@ -1,1430 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbpaintengine.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include "qdirectfbwindowsurface.h"
-#include "qdirectfbscreen.h"
-#include "qdirectfbpixmap.h"
-#include <directfb.h>
-#include <qtransform.h>
-#include <qvarlengtharray.h>
-#include <qcache.h>
-#include <qmath.h>
-#include <private/qpixmapdata_p.h>
-#include <private/qpixmap_raster_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-class SurfaceCache;
-class QDirectFBPaintEnginePrivate : public QRasterPaintEnginePrivate
-{
-public:
- enum TransformationTypeFlags {
- Matrix_NegativeScale = 0x100,
- Matrix_RectsUnsupported = (QTransform::TxRotate|QTransform::TxShear|QTransform::TxProject),
- Matrix_BlitsUnsupported = (Matrix_NegativeScale|Matrix_RectsUnsupported)
- };
-
- inline static uint getTransformationType(const QTransform &transform)
- {
- int ret = transform.type();
- if (qMin(transform.m11(), transform.m22()) < 0) {
- ret |= QDirectFBPaintEnginePrivate::Matrix_NegativeScale;
- }
- return ret;
- }
-
- enum CompositionModeStatus {
- PorterDuff_None = 0x0,
- PorterDuff_Supported = 0x1,
- PorterDuff_PremultiplyColors = 0x2,
- PorterDuff_AlwaysBlend = 0x4
- };
-
- enum ClipType {
- ClipUnset,
- NoClip,
- RectClip,
- RegionClip,
- ComplexClip
- };
-
- QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p);
- ~QDirectFBPaintEnginePrivate();
-
- inline void setTransform(const QTransform &transforma);
- inline void setPen(const QPen &pen);
- inline void setCompositionMode(QPainter::CompositionMode mode);
- inline void setRenderHints(QPainter::RenderHints hints);
-
- inline void setDFBColor(const QColor &color);
-
- inline void lock();
- inline void unlock();
- static inline void unlock(QDirectFBPaintDevice *device);
-
- inline bool isSimpleBrush(const QBrush &brush) const;
-
- void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos, const QTransform &pixmapTransform);
- void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src);
-
- inline bool supportsStretchBlit() const;
-
- inline void updateClip();
- virtual void systemStateChanged();
-
- static IDirectFBSurface *getSurface(const QImage &img, bool *release);
-
-#ifdef QT_DIRECTFB_IMAGECACHE
- static inline int cacheCost(const QImage &img) { return img.width() * img.height() * img.depth() / 8; }
-#endif
-
- enum BlitFlag {
- HasAlpha = 0x1,
- Premultiplied = 0x2
- };
- void prepareForBlit(uint blitFlags);
-
- IDirectFBSurface *surface;
-
- bool antialiased;
- bool simplePen;
-
- uint transformationType; // this is QTransform::type() + Matrix_NegativeScale if qMin(transform.m11(), transform.m22()) < 0
-
- SurfaceCache *surfaceCache;
- IDirectFB *fb;
- quint8 opacity;
-
- ClipType clipType;
- QDirectFBPaintDevice *dfbDevice;
- uint compositionModeStatus;
- bool isPremultiplied;
-
- bool inClip;
- QRect currentClip;
-
- QDirectFBPaintEngine *q;
-};
-
-class SurfaceCache
-{
-public:
- SurfaceCache() : surface(0), buffer(0), bufsize(0) {}
- ~SurfaceCache() { clear(); }
- IDirectFBSurface *getSurface(const uint *buf, int size);
- void clear();
-private:
- IDirectFBSurface *surface;
- uint *buffer;
- int bufsize;
-};
-
-
-#ifdef QT_DIRECTFB_IMAGECACHE
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <private/qimage_p.h>
-QT_END_INCLUDE_NAMESPACE
-struct CachedImage
-{
- IDirectFBSurface *surface;
- ~CachedImage()
- {
- if (surface && QDirectFBScreen::instance()) {
- QDirectFBScreen::instance()->releaseDFBSurface(surface);
- }
- }
-};
-static QCache<qint64, CachedImage> imageCache(4*1024*1024); // 4 MB
-#endif
-
-#define VOID_ARG() static_cast<bool>(false)
-enum PaintOperation {
- DRAW_RECTS = 0x0001, DRAW_LINES = 0x0002, DRAW_IMAGE = 0x0004,
- DRAW_PIXMAP = 0x0008, DRAW_TILED_PIXMAP = 0x0010, STROKE_PATH = 0x0020,
- DRAW_PATH = 0x0040, DRAW_POINTS = 0x0080, DRAW_ELLIPSE = 0x0100,
- DRAW_POLYGON = 0x0200, DRAW_TEXT = 0x0400, FILL_PATH = 0x0800,
- FILL_RECT = 0x1000, DRAW_COLORSPANS = 0x2000, DRAW_ROUNDED_RECT = 0x4000,
- DRAW_STATICTEXT = 0x8000, ALL = 0xffff
-};
-
-enum { RasterWarn = 1, RasterDisable = 2 };
-static inline uint rasterFallbacksMask(PaintOperation op)
-{
- uint ret = 0;
-#ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
- if (op & QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)
- ret |= RasterWarn;
-#endif
-#ifdef QT_DIRECTFB_DISABLE_RASTERFALLBACKS
- if (op & QT_DIRECTFB_DISABLE_RASTERFALLBACKS)
- ret |= RasterDisable;
-#endif
- static int warningMask = -1;
- static int disableMask = -1;
- if (warningMask < 0) {
- struct {
- const char *name;
- PaintOperation operation;
- } const operations[] = {
- { "DRAW_RECTS", DRAW_RECTS },
- { "DRAW_LINES", DRAW_LINES },
- { "DRAW_IMAGE", DRAW_IMAGE },
- { "DRAW_PIXMAP", DRAW_PIXMAP },
- { "DRAW_TILED_PIXMAP", DRAW_TILED_PIXMAP },
- { "STROKE_PATH", STROKE_PATH },
- { "DRAW_PATH", DRAW_PATH },
- { "DRAW_POINTS", DRAW_POINTS },
- { "DRAW_ELLIPSE", DRAW_ELLIPSE },
- { "DRAW_POLYGON", DRAW_POLYGON },
- { "DRAW_TEXT", DRAW_TEXT },
- { "FILL_PATH", FILL_PATH },
- { "FILL_RECT", FILL_RECT },
- { "DRAW_COLORSPANS", DRAW_COLORSPANS },
- { "DRAW_ROUNDED_RECT", DRAW_ROUNDED_RECT },
- { "ALL", ALL },
- { 0, ALL }
- };
-
- QStringList warning = QString::fromLatin1(qgetenv("QT_DIRECTFB_WARN_ON_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
- QString::SkipEmptyParts);
- QStringList disable = QString::fromLatin1(qgetenv("QT_DIRECTFB_DISABLE_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
- QString::SkipEmptyParts);
- warningMask = 0;
- disableMask = 0;
- if (!warning.isEmpty() || !disable.isEmpty()) {
- for (int i=0; operations[i].name; ++i) {
- const QString name = QString::fromLatin1(operations[i].name);
- int idx = warning.indexOf(name);
- if (idx != -1) {
- warningMask |= operations[i].operation;
- warning.erase(warning.begin() + idx);
- }
- idx = disable.indexOf(name);
- if (idx != -1) {
- disableMask |= operations[i].operation;
- disable.erase(disable.begin() + idx);
- }
- }
- }
- if (!warning.isEmpty()) {
- qWarning("QDirectFBPaintEngine QT_DIRECTFB_WARN_ON_RASTERFALLBACKS Unknown operation(s): %s",
- qPrintable(warning.join(QLatin1String("|"))));
- }
- if (!disable.isEmpty()) {
- qWarning("QDirectFBPaintEngine QT_DIRECTFB_DISABLE_RASTERFALLBACKS Unknown operation(s): %s",
- qPrintable(disable.join(QLatin1String("|"))));
- }
- }
- if (op & warningMask)
- ret |= RasterWarn;
- if (op & disableMask)
- ret |= RasterDisable;
- return ret;
-}
-
-template <typename device, typename T1, typename T2, typename T3>
-static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
- uint transformationType, bool simplePen,
- uint clipType, uint compositionModeStatus,
- const char *nameOne, const T1 &one,
- const char *nameTwo, const T2 &two,
- const char *nameThree, const T3 &three);
-
-#define RASTERFALLBACK(op, one, two, three) \
- { \
- static const uint rasterFallbacks = rasterFallbacksMask(op); \
- switch (rasterFallbacks) { \
- case 0: break; \
- case RasterWarn: \
- rasterFallbackWarn("Falling back to raster engine for", \
- __FUNCTION__, \
- state()->painter->device(), \
- d_func()->transformationType, \
- d_func()->simplePen, \
- d_func()->clipType, \
- d_func()->compositionModeStatus, \
- #one, one, #two, two, #three, three); \
- break; \
- case RasterDisable|RasterWarn: \
- rasterFallbackWarn("Disabled raster engine operation", \
- __FUNCTION__, \
- state()->painter->device(), \
- d_func()->transformationType, \
- d_func()->simplePen, \
- d_func()->clipType, \
- d_func()->compositionModeStatus, \
- #one, one, #two, two, #three, three); \
- case RasterDisable: \
- return; \
- } \
- }
-
-template <class T>
-static inline void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface);
-template <class T>
-static inline void fillRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface);
-template <class T>
-static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface);
-
-#define CLIPPED_PAINT(operation) { \
- d->unlock(); \
- DFBRegion clipRegion; \
- switch (d->clipType) { \
- case QDirectFBPaintEnginePrivate::NoClip: \
- case QDirectFBPaintEnginePrivate::RectClip: \
- operation; \
- break; \
- case QDirectFBPaintEnginePrivate::RegionClip: { \
- Q_ASSERT(d->clip()); \
- const QVector<QRect> cr = d->clip()->clipRegion.rects(); \
- const int size = cr.size(); \
- for (int i=0; i<size; ++i) { \
- d->currentClip = cr.at(i); \
- clipRegion.x1 = d->currentClip.x(); \
- clipRegion.y1 = d->currentClip.y(); \
- clipRegion.x2 = d->currentClip.right(); \
- clipRegion.y2 = d->currentClip.bottom(); \
- d->surface->SetClip(d->surface, &clipRegion); \
- operation; \
- } \
- d->updateClip(); \
- break; } \
- case QDirectFBPaintEnginePrivate::ComplexClip: \
- case QDirectFBPaintEnginePrivate::ClipUnset: \
- qFatal("CLIPPED_PAINT internal error %d", d->clipType); \
- break; \
- } \
- }
-
-
-QDirectFBPaintEngine::QDirectFBPaintEngine(QPaintDevice *device)
- : QRasterPaintEngine(*(new QDirectFBPaintEnginePrivate(this)), device)
-{
-}
-
-QDirectFBPaintEngine::~QDirectFBPaintEngine()
-{
-}
-
-bool QDirectFBPaintEngine::begin(QPaintDevice *device)
-{
- Q_D(QDirectFBPaintEngine);
- if (device->devType() == QInternal::CustomRaster) {
- d->dfbDevice = static_cast<QDirectFBPaintDevice*>(device);
- } else if (device->devType() == QInternal::Pixmap) {
- QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData();
- Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbPixmapData = static_cast<QDirectFBPixmapData*>(data);
- QDirectFBPaintEnginePrivate::unlock(dfbPixmapData);
- d->dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData);
- }
-
- if (d->dfbDevice)
- d->surface = d->dfbDevice->directFBSurface();
-
- if (!d->surface) {
- qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x",
- device->devType());
- }
- d->isPremultiplied = QDirectFBScreen::isPremultiplied(d->dfbDevice->format());
-
- d->prepare(d->dfbDevice);
- gccaps = AllFeatures;
- d->setCompositionMode(state()->composition_mode);
-
- return QRasterPaintEngine::begin(device);
-}
-
-bool QDirectFBPaintEngine::end()
-{
- Q_D(QDirectFBPaintEngine);
- d->unlock();
- d->dfbDevice = 0;
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- d->surface->ReleaseSource(d->surface);
-#endif
- d->currentClip = QRect();
- d->surface->SetClip(d->surface, NULL);
- d->surface = 0;
- return QRasterPaintEngine::end();
-}
-
-void QDirectFBPaintEngine::clipEnabledChanged()
-{
- Q_D(QDirectFBPaintEngine);
- QRasterPaintEngine::clipEnabledChanged();
- d->updateClip();
-}
-
-void QDirectFBPaintEngine::penChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->setPen(state()->pen);
-
- QRasterPaintEngine::penChanged();
-}
-
-void QDirectFBPaintEngine::opacityChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->opacity = quint8(state()->opacity * 255);
- QRasterPaintEngine::opacityChanged();
-}
-
-void QDirectFBPaintEngine::compositionModeChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->setCompositionMode(state()->compositionMode());
- QRasterPaintEngine::compositionModeChanged();
-}
-
-void QDirectFBPaintEngine::renderHintsChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->setRenderHints(state()->renderHints);
- QRasterPaintEngine::renderHintsChanged();
-}
-
-void QDirectFBPaintEngine::transformChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->setTransform(state()->matrix);
- QRasterPaintEngine::transformChanged();
-}
-
-void QDirectFBPaintEngine::setState(QPainterState *state)
-{
- Q_D(QDirectFBPaintEngine);
- QRasterPaintEngine::setState(state);
- d->setPen(state->pen);
- d->opacity = quint8(state->opacity * 255);
- d->setCompositionMode(state->compositionMode());
- d->setTransform(state->transform());
- d->setRenderHints(state->renderHints);
- if (d->surface)
- d->updateClip();
-}
-
-void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
-{
- Q_D(QDirectFBPaintEngine);
- const bool wasInClip = d->inClip;
- d->inClip = true;
- QRasterPaintEngine::clip(path, op);
- if (!wasInClip) {
- d->inClip = false;
- d->updateClip();
- }
-}
-
-void QDirectFBPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
-{
- Q_D(QDirectFBPaintEngine);
- const bool wasInClip = d->inClip;
- d->inClip = true;
- QRasterPaintEngine::clip(region, op);
- if (!wasInClip) {
- d->inClip = false;
- d->updateClip();
- }
-}
-
-void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
-{
- Q_D(QDirectFBPaintEngine);
- const bool wasInClip = d->inClip;
- d->inClip = true;
- QRasterPaintEngine::clip(rect, op);
- if (!wasInClip) {
- d->inClip = false;
- d->updateClip();
- }
-}
-
-void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
-{
- Q_D(QDirectFBPaintEngine);
- const QPen &pen = state()->pen;
- const QBrush &brush = state()->brush;
- if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
- return;
-
- if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
- || !d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !d->isSimpleBrush(brush)
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
- d->lock();
- QRasterPaintEngine::drawRects(rects, rectCount);
- return;
- }
-
- if (brush.style() != Qt::NoBrush) {
- d->setDFBColor(brush.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(fillRects<QRect>)(rects, rectCount, state()->matrix, d->surface));
- }
-
- if (pen.style() != Qt::NoPen) {
- d->setDFBColor(pen.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawRects<QRect>)(rects, rectCount, state()->matrix, d->surface));
- }
-}
-
-void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QDirectFBPaintEngine);
- const QPen &pen = state()->pen;
- const QBrush &brush = state()->brush;
- if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
- return;
-
- if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
- || !d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !d->isSimpleBrush(brush)
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
- d->lock();
- QRasterPaintEngine::drawRects(rects, rectCount);
- return;
- }
-
- if (brush.style() != Qt::NoBrush) {
- d->setDFBColor(brush.color());
- CLIPPED_PAINT(fillRects<QRectF>(rects, rectCount, state()->matrix, d->surface));
- }
-
- if (pen.style() != Qt::NoPen) {
- d->setDFBColor(pen.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawRects<QRectF>)(rects, rectCount, state()->matrix, d->surface));
- }
-}
-
-void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
-{
- Q_D(QDirectFBPaintEngine);
-
- const QPen &pen = state()->pen;
- if (!d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
- d->lock();
- QRasterPaintEngine::drawLines(lines, lineCount);
- return;
- }
-
- if (pen.style() != Qt::NoPen) {
- d->setDFBColor(pen.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface));
- }
-}
-
-void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
- Q_D(QDirectFBPaintEngine);
-
- const QPen &pen = state()->pen;
- if (!d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
- d->lock();
- QRasterPaintEngine::drawLines(lines, lineCount);
- return;
- }
-
- if (pen.style() != Qt::NoPen) {
- d->setDFBColor(pen.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface));
- }
-}
-
-void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
- const QRectF &sr,
- Qt::ImageConversionFlags flags)
-{
- Q_D(QDirectFBPaintEngine);
- Q_UNUSED(flags);
-
- /* This is hard to read. The way it works is like this:
-
- - If you do not have support for preallocated surfaces and do not use an
- image cache we always fall back to raster engine.
-
- - If it's rotated/sheared/mirrored (negative scale) or we can't
- clip it we fall back to raster engine.
-
- - If we don't cache the image, but we do have support for
- preallocated surfaces we fall back to the raster engine if the
- image is in a format DirectFB can't handle.
-
- - If we do cache the image but don't have support for preallocated
- images and the cost of caching the image (bytes used) is higher
- than the max image cache size we fall back to raster engine.
- */
-
-#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
- || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())
-#ifndef QT_DIRECTFB_IMAGECACHE
- || (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN)
-#elif defined QT_NO_DIRECTFB_PREALLOCATED
- || (QDirectFBPaintEnginePrivate::cacheCost(image) > imageCache.maxCost())
-#endif
- )
-#endif
- {
- RASTERFALLBACK(DRAW_IMAGE, r, image.size(), sr);
- d->lock();
- QRasterPaintEngine::drawImage(r, image, sr, flags);
- return;
- }
-#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
- bool release;
- IDirectFBSurface *imgSurface = d->getSurface(image, &release);
- uint blitFlags = 0;
- if (image.hasAlphaChannel())
- blitFlags |= QDirectFBPaintEnginePrivate::HasAlpha;
- if (QDirectFBScreen::isPremultiplied(image.format()))
- blitFlags |= QDirectFBPaintEnginePrivate::Premultiplied;
- d->prepareForBlit(blitFlags);
- CLIPPED_PAINT(d->blit(r, imgSurface, sr));
- if (release) {
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- d->surface->ReleaseSource(d->surface);
-#endif
- imgSurface->Release(imgSurface);
- }
-#endif
-}
-
-void QDirectFBPaintEngine::drawImage(const QPointF &p, const QImage &img)
-{
- drawImage(QRectF(p, img.size()), img, img.rect());
-}
-
-void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap,
- const QRectF &sr)
-{
- Q_D(QDirectFBPaintEngine);
-
- if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
- RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
- d->lock();
- QRasterPaintEngine::drawPixmap(r, pixmap, sr);
- } else {
- QPixmapData *data = pixmap.pixmapData();
- Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
- || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())) {
- RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
- const QImage *img = dfbData->buffer();
- d->lock();
- QRasterPaintEngine::drawImage(r, *img, sr);
- } else {
- QDirectFBPaintEnginePrivate::unlock(dfbData);
- IDirectFBSurface *s = dfbData->directFBSurface();
- uint blitFlags = 0;
- if (pixmap.hasAlphaChannel())
- blitFlags |= QDirectFBPaintEnginePrivate::HasAlpha;
- if (QDirectFBScreen::isPremultiplied(dfbData->pixelFormat()))
- blitFlags |= QDirectFBPaintEnginePrivate::Premultiplied;
-
- d->prepareForBlit(blitFlags);
- CLIPPED_PAINT(d->blit(r, s, sr));
- }
- }
-}
-
-void QDirectFBPaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
-{
- drawPixmap(QRectF(p, pm.size()), pm, pm.rect());
-}
-
-void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r,
- const QPixmap &pixmap,
- const QPointF &offset)
-{
- Q_D(QDirectFBPaintEngine);
- if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
- RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
- d->lock();
- QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset);
- } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
- || (!d->supportsStretchBlit() && state()->matrix.isScaling())) {
- RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
- QPixmapData *pixmapData = pixmap.pixmapData();
- Q_ASSERT(pixmapData->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(pixmapData);
- const QImage *img = dfbData->buffer();
- d->lock();
- QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType);
- data->fromImage(*img, Qt::AutoColor);
- const QPixmap pix(data);
- QRasterPaintEngine::drawTiledPixmap(r, pix, offset);
- } else {
- QTransform transform(state()->matrix);
- CLIPPED_PAINT(d->drawTiledPixmap(r, pixmap, offset, transform));
- }
-}
-
-
-void QDirectFBPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
-{
- RASTERFALLBACK(STROKE_PATH, path, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::stroke(path, pen);
-}
-
-void QDirectFBPaintEngine::drawPath(const QPainterPath &path)
-{
- RASTERFALLBACK(DRAW_PATH, path, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPath(path);
-}
-
-void QDirectFBPaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
- RASTERFALLBACK(DRAW_POINTS, pointCount, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPoints(points, pointCount);
-}
-
-void QDirectFBPaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
- RASTERFALLBACK(DRAW_POINTS, pointCount, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPoints(points, pointCount);
-}
-
-void QDirectFBPaintEngine::drawEllipse(const QRectF &rect)
-{
- RASTERFALLBACK(DRAW_ELLIPSE, rect, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawEllipse(rect);
-}
-
-void QDirectFBPaintEngine::drawPolygon(const QPointF *points, int pointCount,
- PolygonDrawMode mode)
-{
- RASTERFALLBACK(DRAW_POLYGON, pointCount, mode, VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPolygon(points, pointCount, mode);
-}
-
-void QDirectFBPaintEngine::drawPolygon(const QPoint *points, int pointCount,
- PolygonDrawMode mode)
-{
- RASTERFALLBACK(DRAW_POLYGON, pointCount, mode, VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPolygon(points, pointCount, mode);
-}
-
-void QDirectFBPaintEngine::drawTextItem(const QPointF &p,
- const QTextItem &textItem)
-{
- RASTERFALLBACK(DRAW_TEXT, p, textItem.text(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawTextItem(p, textItem);
-}
-
-void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
-{
- if (brush.style() == Qt::NoBrush)
- return;
- RASTERFALLBACK(FILL_PATH, path, brush, VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::fill(path, brush);
-}
-
-void QDirectFBPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode)
-{
- RASTERFALLBACK(DRAW_ROUNDED_RECT, rect, xrad, yrad);
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawRoundedRect(rect, xrad, yrad, mode);
-}
-
-void QDirectFBPaintEngine::drawStaticTextItem(QStaticTextItem *item)
-{
- RASTERFALLBACK(DRAW_STATICTEXT, item, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawStaticTextItem(item);
-}
-
-void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
-{
- Q_D(QDirectFBPaintEngine);
- if (brush.style() == Qt::NoBrush)
- return;
- if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) {
- switch (brush.style()) {
- case Qt::SolidPattern: {
- const QColor color = brush.color();
- if (!color.isValid())
- return;
-
- if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- break;
- }
- d->setDFBColor(color);
- const QRect r = state()->matrix.mapRect(rect).toRect();
- CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()));
- return; }
-
- case Qt::TexturePattern: {
- const QPointF &brushOrigin = state()->brushOrigin;
- const QTransform stateTransform = state()->matrix;
- QTransform transform(stateTransform);
- transform.translate(brushOrigin.x(), brushOrigin.y());
- transform = brush.transform() * transform;
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
- || (QDirectFBPaintEnginePrivate::getTransformationType(transform) & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || (!d->supportsStretchBlit() && transform.isScaling())) {
- break;
- }
-
- const QPixmap texture = brush.texture();
- if (texture.pixmapData()->classId() != QPixmapData::DirectFBClass)
- break;
-
- CLIPPED_PAINT(d->drawTiledPixmap(stateTransform.mapRect(rect), texture, rect.topLeft() - brushOrigin, transform));
- return; }
- default:
- break;
- }
- }
- RASTERFALLBACK(FILL_RECT, rect, brush, VOID_ARG());
- d->lock();
- QRasterPaintEngine::fillRect(rect, brush);
-}
-
-void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
-{
- if (!color.isValid())
- return;
- Q_D(QDirectFBPaintEngine);
- if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
- || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
- d->lock();
- QRasterPaintEngine::fillRect(rect, color);
- } else {
- d->setDFBColor(color);
- const QRect r = state()->matrix.mapRect(rect).toRect();
- CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()));
- }
-}
-
-void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
- int x, int y, int length,
- uint const_alpha)
-{
- Q_D(QDirectFBPaintEngine);
- IDirectFBSurface *src = d->surfaceCache->getSurface(buffer, bufsize);
- // ### how does this play with setDFBColor
- src->SetColor(src, 0, 0, 0, const_alpha);
- const DFBRectangle rect = { 0, 0, length, 1 };
- d->surface->Blit(d->surface, src, &rect, x, y);
-}
-
-#ifdef QT_DIRECTFB_IMAGECACHE
-static void cachedImageCleanupHook(qint64 key)
-{
- delete imageCache.take(key);
-}
-void QDirectFBPaintEngine::initImageCache(int size)
-{
- Q_ASSERT(size >= 0);
- imageCache.setMaxCost(size);
- QImagePixmapCleanupHooks::instance()->addImageHook(cachedImageCleanupHook);
-}
-
-#endif // QT_DIRECTFB_IMAGECACHE
-
-// ---- QDirectFBPaintEnginePrivate ----
-
-
-QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p)
- : surface(0), antialiased(false), simplePen(false),
- transformationType(0), opacity(255),
- clipType(ClipUnset), dfbDevice(0),
- compositionModeStatus(0), isPremultiplied(false), inClip(false), q(p)
-{
- fb = QDirectFBScreen::instance()->dfb();
- surfaceCache = new SurfaceCache;
-}
-
-QDirectFBPaintEnginePrivate::~QDirectFBPaintEnginePrivate()
-{
- delete surfaceCache;
-}
-
-bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const
-{
- return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
-}
-
-void QDirectFBPaintEnginePrivate::lock()
-{
- // We will potentially get a new pointer to the buffer after a
- // lock so we need to call the base implementation of prepare so
- // it updates its rasterBuffer to point to the new buffer address.
- Q_ASSERT(dfbDevice);
- if (dfbDevice->lockSurface(DSLF_READ|DSLF_WRITE)) {
- prepare(dfbDevice);
- }
-}
-
-void QDirectFBPaintEnginePrivate::unlock()
-{
- Q_ASSERT(dfbDevice);
-#ifdef QT_DIRECTFB_SUBSURFACE
- dfbDevice->syncPending = true;
-#else
- QDirectFBPaintEnginePrivate::unlock(dfbDevice);
-#endif
-}
-
-void QDirectFBPaintEnginePrivate::unlock(QDirectFBPaintDevice *device)
-{
-#ifdef QT_NO_DIRECTFB_SUBSURFACE
- Q_ASSERT(device);
- device->unlockSurface();
-#else
- Q_UNUSED(device);
-#endif
-}
-
-void QDirectFBPaintEnginePrivate::setTransform(const QTransform &transform)
-{
- transformationType = getTransformationType(transform);
- setPen(q->state()->pen);
-}
-
-void QDirectFBPaintEnginePrivate::setPen(const QPen &pen)
-{
- if (pen.style() == Qt::NoPen) {
- simplePen = true;
- } else if (pen.style() == Qt::SolidLine
- && !antialiased
- && pen.brush().style() == Qt::SolidPattern
- && pen.widthF() <= 1.0
- && (transformationType < QTransform::TxScale || pen.isCosmetic())) {
- simplePen = true;
- } else {
- simplePen = false;
- }
-}
-
-void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode)
-{
- if (!surface)
- return;
-
- static const bool forceRasterFallBack = qgetenv("QT_DIRECTFB_FORCE_RASTER").toInt() > 0;
- if (forceRasterFallBack) {
- compositionModeStatus = PorterDuff_None;
- return;
- }
-
- compositionModeStatus = PorterDuff_Supported|PorterDuff_PremultiplyColors|PorterDuff_AlwaysBlend;
- switch (mode) {
- case QPainter::CompositionMode_Clear:
- surface->SetPorterDuff(surface, DSPD_CLEAR);
- break;
- case QPainter::CompositionMode_Source:
- surface->SetPorterDuff(surface, DSPD_SRC);
- compositionModeStatus &= ~PorterDuff_AlwaysBlend;
- if (!isPremultiplied)
- compositionModeStatus &= ~PorterDuff_PremultiplyColors;
- break;
- case QPainter::CompositionMode_SourceOver:
- compositionModeStatus &= ~PorterDuff_AlwaysBlend;
- surface->SetPorterDuff(surface, DSPD_SRC_OVER);
- break;
- case QPainter::CompositionMode_DestinationOver:
- surface->SetPorterDuff(surface, DSPD_DST_OVER);
- break;
- case QPainter::CompositionMode_SourceIn:
- surface->SetPorterDuff(surface, DSPD_SRC_IN);
- if (!isPremultiplied)
- compositionModeStatus &= ~PorterDuff_PremultiplyColors;
- break;
- case QPainter::CompositionMode_DestinationIn:
- surface->SetPorterDuff(surface, DSPD_DST_IN);
- break;
- case QPainter::CompositionMode_SourceOut:
- surface->SetPorterDuff(surface, DSPD_SRC_OUT);
- break;
- case QPainter::CompositionMode_DestinationOut:
- surface->SetPorterDuff(surface, DSPD_DST_OUT);
- break;
- case QPainter::CompositionMode_Destination:
- surface->SetSrcBlendFunction(surface, DSBF_ZERO);
- surface->SetDstBlendFunction(surface, DSBF_ONE);
- break;
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- case QPainter::CompositionMode_SourceAtop:
- surface->SetPorterDuff(surface, DSPD_SRC_ATOP);
- break;
- case QPainter::CompositionMode_DestinationAtop:
- surface->SetPorterDuff(surface, DSPD_DST_ATOP);
- break;
- case QPainter::CompositionMode_Plus:
- surface->SetPorterDuff(surface, DSPD_ADD);
- break;
- case QPainter::CompositionMode_Xor:
- surface->SetPorterDuff(surface, DSPD_XOR);
- break;
-#endif
- default:
- compositionModeStatus = PorterDuff_None;
- break;
- }
-}
-
-void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints)
-{
- const bool old = antialiased;
- antialiased = bool(hints & QPainter::Antialiasing);
- if (old != antialiased) {
- setPen(q->state()->pen);
- }
-}
-
-void QDirectFBPaintEnginePrivate::prepareForBlit(uint flags)
-{
- DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX;
- if (flags & Premultiplied)
- blittingFlags |= DSBLIT_SRC_PREMULTIPLY;
- if (flags & HasAlpha)
- blittingFlags |= DSBLIT_BLEND_ALPHACHANNEL;
- if (opacity != 255) {
- blittingFlags |= DSBLIT_BLEND_COLORALPHA;
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
- }
-
- surface->SetBlittingFlags(surface, blittingFlags);
-}
-
-static inline uint ALPHA_MUL(uint x, uint a)
-{
- uint t = x * a;
- t = ((t + (t >> 8) + 0x80) >> 8) & 0xff;
- return t;
-}
-
-void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color)
-{
- Q_ASSERT(surface);
- Q_ASSERT(compositionModeStatus & PorterDuff_Supported);
- const quint8 alpha = (opacity == 255 ?
- color.alpha() : ALPHA_MUL(color.alpha(), opacity));
- QColor col;
- if (compositionModeStatus & PorterDuff_PremultiplyColors) {
- col = QColor(ALPHA_MUL(color.red(), alpha),
- ALPHA_MUL(color.green(), alpha),
- ALPHA_MUL(color.blue(), alpha),
- alpha);
- } else {
- col = QColor(color.red(), color.green(), color.blue(), alpha);
- }
- surface->SetColor(surface, col.red(), col.green(), col.blue(), col.alpha());
- surface->SetDrawingFlags(surface, alpha == 255 && !(compositionModeStatus & PorterDuff_AlwaysBlend) ? DSDRAW_NOFX : DSDRAW_BLEND);
-}
-
-IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release)
-{
-#ifdef QT_NO_DIRECTFB_IMAGECACHE
- *release = true;
- return QDirectFBScreen::instance()->createDFBSurface(img, img.format(), QDirectFBScreen::DontTrackSurface);
-#else
- const qint64 key = img.cacheKey();
- *release = false;
- if (imageCache.contains(key)) {
- return imageCache[key]->surface;
- }
-
- const int cost = cacheCost(img);
- const bool cache = cost <= imageCache.maxCost();
- QDirectFBScreen *screen = QDirectFBScreen::instance();
- const QImage::Format format = (img.format() == screen->alphaPixmapFormat() || QDirectFBPixmapData::hasAlphaChannel(img)
- ? screen->alphaPixmapFormat() : screen->pixelFormat());
-
- IDirectFBSurface *surface = screen->createDFBSurface(img, format,
- cache
- ? QDirectFBScreen::TrackSurface
- : QDirectFBScreen::DontTrackSurface);
- if (cache) {
- CachedImage *cachedImage = new CachedImage;
- const_cast<QImage&>(img).data_ptr()->is_cached = true;
- cachedImage->surface = surface;
- imageCache.insert(key, cachedImage, cost);
- } else {
- *release = true;
- }
- return surface;
-#endif
-}
-
-
-void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s, const QRectF &src)
-{
- const QRect sr = src.toRect();
- const QRect dr = q->state()->matrix.mapRect(dest).toRect();
- if (dr.isEmpty())
- return;
- const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() };
- DFBResult result;
-
- if (dr.size() == sr.size()) {
- result = surface->Blit(surface, s, &sRect, dr.x(), dr.y());
- } else {
- Q_ASSERT(supportsStretchBlit());
- const DFBRectangle dRect = { dr.x(), dr.y(), dr.width(), dr.height() };
- result = surface->StretchBlit(surface, s, &sRect, &dRect);
- }
- if (result != DFB_OK)
- DirectFBError("QDirectFBPaintEngine::drawPixmap()", result);
-}
-
-static inline qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset)
-{
- qreal pos = rect_pos - offset;
- while (pos > rect_pos)
- pos -= pixmapSize;
- while (pos + pixmapSize < rect_pos)
- pos += pixmapSize;
- return pos;
-}
-
-void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap,
- const QPointF &off, const QTransform &pixmapTransform)
-{
- const QTransform &transform = q->state()->matrix;
- Q_ASSERT(!(getTransformationType(transform) & Matrix_BlitsUnsupported) &&
- !(getTransformationType(pixmapTransform) & Matrix_BlitsUnsupported));
- const QRect destinationRect = transform.mapRect(dest).toRect().normalized();
- QRect newClip = destinationRect;
- if (!currentClip.isEmpty())
- newClip &= currentClip;
-
- if (newClip.isNull())
- return;
-
- const DFBRegion clip = {
- newClip.x(),
- newClip.y(),
- newClip.right(),
- newClip.bottom()
- };
- surface->SetClip(surface, &clip);
-
- QPointF offset = pixmapTransform.inverted().map(off);
- Q_ASSERT(transform.type() <= QTransform::TxScale);
- QPixmapData *data = pixmap.pixmapData();
- Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- IDirectFBSurface *sourceSurface = dfbData->directFBSurface();
- uint blitFlags = 0;
- if (dfbData->hasAlphaChannel())
- blitFlags |= HasAlpha;
- if (QDirectFBScreen::isPremultiplied(dfbData->pixelFormat()))
- blitFlags |= Premultiplied;
- prepareForBlit(blitFlags);
- QDirectFBPaintEnginePrivate::unlock(dfbData);
- const QSize pixmapSize = dfbData->size();
- if (transform.isScaling() || pixmapTransform.isScaling()) {
- Q_ASSERT(supportsStretchBlit());
- Q_ASSERT(qMin(transform.m11(), transform.m22()) >= 0);
- offset.rx() *= transform.m11();
- offset.ry() *= transform.m22();
-
- const QSizeF mappedSize(pixmapSize.width() * pixmapTransform.m11(), pixmapSize.height() * pixmapTransform.m22());
- qreal y = fixCoord(destinationRect.y(), mappedSize.height(), offset.y());
- const qreal startX = fixCoord(destinationRect.x(), mappedSize.width(), offset.x());
- while (y <= destinationRect.bottom()) {
- qreal x = startX;
- while (x <= destinationRect.right()) {
- const DFBRectangle destination = { qRound(x), qRound(y), mappedSize.width(), mappedSize.height() };
- surface->StretchBlit(surface, sourceSurface, 0, &destination);
- x += mappedSize.width();
- }
- y += mappedSize.height();
- }
- } else {
- qreal y = fixCoord(destinationRect.y(), pixmapSize.height(), offset.y());
- const qreal startX = fixCoord(destinationRect.x(), pixmapSize.width(), offset.x());
- int horizontal = qMax(1, destinationRect.width() / pixmapSize.width()) + 1;
- if (startX != destinationRect.x())
- ++horizontal;
- int vertical = qMax(1, destinationRect.height() / pixmapSize.height()) + 1;
- if (y != destinationRect.y())
- ++vertical;
-
- const int maxCount = (vertical * horizontal);
- QVarLengthArray<DFBRectangle, 16> sourceRects(maxCount);
- QVarLengthArray<DFBPoint, 16> points(maxCount);
-
- int i = 0;
- while (y <= destinationRect.bottom()) {
- Q_ASSERT(i < maxCount);
- qreal x = startX;
- while (x <= destinationRect.right()) {
- points[i].x = qRound(x);
- points[i].y = qRound(y);
- sourceRects[i].x = 0;
- sourceRects[i].y = 0;
- sourceRects[i].w = int(pixmapSize.width());
- sourceRects[i].h = int(pixmapSize.height());
- x += pixmapSize.width();
- ++i;
- }
- y += pixmapSize.height();
- }
- surface->BatchBlit(surface, sourceSurface, sourceRects.constData(), points.constData(), i);
- }
-
- if (currentClip.isEmpty()) {
- surface->SetClip(surface, 0);
- } else {
- const DFBRegion clip = {
- currentClip.x(),
- currentClip.y(),
- currentClip.right(),
- currentClip.bottom()
- };
- surface->SetClip(surface, &clip);
- }
-}
-
-void QDirectFBPaintEnginePrivate::updateClip()
-{
- Q_ASSERT(surface);
- currentClip = QRect();
- const QClipData *clipData = clip();
- if (!clipData || !clipData->enabled) {
- surface->SetClip(surface, NULL);
- clipType = NoClip;
- } else if (clipData->hasRectClip) {
- const DFBRegion r = {
- clipData->clipRect.x(),
- clipData->clipRect.y(),
- clipData->clipRect.right(),
- clipData->clipRect.bottom()
- };
- surface->SetClip(surface, &r);
- currentClip = clipData->clipRect.normalized();
- // ### is this guaranteed to always be normalized?
- clipType = RectClip;
- } else if (clipData->hasRegionClip) {
- clipType = RegionClip;
- } else {
- clipType = ComplexClip;
- }
-}
-
-bool QDirectFBPaintEnginePrivate::supportsStretchBlit() const
-{
-#ifdef QT_DIRECTFB_STRETCHBLIT
- return !(q->state()->renderHints & QPainter::SmoothPixmapTransform);
-#else
- return false;
-#endif
-}
-
-
-void QDirectFBPaintEnginePrivate::systemStateChanged()
-{
- QRasterPaintEnginePrivate::systemStateChanged();
- updateClip();
-}
-
-IDirectFBSurface *SurfaceCache::getSurface(const uint *buf, int size)
-{
- if (buffer == buf && bufsize == size)
- return surface;
-
- clear();
-
- const DFBSurfaceDescription description = QDirectFBScreen::getSurfaceDescription(buf, size);
- surface = QDirectFBScreen::instance()->createDFBSurface(description, QDirectFBScreen::TrackSurface, 0);
- if (!surface)
- qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface");
-
- buffer = const_cast<uint*>(buf);
- bufsize = size;
-
- return surface;
-}
-
-void SurfaceCache::clear()
-{
- if (surface && QDirectFBScreen::instance())
- QDirectFBScreen::instance()->releaseDFBSurface(surface);
- surface = 0;
- buffer = 0;
- bufsize = 0;
-}
-
-
-static inline QRect mapRect(const QTransform &transform, const QRect &rect) { return transform.mapRect(rect); }
-static inline QRect mapRect(const QTransform &transform, const QRectF &rect) { return transform.mapRect(rect).toRect(); }
-static inline QLine map(const QTransform &transform, const QLine &line) { return transform.map(line); }
-static inline QLine map(const QTransform &transform, const QLineF &line) { return transform.map(line).toLine(); }
-template <class T>
-static inline void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface)
-{
- if (n == 1) {
- const QLine l = map(transform, lines[0]);
- surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2());
- } else {
- QVarLengthArray<DFBRegion, 32> lineArray(n);
- for (int i=0; i<n; ++i) {
- const QLine l = map(transform, lines[i]);
- lineArray[i].x1 = l.x1();
- lineArray[i].y1 = l.y1();
- lineArray[i].x2 = l.x2();
- lineArray[i].y2 = l.y2();
- }
- surface->DrawLines(surface, lineArray.constData(), n);
- }
-}
-
-template <class T>
-static inline void fillRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface)
-{
- if (n == 1) {
- const QRect r = mapRect(transform, rects[0]);
- surface->FillRectangle(surface, r.x(), r.y(), r.width(), r.height());
- } else {
- QVarLengthArray<DFBRectangle, 32> rectArray(n);
- for (int i=0; i<n; ++i) {
- const QRect r = mapRect(transform, rects[i]);
- rectArray[i].x = r.x();
- rectArray[i].y = r.y();
- rectArray[i].w = r.width();
- rectArray[i].h = r.height();
- }
- surface->FillRectangles(surface, rectArray.constData(), n);
- }
-}
-
-template <class T>
-static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface)
-{
- for (int i=0; i<n; ++i) {
- const QRect r = mapRect(transform, rects[i]);
- surface->DrawRectangle(surface, r.x(), r.y(), r.width(), r.height());
- }
-}
-
-template <typename T> inline const T *ptr(const T &t) { return &t; }
-template <> inline const bool* ptr<bool>(const bool &) { return 0; }
-template <typename device, typename T1, typename T2, typename T3>
-static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
- uint transformationType, bool simplePen,
- uint clipType, uint compositionModeStatus,
- const char *nameOne, const T1 &one,
- const char *nameTwo, const T2 &two,
- const char *nameThree, const T3 &three)
-{
- QString out;
- QDebug dbg(&out);
- dbg << msg << (QByteArray(func) + "()") << "painting on";
- if (dev->devType() == QInternal::Widget) {
- dbg << static_cast<const QWidget*>(dev);
- } else {
- dbg << dev << "of type" << dev->devType();
- }
-
- dbg << QString::fromLatin1("transformationType 0x%1").arg(transformationType, 3, 16, QLatin1Char('0'))
- << "simplePen" << simplePen
- << "clipType" << clipType
- << "compositionModeStatus" << compositionModeStatus;
-
- const T1 *t1 = ptr(one);
- const T2 *t2 = ptr(two);
- const T3 *t3 = ptr(three);
-
- if (t1) {
- dbg << nameOne << *t1;
- if (t2) {
- dbg << nameTwo << *t2;
- if (t3) {
- dbg << nameThree << *t3;
- }
- }
- }
- qWarning("%s", qPrintable(out));
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h
deleted file mode 100644
index a3217d0f32..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_DIRECTFB_P_H
-#define QPAINTENGINE_DIRECTFB_P_H
-
-#include <QtGui/qpaintengine.h>
-#include <private/qpaintengine_raster_p.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDirectFBPaintEnginePrivate;
-
-class QDirectFBPaintEngine : public QRasterPaintEngine
-{
- Q_DECLARE_PRIVATE(QDirectFBPaintEngine)
-public:
- QDirectFBPaintEngine(QPaintDevice *device);
- virtual ~QDirectFBPaintEngine();
-
- virtual bool begin(QPaintDevice *device);
- virtual bool end();
-
- virtual void drawRects(const QRect *rects, int rectCount);
- virtual void drawRects(const QRectF *rects, int rectCount);
-
- virtual void fillRect(const QRectF &r, const QBrush &brush);
- virtual void fillRect(const QRectF &r, const QColor &color);
-
- virtual void drawLines(const QLine *line, int lineCount);
- virtual void drawLines(const QLineF *line, int lineCount);
-
- virtual void drawImage(const QPointF &p, const QImage &img);
- virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
- Qt::ImageConversionFlags falgs = Qt::AutoColor);
-
- virtual void drawPixmap(const QPointF &p, const QPixmap &pm);
- virtual void drawPixmap(const QRectF &r, const QPixmap &pixmap, const QRectF &sr);
- virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
-
- virtual void drawBufferSpan(const uint *buffer, int bufsize,
- int x, int y, int length, uint const_alpha);
-
- virtual void stroke(const QVectorPath &path, const QPen &pen);
- virtual void drawPath(const QPainterPath &path);
- virtual void drawPoints(const QPointF *points, int pointCount);
- virtual void drawPoints(const QPoint *points, int pointCount);
- virtual void drawEllipse(const QRectF &rect);
- virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
- virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
- virtual void fill(const QVectorPath &path, const QBrush &brush);
- virtual void drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode);
-
- virtual void clipEnabledChanged();
- virtual void penChanged();
- virtual void opacityChanged();
- virtual void compositionModeChanged();
- virtual void renderHintsChanged();
- virtual void transformChanged();
-
- virtual void setState(QPainterState *state);
-
- virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
- virtual void clip(const QRegion &region, Qt::ClipOperation op);
- virtual void clip(const QRect &rect, Qt::ClipOperation op);
-
- virtual void drawStaticTextItem(QStaticTextItem *item);
-
- static void initImageCache(int size);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-
-#endif // QPAINTENGINE_DIRECTFB_P_H
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
deleted file mode 100644
index 5259a93698..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbpixmap.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include "qdirectfbscreen.h"
-#include "qdirectfbpaintengine.h"
-
-#include <QtGui/qbitmap.h>
-#include <QtCore/qfile.h>
-#include <directfb.h>
-
-
-QT_BEGIN_NAMESPACE
-
-static int global_ser_no = 0;
-
-QDirectFBPixmapData::QDirectFBPixmapData(QDirectFBScreen *screen, PixelType pixelType)
- : QPixmapData(pixelType, DirectFBClass), QDirectFBPaintDevice(screen),
- alpha(false)
-{
- setSerialNumber(0);
-}
-
-QDirectFBPixmapData::~QDirectFBPixmapData()
-{
-}
-
-void QDirectFBPixmapData::resize(int width, int height)
-{
- if (width <= 0 || height <= 0) {
- invalidate();
- return;
- }
-
- imageFormat = screen->pixelFormat();
- dfbSurface = screen->createDFBSurface(QSize(width, height),
- imageFormat,
- QDirectFBScreen::TrackSurface);
- d = QDirectFBScreen::depth(imageFormat);
- alpha = false;
- if (!dfbSurface) {
- invalidate();
- qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface");
- return;
- }
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
- setSerialNumber(++global_ser_no);
-}
-
-#ifdef QT_DIRECTFB_OPAQUE_DETECTION
-// mostly duplicated from qimage.cpp (QImageData::checkForAlphaPixels)
-static bool checkForAlphaPixels(const QImage &img)
-{
- const uchar *bits = img.bits();
- const int bytes_per_line = img.bytesPerLine();
- const uchar *end_bits = bits + bytes_per_line;
- const int width = img.width();
- const int height = img.height();
- switch (img.format()) {
- case QImage::Format_Indexed8:
- return img.hasAlphaChannel();
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- for (int y=0; y<height; ++y) {
- for (int x=0; x<width; ++x) {
- if ((((uint *)bits)[x] & 0xff000000) != 0xff000000) {
- return true;
- }
- }
- bits += bytes_per_line;
- }
- break;
-
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_ARGB8565_Premultiplied:
- for (int y=0; y<height; ++y) {
- while (bits < end_bits) {
- if (bits[0] != 0) {
- return true;
- }
- bits += 3;
- }
- bits = end_bits;
- end_bits += bytes_per_line;
- }
- break;
-
- case QImage::Format_ARGB6666_Premultiplied:
- for (int y=0; y<height; ++y) {
- while (bits < end_bits) {
- if ((bits[0] & 0xfc) != 0) {
- return true;
- }
- bits += 3;
- }
- bits = end_bits;
- end_bits += bytes_per_line;
- }
- break;
-
- case QImage::Format_ARGB4444_Premultiplied:
- for (int y=0; y<height; ++y) {
- while (bits < end_bits) {
- if ((bits[0] & 0xf0) != 0) {
- return true;
- }
- bits += 2;
- }
- bits = end_bits;
- end_bits += bytes_per_line;
- }
- break;
-
- default:
- break;
- }
-
- return false;
-}
-#endif // QT_DIRECTFB_OPAQUE_DETECTION
-
-bool QDirectFBPixmapData::hasAlphaChannel(const QImage &img, Qt::ImageConversionFlags flags)
-{
- if (img.depth() == 1)
- return true;
-#ifdef QT_DIRECTFB_OPAQUE_DETECTION
- return ((flags & Qt::NoOpaqueDetection) ? img.hasAlphaChannel() : checkForAlphaPixels(img));
-#else
- Q_UNUSED(flags);
- return img.hasAlphaChannel();
-#endif
-}
-
-#ifdef QT_DIRECTFB_IMAGEPROVIDER
-bool QDirectFBPixmapData::fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags)
-{
- if (!QFile::exists(filename))
- return false;
- if (flags == Qt::AutoColor) {
- if (filename.startsWith(QLatin1Char(':'))) { // resource
- QFile file(filename);
- if (!file.open(QIODevice::ReadOnly))
- return false;
- const QByteArray data = file.readAll();
- file.close();
- return fromData(reinterpret_cast<const uchar*>(data.constData()), data.size(), format, flags);
- } else {
- DFBDataBufferDescription description;
- description.flags = DBDESC_FILE;
- const QByteArray fileNameData = filename.toLocal8Bit();
- description.file = fileNameData.constData();
- if (fromDataBufferDescription(description)) {
- return true;
- }
- // fall back to Qt
- }
- }
- return QPixmapData::fromFile(filename, format, flags);
-}
-
-bool QDirectFBPixmapData::fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags)
-{
- if (flags == Qt::AutoColor) {
- DFBDataBufferDescription description;
- description.flags = DBDESC_MEMORY;
- description.memory.data = buffer;
- description.memory.length = len;
- if (fromDataBufferDescription(description))
- return true;
- // fall back to Qt
- }
- return QPixmapData::fromData(buffer, len, format, flags);
-}
-
-template <typename T> struct QDirectFBInterfaceCleanupHandler
-{
- static void cleanup(T *t) { if (t) t->Release(t); }
-};
-
-template <typename T>
-class QDirectFBPointer : public QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> >
-{
-public:
- QDirectFBPointer(T *t = 0)
- : QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> >(t)
- {}
-};
-
-bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescription &dataBufferDescription)
-{
- IDirectFB *dfb = screen->dfb();
- Q_ASSERT(dfb);
- DFBResult result = DFB_OK;
- IDirectFBDataBuffer *dataBufferPtr;
- if ((result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, &dataBufferPtr)) != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromDataBufferDescription()", result);
- return false;
- }
- QDirectFBPointer<IDirectFBDataBuffer> dataBuffer(dataBufferPtr);
-
- IDirectFBImageProvider *providerPtr;
- if ((result = dataBuffer->CreateImageProvider(dataBuffer.data(), &providerPtr)) != DFB_OK)
- return false;
-
- QDirectFBPointer<IDirectFBImageProvider> provider(providerPtr);
-
- DFBImageDescription imageDescription;
- result = provider->GetImageDescription(provider.data(), &imageDescription);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't get image description", result);
- return false;
- }
-
- if (imageDescription.caps & DICAPS_COLORKEY) {
- return false;
- }
-
- DFBSurfaceDescription surfaceDescription;
- if ((result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription)) != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't get surface description", result);
- return false;
- }
-
- alpha = imageDescription.caps & DICAPS_ALPHACHANNEL;
- imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat();
-
- dfbSurface = screen->createDFBSurface(QSize(surfaceDescription.width, surfaceDescription.height),
- imageFormat, QDirectFBScreen::TrackSurface);
-
- result = provider->RenderTo(provider.data(), dfbSurface, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't render to surface", result);
- return false;
- }
-
- w = surfaceDescription.width;
- h = surfaceDescription.height;
- is_null = (w <= 0 || h <= 0);
- d = QDirectFBScreen::depth(imageFormat);
- setSerialNumber(++global_ser_no);
-
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- screen->setDirectFBImageProvider(providerPtr);
- provider.take();
-#endif
-
- return true;
-}
-
-#endif
-
-void QDirectFBPixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
-{
- alpha = QDirectFBPixmapData::hasAlphaChannel(img, flags);
- imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat();
-
- QImage image;
- if ((flags & ~Qt::NoOpaqueDetection) != Qt::AutoColor) {
- image = img.convertToFormat(imageFormat, flags);
- flags = Qt::AutoColor;
- } else if (img.format() == QImage::Format_RGB32 || img.depth() == 1) {
- image = img.convertToFormat(imageFormat, flags);
- } else if (img.format() != imageFormat) {
- image = img.convertToFormat(imageFormat, flags);
- } else {
- image = img;
- }
-
- dfbSurface = screen->createDFBSurface(image, image.format(), QDirectFBScreen::NoPreallocated | QDirectFBScreen::TrackSurface);
- if (!dfbSurface) {
- qWarning("QDirectFBPixmapData::fromImage()");
- invalidate();
- return;
- }
-
- w = image.width();
- h = image.height();
- is_null = (w <= 0 || h <= 0);
- d = QDirectFBScreen::depth(imageFormat);
- setSerialNumber(++global_ser_no);
-#ifdef QT_NO_DIRECTFB_OPAQUE_DETECTION
- Q_UNUSED(flags);
-#endif
-}
-
-void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->classId() != DirectFBClass) {
- QPixmapData::copy(data, rect);
- return;
- }
-
- const QDirectFBPixmapData *otherData = static_cast<const QDirectFBPixmapData*>(data);
-#ifdef QT_NO_DIRECTFB_SUBSURFACE
- if (otherData->lockFlags()) {
- const_cast<QDirectFBPixmapData*>(otherData)->unlockSurface();
- }
-#endif
- IDirectFBSurface *src = otherData->directFBSurface();
- alpha = data->hasAlphaChannel();
- imageFormat = (alpha
- ? QDirectFBScreen::instance()->alphaPixmapFormat()
- : QDirectFBScreen::instance()->pixelFormat());
-
-
- dfbSurface = screen->createDFBSurface(rect.size(), imageFormat,
- QDirectFBScreen::TrackSurface);
- if (!dfbSurface) {
- qWarning("QDirectFBPixmapData::copy()");
- invalidate();
- return;
- }
-
- if (alpha) {
- dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
- dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_BLEND_ALPHACHANNEL);
- } else {
- dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
- }
- const DFBRectangle blitRect = { rect.x(), rect.y(),
- rect.width(), rect.height() };
- w = rect.width();
- h = rect.height();
- d = otherData->d;
- is_null = (w <= 0 || h <= 0);
- unlockSurface();
- DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0);
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- dfbSurface->ReleaseSource(dfbSurface);
-#endif
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::copy()", result);
- invalidate();
- return;
- }
-
- setSerialNumber(++global_ser_no);
-}
-
-static inline bool isOpaqueFormat(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_RGB32:
- case QImage::Format_RGB16:
- case QImage::Format_RGB666:
- case QImage::Format_RGB555:
- case QImage::Format_RGB888:
- case QImage::Format_RGB444:
- return true;
- default:
- break;
- }
- return false;
-}
-
-void QDirectFBPixmapData::fill(const QColor &color)
-{
- if (!serialNumber())
- return;
-
- Q_ASSERT(dfbSurface);
-
- alpha |= (color.alpha() < 255);
-
- if (alpha && isOpaqueFormat(imageFormat)) {
- QSize size;
- dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight());
- screen->releaseDFBSurface(dfbSurface);
- imageFormat = screen->alphaPixmapFormat();
- d = QDirectFBScreen::depth(imageFormat);
- dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface);
- setSerialNumber(++global_ser_no);
- if (!dfbSurface) {
- qWarning("QDirectFBPixmapData::fill()");
- invalidate();
- return;
- }
- }
-
- dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(), color.alpha());
-}
-
-QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
- Qt::TransformationMode mode) const
-{
- QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
-#ifdef QT_NO_DIRECTFB_SUBSURFACE
- if (lockFlags())
- that->unlockSurface();
-#endif
-
- if (!dfbSurface || transform.type() != QTransform::TxScale
- || mode != Qt::FastTransformation)
- {
- const QImage *image = that->buffer();
- Q_ASSERT(image);
- const QImage transformed = image->transformed(transform, mode);
- QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType);
- data->fromImage(transformed, Qt::AutoColor);
- return QPixmap(data);
- }
-
- const QSize size = transform.mapRect(QRect(0, 0, w, h)).size();
- if (size.isEmpty())
- return QPixmap();
-
- QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType);
- data->setSerialNumber(++global_ser_no);
- DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
- data->alpha = alpha;
- if (alpha) {
- flags = DSBLIT_BLEND_ALPHACHANNEL;
- }
- data->dfbSurface = screen->createDFBSurface(size,
- imageFormat,
- QDirectFBScreen::TrackSurface);
- if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
- data->dfbSurface->Clear(data->dfbSurface, 0, 0, 0, 0);
- }
- data->dfbSurface->SetBlittingFlags(data->dfbSurface, flags);
-
- const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
- data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect);
- data->w = size.width();
- data->h = size.height();
- data->is_null = (data->w <= 0 || data->h <= 0);
-
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- data->dfbSurface->ReleaseSource(data->dfbSurface);
-#endif
- return QPixmap(data);
-}
-
-QImage QDirectFBPixmapData::toImage() const
-{
- if (!dfbSurface)
- return QImage();
-
-#if 0
- // In later versions of DirectFB one can set a flag to tell
- // DirectFB not to move the surface to videomemory. When that
- // happens we can use this (hopefully faster) codepath
-#ifndef QT_NO_DIRECTFB_PREALLOCATED
- QImage ret(w, h, QDirectFBScreen::getImageFormat(dfbSurface));
- if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
- if (hasAlphaChannel()) {
- imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
- imgSurface->Clear(imgSurface, 0, 0, 0, 0);
- } else {
- imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
- }
- imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0);
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- imgSurface->ReleaseSource(imgSurface);
-#endif
- imgSurface->Release(imgSurface);
- return ret;
- }
-#endif
-#endif
-
- QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
- const QImage *img = that->buffer();
- return img->copy();
-}
-
-/* This is QPixmapData::paintEngine(), not QPaintDevice::paintEngine() */
-
-QPaintEngine *QDirectFBPixmapData::paintEngine() const
-{
- if (!engine) {
- // QDirectFBPixmapData is also a QCustomRasterPaintDevice, so pass
- // that to the paint engine:
- QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
- that->engine = new QDirectFBPaintEngine(that);
- }
- return engine;
-}
-
-QImage *QDirectFBPixmapData::buffer()
-{
- if (!lockFlgs) {
- lockSurface(DSLF_READ|DSLF_WRITE);
- }
- Q_ASSERT(lockFlgs);
- Q_ASSERT(!lockedImage.isNull());
- return &lockedImage;
-}
-
-
-bool QDirectFBPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- if (!dfbSurface) {
- return false;
- }
- unlockSurface();
- DFBResult result = dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::scroll", result);
- return false;
- }
- result = dfbSurface->SetPorterDuff(dfbSurface, DSPD_NONE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::scroll", result);
- return false;
- }
-
- const DFBRectangle source = { rect.x(), rect.y(), rect.width(), rect.height() };
- result = dfbSurface->Blit(dfbSurface, dfbSurface, &source, source.x + dx, source.y + dy);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::scroll", result);
- return false;
- }
-
- return true;
-}
-
-void QDirectFBPixmapData::invalidate()
-{
- if (dfbSurface) {
- screen->releaseDFBSurface(dfbSurface);
- dfbSurface = 0;
- }
- setSerialNumber(0);
- alpha = false;
- d = w = h = 0;
- is_null = true;
- imageFormat = QImage::Format_Invalid;
-}
-
-Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_pixmap(const QPixmap &pixmap)
-{
- const QPixmapData *data = pixmap.pixmapData();
- if (!data || data->classId() != QPixmapData::DirectFBClass)
- return 0;
- const QDirectFBPixmapData *dfbData = static_cast<const QDirectFBPixmapData*>(data);
- return dfbData->directFBSurface();
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
deleted file mode 100644
index bc94b42638..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTFBPIXMAP_H
-#define QDIRECTFBPIXMAP_H
-
-#include <qglobal.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include <QtGui/private/qpixmapdata_p.h>
-#include <QtGui/private/qpaintengine_raster_p.h>
-#include "qdirectfbpaintdevice.h"
-#include <directfb.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDirectFBPaintEngine;
-
-class QDirectFBPixmapData : public QPixmapData, public QDirectFBPaintDevice
-{
-public:
- QDirectFBPixmapData(QDirectFBScreen *screen, PixelType pixelType);
- ~QDirectFBPixmapData();
-
- // Re-implemented from QPixmapData:
- virtual void resize(int width, int height);
- virtual void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
-#ifdef QT_DIRECTFB_IMAGEPROVIDER
- virtual bool fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags);
- virtual bool fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags);
-#endif
- virtual void copy(const QPixmapData *data, const QRect &rect);
- virtual void fill(const QColor &color);
- virtual QPixmap transformed(const QTransform &matrix,
- Qt::TransformationMode mode) const;
- virtual QImage toImage() const;
- virtual QPaintEngine *paintEngine() const;
- virtual QImage *buffer();
- virtual bool scroll(int dx, int dy, const QRect &rect);
- // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice
- virtual int metric(QPaintDevice::PaintDeviceMetric m) const { return QDirectFBPaintDevice::metric(m); }
-
- inline QImage::Format pixelFormat() const { return imageFormat; }
- inline bool hasAlphaChannel() const { return alpha; }
- static bool hasAlphaChannel(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor);
-private:
-#ifdef QT_DIRECTFB_IMAGEPROVIDER
- bool fromDataBufferDescription(const DFBDataBufferDescription &dataBuffer);
-#endif
- void invalidate();
- bool alpha;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-
-#endif // QDIRECTFBPIXMAP_H
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
deleted file mode 100644
index 7b1538bb49..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ /dev/null
@@ -1,1819 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbscreen.h"
-#include "qdirectfbwindowsurface.h"
-#include "qdirectfbpixmap.h"
-#include "qdirectfbmouse.h"
-#include "qdirectfbkeyboard.h"
-#include <QtGui/qwsdisplay_qws.h>
-#include <QtGui/qcolor.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qwindowsystem_qws.h>
-#include <QtGui/private/qgraphicssystem_qws_p.h>
-#include <QtGui/private/qwssignalhandler_p.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qrect.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_NAMESPACE
-
-class QDirectFBScreenPrivate : public QObject, public QWSGraphicsSystem
-{
- Q_OBJECT
-public:
- QDirectFBScreenPrivate(QDirectFBScreen *qptr);
- ~QDirectFBScreenPrivate();
-
- void setFlipFlags(const QStringList &args);
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
-public slots:
-#ifdef QT_DIRECTFB_WM
- void onWindowEvent(QWSWindow *window, QWSServer::WindowEvent event);
-#endif
-public:
- IDirectFB *dfb;
- DFBSurfaceFlipFlags flipFlags;
- QDirectFBScreen::DirectFBFlags directFBFlags;
- QImage::Format alphaPixmapFormat;
- IDirectFBScreen *dfbScreen;
-#ifdef QT_NO_DIRECTFB_WM
- IDirectFBSurface *primarySurface;
- QColor backgroundColor;
-#endif
-#ifndef QT_NO_DIRECTFB_LAYER
- IDirectFBDisplayLayer *dfbLayer;
-#endif
- QSet<IDirectFBSurface*> allocatedSurfaces;
-
-#ifndef QT_NO_DIRECTFB_MOUSE
- QDirectFBMouseHandler *mouse;
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- QDirectFBKeyboardHandler *keyboard;
-#endif
-#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- IDirectFBImageProvider *imageProvider;
-#endif
- IDirectFBSurface *cursorSurface;
- qint64 cursorImageKey;
-
- QDirectFBScreen *q;
- static QDirectFBScreen *instance;
-};
-
-QDirectFBScreen *QDirectFBScreenPrivate::instance = 0;
-
-QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *qptr)
- : QWSGraphicsSystem(qptr), dfb(0), flipFlags(DSFLIP_NONE),
- directFBFlags(QDirectFBScreen::NoFlags), alphaPixmapFormat(QImage::Format_Invalid),
- dfbScreen(0)
-#ifdef QT_NO_DIRECTFB_WM
- , primarySurface(0)
-#endif
-#ifndef QT_NO_DIRECTFB_LAYER
- , dfbLayer(0)
-#endif
-#ifndef QT_NO_DIRECTFB_MOUSE
- , mouse(0)
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- , keyboard(0)
-#endif
-#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- , imageProvider(0)
-#endif
- , cursorSurface(0)
- , cursorImageKey(0)
- , q(qptr)
-{
-#ifndef QT_NO_QWS_SIGNALHANDLER
- QWSSignalHandler::instance()->addObject(this);
-#endif
-#ifdef QT_DIRECTFB_WM
- connect(QWSServer::instance(), SIGNAL(windowEvent(QWSWindow*,QWSServer::WindowEvent)),
- this, SLOT(onWindowEvent(QWSWindow*,QWSServer::WindowEvent)));
-#endif
-}
-
-QDirectFBScreenPrivate::~QDirectFBScreenPrivate()
-{
-#ifndef QT_NO_DIRECTFB_MOUSE
- delete mouse;
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- delete keyboard;
-#endif
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- if (imageProvider)
- imageProvider->Release(imageProvider);
-#endif
-
- for (QSet<IDirectFBSurface*>::const_iterator it = allocatedSurfaces.begin(); it != allocatedSurfaces.end(); ++it) {
- (*it)->Release(*it);
- }
-
-#ifdef QT_NO_DIRECTFB_WM
- if (primarySurface)
- primarySurface->Release(primarySurface);
-#endif
-
-#ifndef QT_NO_DIRECTFB_LAYER
- if (dfbLayer)
- dfbLayer->Release(dfbLayer);
-#endif
-
- if (dfbScreen)
- dfbScreen->Release(dfbScreen);
-
- if (dfb)
- dfb->Release(dfb);
-}
-
-IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QImage &image, QImage::Format format, SurfaceCreationOptions options, DFBResult *resultPtr)
-{
- if (image.isNull()) // assert?
- return 0;
-
- if (QDirectFBScreen::getSurfacePixelFormat(format) == DSPF_UNKNOWN) {
- format = QDirectFBPixmapData::hasAlphaChannel(image) ? d_ptr->alphaPixmapFormat : pixelFormat();
- }
- if (image.format() != format) {
- return createDFBSurface(image.convertToFormat(format), format, options | NoPreallocated, resultPtr);
- }
-
- DFBSurfaceDescription description;
- memset(&description, 0, sizeof(DFBSurfaceDescription));
- description.width = image.width();
- description.height = image.height();
- description.flags = DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT;
- initSurfaceDescriptionPixelFormat(&description, format);
- bool doMemCopy = true;
-#ifdef QT_DIRECTFB_PREALLOCATED
- if (!(options & NoPreallocated)) {
- doMemCopy = false;
- description.flags |= DSDESC_PREALLOCATED;
- description.preallocated[0].data = const_cast<uchar*>(image.bits());
- description.preallocated[0].pitch = image.bytesPerLine();
- description.preallocated[1].data = 0;
- description.preallocated[1].pitch = 0;
- }
-#endif
- DFBResult result;
- IDirectFBSurface *surface = createDFBSurface(description, options, &result);
- if (resultPtr)
- *resultPtr = result;
- if (!surface) {
- DirectFBError("Couldn't create surface createDFBSurface(QImage, QImage::Format, SurfaceCreationOptions)", result);
- return 0;
- }
- if (doMemCopy) {
- int bplDFB;
- uchar *mem = QDirectFBScreen::lockSurface(surface, DSLF_WRITE, &bplDFB);
- if (mem) {
- const int height = image.height();
- const int bplQt = image.bytesPerLine();
- if (bplQt == bplDFB && bplQt == (image.width() * image.depth() / 8)) {
- memcpy(mem, image.bits(), image.byteCount());
- } else {
- for (int i=0; i<height; ++i) {
- memcpy(mem, image.scanLine(i), bplQt);
- mem += bplDFB;
- }
- }
- surface->Unlock(surface);
- }
- }
-#ifdef QT_DIRECTFB_PALETTE
- if (image.colorCount() != 0 && surface)
- QDirectFBScreen::setSurfaceColorTable(surface, image);
-#endif
- return surface;
-}
-
-IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result)
-{
- Q_ASSERT(src);
- QSize size;
- src->GetSize(src, &size.rwidth(), &size.rheight());
- IDirectFBSurface *surface = createDFBSurface(size, format, options, result);
- DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlphaChannel(surface)
- ? DSBLIT_BLEND_ALPHACHANNEL
- : DSBLIT_NOFX;
- if (flags & DSBLIT_BLEND_ALPHACHANNEL)
- surface->Clear(surface, 0, 0, 0, 0);
-
- surface->SetBlittingFlags(surface, flags);
- surface->Blit(surface, src, 0, 0, 0);
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- surface->ReleaseSource(surface);
-#endif
- return surface;
-}
-
-IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result)
-{
- DFBSurfaceDescription desc;
- memset(&desc, 0, sizeof(DFBSurfaceDescription));
- desc.flags |= DSDESC_WIDTH|DSDESC_HEIGHT;
- if (!QDirectFBScreen::initSurfaceDescriptionPixelFormat(&desc, format))
- return 0;
- desc.width = size.width();
- desc.height = size.height();
- return createDFBSurface(desc, options, result);
-}
-
-IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc, SurfaceCreationOptions options, DFBResult *resultPtr)
-{
- DFBResult tmp;
- DFBResult &result = (resultPtr ? *resultPtr : tmp);
- result = DFB_OK;
- IDirectFBSurface *newSurface = 0;
-
- if (!d_ptr->dfb) {
- qWarning("QDirectFBScreen::createDFBSurface() - not connected");
- return 0;
- }
-
- if (d_ptr->directFBFlags & VideoOnly
- && !(desc.flags & DSDESC_PREALLOCATED)
- && (!(desc.flags & DSDESC_CAPS) || !(desc.caps & DSCAPS_SYSTEMONLY))) {
- // Add the video only capability. This means the surface will be created in video ram
- if (!(desc.flags & DSDESC_CAPS)) {
- desc.caps = DSCAPS_VIDEOONLY;
- desc.flags |= DSDESC_CAPS;
- } else {
- desc.caps |= DSCAPS_VIDEOONLY;
- }
- result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface);
- if (result != DFB_OK
-#ifdef QT_NO_DEBUG
- && (desc.flags & DSDESC_CAPS) && (desc.caps & DSCAPS_PRIMARY)
-#endif
- ) {
- qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n"
- " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s",
- desc.flags, desc.caps, desc.width, desc.height,
- desc.pixelformat, DFB_PIXELFORMAT_INDEX(desc.pixelformat),
- desc.preallocated[0].data, desc.preallocated[0].pitch,
- DirectFBErrorString(result));
- }
- desc.caps &= ~DSCAPS_VIDEOONLY;
- }
-
- if (d_ptr->directFBFlags & SystemOnly)
- desc.caps |= DSCAPS_SYSTEMONLY;
-
- if (!newSurface)
- result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface);
-
- if (result != DFB_OK) {
- qWarning("QDirectFBScreen::createDFBSurface() Failed!\n"
- " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s",
- desc.flags, desc.caps, desc.width, desc.height,
- desc.pixelformat, DFB_PIXELFORMAT_INDEX(desc.pixelformat),
- desc.preallocated[0].data, desc.preallocated[0].pitch,
- DirectFBErrorString(result));
- return 0;
- }
-
- Q_ASSERT(newSurface);
-
- if (options & TrackSurface) {
- d_ptr->allocatedSurfaces.insert(newSurface);
- }
-
- return newSurface;
-}
-
-#ifdef QT_DIRECTFB_SUBSURFACE
-IDirectFBSurface *QDirectFBScreen::getSubSurface(IDirectFBSurface *surface,
- const QRect &rect,
- SurfaceCreationOptions options,
- DFBResult *resultPtr)
-{
- Q_ASSERT(!(options & NoPreallocated));
- Q_ASSERT(surface);
- DFBResult res;
- DFBResult &result = (resultPtr ? *resultPtr : res);
- IDirectFBSurface *subSurface = 0;
- if (rect.isNull()) {
- result = surface->GetSubSurface(surface, 0, &subSurface);
- } else {
- const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() };
- result = surface->GetSubSurface(surface, &subRect, &subSurface);
- }
- if (result != DFB_OK) {
- DirectFBError("Can't get sub surface", result);
- } else if (options & TrackSurface) {
- d_ptr->allocatedSurfaces.insert(subSurface);
- }
- return subSurface;
-}
-#endif
-
-
-void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface)
-{
- Q_ASSERT(QDirectFBScreen::instance());
- Q_ASSERT(surface);
- surface->Release(surface);
- if (!d_ptr->allocatedSurfaces.remove(surface))
- qWarning("QDirectFBScreen::releaseDFBSurface() - %p not in list", surface);
-
- //qDebug("Released surface at %p. New count = %d", surface, d_ptr->allocatedSurfaces.count());
-}
-
-QDirectFBScreen::DirectFBFlags QDirectFBScreen::directFBFlags() const
-{
- return d_ptr->directFBFlags;
-}
-
-IDirectFB *QDirectFBScreen::dfb()
-{
- return d_ptr->dfb;
-}
-
-#ifdef QT_NO_DIRECTFB_WM
-IDirectFBSurface *QDirectFBScreen::primarySurface()
-{
- return d_ptr->primarySurface;
-}
-#endif
-
-#ifndef QT_NO_DIRECTFB_LAYER
-IDirectFBDisplayLayer *QDirectFBScreen::dfbDisplayLayer()
-{
- return d_ptr->dfbLayer;
-}
-#endif
-
-DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format format)
-{
- switch (format) {
-#ifndef QT_NO_DIRECTFB_PALETTE
- case QImage::Format_Indexed8:
- return DSPF_LUT8;
-#endif
- case QImage::Format_RGB888:
- return DSPF_RGB24;
- case QImage::Format_ARGB4444_Premultiplied:
- return DSPF_ARGB4444;
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case QImage::Format_RGB444:
- return DSPF_RGB444;
- case QImage::Format_RGB555:
- return DSPF_RGB555;
-#endif
- case QImage::Format_RGB16:
- return DSPF_RGB16;
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- case QImage::Format_ARGB6666_Premultiplied:
- return DSPF_ARGB6666;
- case QImage::Format_RGB666:
- return DSPF_RGB18;
-#endif
- case QImage::Format_RGB32:
- return DSPF_RGB32;
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB32:
- return DSPF_ARGB;
- default:
- return DSPF_UNKNOWN;
- };
-}
-
-QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface)
-{
- DFBSurfacePixelFormat format;
- surface->GetPixelFormat(surface, &format);
-
- switch (format) {
- case DSPF_LUT8:
- return QImage::Format_Indexed8;
- case DSPF_RGB24:
- return QImage::Format_RGB888;
- case DSPF_ARGB4444:
- return QImage::Format_ARGB4444_Premultiplied;
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case DSPF_RGB444:
- return QImage::Format_RGB444;
- case DSPF_RGB555:
-#endif
- case DSPF_ARGB1555:
- return QImage::Format_RGB555;
- case DSPF_RGB16:
- return QImage::Format_RGB16;
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- case DSPF_ARGB6666:
- return QImage::Format_ARGB6666_Premultiplied;
- case DSPF_RGB18:
- return QImage::Format_RGB666;
-#endif
- case DSPF_RGB32:
- return QImage::Format_RGB32;
- case DSPF_ARGB: {
- DFBSurfaceCapabilities caps;
- const DFBResult result = surface->GetCapabilities(surface, &caps);
- Q_ASSERT(result == DFB_OK);
- Q_UNUSED(result);
- return (caps & DSCAPS_PREMULTIPLIED
- ? QImage::Format_ARGB32_Premultiplied
- : QImage::Format_ARGB32); }
- default:
- break;
- }
- return QImage::Format_Invalid;
-}
-
-DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const uint *buffer,
- int length)
-{
- DFBSurfaceDescription description;
- memset(&description, 0, sizeof(DFBSurfaceDescription));
-
- description.flags = DSDESC_CAPS|DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT|DSDESC_PREALLOCATED;
- description.caps = DSCAPS_PREMULTIPLIED;
- description.width = length;
- description.height = 1;
- description.pixelformat = DSPF_ARGB;
- description.preallocated[0].data = (void*)buffer;
- description.preallocated[0].pitch = length * sizeof(uint);
- description.preallocated[1].data = 0;
- description.preallocated[1].pitch = 0;
- return description;
-}
-
-#ifndef QT_NO_DIRECTFB_PALETTE
-void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface,
- const QImage &image)
-{
- if (!surface)
- return;
-
- const int numColors = image.colorCount();
- if (numColors == 0)
- return;
-
- QVarLengthArray<DFBColor, 256> colors(numColors);
- for (int i = 0; i < numColors; ++i) {
- QRgb c = image.color(i);
- colors[i].a = qAlpha(c);
- colors[i].r = qRed(c);
- colors[i].g = qGreen(c);
- colors[i].b = qBlue(c);
- }
-
- IDirectFBPalette *palette;
- DFBResult result;
- result = surface->GetPalette(surface, &palette);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setSurfaceColorTable GetPalette",
- result);
- return;
- }
- result = palette->SetEntries(palette, colors.data(), numColors, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setSurfaceColorTable SetEntries",
- result);
- }
- palette->Release(palette);
-}
-
-#endif // QT_NO_DIRECTFB_PALETTE
-
-#if defined QT_DIRECTFB_CURSOR
-class Q_GUI_EXPORT QDirectFBScreenCursor : public QScreenCursor
-{
-public:
- QDirectFBScreenCursor();
- virtual void set(const QImage &image, int hotx, int hoty);
- virtual void move(int x, int y);
- virtual void show();
- virtual void hide();
-private:
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- ~QDirectFBScreenCursor();
- bool createWindow();
- IDirectFBWindow *window;
-#endif
- IDirectFBDisplayLayer *layer;
-};
-
-QDirectFBScreenCursor::QDirectFBScreenCursor()
-{
- IDirectFB *fb = QDirectFBScreen::instance()->dfb();
- if (!fb)
- qFatal("QDirectFBScreenCursor: DirectFB not initialized");
-
- layer = QDirectFBScreen::instance()->dfbDisplayLayer();
- Q_ASSERT(layer);
-
- enable = false;
- hwaccel = true;
- supportsAlpha = true;
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- window = 0;
- DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorOpacity(layer, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cursor opacity", result);
- }
-
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cooperative level", result);
- }
-#endif
-}
-
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
-QDirectFBScreenCursor::~QDirectFBScreenCursor()
-{
- if (window) {
- window->Release(window);
- window = 0;
- }
-}
-
-bool QDirectFBScreenCursor::createWindow()
-{
- Q_ASSERT(!window);
- Q_ASSERT(!cursor.isNull());
- DFBWindowDescription description;
- memset(&description, 0, sizeof(DFBWindowDescription));
- description.flags = DWDESC_POSX|DWDESC_POSY|DWDESC_WIDTH|DWDESC_HEIGHT|DWDESC_CAPS|DWDESC_PIXELFORMAT|DWDESC_SURFACE_CAPS;
- description.width = cursor.width();
- description.height = cursor.height();
- description.posx = pos.x() - hotspot.x();
- description.posy = pos.y() - hotspot.y();
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- description.flags |= DWDESC_OPTIONS;
- description.options = DWOP_GHOST|DWOP_ALPHACHANNEL;
-#endif
- description.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER;
- const QImage::Format format = QDirectFBScreen::instance()->alphaPixmapFormat();
- description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
- if (QDirectFBScreen::isPremultiplied(format))
- description.surface_caps = DSCAPS_PREMULTIPLIED;
-
- DFBResult result = layer->CreateWindow(layer, &description, &window);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::createWindow: Unable to create window", result);
- return false;
- }
- result = window->SetOpacity(window, 255);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::createWindow: Unable to set opacity ", result);
- return false;
- }
-
- result = window->SetStackingClass(window, DWSC_UPPER);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::createWindow: Unable to set stacking class ", result);
- return false;
- }
-
- result = window->RaiseToTop(window);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::createWindow: Unable to raise window ", result);
- return false;
- }
-
- return true;
-}
-#endif
-
-void QDirectFBScreenCursor::move(int x, int y)
-{
- pos = QPoint(x, y);
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- if (window) {
- const QPoint p = pos - hotspot;
- DFBResult result = window->MoveTo(window, p.x(), p.y());
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::move: Unable to move window", result);
- }
- }
-#else
- layer->WarpCursor(layer, x, y);
-#endif
-}
-
-void QDirectFBScreenCursor::hide()
-{
- if (enable) {
- enable = false;
- DFBResult result;
-#ifndef QT_DIRECTFB_WINDOW_AS_CURSOR
- result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorOpacity(layer, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cursor opacity", result);
- }
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cooperative level", result);
- }
-#else
- if (window) {
- result = window->SetOpacity(window, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set window opacity", result);
- }
- }
-#endif
- }
-}
-
-void QDirectFBScreenCursor::show()
-{
- if (!enable) {
- enable = true;
- DFBResult result;
- result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorOpacity(layer,
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- 0
-#else
- 255
-#endif
- );
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cursor shape", result);
- }
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- if (window) {
- DFBResult result = window->SetOpacity(window, 255);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set window opacity", result);
- }
- }
-#endif
- }
-}
-
-void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty)
-{
- QDirectFBScreen *screen = QDirectFBScreen::instance();
- if (!screen)
- return;
-
- if (image.isNull()) {
- cursor = QImage();
- hide();
- } else {
- cursor = image.convertToFormat(screen->alphaPixmapFormat());
- size = cursor.size();
- hotspot = QPoint(hotx, hoty);
- DFBResult result = DFB_OK;
- IDirectFBSurface *surface = screen->createDFBSurface(cursor, screen->alphaPixmapFormat(),
- QDirectFBScreen::DontTrackSurface, &result);
- if (!surface) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to create surface", result);
- return;
- }
-#ifndef QT_DIRECTFB_WINDOW_AS_CURSOR
- result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorShape(layer, surface, hotx, hoty);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cursor shape", result);
- }
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
-#else
- if (window || createWindow()) {
- QSize windowSize;
- result = window->GetSize(window, &windowSize.rwidth(), &windowSize.rheight());
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: "
- "Unable to get window size", result);
- }
- result = window->Resize(window, size.width(), size.height());
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to resize window", result);
- }
-
- IDirectFBSurface *windowSurface;
- result = window->GetSurface(window, &windowSurface);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to get window surface", result);
- } else {
- result = windowSurface->Clear(windowSurface, 0, 0, 0, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to clear surface", result);
- }
-
- result = windowSurface->Blit(windowSurface, surface, 0, 0, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to blit to surface", result);
- }
- }
- result = windowSurface->Flip(windowSurface, 0, DSFLIP_NONE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to flip window", result);
- }
-
- windowSurface->Release(windowSurface);
- }
-#endif
- surface->Release(surface);
- show();
- }
-
-}
-#endif // QT_DIRECTFB_CURSOR
-
-QDirectFBScreen::QDirectFBScreen(int display_id)
- : QScreen(display_id, DirectFBClass), d_ptr(new QDirectFBScreenPrivate(this))
-{
- QDirectFBScreenPrivate::instance = this;
-}
-
-QDirectFBScreen::~QDirectFBScreen()
-{
- if (QDirectFBScreenPrivate::instance == this)
- QDirectFBScreenPrivate::instance = 0;
- delete d_ptr;
-}
-
-QDirectFBScreen *QDirectFBScreen::instance()
-{
- return QDirectFBScreenPrivate::instance;
-}
-
-int QDirectFBScreen::depth(DFBSurfacePixelFormat format)
-{
- switch (format) {
- case DSPF_A1:
- return 1;
- case DSPF_A8:
- case DSPF_RGB332:
- case DSPF_LUT8:
- case DSPF_ALUT44:
- return 8;
- case DSPF_I420:
- case DSPF_YV12:
- case DSPF_NV12:
- case DSPF_NV21:
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case DSPF_RGB444:
-#endif
- return 12;
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case DSPF_RGB555:
- return 15;
-#endif
- case DSPF_ARGB1555:
- case DSPF_RGB16:
- case DSPF_YUY2:
- case DSPF_UYVY:
- case DSPF_NV16:
- case DSPF_ARGB2554:
- case DSPF_ARGB4444:
- return 16;
- case DSPF_RGB24:
- return 24;
- case DSPF_RGB32:
- case DSPF_ARGB:
- case DSPF_AiRGB:
- return 32;
- case DSPF_UNKNOWN:
- default:
- return 0;
- };
- return 0;
-}
-
-int QDirectFBScreen::depth(QImage::Format format)
-{
- int depth = 0;
- switch(format) {
- case QImage::Format_Invalid:
- case QImage::NImageFormats:
- Q_ASSERT(false);
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- depth = 1;
- break;
- case QImage::Format_Indexed8:
- depth = 8;
- break;
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- depth = 32;
- break;
- case QImage::Format_RGB555:
- case QImage::Format_RGB16:
- case QImage::Format_RGB444:
- case QImage::Format_ARGB4444_Premultiplied:
- depth = 16;
- break;
- case QImage::Format_RGB666:
- case QImage::Format_ARGB6666_Premultiplied:
- case QImage::Format_ARGB8565_Premultiplied:
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_RGB888:
- depth = 24;
- break;
- }
- return depth;
-}
-
-void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args)
-{
- QRegExp flipRegexp(QLatin1String("^flip=([\\w,]*)$"));
- int index = args.indexOf(flipRegexp);
- if (index >= 0) {
- const QStringList flips = flipRegexp.cap(1).split(QLatin1Char(','),
- QString::SkipEmptyParts);
- flipFlags = DSFLIP_NONE;
- foreach(const QString &flip, flips) {
- if (flip == QLatin1String("wait"))
- flipFlags |= DSFLIP_WAIT;
- else if (flip == QLatin1String("blit"))
- flipFlags |= DSFLIP_BLIT;
- else if (flip == QLatin1String("onsync"))
- flipFlags |= DSFLIP_ONSYNC;
- else if (flip == QLatin1String("pipeline"))
- flipFlags |= DSFLIP_PIPELINE;
- else
- qWarning("QDirectFBScreen: Unknown flip argument: %s",
- qPrintable(flip));
- }
- } else {
- flipFlags = DSFLIP_BLIT|DSFLIP_ONSYNC;
- }
-}
-
-#ifdef QT_DIRECTFB_WM
-void QDirectFBScreenPrivate::onWindowEvent(QWSWindow *window, QWSServer::WindowEvent event)
-{
- if (event == QWSServer::Raise) {
- QWSWindowSurface *windowSurface = window->windowSurface();
- if (windowSurface && windowSurface->key() == QLatin1String("directfb")) {
- static_cast<QDirectFBWindowSurface*>(windowSurface)->raise();
- }
- }
-}
-#endif
-
-QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType type) const
-{
- if (type == QPixmapData::BitmapType)
- return QWSGraphicsSystem::createPixmapData(type);
-
- return new QDirectFBPixmapData(q, type);
-}
-
-#if (Q_DIRECTFB_VERSION >= 0x000923)
-#ifdef QT_NO_DEBUG
-struct FlagDescription;
-static const FlagDescription *accelerationDescriptions = 0;
-static const FlagDescription *blitDescriptions = 0;
-static const FlagDescription *drawDescriptions = 0;
-#else
-struct FlagDescription {
- const char *name;
- uint flag;
-};
-
-static const FlagDescription accelerationDescriptions[] = {
- { "DFXL_NONE", DFXL_NONE },
- { "DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE },
- { "DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE },
- { "DFXL_DRAWLINE", DFXL_DRAWLINE },
- { "DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE },
- { "DFXL_BLIT", DFXL_BLIT },
- { "DFXL_STRETCHBLIT", DFXL_STRETCHBLIT },
- { "DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES },
- { "DFXL_DRAWSTRING", DFXL_DRAWSTRING },
- { 0, 0 }
-};
-
-static const FlagDescription blitDescriptions[] = {
- { "DSBLIT_NOFX", DSBLIT_NOFX },
- { "DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL },
- { "DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA },
- { "DSBLIT_COLORIZE", DSBLIT_COLORIZE },
- { "DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY },
- { "DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY },
- { "DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY },
- { "DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY },
- { "DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY },
- { "DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE },
-#if (Q_DIRECTFB_VERSION >= 0x000923)
- { "DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR },
- { "DSBLIT_XOR", DSBLIT_XOR },
-#endif
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- { "DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION },
-#endif
- { 0, 0 }
-};
-
-static const FlagDescription drawDescriptions[] = {
- { "DSDRAW_NOFX", DSDRAW_NOFX },
- { "DSDRAW_BLEND", DSDRAW_BLEND },
- { "DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY },
- { "DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY },
- { "DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY },
- { "DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY },
- { "DSDRAW_XOR", DSDRAW_XOR },
- { 0, 0 }
-};
-#endif
-
-static const QByteArray flagDescriptions(uint mask, const FlagDescription *flags)
-{
-#ifdef QT_NO_DEBUG
- Q_UNUSED(mask);
- Q_UNUSED(flags);
- return QByteArray("");
-#else
- if (!mask)
- return flags[0].name;
-
- QStringList list;
- for (int i=1; flags[i].name; ++i) {
- if (mask & flags[i].flag) {
- list.append(QString::fromLatin1(flags[i].name));
- }
- }
- Q_ASSERT(!list.isEmpty());
- return (QLatin1Char(' ') + list.join(QLatin1String("|"))).toLatin1();
-#endif
-}
-static void printDirectFBInfo(IDirectFB *fb, IDirectFBSurface *primarySurface)
-{
- DFBResult result;
- DFBGraphicsDeviceDescription dev;
-
- result = fb->GetDeviceDescription(fb, &dev);
- if (result != DFB_OK) {
- DirectFBError("Error reading graphics device description", result);
- return;
- }
-
- DFBSurfacePixelFormat pixelFormat;
- primarySurface->GetPixelFormat(primarySurface, &pixelFormat);
-
- qDebug("Device: %s (%s), Driver: %s v%i.%i (%s) Pixelformat: %d (%d)\n"
- "acceleration: 0x%x%s\nblit: 0x%x%s\ndraw: 0x%0x%s\nvideo: %iKB\n",
- dev.name, dev.vendor, dev.driver.name, dev.driver.major,
- dev.driver.minor, dev.driver.vendor, DFB_PIXELFORMAT_INDEX(pixelFormat),
- QDirectFBScreen::getImageFormat(primarySurface), dev.acceleration_mask,
- flagDescriptions(dev.acceleration_mask, accelerationDescriptions).constData(),
- dev.blitting_flags, flagDescriptions(dev.blitting_flags, blitDescriptions).constData(),
- dev.drawing_flags, flagDescriptions(dev.drawing_flags, drawDescriptions).constData(),
- (dev.video_memory >> 10));
-}
-#endif
-
-static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value)
-{
- Q_ASSERT(value);
- QRegExp rx(QString::fromLatin1("%1=?(\\d+)").arg(variable));
- rx.setCaseSensitivity(Qt::CaseInsensitive);
- if (arguments.indexOf(rx) != -1) {
- *value = rx.cap(1).toInt();
- return true;
- }
- return false;
-}
-
-static inline QColor colorFromName(const QString &name)
-{
- QRegExp rx(QLatin1String("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])"));
- rx.setCaseSensitivity(Qt::CaseInsensitive);
- if (rx.exactMatch(name)) {
- Q_ASSERT(rx.captureCount() == 4);
- int ints[4];
- int i;
- for (i=0; i<4; ++i) {
- bool ok;
- ints[i] = rx.cap(i + 1).toUInt(&ok, 16);
- if (!ok || ints[i] > 255)
- break;
- }
- if (i == 4)
- return QColor(ints[0], ints[1], ints[2], ints[3]);
- }
- return QColor(name);
-}
-
-bool QDirectFBScreen::connect(const QString &displaySpec)
-{
- DFBResult result = DFB_OK;
-
- { // pass command line arguments to DirectFB
- const QStringList args = QCoreApplication::arguments();
- int argc = args.size();
- char **argv = new char*[argc];
-
- for (int i = 0; i < argc; ++i)
- argv[i] = qstrdup(args.at(i).toLocal8Bit().constData());
-
- result = DirectFBInit(&argc, &argv);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen: error initializing DirectFB",
- result);
- }
- delete[] argv;
- }
-
- const QStringList displayArgs = displaySpec.split(QLatin1Char(':'),
- QString::SkipEmptyParts);
-
- d_ptr->setFlipFlags(displayArgs);
-
- result = DirectFBCreate(&d_ptr->dfb);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen: error creating DirectFB interface",
- result);
- return false;
- }
-
- if (displayArgs.contains(QLatin1String("videoonly"), Qt::CaseInsensitive))
- d_ptr->directFBFlags |= VideoOnly;
-
- if (displayArgs.contains(QLatin1String("systemonly"), Qt::CaseInsensitive)) {
- if (d_ptr->directFBFlags & VideoOnly) {
- qWarning("QDirectFBScreen: error. videoonly and systemonly are mutually exclusive");
- } else {
- d_ptr->directFBFlags |= SystemOnly;
- }
- }
-
- if (displayArgs.contains(QLatin1String("boundingrectflip"), Qt::CaseInsensitive)) {
- d_ptr->directFBFlags |= BoundingRectFlip;
- } else if (displayArgs.contains(QLatin1String("nopartialflip"), Qt::CaseInsensitive)) {
- d_ptr->directFBFlags |= NoPartialFlip;
- }
-
-#ifdef QT_DIRECTFB_IMAGECACHE
- int imageCacheSize = 4 * 1024 * 1024; // 4 MB
- setIntOption(displayArgs, QLatin1String("imagecachesize"), &imageCacheSize);
- QDirectFBPaintEngine::initImageCache(imageCacheSize);
-#endif
-
-#ifndef QT_NO_DIRECTFB_WM
- if (displayArgs.contains(QLatin1String("fullscreen")))
-#endif
- d_ptr->dfb->SetCooperativeLevel(d_ptr->dfb, DFSCL_FULLSCREEN);
-
- const bool forcePremultiplied = displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive);
-
- DFBSurfaceDescription description;
- memset(&description, 0, sizeof(DFBSurfaceDescription));
- IDirectFBSurface *surface;
-
-#ifdef QT_NO_DIRECTFB_WM
- description.flags = DSDESC_CAPS;
- if (::setIntOption(displayArgs, QLatin1String("width"), &description.width))
- description.flags |= DSDESC_WIDTH;
- if (::setIntOption(displayArgs, QLatin1String("height"), &description.height))
- description.flags |= DSDESC_HEIGHT;
-
- description.caps = DSCAPS_PRIMARY|DSCAPS_DOUBLE;
- struct {
- const char *name;
- const DFBSurfaceCapabilities cap;
- } const capabilities[] = {
- { "static_alloc", DSCAPS_STATIC_ALLOC },
- { "triplebuffer", DSCAPS_TRIPLE },
- { "interlaced", DSCAPS_INTERLACED },
- { "separated", DSCAPS_SEPARATED },
-// { "depthbuffer", DSCAPS_DEPTH }, // only makes sense with TextureTriangles which are not supported
- { 0, DSCAPS_NONE }
- };
- for (int i=0; capabilities[i].name; ++i) {
- if (displayArgs.contains(QString::fromLatin1(capabilities[i].name), Qt::CaseInsensitive))
- description.caps |= capabilities[i].cap;
- }
-
- if (forcePremultiplied) {
- description.caps |= DSCAPS_PREMULTIPLIED;
- }
-
- // We don't track the primary surface as it's released in disconnect
- d_ptr->primarySurface = createDFBSurface(description, DontTrackSurface, &result);
- if (!d_ptr->primarySurface) {
- DirectFBError("QDirectFBScreen: error creating primary surface",
- result);
- return false;
- }
-
- surface = d_ptr->primarySurface;
-#else
- description.flags = DSDESC_WIDTH|DSDESC_HEIGHT;
- description.width = description.height = 1;
- surface = createDFBSurface(description, DontTrackSurface, &result);
- if (!surface) {
- DirectFBError("QDirectFBScreen: error creating surface", result);
- return false;
- }
-#endif
- // Work out what format we're going to use for surfaces with an alpha channel
- QImage::Format pixelFormat = QDirectFBScreen::getImageFormat(surface);
- d_ptr->alphaPixmapFormat = pixelFormat;
-
- switch (pixelFormat) {
- case QImage::Format_RGB666:
- d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied;
- break;
- case QImage::Format_RGB444:
- d_ptr->alphaPixmapFormat = QImage::Format_ARGB4444_Premultiplied;
- break;
- case QImage::Format_RGB32:
- pixelFormat = d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
- // ### Format_RGB32 doesn't work so well with Qt. Force ARGB32 for windows/pixmaps
- break;
- case QImage::Format_Indexed8:
- qWarning("QDirectFBScreen::connect(). Qt/DirectFB does not work with the LUT8 pixelformat.");
- return false;
- case QImage::NImageFormats:
- case QImage::Format_Invalid:
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- case QImage::Format_RGB888:
- case QImage::Format_RGB16:
- case QImage::Format_RGB555:
- d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
- break;
- case QImage::Format_ARGB32:
- if (forcePremultiplied)
- d_ptr->alphaPixmapFormat = pixelFormat = QImage::Format_ARGB32_Premultiplied;
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB4444_Premultiplied:
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_ARGB8565_Premultiplied:
- case QImage::Format_ARGB6666_Premultiplied:
- // works already
- break;
- }
- setPixelFormat(pixelFormat);
- QScreen::d = QDirectFBScreen::depth(pixelFormat);
- data = 0;
- lstep = 0;
- size = 0;
-
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect: "
- "Unable to get screen!", result);
- return false;
- }
- const QString qws_size = QString::fromLatin1(qgetenv("QWS_SIZE"));
- if (!qws_size.isEmpty()) {
- QRegExp rx(QLatin1String("(\\d+)x(\\d+)"));
- if (!rx.exactMatch(qws_size)) {
- qWarning("QDirectFBScreen::connect: Can't parse QWS_SIZE=\"%s\"", qPrintable(qws_size));
- } else {
- int *ints[2] = { &w, &h };
- for (int i=0; i<2; ++i) {
- *ints[i] = rx.cap(i + 1).toInt();
- if (*ints[i] <= 0) {
- qWarning("QDirectFBScreen::connect: %s is not a positive integer",
- qPrintable(rx.cap(i + 1)));
- w = h = 0;
- break;
- }
- }
- }
- }
-
- setIntOption(displayArgs, QLatin1String("width"), &w);
- setIntOption(displayArgs, QLatin1String("height"), &h);
-
-#ifndef QT_NO_DIRECTFB_LAYER
- int layerId = DLID_PRIMARY;
- setIntOption(displayArgs, QLatin1String("layerid"), &layerId);
-
- result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, static_cast<DFBDisplayLayerID>(layerId),
- &d_ptr->dfbLayer);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect: "
- "Unable to get display layer!", result);
- return false;
- }
- result = d_ptr->dfbLayer->GetScreen(d_ptr->dfbLayer, &d_ptr->dfbScreen);
-#else
- result = d_ptr->dfb->GetScreen(d_ptr->dfb, 0, &d_ptr->dfbScreen);
-#endif
-
- if (w <= 0 || h <= 0) {
-#ifdef QT_NO_DIRECTFB_WM
- result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h);
-#elif (Q_DIRECTFB_VERSION >= 0x010000)
- IDirectFBSurface *layerSurface;
- if (d_ptr->dfbLayer->GetSurface(d_ptr->dfbLayer, &layerSurface) == DFB_OK) {
- result = layerSurface->GetSize(layerSurface, &w, &h);
- layerSurface->Release(layerSurface);
- }
- if (w <= 0 || h <= 0) {
- result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h);
- }
-#else
- qWarning("QDirectFBScreen::connect: DirectFB versions prior to 1.0 do not offer a way\n"
- "query the size of the primary surface in windowed mode. You have to specify\n"
- "the size of the display using QWS_SIZE=[0-9]x[0-9] or\n"
- "QWS_DISPLAY=directfb:width=[0-9]:height=[0-9]");
- return false;
-#endif
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect: "
- "Unable to get screen size!", result);
- return false;
- }
- }
-
-
- dw = w;
- dh = h;
-
- Q_ASSERT(dw != 0 && dh != 0);
-
- physWidth = physHeight = -1;
- setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth);
- setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight);
- const int dpi = 72;
- if (physWidth < 0)
- physWidth = qRound(dw * 25.4 / dpi);
- if (physHeight < 0)
- physHeight = qRound(dh * 25.4 / dpi);
-
- setGraphicsSystem(d_ptr);
-
-#if (Q_DIRECTFB_VERSION >= 0x000923)
- if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive))
- printDirectFBInfo(d_ptr->dfb, surface);
-#endif
-#ifdef QT_DIRECTFB_WM
- surface->Release(surface);
- QColor backgroundColor;
-#else
- QColor &backgroundColor = d_ptr->backgroundColor;
-#endif
-
- QRegExp backgroundColorRegExp(QLatin1String("bgcolor=(.+)"));
- backgroundColorRegExp.setCaseSensitivity(Qt::CaseInsensitive);
- if (displayArgs.indexOf(backgroundColorRegExp) != -1) {
- backgroundColor = colorFromName(backgroundColorRegExp.cap(1));
- }
-#ifdef QT_NO_DIRECTFB_WM
- if (!backgroundColor.isValid())
- backgroundColor = Qt::green;
- d_ptr->primarySurface->Clear(d_ptr->primarySurface, backgroundColor.red(),
- backgroundColor.green(), backgroundColor.blue(),
- backgroundColor.alpha());
- d_ptr->primarySurface->Flip(d_ptr->primarySurface, 0, d_ptr->flipFlags);
-#else
- if (backgroundColor.isValid()) {
- DFBResult result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect "
- "Unable to set cooperative level", result);
- }
- result = d_ptr->dfbLayer->SetBackgroundColor(d_ptr->dfbLayer, backgroundColor.red(), backgroundColor.green(),
- backgroundColor.blue(), backgroundColor.alpha());
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::connect: "
- "Unable to set background color", result);
- }
-
- result = d_ptr->dfbLayer->SetBackgroundMode(d_ptr->dfbLayer, DLBM_COLOR);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::connect: "
- "Unable to set background mode", result);
- }
-
- result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect "
- "Unable to set cooperative level", result);
- }
-
- }
-#endif
-
- return true;
-}
-
-void QDirectFBScreen::disconnect()
-{
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- if (d_ptr->imageProvider)
- d_ptr->imageProvider->Release(d_ptr->imageProvider);
-#endif
-#ifdef QT_NO_DIRECTFB_WM
- d_ptr->primarySurface->Release(d_ptr->primarySurface);
- d_ptr->primarySurface = 0;
-#endif
-
- foreach (IDirectFBSurface *surf, d_ptr->allocatedSurfaces)
- surf->Release(surf);
- d_ptr->allocatedSurfaces.clear();
-
-#ifndef QT_NO_DIRECTFB_LAYER
- d_ptr->dfbLayer->Release(d_ptr->dfbLayer);
- d_ptr->dfbLayer = 0;
-#endif
-
- d_ptr->dfbScreen->Release(d_ptr->dfbScreen);
- d_ptr->dfbScreen = 0;
-
- d_ptr->dfb->Release(d_ptr->dfb);
- d_ptr->dfb = 0;
-}
-
-bool QDirectFBScreen::initDevice()
-{
-#ifndef QT_NO_DIRECTFB_MOUSE
- if (qgetenv("QWS_MOUSE_PROTO").isEmpty()) {
- QWSServer::instance()->setDefaultMouse("None");
- d_ptr->mouse = new QDirectFBMouseHandler;
- }
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- if (qgetenv("QWS_KEYBOARD").isEmpty()) {
- QWSServer::instance()->setDefaultKeyboard("None");
- d_ptr->keyboard = new QDirectFBKeyboardHandler(QString());
- }
-#endif
-
-#ifdef QT_DIRECTFB_CURSOR
- qt_screencursor = new QDirectFBScreenCursor;
-#elif !defined QT_NO_QWS_CURSOR
- QScreenCursor::initSoftwareCursor();
-#endif
- return true;
-}
-
-void QDirectFBScreen::shutdownDevice()
-{
-#ifndef QT_NO_DIRECTFB_MOUSE
- delete d_ptr->mouse;
- d_ptr->mouse = 0;
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- delete d_ptr->keyboard;
- d_ptr->keyboard = 0;
-#endif
-
-#ifndef QT_NO_QWS_CURSOR
- delete qt_screencursor;
- qt_screencursor = 0;
-#endif
-}
-
-void QDirectFBScreen::setMode(int width, int height, int depth)
-{
- d_ptr->dfb->SetVideoMode(d_ptr->dfb, width, height, depth);
-}
-
-void QDirectFBScreen::blank(bool on)
-{
- d_ptr->dfbScreen->SetPowerMode(d_ptr->dfbScreen,
- (on ? DSPM_ON : DSPM_SUSPEND));
-}
-
-QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const
-{
-#ifdef QT_NO_DIRECTFB_WM
- if (QApplication::type() == QApplication::GuiServer) {
- return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
- } else {
- return QScreen::createSurface(widget);
- }
-#else
- return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
-#endif
-}
-
-QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const
-{
- if (key == QLatin1String("directfb")) {
- return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this));
- }
- return QScreen::createSurface(key);
-}
-
-#if defined QT_NO_DIRECTFB_WM
-struct PaintCommand {
- PaintCommand() : dfbSurface(0), windowOpacity(255), blittingFlags(DSBLIT_NOFX) {}
- IDirectFBSurface *dfbSurface;
- QImage image;
- QPoint windowPosition;
- QRegion source;
- quint8 windowOpacity;
- DFBSurfaceBlittingFlags blittingFlags;
-};
-
-static inline void initParameters(DFBRectangle &source, const QRect &sourceGlobal, const QPoint &pos)
-{
- source.x = sourceGlobal.x() - pos.x();
- source.y = sourceGlobal.y() - pos.y();
- source.w = sourceGlobal.width();
- source.h = sourceGlobal.height();
-}
-#endif
-
-void QDirectFBScreen::exposeRegion(QRegion r, int)
-{
- Q_UNUSED(r);
-#if defined QT_NO_DIRECTFB_WM
-
- r &= region();
- if (r.isEmpty()) {
- return;
- }
- r = r.boundingRect();
-
- IDirectFBSurface *primary = d_ptr->primarySurface;
- const QList<QWSWindow*> windows = QWSServer::instance()->clientWindows();
- QVarLengthArray<PaintCommand, 4> commands(windows.size());
- QRegion region = r;
- int idx = 0;
- for (int i=0; i<windows.size(); ++i) {
- QWSWindowSurface *surface = windows.at(i)->windowSurface();
- if (!surface)
- continue;
-
- const QRect windowGeometry = surface->geometry();
- const QRegion intersection = region & windowGeometry;
- if (intersection.isEmpty()) {
- continue;
- }
-
- PaintCommand &cmd = commands[idx];
-
- if (surface->key() == QLatin1String("directfb")) {
- const QDirectFBWindowSurface *ws = static_cast<QDirectFBWindowSurface*>(surface);
- cmd.dfbSurface = ws->directFBSurface();
-
- if (!cmd.dfbSurface) {
- continue;
- }
- } else {
- cmd.image = surface->image();
- if (cmd.image.isNull()) {
- continue;
- }
- }
- ++idx;
-
- cmd.windowPosition = windowGeometry.topLeft();
- cmd.source = intersection;
- if (windows.at(i)->isOpaque()) {
- region -= intersection;
- if (region.isEmpty())
- break;
- } else {
- cmd.windowOpacity = windows.at(i)->opacity();
- cmd.blittingFlags = cmd.windowOpacity == 255
- ? DSBLIT_BLEND_ALPHACHANNEL
- : (DSBLIT_BLEND_ALPHACHANNEL|DSBLIT_BLEND_COLORALPHA);
- }
- }
-
- solidFill(d_ptr->backgroundColor, region);
-
- while (idx > 0) {
- const PaintCommand &cmd = commands[--idx];
- Q_ASSERT(cmd.dfbSurface || !cmd.image.isNull());
- IDirectFBSurface *surface;
- if (cmd.dfbSurface) {
- surface = cmd.dfbSurface;
- } else {
- Q_ASSERT(!cmd.image.isNull());
- DFBResult result;
- surface = createDFBSurface(cmd.image, cmd.image.format(), DontTrackSurface, &result);
- Q_ASSERT((result != DFB_OK) == !surface);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::exposeRegion: Can't create surface from image", result);
- continue;
- }
- }
-
- primary->SetBlittingFlags(primary, cmd.blittingFlags);
- if (cmd.blittingFlags & DSBLIT_BLEND_COLORALPHA) {
- primary->SetColor(primary, 0xff, 0xff, 0xff, cmd.windowOpacity);
- }
- const QRegion &region = cmd.source;
- const int rectCount = region.rectCount();
- DFBRectangle source;
- if (rectCount == 1) {
- ::initParameters(source, region.boundingRect(), cmd.windowPosition);
- primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y);
- } else {
- const QVector<QRect> rects = region.rects();
- for (int i=0; i<rectCount; ++i) {
- ::initParameters(source, rects.at(i), cmd.windowPosition);
- primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y);
- }
- }
- if (surface != cmd.dfbSurface) {
- surface->Release(surface);
- }
- }
-
- primary->SetColor(primary, 0xff, 0xff, 0xff, 0xff);
-
-#if defined QT_NO_DIRECTFB_CURSOR and !defined QT_NO_QWS_CURSOR
- if (QScreenCursor *cursor = QScreenCursor::instance()) {
- const QRect cursorRectangle = cursor->boundingRect();
- if (cursor->isVisible() && !cursor->isAccelerated() && r.intersects(cursorRectangle)) {
- const QImage image = cursor->image();
- if (image.cacheKey() != d_ptr->cursorImageKey) {
- if (d_ptr->cursorSurface) {
- releaseDFBSurface(d_ptr->cursorSurface);
- }
- d_ptr->cursorSurface = createDFBSurface(image, image.format(), QDirectFBScreen::TrackSurface);
- d_ptr->cursorImageKey = image.cacheKey();
- }
-
- Q_ASSERT(d_ptr->cursorSurface);
- primary->SetBlittingFlags(primary, DSBLIT_BLEND_ALPHACHANNEL);
- primary->Blit(primary, d_ptr->cursorSurface, 0, cursorRectangle.x(), cursorRectangle.y());
- }
- }
-#endif
- flipSurface(primary, d_ptr->flipFlags, r, QPoint());
- primary->SetBlittingFlags(primary, DSBLIT_NOFX);
-#endif
-}
-
-void QDirectFBScreen::solidFill(const QColor &color, const QRegion &region)
-{
-#ifdef QT_DIRECTFB_WM
- Q_UNUSED(color);
- Q_UNUSED(region);
-#else
- QDirectFBScreen::solidFill(d_ptr->primarySurface, color, region);
-#endif
-}
-
-static inline void clearRect(IDirectFBSurface *surface, const QColor &color, const QRect &rect)
-{
- Q_ASSERT(surface);
- const DFBRegion region = { rect.left(), rect.top(), rect.right(), rect.bottom() };
- // could just reinterpret_cast this to a DFBRegion
- surface->SetClip(surface, &region);
- surface->Clear(surface, color.red(), color.green(), color.blue(), color.alpha());
-}
-
-void QDirectFBScreen::solidFill(IDirectFBSurface *surface, const QColor &color, const QRegion &region)
-{
- if (region.isEmpty())
- return;
-
- const int n = region.rectCount();
- if (n == 1) {
- clearRect(surface, color, region.boundingRect());
- } else {
- const QVector<QRect> rects = region.rects();
- for (int i=0; i<n; ++i) {
- clearRect(surface, color, rects.at(i));
- }
- }
- surface->SetClip(surface, 0);
-}
-
-QImage::Format QDirectFBScreen::alphaPixmapFormat() const
-{
- return d_ptr->alphaPixmapFormat;
-}
-
-bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description,
- QImage::Format format)
-{
- const DFBSurfacePixelFormat pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
- if (pixelformat == DSPF_UNKNOWN)
- return false;
- description->flags |= DSDESC_PIXELFORMAT;
- description->pixelformat = pixelformat;
- if (QDirectFBScreen::isPremultiplied(format)) {
- if (!(description->flags & DSDESC_CAPS)) {
- description->caps = DSCAPS_PREMULTIPLIED;
- description->flags |= DSDESC_CAPS;
- } else {
- description->caps |= DSCAPS_PREMULTIPLIED;
- }
- }
- return true;
-}
-
-uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl)
-{
- void *mem = 0;
- const DFBResult result = surface->Lock(surface, flags, &mem, bpl);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::lockSurface()", result);
- }
-
- return reinterpret_cast<uchar*>(mem);
-}
-
-static inline bool isFullUpdate(IDirectFBSurface *surface, const QRegion &region, const QPoint &offset)
-{
- if (offset == QPoint(0, 0) && region.rectCount() == 1) {
- QSize size;
- surface->GetSize(surface, &size.rwidth(), &size.rheight());
- if (region.boundingRect().size() == size)
- return true;
- }
- return false;
-}
-
-void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags,
- const QRegion &region, const QPoint &offset)
-{
- if (d_ptr->directFBFlags & NoPartialFlip
- || (!(flipFlags & DSFLIP_BLIT) && QT_PREPEND_NAMESPACE(isFullUpdate(surface, region, offset)))) {
- surface->Flip(surface, 0, flipFlags);
- } else {
- if (!(d_ptr->directFBFlags & BoundingRectFlip) && region.rectCount() > 1) {
- const QVector<QRect> rects = region.rects();
- const DFBSurfaceFlipFlags nonWaitFlags = flipFlags & ~DSFLIP_WAIT;
- for (int i=0; i<rects.size(); ++i) {
- const QRect &r = rects.at(i);
- const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
- r.right() + offset.x(),
- r.bottom() + offset.y() };
- surface->Flip(surface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags);
- }
- } else {
- const QRect r = region.boundingRect();
- const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
- r.right() + offset.x(),
- r.bottom() + offset.y() };
- surface->Flip(surface, &dfbReg, flipFlags);
- }
- }
-}
-
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
-void QDirectFBScreen::setDirectFBImageProvider(IDirectFBImageProvider *provider)
-{
- Q_ASSERT(provider);
- if (d_ptr->imageProvider)
- d_ptr->imageProvider->Release(d_ptr->imageProvider);
- d_ptr->imageProvider = provider;
-}
-#endif
-
-void QDirectFBScreen::waitIdle()
-{
- d_ptr->dfb->WaitIdle(d_ptr->dfb);
-}
-
-#ifdef QT_DIRECTFB_WM
-IDirectFBWindow *QDirectFBScreen::windowForWidget(const QWidget *widget) const
-{
- if (widget) {
- const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
- if (surface && surface->key() == QLatin1String("directfb")) {
- return static_cast<const QDirectFBWindowSurface*>(surface)->directFBWindow();
- }
- }
- return 0;
-}
-#endif
-
-IDirectFBSurface * QDirectFBScreen::surfaceForWidget(const QWidget *widget, QRect *rect) const
-{
- Q_ASSERT(widget);
- if (!widget->isVisible() || widget->size().isNull())
- return 0;
-
- const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
- if (surface && surface->key() == QLatin1String("directfb")) {
- return static_cast<const QDirectFBWindowSurface*>(surface)->surfaceForWidget(widget, rect);
- }
- return 0;
-}
-
-#ifdef QT_DIRECTFB_SUBSURFACE
-IDirectFBSurface *QDirectFBScreen::subSurfaceForWidget(const QWidget *widget, const QRect &area) const
-{
- Q_ASSERT(widget);
- QRect rect;
- IDirectFBSurface *surface = surfaceForWidget(widget, &rect);
- IDirectFBSurface *subSurface = 0;
- if (surface) {
- if (!area.isNull())
- rect &= area.translated(widget->mapTo(widget->window(), QPoint(0, 0)));
- if (!rect.isNull()) {
- const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() };
- const DFBResult result = surface->GetSubSurface(surface, &subRect, &subSurface);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::subSurface(): Can't get sub surface", result);
- }
- }
- }
- return subSurface;
-}
-#endif
-
-Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_widget(const QWidget *widget, QRect *rect)
-{
- return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->surfaceForWidget(widget, rect) : 0;
-}
-#ifdef QT_DIRECTFB_SUBSURFACE
-Q_GUI_EXPORT IDirectFBSurface *qt_directfb_subsurface_for_widget(const QWidget *widget, const QRect &area)
-{
- return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->subSurfaceForWidget(widget, area) : 0;
-}
-#endif
-#ifdef QT_DIRECTFB_WM
-Q_GUI_EXPORT IDirectFBWindow *qt_directfb_window_for_widget(const QWidget *widget)
-{
- return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->windowForWidget(widget) : 0;
-}
-
-#endif
-
-QT_END_NAMESPACE
-
-#include "qdirectfbscreen.moc"
-#endif // QT_NO_QWS_DIRECTFB
-
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
deleted file mode 100644
index afc153bab2..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTFBSCREEN_H
-#define QDIRECTFBSCREEN_H
-
-#include <qglobal.h>
-#ifndef QT_NO_QWS_DIRECTFB
-#include <QtGui/qscreen_qws.h>
-#include <directfb.h>
-#include <directfb_version.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined QT_DIRECTFB_SUBSURFACE && !defined QT_NO_DIRECTFB_SUBSURFACE
-#define QT_NO_DIRECTFB_SUBSURFACE
-#endif
-#if !defined QT_NO_DIRECTFB_LAYER && !defined QT_DIRECTFB_LAYER
-#define QT_DIRECTFB_LAYER
-#endif
-#if !defined QT_NO_DIRECTFB_WM && !defined QT_DIRECTFB_WM
-#define QT_DIRECTFB_WM
-#endif
-#if !defined QT_DIRECTFB_IMAGECACHE && !defined QT_NO_DIRECTFB_IMAGECACHE
-#define QT_NO_DIRECTFB_IMAGECACHE
-#endif
-#if !defined QT_NO_DIRECTFB_IMAGEPROVIDER && !defined QT_DIRECTFB_IMAGEPROVIDER
-#define QT_DIRECTFB_IMAGEPROVIDER
-#endif
-#if !defined QT_NO_DIRECTFB_STRETCHBLIT && !defined QT_DIRECTFB_STRETCHBLIT
-#define QT_DIRECTFB_STRETCHBLIT
-#endif
-#if !defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE && !defined QT_NO_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
-#define QT_NO_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
-#endif
-#if !defined QT_DIRECTFB_WINDOW_AS_CURSOR && !defined QT_NO_DIRECTFB_WINDOW_AS_CURSOR
-#define QT_NO_DIRECTFB_WINDOW_AS_CURSOR
-#endif
-#if !defined QT_DIRECTFB_PALETTE && !defined QT_NO_DIRECTFB_PALETTE
-#define QT_NO_DIRECTFB_PALETTE
-#endif
-#if !defined QT_NO_DIRECTFB_PREALLOCATED && !defined QT_DIRECTFB_PREALLOCATED
-#define QT_DIRECTFB_PREALLOCATED
-#endif
-#if !defined QT_NO_DIRECTFB_MOUSE && !defined QT_DIRECTFB_MOUSE
-#define QT_DIRECTFB_MOUSE
-#endif
-#if !defined QT_NO_DIRECTFB_KEYBOARD && !defined QT_DIRECTFB_KEYBOARD
-#define QT_DIRECTFB_KEYBOARD
-#endif
-#if !defined QT_NO_DIRECTFB_OPAQUE_DETECTION && !defined QT_DIRECTFB_OPAQUE_DETECTION
-#define QT_DIRECTFB_OPAQUE_DETECTION
-#endif
-#ifndef QT_NO_QWS_CURSOR
-#if defined QT_DIRECTFB_WM && defined QT_DIRECTFB_WINDOW_AS_CURSOR
-#define QT_DIRECTFB_CURSOR
-#elif defined QT_DIRECTFB_LAYER
-#define QT_DIRECTFB_CURSOR
-#endif
-#endif
-#ifndef QT_DIRECTFB_CURSOR
-#define QT_NO_DIRECTFB_CURSOR
-#endif
-#if defined QT_NO_DIRECTFB_LAYER && defined QT_DIRECTFB_WM
-#error QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM
-#endif
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE && defined QT_NO_DIRECTFB_IMAGEPROVIDER
-#error QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE requires QT_DIRECTFB_IMAGEPROVIDER to be defined
-#endif
-#if defined QT_DIRECTFB_WINDOW_AS_CURSOR && defined QT_NO_DIRECTFB_WM
-#error QT_DIRECTFB_WINDOW_AS_CURSOR requires QT_DIRECTFB_WM to be defined
-#endif
-
-#define Q_DIRECTFB_VERSION ((DIRECTFB_MAJOR_VERSION << 16) | (DIRECTFB_MINOR_VERSION << 8) | DIRECTFB_MICRO_VERSION)
-
-#define DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(F) \
- static inline F operator~(F f) { return F(~int(f)); } \
- static inline F operator&(F left, F right) { return F(int(left) & int(right)); } \
- static inline F operator|(F left, F right) { return F(int(left) | int(right)); } \
- static inline F &operator|=(F &left, F right) { left = (left | right); return left; } \
- static inline F &operator&=(F &left, F right) { left = (left & right); return left; }
-
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBInputDeviceCapabilities);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowDescriptionFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowCapabilities);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowOptions);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceDescriptionFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceCapabilities);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceLockFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceBlittingFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceDrawingFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceFlipFlags);
-
-class QDirectFBScreenPrivate;
-class Q_GUI_EXPORT QDirectFBScreen : public QScreen
-{
-public:
- QDirectFBScreen(int display_id);
- ~QDirectFBScreen();
-
- enum DirectFBFlag {
- NoFlags = 0x00,
- VideoOnly = 0x01,
- SystemOnly = 0x02,
- BoundingRectFlip = 0x04,
- NoPartialFlip = 0x08
- };
-
- Q_DECLARE_FLAGS(DirectFBFlags, DirectFBFlag);
-
- DirectFBFlags directFBFlags() const;
-
- bool connect(const QString &displaySpec);
- void disconnect();
- bool initDevice();
- void shutdownDevice();
-
- void exposeRegion(QRegion r, int changing);
- void solidFill(const QColor &color, const QRegion &region);
- static void solidFill(IDirectFBSurface *surface, const QColor &color, const QRegion &region);
-
- void setMode(int width, int height, int depth);
- void blank(bool on);
-
- QWSWindowSurface *createSurface(QWidget *widget) const;
- QWSWindowSurface *createSurface(const QString &key) const;
-
- static QDirectFBScreen *instance();
- void waitIdle();
- IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const;
-#ifdef QT_DIRECTFB_SUBSURFACE
- IDirectFBSurface *subSurfaceForWidget(const QWidget *widget, const QRect &area = QRect()) const;
-#endif
- IDirectFB *dfb();
-#ifdef QT_DIRECTFB_WM
- IDirectFBWindow *windowForWidget(const QWidget *widget) const;
-#else
- IDirectFBSurface *primarySurface();
-#endif
-#ifndef QT_NO_DIRECTFB_LAYER
- IDirectFBDisplayLayer *dfbDisplayLayer();
-#endif
-
- // Track surface creation/release so we can release all on exit
- enum SurfaceCreationOption {
- DontTrackSurface = 0x1,
- TrackSurface = 0x2,
- NoPreallocated = 0x4
- };
- Q_DECLARE_FLAGS(SurfaceCreationOptions, SurfaceCreationOption);
- IDirectFBSurface *createDFBSurface(const QImage &image,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result = 0);
- IDirectFBSurface *createDFBSurface(const QSize &size,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result = 0);
- IDirectFBSurface *copyDFBSurface(IDirectFBSurface *src,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result = 0);
- IDirectFBSurface *createDFBSurface(DFBSurfaceDescription desc,
- SurfaceCreationOptions options,
- DFBResult *result);
-#ifdef QT_DIRECTFB_SUBSURFACE
- IDirectFBSurface *getSubSurface(IDirectFBSurface *surface,
- const QRect &rect,
- SurfaceCreationOptions options,
- DFBResult *result);
-#endif
-
- void flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags,
- const QRegion &region, const QPoint &offset);
- void releaseDFBSurface(IDirectFBSurface *surface);
-
- using QScreen::depth;
- static int depth(DFBSurfacePixelFormat format);
- static int depth(QImage::Format format);
-
- static DFBSurfacePixelFormat getSurfacePixelFormat(QImage::Format format);
- static DFBSurfaceDescription getSurfaceDescription(const uint *buffer,
- int length);
- static QImage::Format getImageFormat(IDirectFBSurface *surface);
- static bool initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format);
- static inline bool isPremultiplied(QImage::Format format);
- static inline bool hasAlphaChannel(DFBSurfacePixelFormat format);
- static inline bool hasAlphaChannel(IDirectFBSurface *surface);
- QImage::Format alphaPixmapFormat() const;
-
-#ifndef QT_NO_DIRECTFB_PALETTE
- static void setSurfaceColorTable(IDirectFBSurface *surface,
- const QImage &image);
-#endif
-
- static uchar *lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl = 0);
-#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- void setDirectFBImageProvider(IDirectFBImageProvider *provider);
-#endif
-private:
- QDirectFBScreenPrivate *d_ptr;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDirectFBScreen::SurfaceCreationOptions);
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDirectFBScreen::DirectFBFlags);
-
-inline bool QDirectFBScreen::isPremultiplied(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB8565_Premultiplied:
- case QImage::Format_ARGB6666_Premultiplied:
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_ARGB4444_Premultiplied:
- return true;
- default:
- break;
- }
- return false;
-}
-
-inline bool QDirectFBScreen::hasAlphaChannel(DFBSurfacePixelFormat format)
-{
- switch (format) {
- case DSPF_ARGB1555:
- case DSPF_ARGB:
- case DSPF_LUT8:
- case DSPF_AiRGB:
- case DSPF_A1:
- case DSPF_ARGB2554:
- case DSPF_ARGB4444:
-#if (Q_DIRECTFB_VERSION >= 0x000923)
- case DSPF_AYUV:
-#endif
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- case DSPF_A4:
- case DSPF_ARGB1666:
- case DSPF_ARGB6666:
- case DSPF_LUT2:
-#endif
- return true;
- default:
- return false;
- }
-}
-
-inline bool QDirectFBScreen::hasAlphaChannel(IDirectFBSurface *surface)
-{
- Q_ASSERT(surface);
- DFBSurfacePixelFormat format;
- surface->GetPixelFormat(surface, &format);
- return QDirectFBScreen::hasAlphaChannel(format);
-}
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-#endif // QDIRECTFBSCREEN_H
-
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
deleted file mode 100644
index b8fc811e4d..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ /dev/null
@@ -1,506 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbwindowsurface.h"
-#include "qdirectfbscreen.h"
-#include "qdirectfbpaintengine.h"
-
-#include <private/qwidget_p.h>
-#include <qwidget.h>
-#include <qwindowsystem_qws.h>
-#include <qpaintdevice.h>
-#include <qvarlengtharray.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_NAMESPACE
-
-QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr)
- : QDirectFBPaintDevice(scr)
-#ifndef QT_NO_DIRECTFB_WM
- , dfbWindow(0)
-#endif
- , flipFlags(flip)
- , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
- , flushPending(false)
-{
-#ifdef QT_NO_DIRECTFB_WM
- mode = Offscreen;
-#endif
- setSurfaceFlags(Opaque | Buffered);
-#ifdef QT_DIRECTFB_TIMING
- frames = 0;
- timer.start();
-#endif
-}
-
-QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget)
- : QWSWindowSurface(widget), QDirectFBPaintDevice(scr)
-#ifndef QT_NO_DIRECTFB_WM
- , dfbWindow(0)
-#endif
- , flipFlags(flip)
- , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
- , flushPending(false)
-{
- SurfaceFlags flags = 0;
- if (!widget || widget->window()->windowOpacity() == 0xff)
- flags |= Opaque;
-#ifdef QT_NO_DIRECTFB_WM
- if (widget && widget->testAttribute(Qt::WA_PaintOnScreen)) {
- flags = RegionReserved;
- mode = Primary;
- } else {
- mode = Offscreen;
- flags = Buffered;
- }
-#endif
- setSurfaceFlags(flags);
-#ifdef QT_DIRECTFB_TIMING
- frames = 0;
- timer.start();
-#endif
-}
-
-QDirectFBWindowSurface::~QDirectFBWindowSurface()
-{
- releaseSurface();
- // these are not tracked by QDirectFBScreen so we don't want QDirectFBPaintDevice to release it
-}
-
-bool QDirectFBWindowSurface::isValid() const
-{
- return true;
-}
-
-#ifdef QT_DIRECTFB_WM
-void QDirectFBWindowSurface::raise()
-{
- if (IDirectFBWindow *window = directFBWindow()) {
- window->RaiseToTop(window);
- }
-}
-
-IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const
-{
- return dfbWindow;
-}
-
-void QDirectFBWindowSurface::createWindow(const QRect &rect)
-{
- IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
- if (!layer)
- qFatal("QDirectFBWindowSurface: Unable to get primary display layer!");
-
- updateIsOpaque();
-
- DFBWindowDescription description;
- memset(&description, 0, sizeof(DFBWindowDescription));
-
- description.flags = DWDESC_CAPS|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT;
- description.caps = DWCAPS_NODECORATION;
- description.surface_caps = DSCAPS_NONE;
- imageFormat = screen->pixelFormat();
-
- if (!(surfaceFlags() & Opaque)) {
- imageFormat = screen->alphaPixmapFormat();
- description.caps |= DWCAPS_ALPHACHANNEL;
-#if (Q_DIRECTFB_VERSION >= 0x010200)
- description.flags |= DWDESC_OPTIONS;
- description.options |= DWOP_ALPHACHANNEL;
-#endif
- }
- description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(imageFormat);
- description.posx = rect.x();
- description.posy = rect.y();
- description.width = rect.width();
- description.height = rect.height();
-
- if (QDirectFBScreen::isPremultiplied(imageFormat))
- description.surface_caps = DSCAPS_PREMULTIPLIED;
-
- if (screen->directFBFlags() & QDirectFBScreen::VideoOnly)
- description.surface_caps |= DSCAPS_VIDEOONLY;
-
- DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);
-
- if (result != DFB_OK)
- DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result);
-
- if (window()) {
- if (window()->windowFlags() & Qt::WindowStaysOnTopHint) {
- dfbWindow->SetStackingClass(dfbWindow, DWSC_UPPER);
- }
- DFBWindowID winid;
- result = dfbWindow->GetID(dfbWindow, &winid);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBWindowSurface::createWindow. Can't get ID", result);
- } else {
- window()->setProperty("_q_DirectFBWindowID", winid);
- }
- }
-
- Q_ASSERT(!dfbSurface);
- dfbWindow->GetSurface(dfbWindow, &dfbSurface);
-}
-
-static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect)
-{
- DFBResult result = DFB_OK;
- const bool isMove = old.isEmpty() || rect.topLeft() != old.topLeft();
- const bool isResize = rect.size() != old.size();
-
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- if (isResize && isMove) {
- result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(),
- rect.width(), rect.height());
- } else if (isResize) {
- result = dfbWindow->Resize(dfbWindow,
- rect.width(), rect.height());
- } else if (isMove) {
- result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y());
- }
-#else
- if (isResize) {
- result = dfbWindow->Resize(dfbWindow,
- rect.width(), rect.height());
- }
- if (isMove) {
- result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y());
- }
-#endif
- return result;
-}
-#endif // QT_NO_DIRECTFB_WM
-
-void QDirectFBWindowSurface::setGeometry(const QRect &rect)
-{
- const QRect oldRect = geometry();
- if (oldRect == rect)
- return;
-
- IDirectFBSurface *oldSurface = dfbSurface;
- const bool sizeChanged = oldRect.size() != rect.size();
- if (sizeChanged) {
- delete engine;
- engine = 0;
- releaseSurface();
- Q_ASSERT(!dfbSurface);
- }
-
- if (rect.isNull()) {
-#ifndef QT_NO_DIRECTFB_WM
- if (dfbWindow) {
- if (window())
- window()->setProperty("_q_DirectFBWindowID", QVariant());
-
- dfbWindow->Release(dfbWindow);
- dfbWindow = 0;
- }
-#endif
- Q_ASSERT(!dfbSurface);
-#ifdef QT_DIRECTFB_SUBSURFACE
- Q_ASSERT(!subSurface);
-#endif
- } else {
-#ifdef QT_DIRECTFB_WM
- if (!dfbWindow) {
- createWindow(rect);
- } else {
- setWindowGeometry(dfbWindow, oldRect, rect);
- Q_ASSERT(!sizeChanged || !dfbSurface);
- if (sizeChanged)
- dfbWindow->GetSurface(dfbWindow, &dfbSurface);
- }
-#else
- IDirectFBSurface *primarySurface = screen->primarySurface();
- DFBResult result = DFB_OK;
- if (mode == Primary) {
- Q_ASSERT(primarySurface);
- if (rect == screen->region().boundingRect()) {
- dfbSurface = primarySurface;
- } else {
- const DFBRectangle r = { rect.x(), rect.y(),
- rect.width(), rect.height() };
- result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
- }
- } else { // mode == Offscreen
- if (!dfbSurface) {
- dfbSurface = screen->createDFBSurface(rect.size(), surfaceFlags() & Opaque ? screen->pixelFormat() : screen->alphaPixmapFormat(),
- QDirectFBScreen::DontTrackSurface);
- }
- }
- if (result != DFB_OK)
- DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result);
-#endif
- }
- if (oldSurface != dfbSurface) {
- imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
- }
-
- if (oldRect.size() != rect.size()) {
- QWSWindowSurface::setGeometry(rect);
- } else {
- QWindowSurface::setGeometry(rect);
- }
-}
-
-QByteArray QDirectFBWindowSurface::permanentState() const
-{
- QByteArray state(sizeof(SurfaceFlags) + sizeof(DFBWindowID), 0);
- char *ptr = state.data();
- SurfaceFlags flags = surfaceFlags();
- memcpy(ptr, &flags, sizeof(SurfaceFlags));
- ptr += sizeof(SurfaceFlags);
- DFBWindowID did = (DFBWindowID)(-1);
- if (dfbWindow)
- dfbWindow->GetID(dfbWindow, &did);
- memcpy(ptr, &did, sizeof(DFBWindowID));
- return state;
-}
-
-void QDirectFBWindowSurface::setPermanentState(const QByteArray &state)
-{
- const char *ptr = state.constData();
- IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
- SurfaceFlags flags;
- memcpy(&flags, ptr, sizeof(SurfaceFlags));
-
- setSurfaceFlags(flags);
- ptr += sizeof(SurfaceFlags);
- DFBWindowID id;
- memcpy(&id, ptr, sizeof(DFBWindowID));
- if (dfbSurface)
- dfbSurface->Release(dfbSurface);
- if (id != (DFBWindowID)-1) {
- IDirectFBWindow *dw;
- layer->GetWindow(layer, id, &dw);
- if (dw->GetSurface(dw, &dfbSurface) != DFB_OK)
- dfbSurface = 0;
- dw->Release(dw);
- }
- else {
- dfbSurface = 0;
- }
-}
-
-bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
-{
- if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.rectCount() != 1)
- return false;
- if (flushPending) {
- dfbSurface->Flip(dfbSurface, 0, DSFLIP_BLIT);
- } else {
- flushPending = true;
- }
- dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
- const QRect r = region.boundingRect();
- const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() };
- dfbSurface->Blit(dfbSurface, dfbSurface, &rect, r.x() + dx, r.y() + dy);
- return true;
-}
-
-bool QDirectFBWindowSurface::move(const QPoint &moveBy)
-{
- setGeometry(geometry().translated(moveBy));
- return true;
-}
-
-void QDirectFBWindowSurface::setOpaque(bool opaque)
-{
- SurfaceFlags flags = surfaceFlags();
- if (opaque != (flags & Opaque)) {
- if (opaque) {
- flags |= Opaque;
- } else {
- flags &= ~Opaque;
- }
- setSurfaceFlags(flags);
- }
-}
-
-
-void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion &region,
- const QPoint &offset)
-{
- QWidget *win = window();
- if (!win)
- return;
-
-#if !defined(QT_NO_QWS_PROXYSCREEN) && !defined(QT_NO_GRAPHICSVIEW)
- QWExtra *extra = qt_widget_private(widget)->extraData();
- if (extra && extra->proxyWidget)
- return;
-#else
- Q_UNUSED(widget);
-#endif
-
- const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff);
- const QRect windowGeometry = geometry();
-#ifdef QT_DIRECTFB_WM
- quint8 currentOpacity;
- Q_ASSERT(dfbWindow);
- dfbWindow->GetOpacity(dfbWindow, &currentOpacity);
- if (currentOpacity != windowOpacity) {
- dfbWindow->SetOpacity(dfbWindow, windowOpacity);
- }
-
- screen->flipSurface(dfbSurface, flipFlags, region, offset);
-#else
- setOpaque(windowOpacity == 0xff);
- if (mode == Offscreen) {
- screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0);
- } else {
- screen->flipSurface(dfbSurface, flipFlags, region, offset);
- }
-#endif
-
-#ifdef QT_DIRECTFB_TIMING
- enum { Secs = 3 };
- ++frames;
- if (timer.elapsed() >= Secs * 1000) {
- qDebug("%d fps", int(double(frames) / double(Secs)));
- frames = 0;
- timer.restart();
- }
-#endif
- flushPending = false;
-}
-
-void QDirectFBWindowSurface::beginPaint(const QRegion &region)
-{
- if (!engine) {
- engine = new QDirectFBPaintEngine(this);
- }
-
- if (dfbSurface) {
- const QWidget *win = window();
- if (win && win->testAttribute(Qt::WA_NoSystemBackground)) {
- QDirectFBScreen::solidFill(dfbSurface, Qt::transparent, region);
- }
- }
- flushPending = true;
-}
-
-void QDirectFBWindowSurface::endPaint(const QRegion &)
-{
-#ifdef QT_NO_DIRECTFB_SUBSURFACE
- unlockSurface();
-#endif
-}
-
-IDirectFBSurface *QDirectFBWindowSurface::directFBSurface() const
-{
- return dfbSurface;
-}
-
-
-IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget, QRect *rect) const
-{
- Q_ASSERT(widget);
- if (!dfbSurface)
- return 0;
- QWidget *win = window();
- Q_ASSERT(win);
- if (rect) {
- if (win == widget) {
- *rect = widget->rect();
- } else {
- *rect = QRect(widget->mapTo(win, QPoint(0, 0)), widget->size());
- }
- }
-
- Q_ASSERT(win == widget || win->isAncestorOf(widget));
- return dfbSurface;
-}
-
-void QDirectFBWindowSurface::releaseSurface()
-{
- if (dfbSurface) {
-#ifdef QT_DIRECTFB_SUBSURFACE
- releaseSubSurface();
-#else
- unlockSurface();
-#endif
-#ifdef QT_NO_DIRECTFB_WM
- Q_ASSERT(screen->primarySurface());
- if (dfbSurface != screen->primarySurface())
-#endif
-
- dfbSurface->Release(dfbSurface);
- dfbSurface = 0;
- }
-}
-
-void QDirectFBWindowSurface::updateIsOpaque()
-{
- const QWidget *win = window();
- Q_ASSERT(win);
- if (win->testAttribute(Qt::WA_OpaquePaintEvent) || win->testAttribute(Qt::WA_PaintOnScreen)) {
- setOpaque(true);
- return;
- }
-
- if (qFuzzyCompare(static_cast<float>(win->windowOpacity()), 1.0f)) {
- const QPalette &pal = win->palette();
-
- if (win->autoFillBackground()) {
- const QBrush &autoFillBrush = pal.brush(win->backgroundRole());
- if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
- setOpaque(true);
- return;
- }
- }
-
- if (win->isWindow() && !win->testAttribute(Qt::WA_NoSystemBackground)) {
- const QBrush &windowBrush = win->palette().brush(QPalette::Window);
- if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
- setOpaque(true);
- return;
- }
- }
- }
- setOpaque(false);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
deleted file mode 100644
index df9baa1ff2..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECFBWINDOWSURFACE_H
-#define QDIRECFBWINDOWSURFACE_H
-
-#include "qdirectfbpaintengine.h"
-#include "qdirectfbpaintdevice.h"
-#include "qdirectfbscreen.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include <private/qpaintengine_raster_p.h>
-#include <private/qwindowsurface_qws_p.h>
-
-#ifdef QT_DIRECTFB_TIMING
-#include <qdatetime.h>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDirectFBWindowSurface : public QWSWindowSurface, public QDirectFBPaintDevice
-{
-public:
- QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen *scr);
- QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen *scr, QWidget *widget);
- ~QDirectFBWindowSurface();
-
-#ifdef QT_DIRECTFB_WM
- void raise();
-#endif
- bool isValid() const;
-
- void setGeometry(const QRect &rect);
-
- QString key() const { return QLatin1String("directfb"); }
- QByteArray permanentState() const;
- void setPermanentState(const QByteArray &state);
-
- bool scroll(const QRegion &area, int dx, int dy);
-
- bool move(const QPoint &offset);
-
- QImage image() const { return QImage(); }
- QPaintDevice *paintDevice() { return this; }
-
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
- void beginPaint(const QRegion &);
- void endPaint(const QRegion &);
-
- IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const;
- IDirectFBSurface *directFBSurface() const;
-#ifdef QT_DIRECTFB_WM
- IDirectFBWindow *directFBWindow() const;
-#endif
-private:
- void updateIsOpaque();
- void setOpaque(bool opaque);
- void releaseSurface();
-
-#ifdef QT_DIRECTFB_WM
- void createWindow(const QRect &rect);
- IDirectFBWindow *dfbWindow;
-#else
- enum Mode {
- Primary,
- Offscreen
- } mode;
-#endif
-
- DFBSurfaceFlipFlags flipFlags;
- bool boundingRectFlip;
- bool flushPending;
-#ifdef QT_DIRECTFB_TIMING
- int frames;
- QTime timer;
-#endif
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-
-#endif // QDIRECFBWINDOWSURFACE_H
diff --git a/src/plugins/gfxdrivers/eglnullws/README b/src/plugins/gfxdrivers/eglnullws/README
deleted file mode 100644
index 80b88c7e01..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/README
+++ /dev/null
@@ -1,48 +0,0 @@
-EGL NullWS QScreen Driver
-=========================
-
-If your application draws everything within a single full-screen QGLWidget then
-you may wish to use this QScreen plugin driver. This driver simply returns 0
-(as a EGLNativeWindowType value) when asked by the QtOpenGl module to create a
-native window. Some OpenGL ES implementations (including PowerVR) interpret this
-to mean that a full-screen OpenGL context is desired without any windowing
-support (NullWS).
-
-To tell a Qt/Embedded application to use this driver use the -display command
-line option or the QWS_DISPLAY environment variable. The following driver
-options are supported:
-
-size=WIDTHxHEIGHT Screen size reported by the driver
-format=FORMAT Screen format
-
-Run with '-display eglnullws:help' to get a full list of options (including a
-list of supported format strings).
-
-If you choose a screen format that is not supported by the hardware then the
-QtOpenGl module will write out a list of supported EGL configurations. Use
-one of the supported screen formats from this list.
-
-Using this driver with PowerVR hardware
----------------------------------------
-
-Using this plugin with PowerVR hardware should give a significant speedup
-compared to running with the Qt powervr driver (with a full-screen QGLWidget).
-This is because sacrificing the window system allows less work to be done in
-order to get graphics on the screen. Using this driver also avoids the memory
-fragmentation issues present in the powervr driver and avoids any direct
-dependencies on the deprecated PVR2D API from Imagination Technologies.
-
-To use this driver ensure you have /etc/powervr.ini with contents similar to
-this:
-
-[default]
-WindowSystem=libpvrPVR2D_FLIPWSEGL.so
-
-This driver will also function with libpvrPVR2D_FRONTWSEGL.so, but that draws
-straight into the framebuffer and will therefore cause flickering (it can be
-useful for performance testing though). The flip plugin uses triple buffering,
-so you will need to set the virtual vertical resolution of your framebuffer to
-be three times the physical vertical resolution of your screen. This can be
-done with 'fbset -vyres'. Failure to do this can cause system crashes. You
-should also ensure that the plugin you choose in powervr.ini is in your library
-path (it may just silently default to the flip plugin if not).
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullws.pro b/src/plugins/gfxdrivers/eglnullws/eglnullws.pro
deleted file mode 100644
index cb65c2b627..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullws.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TARGET = qeglnullws
-load(qt_plugin)
-
-CONFIG += warn_on
-QT += opengl
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-HEADERS = eglnullwsscreen.h \
- eglnullwsscreenplugin.h \
- eglnullwswindowsurface.h
-
-SOURCES = eglnullwsscreen.cpp \
- eglnullwsscreenplugin.cpp \
- eglnullwswindowsurface.cpp
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp
deleted file mode 100644
index e8c73cf31d..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "eglnullwsscreen.h"
-#include "eglnullwswindowsurface.h"
-#include "eglnullwsscreenplugin.h"
-
-#include <QHash>
-#include <QDebug>
-
-namespace
-{
- class EGLNullWSScreenSurfaceFunctions : public QGLScreenSurfaceFunctions
- {
- public:
- virtual bool createNativeWindow(QWidget *, EGLNativeWindowType *native)
- { *native = 0; return true; }
- };
-}
-
-EGLNullWSScreen::EGLNullWSScreen(int displayId) : QGLScreen(displayId) {}
-
-EGLNullWSScreen::~EGLNullWSScreen() {}
-
-bool EGLNullWSScreen::initDevice()
-{
- setSurfaceFunctions(new EGLNullWSScreenSurfaceFunctions);
- return true;
-}
-
-static const QHash<QString, QImage::Format> formatDictionary()
-{
- QHash<QString, QImage::Format> dictionary;
- dictionary["rgb32"] = QImage::Format_RGB32;
- dictionary["argb32"] = QImage::Format_ARGB32;
- dictionary["rgb16"] = QImage::Format_RGB16;
- dictionary["rgb666"] = QImage::Format_RGB666;
- dictionary["rgb555"] = QImage::Format_RGB555;
- dictionary["rgb888"] = QImage::Format_RGB888;
- dictionary["rgb444"] = QImage::Format_RGB444;
- return dictionary;
-}
-
-static int depthForFormat(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_RGB32: return 32;
- case QImage::Format_ARGB32: return 32;
- case QImage::Format_RGB16: return 16;
- case QImage::Format_RGB666: return 24;
- case QImage::Format_RGB555: return 16;
- case QImage::Format_RGB888: return 24;
- case QImage::Format_RGB444: return 16;
- default:
- Q_ASSERT_X(false, "EGLNullWSScreen", "Unknown format");
- return -1;
- }
-}
-
-static void printHelp(const QHash<QString, QImage::Format> &formatDictionary)
-{
- QByteArray formatsBuf;
- QTextStream(&formatsBuf) << QStringList(formatDictionary.keys()).join(", ");
- qWarning(
- "%s: Valid options are:\n"
- "size=WIDTHxHEIGHT Screen size reported by this driver\n"
- "format=FORMAT Screen format, where FORMAT is one of the following:\n"
- " %s\n",
- PluginName,
- formatsBuf.constData());
-}
-
-bool EGLNullWSScreen::connect(const QString &displaySpec)
-{
- const QStringList args = displaySpec.section(':', 1).split(':', QString::SkipEmptyParts);
- const QHash<QString, QImage::Format> formatDict = formatDictionary();
- Q_FOREACH(const QString arg, args) {
- const QString optionName = arg.section('=', 0, 0);
- const QString optionArg = arg.section('=', 1);
- if (optionName == QLatin1String("size")) {
- w = optionArg.section('x', 0, 0).toInt();
- h = optionArg.section('x', 1, 1).toInt();
- } else if (optionName == QLatin1String("format")) {
- if (formatDict.contains(optionArg))
- setPixelFormat(formatDict.value(optionArg));
- else
- printHelp(formatDict);
- } else {
- printHelp(formatDict);
- }
- }
-
- if (w == 0 || h == 0) {
- w = 640;
- h = 480;
- qWarning("%s: Using default screen size %dx%d", PluginName, w, h);
- }
- dw = w;
- dh = h;
-
- if (pixelFormat() == QImage::Format_Invalid) {
- qWarning("%s: Using default screen format argb32", PluginName);
- setPixelFormat(QImage::Format_ARGB32);
- }
- d = depthForFormat(pixelFormat());
-
- static const int Dpi = 120;
- static const qreal ScalingFactor = static_cast<qreal>(25.4) / Dpi;
- physWidth = qRound(dw * ScalingFactor);
- physHeight = qRound(dh * ScalingFactor);
-
- return true;
-}
-
-void EGLNullWSScreen::disconnect() {}
-
-void EGLNullWSScreen::shutdownDevice() {}
-
-void EGLNullWSScreen::setMode(int /*width*/, int /*height*/, int /*depth*/) {}
-
-void EGLNullWSScreen::blank(bool /*on*/) {}
-
-void EGLNullWSScreen::exposeRegion(QRegion /*r*/, int /*changing*/) {}
-
-QWSWindowSurface* EGLNullWSScreen::createSurface(QWidget *widget) const
-{
- if (qobject_cast<QGLWidget*>(widget)) {
- return new EGLNullWSWindowSurface(widget);
- } else {
- qWarning("%s: Creating non-GL surface", PluginName);
- return QScreen::createSurface(widget);
- }
-}
-
-QWSWindowSurface* EGLNullWSScreen::createSurface(const QString &key) const
-{
- if (key == QLatin1String("eglnullws")) {
- return new EGLNullWSWindowSurface;
- } else {
- qWarning("%s: Creating non-GL surface", PluginName);
- return QScreen::createSurface(key);
- }
-}
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h
deleted file mode 100644
index 8295e5daaa..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef EGLNULLWSSCREEN
-#define EGLNULLWSSCREEN
-
-#include <QGLScreen>
-
-class EGLNullWSScreen : public QGLScreen
-{
-public:
- EGLNullWSScreen(int displayId);
- ~EGLNullWSScreen();
-
- bool initDevice();
- bool connect(const QString &displaySpec);
- void disconnect();
- void shutdownDevice();
-
- void setMode(int width, int height, int depth);
- void blank(bool on);
-
- void exposeRegion(QRegion r, int changing);
-
- QWSWindowSurface* createSurface(QWidget *widget) const;
- QWSWindowSurface* createSurface(const QString &key) const;
-
- bool hasOpenGL() { return true; }
-};
-
-#endif // EGLNULLWSSCREEN
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp
deleted file mode 100644
index ebae53d8c4..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "eglnullwsscreenplugin.h"
-#include "eglnullwsscreen.h"
-
-#include <QScreenDriverPlugin>
-#include <QStringList>
-
-class EGLNullWSScreenPlugin : public QScreenDriverPlugin
-{
-public:
- virtual QStringList keys() const;
- virtual QScreen *create(const QString& driver, int displayId);
-};
-
-QStringList EGLNullWSScreenPlugin::keys() const
-{
- return QStringList() << QLatin1String(PluginName);
-}
-
-QScreen *EGLNullWSScreenPlugin::create(const QString& driver, int displayId)
-{
- return (driver.toLower() == QLatin1String(PluginName) ?
- new EGLNullWSScreen(displayId) : 0);
-}
-
-Q_EXPORT_PLUGIN2(qeglnullws, EGLNullWSScreenPlugin)
diff --git a/src/plugins/gfxdrivers/gfxdrivers.pro b/src/plugins/gfxdrivers/gfxdrivers.pro
deleted file mode 100644
index 1f38942a50..0000000000
--- a/src/plugins/gfxdrivers/gfxdrivers.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-TEMPLATE = subdirs
-contains(gfx-plugins, ahi) :SUBDIRS += ahi
-contains(gfx-plugins, directfb) :SUBDIRS += directfb
-contains(gfx-plugins, linuxfb) :SUBDIRS += linuxfb
-contains(gfx-plugins, qvfb) :SUBDIRS += qvfb
-contains(gfx-plugins, vnc) :SUBDIRS += vnc
-contains(gfx-plugins, transformed) :SUBDIRS += transformed
-contains(gfx-plugins, svgalib) :SUBDIRS += svgalib
-contains(gfx-plugins, powervr) :SUBDIRS += powervr
-contains(gfx-plugins, eglnullws) :SUBDIRS += eglnullws
diff --git a/src/plugins/gfxdrivers/linuxfb/linuxfb.pro b/src/plugins/gfxdrivers/linuxfb/linuxfb.pro
deleted file mode 100644
index 2bbe910e63..0000000000
--- a/src/plugins/gfxdrivers/linuxfb/linuxfb.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qscreenlinuxfb
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-DEFINES += QT_QWS_LINUXFB
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qscreenlinuxfb_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qscreenlinuxfb_qws.cpp
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro b/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro
deleted file mode 100644
index 595cf45301..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro
+++ /dev/null
@@ -1,26 +0,0 @@
-TEMPLATE = lib
-TARGET = pvrQWSWSEGL
-CONFIG += dll warn_on
-CONFIG -= qt
-
-HEADERS+=\
- pvrqwsdrawable.h \
- pvrqwsdrawable_p.h
-
-SOURCES+=\
- pvrqwsdrawable.c \
- pvrqwswsegl.c
-
-INCLUDEPATH += $$QMAKE_INCDIR_EGL
-
-for(p, QMAKE_LIBDIR_EGL) {
- exists($$p):LIBS += -L$$p
-}
-
-LIBS += -lpvr2d
-
-DESTDIR = $$QMAKE_LIBDIR_QT
-target.path = $$[QT_INSTALL_LIBS]
-INSTALLS += target
-
-include(../powervr.pri) \ No newline at end of file
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c
deleted file mode 100644
index c453279155..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c
+++ /dev/null
@@ -1,830 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "pvrqwsdrawable_p.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <linux/fb.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-PvrQwsDisplay pvrQwsDisplay;
-
-static void pvrQwsDestroyDrawableForced(PvrQwsDrawable *drawable);
-
-/* Initialize the /dev/fbN device for a specific screen */
-static int pvrQwsInitFbScreen(int screen)
-{
- struct fb_var_screeninfo var;
- struct fb_fix_screeninfo fix;
- unsigned long start;
- unsigned long length;
- int width, height, stride;
- PVR2DFORMAT format;
- void *mapped;
- int fd, bytesPerPixel;
- char name[64];
- PVR2DMEMINFO *memInfo;
- unsigned long pageAddresses[2];
-
- /* Bail out if already initialized, or the number is incorrect */
- if (screen < 0 || screen >= PVRQWS_MAX_SCREENS)
- return 0;
- if (pvrQwsDisplay.screens[screen].initialized)
- return 1;
-
- /* Open the framebuffer and fetch its properties */
- sprintf(name, "/dev/fb%d", screen);
- fd = open(name, O_RDWR, 0);
- if (fd < 0) {
- perror(name);
- return 0;
- }
- if (ioctl(fd, FBIOGET_VSCREENINFO, &var) < 0) {
- perror("FBIOGET_VSCREENINFO");
- close(fd);
- return 0;
- }
- if (ioctl(fd, FBIOGET_FSCREENINFO, &fix) < 0) {
- perror("FBIOGET_FSCREENINFO");
- close(fd);
- return 0;
- }
- width = var.xres;
- height = var.yres;
- bytesPerPixel = var.bits_per_pixel / 8;
- stride = fix.line_length;
- format = PVR2D_1BPP;
- if (var.bits_per_pixel == 16) {
- if (var.red.length == 5 && var.green.length == 6 &&
- var.blue.length == 5 && var.red.offset == 11 &&
- var.green.offset == 5 && var.blue.offset == 0) {
- format = PVR2D_RGB565;
- }
- if (var.red.length == 4 && var.green.length == 4 &&
- var.blue.length == 4 && var.transp.length == 4 &&
- var.red.offset == 8 && var.green.offset == 4 &&
- var.blue.offset == 0 && var.transp.offset == 12) {
- format = PVR2D_ARGB4444;
- }
- } else if (var.bits_per_pixel == 32) {
- if (var.red.length == 8 && var.green.length == 8 &&
- var.blue.length == 8 && var.transp.length == 8 &&
- var.red.offset == 16 && var.green.offset == 8 &&
- var.blue.offset == 0 && var.transp.offset == 24) {
- format = PVR2D_ARGB8888;
- }
- }
- if (format == PVR2D_1BPP) {
- fprintf(stderr, "%s: could not find a suitable PVR2D pixel format\n", name);
- close(fd);
- return 0;
- }
- start = fix.smem_start;
- length = var.xres_virtual * var.yres_virtual * bytesPerPixel;
-
- if (screen == 0) {
- /* We use PVR2DGetFrameBuffer to map the first screen.
- On some chipsets it is more reliable than using PVR2DMemWrap */
- mapped = 0;
- memInfo = 0;
- } else {
- /* Other screens: map the framebuffer region into memory */
- mapped = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (!mapped || mapped == (void *)(-1)) {
- perror("mmap");
- close(fd);
- return 0;
- }
-
- /* Allocate a PVR2D memory region for the framebuffer */
- memInfo = 0;
- if (pvrQwsDisplay.context) {
- pageAddresses[0] = start & 0xFFFFF000;
- pageAddresses[1] = 0;
- if (PVR2DMemWrap
- (pvrQwsDisplay.context, mapped, PVR2D_WRAPFLAG_CONTIGUOUS,
- length, pageAddresses, &memInfo) != PVR2D_OK) {
- munmap(mapped, length);
- close(fd);
- return 0;
- }
- }
- }
-
- /* We don't need the file descriptor any more */
- close(fd);
-
- /* The framebuffer is ready, so initialize the PvrQwsScreenInfo */
- pvrQwsDisplay.screens[screen].screenRect.x = 0;
- pvrQwsDisplay.screens[screen].screenRect.y = 0;
- pvrQwsDisplay.screens[screen].screenRect.width = width;
- pvrQwsDisplay.screens[screen].screenRect.height = height;
- pvrQwsDisplay.screens[screen].screenStride = stride;
- pvrQwsDisplay.screens[screen].pixelFormat = format;
- pvrQwsDisplay.screens[screen].bytesPerPixel = bytesPerPixel;
- pvrQwsDisplay.screens[screen].screenDrawable = 0;
- if (mapped) {
- /* Don't set these fields if mapped is 0, because PVR2DGetFrameBuffer
- may have already been called and set them */
- pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
- pvrQwsDisplay.screens[screen].mapped = mapped;
- }
- pvrQwsDisplay.screens[screen].mappedLength = length;
- pvrQwsDisplay.screens[screen].screenStart = start;
- pvrQwsDisplay.screens[screen].needsUnmap = (mapped != 0);
- pvrQwsDisplay.screens[screen].initialized = 1;
- return 1;
-}
-
-/* Called when a new drawable is added to ensure that we have a
- PVR2D context and framebuffer PVR2DMEMINFO blocks */
-static int pvrQwsAddDrawable(void)
-{
- int numDevs, screen;
- PVR2DDEVICEINFO *devs;
- unsigned long devId;
- unsigned long pageAddresses[2];
- PVR2DMEMINFO *memInfo;
- PVR2DDISPLAYINFO displayInfo;
-
- /* Bail out early if this is not the first drawable */
- if (pvrQwsDisplay.numDrawables > 0) {
- ++(pvrQwsDisplay.numDrawables);
- return 1;
- }
-
- /* Find the first PVR2D device in the system and open it */
- numDevs = PVR2DEnumerateDevices(0);
- if (numDevs <= 0)
- return 0;
- devs = (PVR2DDEVICEINFO *)malloc(sizeof(PVR2DDEVICEINFO) * numDevs);
- if (!devs)
- return 0;
- if (PVR2DEnumerateDevices(devs) != PVR2D_OK) {
- free(devs);
- return 0;
- }
- devId = devs[0].ulDevID;
- free(devs);
- if (PVR2DCreateDeviceContext(devId, &pvrQwsDisplay.context, 0) != PVR2D_OK)
- return 0;
- pvrQwsDisplay.numFlipBuffers = 0;
- pvrQwsDisplay.flipChain = 0;
- if (PVR2DGetDeviceInfo(pvrQwsDisplay.context, &displayInfo) == PVR2D_OK) {
- if (displayInfo.ulMaxFlipChains > 0 && displayInfo.ulMaxBuffersInChain > 0)
- pvrQwsDisplay.numFlipBuffers = displayInfo.ulMaxBuffersInChain;
- if (pvrQwsDisplay.numFlipBuffers > PVRQWS_MAX_FLIP_BUFFERS)
- pvrQwsDisplay.numFlipBuffers = PVRQWS_MAX_FLIP_BUFFERS;
- }
-
- /* Create the PVR2DMEMINFO blocks for the active framebuffers */
- for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
- if (screen != 0 && pvrQwsDisplay.screens[screen].mapped) {
- pageAddresses[0]
- = pvrQwsDisplay.screens[screen].screenStart & 0xFFFFF000;
- pageAddresses[1] = 0;
- if (PVR2DMemWrap
- (pvrQwsDisplay.context,
- pvrQwsDisplay.screens[screen].mapped,
- PVR2D_WRAPFLAG_CONTIGUOUS,
- pvrQwsDisplay.screens[screen].mappedLength,
- pageAddresses, &memInfo) != PVR2D_OK) {
- PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
- pvrQwsDisplay.context = 0;
- return 0;
- }
- pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
- } else if (screen == 0) {
- if (PVR2DGetFrameBuffer
- (pvrQwsDisplay.context,
- PVR2D_FB_PRIMARY_SURFACE, &memInfo) != PVR2D_OK) {
- fprintf(stderr, "QWSWSEGL: could not get the primary framebuffer surface\n");
- PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
- pvrQwsDisplay.context = 0;
- return 0;
- }
- pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
- pvrQwsDisplay.screens[screen].mapped = memInfo->pBase;
- }
- }
-
- /* Create a flip chain for the screen if supported by the hardware */
- pvrQwsDisplay.usePresentBlit = 0;
- if (pvrQwsDisplay.numFlipBuffers > 0) {
- long stride = 0;
- unsigned long flipId = 0;
- unsigned long numBuffers;
- if (PVR2DCreateFlipChain(pvrQwsDisplay.context, 0,
- //PVR2D_CREATE_FLIPCHAIN_SHARED |
- //PVR2D_CREATE_FLIPCHAIN_QUERY,
- pvrQwsDisplay.numFlipBuffers,
- pvrQwsDisplay.screens[0].screenRect.width,
- pvrQwsDisplay.screens[0].screenRect.height,
- pvrQwsDisplay.screens[0].pixelFormat,
- &stride, &flipId, &(pvrQwsDisplay.flipChain))
- == PVR2D_OK) {
- pvrQwsDisplay.screens[0].screenStride = stride;
- PVR2DGetFlipChainBuffers(pvrQwsDisplay.context,
- pvrQwsDisplay.flipChain,
- &numBuffers,
- pvrQwsDisplay.flipBuffers);
- } else {
- pvrQwsDisplay.flipChain = 0;
- pvrQwsDisplay.numFlipBuffers = 0;
- }
-
- /* PVR2DPresentBlt is a little more reliable than PVR2DBlt
- when flip chains are present, even if we cannot create a
- flip chain at the moment */
- pvrQwsDisplay.usePresentBlit = 1;
- }
-
- /* The context is ready to go */
- ++(pvrQwsDisplay.numDrawables);
- return 1;
-}
-
-/* Called when the last drawable is destroyed. The PVR2D context
- will be destroyed but the raw framebuffer memory will stay mapped */
-static void pvrQwsDestroyContext(void)
-{
- int screen;
- for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
- if (pvrQwsDisplay.screens[screen].frameBuffer) {
- PVR2DMemFree
- (pvrQwsDisplay.context,
- pvrQwsDisplay.screens[screen].frameBuffer);
- pvrQwsDisplay.screens[screen].frameBuffer = 0;
- }
- }
-
- if (pvrQwsDisplay.numFlipBuffers > 0)
- PVR2DDestroyFlipChain(pvrQwsDisplay.context, pvrQwsDisplay.flipChain);
- PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
- pvrQwsDisplay.context = 0;
- pvrQwsDisplay.flipChain = 0;
- pvrQwsDisplay.numFlipBuffers = 0;
- pvrQwsDisplay.usePresentBlit = 0;
-}
-
-int pvrQwsDisplayOpen(void)
-{
- int screen;
-
- /* If the display is already open, increase reference count and return */
- if (pvrQwsDisplay.refCount > 0) {
- ++(pvrQwsDisplay.refCount);
- return 1;
- }
-
- /* Open the framebuffer and map it directly */
- if (!pvrQwsInitFbScreen(0)) {
- --(pvrQwsDisplay.refCount);
- return 0;
- }
-
- /* Clear the other screens. We will create them if they are referenced */
- for (screen = 1; screen < PVRQWS_MAX_SCREENS; ++screen)
- memset(&(pvrQwsDisplay.screens[screen]), 0, sizeof(PvrQwsScreenInfo));
-
- /* The display is open and ready */
- ++(pvrQwsDisplay.refCount);
- return 1;
-}
-
-void pvrQwsDisplayClose(void)
-{
- int screen;
-
- if (pvrQwsDisplay.refCount == 0)
- return;
- if (--(pvrQwsDisplay.refCount) > 0)
- return;
-
- /* Prevent pvrQwsDestroyContext from being called for the time being */
- ++pvrQwsDisplay.numDrawables;
-
- /* Free the screens */
- for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
- PvrQwsScreenInfo *info = &(pvrQwsDisplay.screens[screen]);
- if (info->screenDrawable)
- pvrQwsDestroyDrawableForced(info->screenDrawable);
- if (info->frameBuffer)
- PVR2DMemFree(pvrQwsDisplay.context, info->frameBuffer);
- if (info->mapped && info->needsUnmap)
- munmap(info->mapped, info->mappedLength);
- }
-
- /* Now it is safe to destroy the PVR2D context */
- --pvrQwsDisplay.numDrawables;
- if (pvrQwsDisplay.context)
- PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
-
- memset(&pvrQwsDisplay, 0, sizeof(pvrQwsDisplay));
-}
-
-int pvrQwsDisplayIsOpen(void)
-{
- return (pvrQwsDisplay.refCount > 0);
-}
-
-/* Ensure that a specific screen has been initialized */
-static int pvrQwsEnsureScreen(int screen)
-{
- if (screen < 0 || screen >= PVRQWS_MAX_SCREENS)
- return 0;
- if (!screen)
- return 1;
- return pvrQwsInitFbScreen(screen);
-}
-
-PvrQwsDrawable *pvrQwsScreenWindow(int screen)
-{
- PvrQwsDrawable *drawable;
-
- if (!pvrQwsEnsureScreen(screen))
- return 0;
-
- drawable = pvrQwsDisplay.screens[screen].screenDrawable;
- if (drawable)
- return drawable;
-
- drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
- if (!drawable)
- return 0;
-
- drawable->type = PvrQwsScreen;
- drawable->screen = screen;
- drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
- drawable->rect = pvrQwsDisplay.screens[screen].screenRect;
- drawable->visibleRects[0] = drawable->rect;
- drawable->numVisibleRects = 1;
- drawable->isFullScreen = 1;
-
- if (!pvrQwsAddDrawable()) {
- free(drawable);
- return 0;
- }
-
- pvrQwsDisplay.screens[screen].screenDrawable = drawable;
-
- return drawable;
-}
-
-PvrQwsDrawable *pvrQwsCreateWindow(int screen, long winId, const PvrQwsRect *rect)
-{
- PvrQwsDrawable *drawable;
-
- if (!pvrQwsEnsureScreen(screen))
- return 0;
-
- drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
- if (!drawable)
- return 0;
-
- drawable->type = PvrQwsWindow;
- drawable->winId = winId;
- drawable->refCount = 1;
- drawable->screen = screen;
- drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
- drawable->rect = *rect;
-
- if (!pvrQwsAddDrawable()) {
- free(drawable);
- return 0;
- }
-
- drawable->nextWinId = pvrQwsDisplay.firstWinId;
- pvrQwsDisplay.firstWinId = drawable;
-
- return drawable;
-}
-
-PvrQwsDrawable *pvrQwsFetchWindow(long winId)
-{
- PvrQwsDrawable *drawable = pvrQwsDisplay.firstWinId;
- while (drawable != 0 && drawable->winId != winId)
- drawable = drawable->nextWinId;
-
- if (drawable)
- ++(drawable->refCount);
- return drawable;
-}
-
-int pvrQwsReleaseWindow(PvrQwsDrawable *drawable)
-{
- if (drawable->type == PvrQwsWindow)
- return (--(drawable->refCount) <= 0);
- else
- return 0;
-}
-
-PvrQwsDrawable *pvrQwsCreatePixmap(int width, int height, int screen)
-{
- PvrQwsDrawable *drawable;
-
- if (!pvrQwsEnsureScreen(screen))
- return 0;
-
- drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
- if (!drawable)
- return 0;
-
- drawable->type = PvrQwsPixmap;
- drawable->screen = screen;
- drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
- drawable->rect.x = 0;
- drawable->rect.y = 0;
- drawable->rect.width = width;
- drawable->rect.height = height;
-
- if (!pvrQwsAddDrawable()) {
- free(drawable);
- return 0;
- }
-
- return drawable;
-}
-
-static void pvrQwsDestroyDrawableForced(PvrQwsDrawable *drawable)
-{
- /* Remove the drawable from the display's winId list */
- PvrQwsDrawable *current = pvrQwsDisplay.firstWinId;
- PvrQwsDrawable *prev = 0;
- while (current != 0 && current != drawable) {
- prev = current;
- current = current->nextWinId;
- }
- if (current != 0) {
- if (prev)
- prev->nextWinId = current->nextWinId;
- else
- pvrQwsDisplay.firstWinId = current->nextWinId;
- }
-
- pvrQwsFreeBuffers(drawable);
- free(drawable);
-
- --pvrQwsDisplay.numDrawables;
- if (pvrQwsDisplay.numDrawables == 0)
- pvrQwsDestroyContext();
-}
-
-void pvrQwsDestroyDrawable(PvrQwsDrawable *drawable)
-{
- if (drawable && drawable->type != PvrQwsScreen)
- pvrQwsDestroyDrawableForced(drawable);
-}
-
-PvrQwsDrawableType pvrQwsGetDrawableType(PvrQwsDrawable *drawable)
-{
- return drawable->type;
-}
-
-void pvrQwsSetVisibleRegion
- (PvrQwsDrawable *drawable, const PvrQwsRect *rects, int numRects)
-{
- int index, indexOut;
- PvrQwsRect *rect;
- PvrQwsRect *screenRect;
-
- /* Visible regions don't make sense for pixmaps */
- if (drawable->type == PvrQwsPixmap)
- return;
-
- /* Restrict the number of rectangles to prevent buffer overflow */
- if (numRects > PVRQWS_MAX_VISIBLE_RECTS)
- numRects = PVRQWS_MAX_VISIBLE_RECTS;
- if (numRects > 0)
- memcpy(drawable->visibleRects, rects, numRects * sizeof(PvrQwsRect));
-
- /* Convert the rectangles into screen-relative co-ordinates and
- then clamp them to the screen boundaries. If any of the
- clamped rectangles are empty, remove them from the list */
- screenRect = &(pvrQwsDisplay.screens[drawable->screen].screenRect);
- indexOut = 0;
- for (index = 0, rect = drawable->visibleRects; index < numRects; ++index, ++rect) {
- if (rect->x < 0) {
- rect->width += rect->x;
- rect->x = 0;
- if (rect->width < 0)
- rect->width = 0;
- } else if (rect->x >= screenRect->width) {
- rect->x = screenRect->width;
- rect->width = 0;
- }
- if ((rect->x + rect->width) > screenRect->width) {
- rect->width = screenRect->width - rect->x;
- }
- if (rect->y < 0) {
- rect->height += rect->y;
- rect->y = 0;
- if (rect->height < 0)
- rect->height = 0;
- } else if (rect->y >= screenRect->height) {
- rect->y = screenRect->height;
- rect->height = 0;
- }
- if ((rect->y + rect->height) > screenRect->height) {
- rect->height = screenRect->height - rect->y;
- }
- if (rect->width > 0 && rect->height > 0) {
- if (index != indexOut)
- drawable->visibleRects[indexOut] = *rect;
- ++indexOut;
- }
- }
- drawable->numVisibleRects = indexOut;
-}
-
-void pvrQwsClearVisibleRegion(PvrQwsDrawable *drawable)
-{
- if (drawable->type != PvrQwsPixmap)
- drawable->numVisibleRects = 0;
-}
-
-void pvrQwsSetGeometry(PvrQwsDrawable *drawable, const PvrQwsRect *rect)
-{
- /* We can only change the geometry of window drawables */
- if (drawable->type != PvrQwsWindow)
- return;
-
- /* If the position has changed, then clear the visible region */
- if (drawable->rect.x != rect->x || drawable->rect.y != rect->y) {
- drawable->rect.x = rect->x;
- drawable->rect.y = rect->y;
- drawable->numVisibleRects = 0;
- }
-
- /* If the size has changed, then clear the visible region and
- invalidate the drawable's buffers. Invalidating the buffers
- will force EGL to recreate the drawable, which will then
- allocate new buffers for the new size */
- if (drawable->rect.width != rect->width ||
- drawable->rect.height != rect->height) {
- drawable->rect.width = rect->width;
- drawable->rect.height = rect->height;
- drawable->numVisibleRects = 0;
- pvrQwsInvalidateBuffers(drawable);
- }
-}
-
-void pvrQwsGetGeometry(PvrQwsDrawable *drawable, PvrQwsRect *rect)
-{
- *rect = drawable->rect;
-}
-
-void pvrQwsSetRotation(PvrQwsDrawable *drawable, int angle)
-{
- if (drawable->rotationAngle != angle) {
- drawable->rotationAngle = angle;
-
- /* Force the buffers to be recreated if the rotation angle changes */
- pvrQwsInvalidateBuffers(drawable);
- }
-}
-
-int pvrQwsGetStride(PvrQwsDrawable *drawable)
-{
- if (drawable->backBuffersValid)
- return drawable->strideBytes;
- else
- return 0;
-}
-
-PvrQwsPixelFormat pvrQwsGetPixelFormat(PvrQwsDrawable *drawable)
-{
- return (PvrQwsPixelFormat)(drawable->pixelFormat);
-}
-
-void *pvrQwsGetRenderBuffer(PvrQwsDrawable *drawable)
-{
- if (drawable->backBuffersValid)
- return drawable->backBuffers[drawable->currentBackBuffer]->pBase;
- else
- return 0;
-}
-
-int pvrQwsAllocBuffers(PvrQwsDrawable *drawable)
-{
- int index;
- int numBuffers = PVRQWS_MAX_BACK_BUFFERS;
- if (drawable->type == PvrQwsPixmap)
- numBuffers = 1;
- if (drawable->backBuffers[0]) {
- if (drawable->backBuffersValid)
- return 1;
- if (!drawable->usingFlipBuffers) {
- for (index = 0; index < numBuffers; ++index)
- PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
- }
- }
- drawable->stridePixels = (drawable->rect.width + 31) & ~31;
- drawable->strideBytes =
- drawable->stridePixels *
- pvrQwsDisplay.screens[drawable->screen].bytesPerPixel;
- drawable->usingFlipBuffers =
- (pvrQwsDisplay.numFlipBuffers > 0 && drawable->isFullScreen);
- if (drawable->usingFlipBuffers) {
- if (numBuffers > (int)(pvrQwsDisplay.numFlipBuffers))
- numBuffers = pvrQwsDisplay.numFlipBuffers;
- for (index = 0; index < numBuffers; ++index)
- drawable->backBuffers[index] = pvrQwsDisplay.flipBuffers[index];
- } else {
- for (index = 0; index < numBuffers; ++index) {
- if (PVR2DMemAlloc(pvrQwsDisplay.context,
- drawable->strideBytes * drawable->rect.height,
- 128, 0,
- &(drawable->backBuffers[index])) != PVR2D_OK) {
- while (--index >= 0)
- PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
- memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers));
- drawable->backBuffersValid = 0;
- return 0;
- }
- }
- }
- for (index = numBuffers; index < PVRQWS_MAX_BACK_BUFFERS; ++index) {
- drawable->backBuffers[index] = drawable->backBuffers[0];
- }
- drawable->backBuffersValid = 1;
- drawable->currentBackBuffer = 0;
- return 1;
-}
-
-void pvrQwsFreeBuffers(PvrQwsDrawable *drawable)
-{
- int index;
- int numBuffers = PVRQWS_MAX_BACK_BUFFERS;
- if (drawable->type == PvrQwsPixmap)
- numBuffers = 1;
- if (!drawable->usingFlipBuffers) {
- for (index = 0; index < numBuffers; ++index) {
- if (drawable->backBuffers[index])
- PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
- }
- }
- memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers));
- drawable->backBuffersValid = 0;
- drawable->usingFlipBuffers = 0;
-}
-
-void pvrQwsInvalidateBuffers(PvrQwsDrawable *drawable)
-{
- drawable->backBuffersValid = 0;
-}
-
-int pvrQwsGetBuffers
- (PvrQwsDrawable *drawable, PVR2DMEMINFO **source, PVR2DMEMINFO **render)
-{
- if (!drawable->backBuffersValid)
- return 0;
- *render = drawable->backBuffers[drawable->currentBackBuffer];
- *source = drawable->backBuffers
- [(drawable->currentBackBuffer + PVRQWS_MAX_BACK_BUFFERS - 1) %
- PVRQWS_MAX_BACK_BUFFERS];
- return 1;
-}
-
-int pvrQwsSwapBuffers(PvrQwsDrawable *drawable, int repaintOnly)
-{
- PVR2DMEMINFO *buffer;
- PvrQwsRect *rect;
- int index;
-
- /* Bail out if the back buffers have been invalidated */
- if (!drawable->backBuffersValid)
- return 0;
-
- /* If there is a swap function, then use that instead */
- if (drawable->swapFunction) {
- (*(drawable->swapFunction))(drawable, drawable->userData, repaintOnly);
- if (!repaintOnly) {
- drawable->currentBackBuffer
- = (drawable->currentBackBuffer + 1) % PVRQWS_MAX_BACK_BUFFERS;
- }
- return 1;
- }
-
- /* Iterate through the visible rectangles and blit them to the screen */
- if (!repaintOnly) {
- index = drawable->currentBackBuffer;
- } else {
- index = (drawable->currentBackBuffer + PVRQWS_MAX_BACK_BUFFERS - 1)
- % PVRQWS_MAX_BACK_BUFFERS;
- }
- buffer = drawable->backBuffers[index];
- rect = drawable->visibleRects;
- if (drawable->usingFlipBuffers) {
- PVR2DPresentFlip(pvrQwsDisplay.context, pvrQwsDisplay.flipChain, buffer, 0);
- } else if (pvrQwsDisplay.usePresentBlit && drawable->numVisibleRects > 0) {
- PVR2DRECT pvrRects[PVRQWS_MAX_VISIBLE_RECTS];
- for (index = 0; index < drawable->numVisibleRects; ++index, ++rect) {
- pvrRects[index].left = rect->x;
- pvrRects[index].top = rect->y;
- pvrRects[index].right = rect->x + rect->width;
- pvrRects[index].bottom = rect->y + rect->height;
- }
- for (index = 0; index < drawable->numVisibleRects; index += 4) {
- int numClip = drawable->numVisibleRects - index;
- if (numClip > 4) /* No more than 4 clip rects at a time */
- numClip = 4;
- PVR2DSetPresentBltProperties
- (pvrQwsDisplay.context,
- PVR2D_PRESENT_PROPERTY_SRCSTRIDE |
- PVR2D_PRESENT_PROPERTY_DSTSIZE |
- PVR2D_PRESENT_PROPERTY_DSTPOS |
- PVR2D_PRESENT_PROPERTY_CLIPRECTS,
- drawable->strideBytes,
- drawable->rect.width, drawable->rect.height,
- drawable->rect.x, drawable->rect.y,
- numClip, pvrRects + index, 0);
- PVR2DPresentBlt(pvrQwsDisplay.context, buffer, 0);
- }
- PVR2DQueryBlitsComplete(pvrQwsDisplay.context, buffer, 1);
- } else {
- /* TODO: use PVR2DBltClipped for faster transfers of clipped windows */
- PVR2DBLTINFO blit;
- for (index = 0; index < drawable->numVisibleRects; ++index, ++rect) {
- memset(&blit, 0, sizeof(blit));
-
- blit.CopyCode = PVR2DROPcopy;
- blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
-
- blit.pSrcMemInfo = buffer;
- blit.SrcStride = drawable->strideBytes;
- blit.SrcX = rect->x - drawable->rect.x;
- blit.SrcY = rect->y - drawable->rect.y;
- blit.SizeX = rect->width;
- blit.SizeY = rect->height;
- blit.SrcFormat = drawable->pixelFormat;
-
- blit.pDstMemInfo = pvrQwsDisplay.screens[drawable->screen].frameBuffer;
- blit.DstStride = pvrQwsDisplay.screens[drawable->screen].screenStride;
- blit.DstX = rect->x;
- blit.DstY = rect->y;
- blit.DSizeX = rect->width;
- blit.DSizeY = rect->height;
- blit.DstFormat = pvrQwsDisplay.screens[drawable->screen].pixelFormat;
-
- PVR2DBlt(pvrQwsDisplay.context, &blit);
- }
- }
-
- /* Swap the buffers */
- if (!repaintOnly) {
- drawable->currentBackBuffer
- = (drawable->currentBackBuffer + 1) % PVRQWS_MAX_BACK_BUFFERS;
- }
- return 1;
-}
-
-void pvrQwsSetSwapFunction
- (PvrQwsDrawable *drawable, PvrQwsSwapFunction func, void *userData)
-{
- drawable->swapFunction = func;
- drawable->userData = userData;
-}
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h
deleted file mode 100644
index 40119b0a41..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef PVRQWSDRAWABLE_H
-#define PVRQWSDRAWABLE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
- int x, y, width, height;
-} PvrQwsRect;
-
-typedef enum
-{
- PvrQwsScreen,
- PvrQwsWindow,
- PvrQwsPixmap
-
-} PvrQwsDrawableType;
-
-typedef enum
-{
- PvrQws_1BPP = 0,
- PvrQws_RGB565,
- PvrQws_ARGB4444,
- PvrQws_RGB888,
- PvrQws_ARGB8888,
- PvrQws_VGAEMU
-
-} PvrQwsPixelFormat;
-
-typedef struct _PvrQwsDrawable PvrQwsDrawable;
-
-typedef void (*PvrQwsSwapFunction)
- (PvrQwsDrawable *drawable, void *userData, int repaintOnly);
-
-/* Open the display and prepare for window operations. The display
- can be opened multiple times and each time is reference counted.
- The display will be finally closed when the same number of
- calls to pvrQwsDisplayClose() have been encountered */
-int pvrQwsDisplayOpen(void);
-
-/* Close the display */
-void pvrQwsDisplayClose(void);
-
-/* Determine if the display is already open */
-int pvrQwsDisplayIsOpen(void);
-
-/* Create a window that represents a particular framebuffer screen.
- Initially the visible region will be the whole screen. If the screen
- window has already been created, then will return the same value */
-PvrQwsDrawable *pvrQwsScreenWindow(int screen);
-
-/* Create a top-level window on a particular framebuffer screen.
- Initially the window will not have a visible region */
-PvrQwsDrawable *pvrQwsCreateWindow(int screen, long winId, const PvrQwsRect *rect);
-
-/* Fetch an existing window for a window id and increase its refcount */
-PvrQwsDrawable *pvrQwsFetchWindow(long winId);
-
-/* Release the refcount on a window. Returns 1 if refcount is zero */
-int pvrQwsReleaseWindow(PvrQwsDrawable *drawable);
-
-/* Create an off-screen pixmap */
-PvrQwsDrawable *pvrQwsCreatePixmap(int width, int height, int screen);
-
-/* Destroy a previously-created drawable. Will not destroy screens. */
-void pvrQwsDestroyDrawable(PvrQwsDrawable *drawable);
-
-/* Get a drawable's type */
-PvrQwsDrawableType pvrQwsGetDrawableType(PvrQwsDrawable *drawable);
-
-/* Sets the visible region for a window or screen drawable. Pixels within
- the specified rectangles will be copied to the framebuffer when the window
- or screen is swapped. The rectangles should be in global co-ordinates */
-void pvrQwsSetVisibleRegion
- (PvrQwsDrawable *drawable, const PvrQwsRect *rects, int numRects);
-
-/* Clear the visible region for a window or screen drawable,
- effectively removing it from the screen */
-void pvrQwsClearVisibleRegion(PvrQwsDrawable *drawable);
-
-/* Set the geometry for a drawable. This can only be used on windows */
-void pvrQwsSetGeometry(PvrQwsDrawable *drawable, const PvrQwsRect *rect);
-
-/* Get the current geometry for a drawable */
-void pvrQwsGetGeometry(PvrQwsDrawable *drawable, PvrQwsRect *rect);
-
-/* Set the rotation angle in degrees */
-void pvrQwsSetRotation(PvrQwsDrawable *drawable, int angle);
-
-/* Get the line stride for a drawable. Returns zero if the buffers
- are not allocated or have been invalidated */
-int pvrQwsGetStride(PvrQwsDrawable *drawable);
-
-/* Get the pixel format for a drawable */
-PvrQwsPixelFormat pvrQwsGetPixelFormat(PvrQwsDrawable *drawable);
-
-/* Get a pointer to the beginning of a drawable's current render buffer.
- Returns null if the buffers are not allocated or have been invalidated */
-void *pvrQwsGetRenderBuffer(PvrQwsDrawable *drawable);
-
-/* Allocate the buffers associated with a drawable. We allocate one buffer
- for pixmaps, and several for windows and screens */
-int pvrQwsAllocBuffers(PvrQwsDrawable *drawable);
-
-/* Free the buffers associated with a drawable */
-void pvrQwsFreeBuffers(PvrQwsDrawable *drawable);
-
-/* Invalidate the buffers associated with a drawable. The buffers will
- still be allocated but the next attempt to swap the buffers will fail */
-void pvrQwsInvalidateBuffers(PvrQwsDrawable *drawable);
-
-/* Swap the back buffers for a window or screen and copy to the framebuffer */
-int pvrQwsSwapBuffers(PvrQwsDrawable *drawable, int repaintOnly);
-
-/* Set the swap function for a drawable. When pvrQwsSwapBuffers()
- is called on the drawable, the supplied function will be called
- instead of copying the drawable contents to the screen. This allows
- higher-level compositors to know when a drawable has changed.
- The swap function can be set to null to return to normal processing */
-void pvrQwsSetSwapFunction
- (PvrQwsDrawable *drawable, PvrQwsSwapFunction func, void *userData);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h
deleted file mode 100644
index b20dc023d6..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef PVRQWSDRAWABLE_P_H
-#define PVRQWSDRAWABLE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// reasons. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <pvr2d.h>
-#include "pvrqwsdrawable.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PVRQWS_MAX_VISIBLE_RECTS 32
-#define PVRQWS_MAX_SCREENS 1
-#define PVRQWS_MAX_BACK_BUFFERS 2
-#define PVRQWS_MAX_FLIP_BUFFERS 2
-
-typedef struct {
-
- PvrQwsRect screenRect;
- int screenStride;
- PVR2DFORMAT pixelFormat;
- int bytesPerPixel;
- PVR2DMEMINFO *frameBuffer;
- PvrQwsDrawable *screenDrawable;
- void *mapped;
- int mappedLength;
- unsigned long screenStart;
- int needsUnmap;
- int initialized;
-
-} PvrQwsScreenInfo;
-
-typedef struct {
-
- int refCount;
- PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS];
- PVR2DCONTEXTHANDLE context;
- int numDrawables;
- unsigned long numFlipBuffers;
- PVR2DFLIPCHAINHANDLE flipChain;
- PVR2DMEMINFO *flipBuffers[PVRQWS_MAX_FLIP_BUFFERS];
- int usePresentBlit;
- PvrQwsDrawable *firstWinId;
-
-} PvrQwsDisplay;
-
-extern PvrQwsDisplay pvrQwsDisplay;
-
-struct _PvrQwsDrawable
-{
- PvrQwsDrawableType type;
- long winId;
- int refCount;
- PvrQwsRect rect;
- int screen;
- PVR2DFORMAT pixelFormat;
- PvrQwsRect visibleRects[PVRQWS_MAX_VISIBLE_RECTS];
- int numVisibleRects;
- PVR2DMEMINFO *backBuffers[PVRQWS_MAX_BACK_BUFFERS];
- int currentBackBuffer;
- int backBuffersValid;
- int usingFlipBuffers;
- int isFullScreen;
- int strideBytes;
- int stridePixels;
- int rotationAngle;
- PvrQwsSwapFunction swapFunction;
- void *userData;
- PvrQwsDrawable *nextWinId;
-
-};
-
-/* Get the current source and render buffers for a drawable */
-int pvrQwsGetBuffers
- (PvrQwsDrawable *drawable, PVR2DMEMINFO **source, PVR2DMEMINFO **render);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c
deleted file mode 100644
index ce99e607f2..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <GLES/eglplatform.h>
-#include <wsegl.h>
-#include <pvr2d.h>
-#include <string.h>
-#include <sys/mman.h>
-#include "pvrqwsdrawable_p.h"
-
-#define WSEGL_UNUSED(x) (void)x;
-
-// If the PVR2D version is not specified, then assume MBX-style headers.
-// If the version is defined, then we assume that we have SGX-style headers.
-#if !defined(PVR2D_REV_MAJOR)
-#define WSEGL_CAP_WINDOWS_USE_HW_SYNC WSEGL_CAP_WINDOWS_USE_MBX_SYNC
-#define WSEGL_CAP_PIXMAPS_USE_HW_SYNC WSEGL_CAP_PIXMAPS_USE_MBX_SYNC
-#endif
-
-/* Capability information for the display */
-static WSEGLCaps const wseglDisplayCaps[] = {
- {WSEGL_CAP_WINDOWS_USE_HW_SYNC, 1},
- {WSEGL_CAP_PIXMAPS_USE_HW_SYNC, 1},
- {WSEGL_NO_CAPS, 0}
-};
-
-/* Configuration information for the display */
-static WSEGLConfig wseglDisplayConfigs[] = {
- {WSEGL_DRAWABLE_WINDOW, WSEGL_PIXELFORMAT_565, WSEGL_FALSE,
- 0, 0, 0, WSEGL_OPAQUE, 0},
- {WSEGL_DRAWABLE_PIXMAP, WSEGL_PIXELFORMAT_565, WSEGL_FALSE,
- 0, 0, 0, WSEGL_OPAQUE, 0},
- {WSEGL_NO_DRAWABLE, 0, 0, 0, 0, 0, 0, 0}
-};
-
-/* Determine if nativeDisplay is a valid display handle */
-static WSEGLError wseglIsDisplayValid(NativeDisplayType nativeDisplay)
-{
- /* We only have the default display in this system */
- if (nativeDisplay == WSEGL_DEFAULT_DISPLAY)
- return WSEGL_SUCCESS;
- else
- return WSEGL_BAD_NATIVE_DISPLAY;
-}
-
-/* Initialize a native display for use with WSEGL */
-static WSEGLError wseglInitializeDisplay
- (NativeDisplayType nativeDisplay, WSEGLDisplayHandle *display,
- const WSEGLCaps **caps, WSEGLConfig **configs)
-{
- WSEGLPixelFormat pixelFormat;
-
- /* Bail out if the native display is incorrect */
- if (nativeDisplay != WSEGL_DEFAULT_DISPLAY)
- return WSEGL_CANNOT_INITIALISE;
-
- /* Open the PVR/QWS display, which will initialize the framebuffer */
- if (!pvrQwsDisplayOpen())
- return WSEGL_CANNOT_INITIALISE;
-
- /* Convert the PVR2D pixel format into a WSEGL pixel format */
- switch (pvrQwsDisplay.screens[0].pixelFormat) {
- case PVR2D_RGB565:
- pixelFormat = WSEGL_PIXELFORMAT_565;
- break;
-
- case PVR2D_ARGB4444:
- pixelFormat = WSEGL_PIXELFORMAT_4444;
- break;
-
- case PVR2D_ARGB8888:
- pixelFormat = WSEGL_PIXELFORMAT_8888;
- break;
-
- default:
- pvrQwsDisplayClose();
- return WSEGL_CANNOT_INITIALISE;
- }
- wseglDisplayConfigs[0].ePixelFormat = pixelFormat;
- wseglDisplayConfigs[1].ePixelFormat = pixelFormat;
-
- /* The display has been initialized */
- *display = (WSEGLDisplayHandle)&pvrQwsDisplay;
- *caps = wseglDisplayCaps;
- *configs = wseglDisplayConfigs;
- return WSEGL_SUCCESS;
-}
-
-/* Close the WSEGL display */
-static WSEGLError wseglCloseDisplay(WSEGLDisplayHandle display)
-{
- if (display == (WSEGLDisplayHandle)&pvrQwsDisplay)
- pvrQwsDisplayClose();
- return WSEGL_SUCCESS;
-}
-
-static WSEGLRotationAngle wseglRotationValue(int degrees)
-{
- switch (degrees) {
- case 90: return WSEGL_ROTATE_90;
- case 180: return WSEGL_ROTATE_180;
- case 270: return WSEGL_ROTATE_270;
- default: return WSEGL_ROTATE_0;
- }
-}
-
-/* Create the WSEGL drawable version of a native window */
-static WSEGLError wseglCreateWindowDrawable
- (WSEGLDisplayHandle display, WSEGLConfig *config,
- WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow,
- WSEGLRotationAngle *rotationAngle)
-{
- PvrQwsDrawable *draw;
-
- WSEGL_UNUSED(display);
- WSEGL_UNUSED(config);
-
- /* Check for special handles that indicate framebuffer screens */
- if (nativeWindow >= (NativeWindowType)0 &&
- nativeWindow < (NativeWindowType)PVRQWS_MAX_SCREENS) {
- PvrQwsDrawable *screen = pvrQwsScreenWindow((int)nativeWindow);
- if (!screen)
- return WSEGL_OUT_OF_MEMORY;
- *drawable = (WSEGLDrawableHandle)screen;
- if (!pvrQwsAllocBuffers(screen))
- return WSEGL_OUT_OF_MEMORY;
- *rotationAngle = wseglRotationValue(screen->rotationAngle);
- return WSEGL_SUCCESS;
- }
-
- /* The native window is the winId - fetch the underlying drawable */
- draw = pvrQwsFetchWindow((long)nativeWindow);
- if (!draw)
- return WSEGL_BAD_DRAWABLE;
-
- /* The drawable is ready to go */
- *drawable = (WSEGLDrawableHandle)draw;
- *rotationAngle = wseglRotationValue(draw->rotationAngle);
- if (!pvrQwsAllocBuffers(draw))
- return WSEGL_OUT_OF_MEMORY;
- return WSEGL_SUCCESS;
-}
-
-/* Create the WSEGL drawable version of a native pixmap */
-static WSEGLError wseglCreatePixmapDrawable
- (WSEGLDisplayHandle display, WSEGLConfig *config,
- WSEGLDrawableHandle *drawable, NativePixmapType nativePixmap,
- WSEGLRotationAngle *rotationAngle)
-{
- WSEGL_UNUSED(display);
- WSEGL_UNUSED(config);
- if (!nativePixmap)
- return WSEGL_BAD_NATIVE_PIXMAP;
- if (!pvrQwsAllocBuffers((PvrQwsDrawable *)nativePixmap))
- return WSEGL_OUT_OF_MEMORY;
- *drawable = (WSEGLDrawableHandle)nativePixmap;
- *rotationAngle = WSEGL_ROTATE_0;
- return WSEGL_SUCCESS;
-}
-
-/* Delete a specific drawable */
-static WSEGLError wseglDeleteDrawable(WSEGLDrawableHandle _drawable)
-{
- PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
- if (!drawable || drawable->type == PvrQwsScreen)
- return WSEGL_SUCCESS;
- if (pvrQwsDisplay.numFlipBuffers == 0)
- pvrQwsFreeBuffers(drawable);
- if (pvrQwsReleaseWindow(drawable))
- pvrQwsDestroyDrawable(drawable);
- return WSEGL_SUCCESS;
-}
-
-/* Swap the contents of a drawable to the screen */
-static WSEGLError wseglSwapDrawable
- (WSEGLDrawableHandle _drawable, unsigned long data)
-{
- WSEGL_UNUSED(data);
- PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
- if (drawable->type != PvrQwsPixmap && !pvrQwsSwapBuffers(drawable, 0))
- return WSEGL_BAD_DRAWABLE;
- else
- return WSEGL_SUCCESS;
-}
-
-/* Set the swap interval of a window drawable */
-static WSEGLError wseglSwapControlInterval
- (WSEGLDrawableHandle drawable, unsigned long interval)
-{
- WSEGL_UNUSED(drawable);
- if (pvrQwsDisplay.flipChain) {
- PVR2DSetPresentFlipProperties
- (pvrQwsDisplay.context, pvrQwsDisplay.flipChain,
- PVR2D_PRESENT_PROPERTY_INTERVAL, 0, 0, 0, NULL, interval);
- }
- return WSEGL_SUCCESS;
-}
-
-/* Flush native rendering requests on a drawable */
-static WSEGLError wseglWaitNative
- (WSEGLDrawableHandle drawable, unsigned long engine)
-{
- WSEGL_UNUSED(drawable);
- if (engine == WSEGL_DEFAULT_NATIVE_ENGINE)
- return WSEGL_SUCCESS;
- else
- return WSEGL_BAD_NATIVE_ENGINE;
-}
-
-/* Copy color data from a drawable to a native pixmap */
-static WSEGLError wseglCopyFromDrawable
- (WSEGLDrawableHandle _drawable, NativePixmapType nativePixmap)
-{
- PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
- PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
- PVR2DBLTINFO blit;
-
- if (!drawable || !drawable->backBuffersValid)
- return WSEGL_BAD_NATIVE_WINDOW;
- if (!pixmap || !pixmap->backBuffersValid)
- return WSEGL_BAD_NATIVE_PIXMAP;
-
- memset(&blit, 0, sizeof(blit));
-
- blit.CopyCode = PVR2DROPcopy;
- blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
-
- blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer];
- blit.SrcStride = drawable->strideBytes;
- blit.SrcX = 0;
- blit.SrcY = 0;
- blit.SizeX = drawable->rect.width;
- blit.SizeY = drawable->rect.height;
- blit.SrcFormat = drawable->pixelFormat;
-
- blit.pDstMemInfo = pixmap->backBuffers[pixmap->currentBackBuffer];
- blit.DstStride = pixmap->strideBytes;
- blit.DstX = 0;
- blit.DstY = 0;
- blit.DSizeX = pixmap->rect.width;
- blit.DSizeY = pixmap->rect.height;
- blit.DstFormat = pixmap->pixelFormat;
-
- PVR2DBlt(pvrQwsDisplay.context, &blit);
- PVR2DQueryBlitsComplete
- (pvrQwsDisplay.context, pixmap->backBuffers[pixmap->currentBackBuffer], 1);
-
- return WSEGL_SUCCESS;
-}
-
-/* Copy color data from a PBuffer to a native pixmap */
-static WSEGLError wseglCopyFromPBuffer
- (void *address, unsigned long width, unsigned long height,
- unsigned long stride, WSEGLPixelFormat format,
- NativePixmapType nativePixmap)
-{
- PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
- PVR2DFORMAT pixelFormat;
-
- if (!pixmap)
- return WSEGL_BAD_NATIVE_PIXMAP;
-
- /* We can only copy under certain conditions */
- switch (format) {
- case WSEGL_PIXELFORMAT_565:
- pixelFormat = PVR2D_RGB565; break;
- case WSEGL_PIXELFORMAT_4444:
- pixelFormat = PVR2D_ARGB4444; break;
- case WSEGL_PIXELFORMAT_8888:
- pixelFormat = PVR2D_ARGB8888; break;
- default:
- return WSEGL_BAD_CONFIG;
- }
- if (width > (unsigned long)(pixmap->rect.width) ||
- height > (unsigned long)(pixmap->rect.height) ||
- pixelFormat != pixmap->pixelFormat) {
- return WSEGL_BAD_CONFIG;
- }
-
- /* We'd like to use PVR2DBlt to do this, but there is no easy way
- to map the virtual "address" into physical space to be able
- to use the hardware assist. Use memcpy to do the work instead.
- Note: PBuffer's are upside down, so we copy from the bottom up */
- char *srcaddr = (char *)address;
- char *dstaddr = (char *)(pixmap->backBuffers[pixmap->currentBackBuffer]->pBase);
- int dststride = pixmap->strideBytes;
- int srcwidth = ((int)width) * pvrQwsDisplay.screens[0].bytesPerPixel;
- srcaddr += height * stride;
- while (height > 0) {
- srcaddr -= (int)stride;
- memcpy(dstaddr, srcaddr, srcwidth);
- dstaddr += dststride;
- --height;
- }
- return WSEGL_SUCCESS;
-}
-
-/* Return the parameters of a drawable that are needed by the EGL layer */
-static WSEGLError wseglGetDrawableParameters
- (WSEGLDrawableHandle _drawable, WSEGLDrawableParams *sourceParams,
- WSEGLDrawableParams *renderParams)
-{
- PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
- PVR2DMEMINFO *source, *render;
- WSEGLPixelFormat pixelFormat;
-
- if (!pvrQwsGetBuffers(drawable, &source, &render))
- return WSEGL_BAD_DRAWABLE;
-
- switch (drawable->pixelFormat) {
- case PVR2D_RGB565:
- default:
- pixelFormat = WSEGL_PIXELFORMAT_565;
- break;
-
- case PVR2D_ARGB4444:
- pixelFormat = WSEGL_PIXELFORMAT_4444;
- break;
-
- case PVR2D_ARGB8888:
- pixelFormat = WSEGL_PIXELFORMAT_8888;
- break;
- }
-
- sourceParams->ui32Width = drawable->rect.width;
- sourceParams->ui32Height = drawable->rect.height;
- sourceParams->ui32Stride = drawable->stridePixels;
- sourceParams->ePixelFormat = pixelFormat;
- sourceParams->pvLinearAddress = source->pBase;
- sourceParams->ui32HWAddress = source->ui32DevAddr;
- sourceParams->hPrivateData = source->hPrivateData;
-
- renderParams->ui32Width = drawable->rect.width;
- renderParams->ui32Height = drawable->rect.height;
- renderParams->ui32Stride = drawable->stridePixels;
- renderParams->ePixelFormat = pixelFormat;
- renderParams->pvLinearAddress = render->pBase;
- renderParams->ui32HWAddress = render->ui32DevAddr;
- renderParams->hPrivateData = render->hPrivateData;
-
- return WSEGL_SUCCESS;
-}
-
-static WSEGL_FunctionTable const wseglFunctions = {
- WSEGL_VERSION,
- wseglIsDisplayValid,
- wseglInitializeDisplay,
- wseglCloseDisplay,
- wseglCreateWindowDrawable,
- wseglCreatePixmapDrawable,
- wseglDeleteDrawable,
- wseglSwapDrawable,
- wseglSwapControlInterval,
- wseglWaitNative,
- wseglCopyFromDrawable,
- wseglCopyFromPBuffer,
- wseglGetDrawableParameters
-};
-
-/* Return the table of WSEGL functions to the EGL implementation */
-const WSEGL_FunctionTable *WSEGL_GetFunctionTablePointer(void)
-{
- return &wseglFunctions;
-}
diff --git a/src/plugins/gfxdrivers/powervr/README b/src/plugins/gfxdrivers/powervr/README
deleted file mode 100644
index 513e7f5e9e..0000000000
--- a/src/plugins/gfxdrivers/powervr/README
+++ /dev/null
@@ -1,66 +0,0 @@
-PowerVR QScreen Driver
-======================
-
-This QScreen plugin driver allows the QtOpenGl module to integrate with PowerVR
-hardware from Imagination Technologies. Using this plugin, applications may use
-QGLWidget & QGLPixelBuffer with OpenGL ES. The integration with PowerVR drivers
-is built as two libraries: The actual QScreen plugin used by Qt (in the
-pvreglscreen directory) and a WSEGL plugin for the PowerVR drivers (in the
-QWSWSEGL directory).
-
-Qt/Embedded needs to be configured with the QT_QWS_CLIENTBLIT and
-QT_NO_QWS_CURSOR defines.
-
-The PowerVR drivers provide the WSEGL plugin API to allow window systems such as
-QWS to integrate correctly. In order to use the integration, the WSEGL plugin
-(libpvrQWSWSEGL.so, usually installed into the Qt library directory) must be in
-the LD library path. The PowerVR driver also needs to be told which WSEGL library
-to use. This is done by creating/modifying /etc/powervr.ini:
-
-[default]
-WindowSystem=libpvrQWSWSEGL.so
-
-Note: It is important that the /etc/powervr.ini file not contain ^M (Ctrl-M) DOS
-end of line markers at the end of its lines. If ^M markers are present, then the
-libpvrQWSWSEGL.so driver will not be loaded and the default null Linux driver
-will be loaded silently instead. Make sure that the end of line markers are
-strictly Unix-style markers.
-
-
-***************************************************************************
-* IMPORTANT: To build the QScreen plugin and the WSEGL library it depends *
-* on, the pvr2d.h, wsegl.h headers for your platform are required. You *
-* can find a copy of these headers in src/3rdparty/powervr for SGX based *
-* platforms like the TI OMAP3xxx. They probably will not work on MBX *
-* because of differences in the layout of certain PVR2D structures. *
-* You can tell Qt where to find the actual headers for your system by *
-* setting QMAKE_INCDIR_POWERVR in the mkspec. *
-***************************************************************************
-
-When you start a Qt/Embedded application, you should modify the QWS_DISPLAY
-environment variable to use the "powervr" driver instead of "LinuxFb". For
-example, if your original QWS_DISPLAY variable was:
-
- LinuxFb:mmWidth40:mmHeight54:0
-
-then it should be changed to:
-
- powervr:mmWidth40:mmHeight54:0
-
-To test the OpenGL ES integration, you can use the hellogl_es example and run it
-on the device with:
-
- hellogl_es -qws
-
-The driver also supports screen rotation if Qt is configured with the
--qt-gfx-transformed option and the QWS_DISPLAY variable is wrapped in a
-"Transformed" declaration:
-
- Transformed:powervr:mmWidth40:mmHeight54:Rot90:0
-
-Know Issues:
- * A QGLWidget may not have window decorations if it is a top-level window.
- * On some platforms, starting a QWS application after the system has been up
- for a long time may cause the driver to fail. This is due to fragmentation
- of main memory prevening older PowerVR drivers from allocating a contiguous
- region of phyical RAM for the GL surface.
diff --git a/src/plugins/gfxdrivers/powervr/powervr.pri b/src/plugins/gfxdrivers/powervr/powervr.pri
deleted file mode 100644
index 9df8c0ed5b..0000000000
--- a/src/plugins/gfxdrivers/powervr/powervr.pri
+++ /dev/null
@@ -1,2 +0,0 @@
-
-INCLUDEPATH += $$QMAKE_INCDIR_POWERVR
diff --git a/src/plugins/gfxdrivers/powervr/powervr.pro b/src/plugins/gfxdrivers/powervr/powervr.pro
deleted file mode 100644
index f31ad042d8..0000000000
--- a/src/plugins/gfxdrivers/powervr/powervr.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = QWSWSEGL pvreglscreen
-CONFIG += ordered
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
deleted file mode 100644
index 0171de6797..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "pvreglscreen.h"
-#include "pvreglwindowsurface.h"
-#include "pvrqwsdrawable_p.h"
-#include <QRegExp>
-#include <qwindowsystem_qws.h>
-#ifndef QT_NO_QWS_TRANSFORMED
-#include <qscreentransformed_qws.h>
-#endif
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/kd.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-//![0]
-PvrEglScreen::PvrEglScreen(int displayId)
- : QGLScreen(displayId)
-{
- setOptions(NativeWindows);
- setSupportsBlitInClients(true);
- setSurfaceFunctions(new PvrEglScreenSurfaceFunctions(this, displayId));
-//![0]
- fd = -1;
- ttyfd = -1;
- doGraphicsMode = true;
- oldKdMode = KD_TEXT;
- parent = 0;
-
- // Make sure that the EGL layer is initialized and the drivers loaded.
- EGLDisplay dpy = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
- if (!eglInitialize(dpy, 0, 0))
- qWarning("Could not initialize EGL display - are the drivers loaded?");
-
- // Make sure that screen 0 is initialized.
- pvrQwsScreenWindow(0);
-}
-
-PvrEglScreen::~PvrEglScreen()
-{
- if (fd >= 0)
- ::close(fd);
-}
-
-bool PvrEglScreen::initDevice()
-{
- openTty();
- return true;
-}
-
-bool PvrEglScreen::connect(const QString &displaySpec)
-{
- if (!pvrQwsDisplayOpen())
- return false;
-
- // Initialize the QScreen properties.
- data = (uchar *)(pvrQwsDisplay.screens[0].mapped);
- w = pvrQwsDisplay.screens[0].screenRect.width;
- h = pvrQwsDisplay.screens[0].screenRect.height;
- lstep = pvrQwsDisplay.screens[0].screenStride;
- dw = w;
- dh = h;
- size = h * lstep;
- mapsize = size;
- switch (pvrQwsDisplay.screens[0].pixelFormat) {
- case PVR2D_RGB565:
- d = 16;
- setPixelFormat(QImage::Format_RGB16);
- break;
- case PVR2D_ARGB4444:
- d = 16;
- setPixelFormat(QImage::Format_ARGB4444_Premultiplied);
- break;
- case PVR2D_ARGB8888:
- d = 32;
- setPixelFormat(QImage::Format_ARGB32_Premultiplied);
- break;
- default:
- pvrQwsDisplayClose();
- qWarning("PvrEglScreen::connect: unsupported pixel format %d", (int)(pvrQwsDisplay.screens[0].pixelFormat));
- return false;
- }
-
- // Handle display physical size spec.
- QStringList displayArgs = displaySpec.split(QLatin1Char(':'));
- QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)"));
- int dimIdxW = displayArgs.indexOf(mmWidthRx);
- QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)"));
- int dimIdxH = displayArgs.indexOf(mmHeightRx);
- if (dimIdxW >= 0) {
- mmWidthRx.exactMatch(displayArgs.at(dimIdxW));
- physWidth = mmWidthRx.cap(1).toInt();
- if (dimIdxH < 0)
- physHeight = dh*physWidth/dw;
- }
- if (dimIdxH >= 0) {
- mmHeightRx.exactMatch(displayArgs.at(dimIdxH));
- physHeight = mmHeightRx.cap(1).toInt();
- if (dimIdxW < 0)
- physWidth = dw*physHeight/dh;
- }
- if (dimIdxW < 0 && dimIdxH < 0) {
- const int dpi = 72;
- physWidth = qRound(dw * 25.4 / dpi);
- physHeight = qRound(dh * 25.4 / dpi);
- }
-
- // Find the name of the tty device to use.
- QRegExp ttyRegExp(QLatin1String("tty=(.*)"));
- if (displayArgs.indexOf(ttyRegExp) != -1)
- ttyDevice = ttyRegExp.cap(1);
- if (displayArgs.contains(QLatin1String("nographicsmodeswitch")))
- doGraphicsMode = false;
-
- // The screen is ready.
- return true;
-}
-
-void PvrEglScreen::disconnect()
-{
- pvrQwsDisplayClose();
-}
-
-void PvrEglScreen::shutdownDevice()
-{
- closeTty();
-}
-
-void PvrEglScreen::blit(const QImage &img, const QPoint &topLeft, const QRegion &region)
-{
- QGLScreen::blit(img, topLeft, region);
- sync();
-}
-
-void PvrEglScreen::solidFill(const QColor &color, const QRegion &region)
-{
- QGLScreen::solidFill(color, region);
- sync();
-}
-
-bool PvrEglScreen::chooseContext
- (QGLContext *context, const QGLContext *shareContext)
-{
- // We use PvrEglScreenSurfaceFunctions instead.
- Q_UNUSED(context);
- Q_UNUSED(shareContext);
- return false;
-}
-
-bool PvrEglScreen::hasOpenGL()
-{
- return true;
-}
-
-//![1]
-QWSWindowSurface* PvrEglScreen::createSurface(QWidget *widget) const
-{
- if (qobject_cast<QGLWidget*>(widget))
- return new PvrEglWindowSurface(widget, (PvrEglScreen *)this, displayId);
-
- return QScreen::createSurface(widget);
-}
-
-QWSWindowSurface* PvrEglScreen::createSurface(const QString &key) const
-{
- if (key == QLatin1String("PvrEgl"))
- return new PvrEglWindowSurface();
-
- return QScreen::createSurface(key);
-}
-//![1]
-
-#ifndef QT_NO_QWS_TRANSFORMED
-
-static const QScreen *parentScreen
- (const QScreen *current, const QScreen *lookingFor)
-{
- if (!current)
- return 0;
- switch (current->classId()) {
- case QScreen::ProxyClass:
- case QScreen::TransformedClass: {
- const QScreen *child =
- static_cast<const QProxyScreen *>(current)->screen();
- if (child == lookingFor)
- return current;
- else
- return parentScreen(child, lookingFor);
- }
- // Not reached.
-
- case QScreen::MultiClass: {
- QList<QScreen *> screens = current->subScreens();
- foreach (QScreen *screen, screens) {
- if (screen == lookingFor)
- return current;
- const QScreen *parent = parentScreen(screen, lookingFor);
- if (parent)
- return parent;
- }
- }
- break;
-
- default: break;
- }
- return 0;
-}
-
-int PvrEglScreen::transformation() const
-{
- // We need to search for our parent screen, which is assumed to be
- // "Transformed". If it isn't, then there is no transformation.
- // There is no direct method to get the parent screen so we need
- // to search every screen until we find ourselves.
- if (!parent && qt_screen != this)
- parent = parentScreen(qt_screen, this);
- if (!parent)
- return 0;
- if (parent->classId() != QScreen::TransformedClass)
- return 0;
- return 90 * static_cast<const QTransformedScreen *>(parent)
- ->transformOrientation();
-}
-
-#else
-
-int PvrEglScreen::transformation() const
-{
- return 0;
-}
-
-#endif
-
-void PvrEglScreen::sync()
-{
- // Put code here to synchronize 2D and 3D operations if necessary.
-}
-
-void PvrEglScreen::openTty()
-{
- const char *const devs[] = {"/dev/tty0", "/dev/tty", "/dev/console", 0};
-
- if (ttyDevice.isEmpty()) {
- for (const char * const *dev = devs; *dev; ++dev) {
- ttyfd = ::open(*dev, O_RDWR);
- if (ttyfd != -1)
- break;
- }
- } else {
- ttyfd = ::open(ttyDevice.toAscii().constData(), O_RDWR);
- }
-
- if (ttyfd == -1)
- return;
-
- ::fcntl(ttyfd, F_SETFD, FD_CLOEXEC);
-
- if (doGraphicsMode) {
- ioctl(ttyfd, KDGETMODE, &oldKdMode);
- if (oldKdMode != KD_GRAPHICS) {
- int ret = ioctl(ttyfd, KDSETMODE, KD_GRAPHICS);
- if (ret == -1)
- doGraphicsMode = false;
- }
- }
-
- // No blankin' screen, no blinkin' cursor!, no cursor!
- const char termctl[] = "\033[9;0]\033[?33l\033[?25l\033[?1c";
- ::write(ttyfd, termctl, sizeof(termctl));
-}
-
-void PvrEglScreen::closeTty()
-{
- if (ttyfd == -1)
- return;
-
- if (doGraphicsMode)
- ioctl(ttyfd, KDSETMODE, oldKdMode);
-
- // Blankin' screen, blinkin' cursor!
- const char termctl[] = "\033[9;15]\033[?33h\033[?25h\033[?0c";
- ::write(ttyfd, termctl, sizeof(termctl));
-
- ::close(ttyfd);
- ttyfd = -1;
-}
-
-//![2]
-bool PvrEglScreenSurfaceFunctions::createNativeWindow(QWidget *widget, EGLNativeWindowType *native)
-{
-//![2]
- QWSWindowSurface *surface =
- static_cast<QWSWindowSurface *>(widget->windowSurface());
- if (!surface) {
- // The widget does not have a surface yet, so give it one.
- surface = new PvrEglWindowSurface(widget, screen, displayId);
- widget->setWindowSurface(surface);
- } else if (surface->key() != QLatin1String("PvrEgl")) {
- // The application has attached a QGLContext to an ordinary QWidget.
- // Replace the widget's window surface with a new one that can do GL.
- QRect geometry = widget->frameGeometry();
- geometry.moveTo(widget->mapToGlobal(QPoint(0, 0)));
- surface = new PvrEglWindowSurface(widget, screen, displayId);
- surface->setGeometry(geometry);
- widget->setWindowSurface(surface);
- widget->setAttribute(Qt::WA_NoSystemBackground, true);
- }
- PvrEglWindowSurface *nsurface = static_cast<PvrEglWindowSurface*>(surface);
- *native = (EGLNativeWindowType)(nsurface->nativeDrawable());
- return true;
-}
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro
deleted file mode 100644
index 2b5212a6b3..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro
+++ /dev/null
@@ -1,27 +0,0 @@
-TEMPLATE = lib
-TARGET = qgfxpvregl
-CONFIG += qt plugin warn_on
-QT += opengl
-
-LIBS += -lpvrQWSWSEGL
-
-DEFINES += QT_QWS_CLIENTBLIT
-
-INCLUDEPATH += ../QWSWSEGL
-
-
-HEADERS = \
- pvreglscreen.h \
- pvreglwindowsurface.h
-
-SOURCES = \
- pvreglscreenplugin.cpp \
- pvreglscreen.cpp \
- pvreglwindowsurface.cpp
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-include(../powervr.pri) \ No newline at end of file
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreenplugin.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreenplugin.cpp
deleted file mode 100644
index 943bf9473c..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreenplugin.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "pvreglscreen.h"
-
-#include <QScreenDriverPlugin>
-#include <QStringList>
-
-class PvrEglScreenPlugin : public QScreenDriverPlugin
-{
-public:
- PvrEglScreenPlugin();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-PvrEglScreenPlugin::PvrEglScreenPlugin()
- : QScreenDriverPlugin()
-{
-}
-
-QStringList PvrEglScreenPlugin::keys() const
-{
- return (QStringList() << "powervr");
-}
-
-QScreen* PvrEglScreenPlugin::create(const QString& driver, int displayId)
-{
- if (driver.toLower() != "powervr")
- return 0;
-
- return new PvrEglScreen(displayId);
-}
-
-Q_EXPORT_PLUGIN2(qgfxpvregl, PvrEglScreenPlugin)
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp
deleted file mode 100644
index f23f5c1cc4..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "pvreglwindowsurface.h"
-#include "pvreglscreen.h"
-#include <QScreen>
-#include <QDebug>
-#include <QWSDisplay>
-
-PvrEglWindowSurface::PvrEglWindowSurface
- (QWidget *widget, PvrEglScreen *screen, int screenNum)
- : QWSGLWindowSurface(widget)
-{
- setSurfaceFlags(QWSWindowSurface::Opaque);
-
- this->widget = widget;
- this->screen = screen;
- this->pdevice = 0;
-
- QPoint pos = offset(widget);
- QSize size = widget->size();
-
- PvrQwsRect pvrRect;
- pvrRect.x = pos.x();
- pvrRect.y = pos.y();
- pvrRect.width = size.width();
- pvrRect.height = size.height();
- transformRects(&pvrRect, 1);
-
- // Try to recover a previous PvrQwsDrawable object for the widget
- // if there is one. This can happen when a PvrEglWindowSurface
- // is created for a widget, bound to a EGLSurface, and then destroyed.
- // When a new PvrEglWindowSurface is created for the widget, it will
- // pick up the previous PvrQwsDrawable if the EGLSurface has not been
- // destroyed in the meantime.
- drawable = pvrQwsFetchWindow((long)widget);
- if (drawable)
- pvrQwsSetGeometry(drawable, &pvrRect);
- else
- drawable = pvrQwsCreateWindow(screenNum, (long)widget, &pvrRect);
- pvrQwsSetRotation(drawable, screen->transformation());
-}
-
-PvrEglWindowSurface::PvrEglWindowSurface()
- : QWSGLWindowSurface()
-{
- setSurfaceFlags(QWSWindowSurface::Opaque);
- drawable = 0;
- widget = 0;
- screen = 0;
- pdevice = 0;
-}
-
-PvrEglWindowSurface::~PvrEglWindowSurface()
-{
- // Release the PvrQwsDrawable. If it is bound to an EGLSurface,
- // then it will stay around until a new PvrEglWindowSurface is
- // created for the widget. If it is not bound to an EGLSurface,
- // it will be destroyed immediately.
- if (drawable && pvrQwsReleaseWindow(drawable))
- pvrQwsDestroyDrawable(drawable);
-
- delete pdevice;
-}
-
-bool PvrEglWindowSurface::isValid() const
-{
- return (widget != 0);
-}
-
-void PvrEglWindowSurface::setGeometry(const QRect &rect)
-{
- if (drawable) {
- // XXX: adjust for the screen offset.
- PvrQwsRect pvrRect;
- pvrRect.x = rect.x();
- pvrRect.y = rect.y();
- pvrRect.width = rect.width();
- pvrRect.height = rect.height();
- transformRects(&pvrRect, 1);
- pvrQwsSetGeometry(drawable, &pvrRect);
- pvrQwsSetRotation(drawable, screen->transformation());
- }
- QWSGLWindowSurface::setGeometry(rect);
-}
-
-bool PvrEglWindowSurface::move(const QPoint &offset)
-{
- QRect rect = geometry().translated(offset);
- if (drawable) {
- PvrQwsRect pvrRect;
- pvrRect.x = rect.x();
- pvrRect.y = rect.y();
- pvrRect.width = rect.width();
- pvrRect.height = rect.height();
- transformRects(&pvrRect, 1);
- pvrQwsSetGeometry(drawable, &pvrRect);
- pvrQwsSetRotation(drawable, screen->transformation());
- }
- return QWSGLWindowSurface::move(offset);
-}
-
-QByteArray PvrEglWindowSurface::permanentState() const
-{
- // Nothing interesting to pass to the server just yet.
- return QByteArray();
-}
-
-void PvrEglWindowSurface::setPermanentState(const QByteArray &state)
-{
- Q_UNUSED(state);
-}
-
-void PvrEglWindowSurface::flush
- (QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- // The GL paint engine is responsible for the swapBuffers() call.
- // If we were to call the base class's implementation of flush()
- // then it would fetch the image() and manually blit it to the
- // screeen instead of using the fast PVR2D blit.
- Q_UNUSED(widget);
- Q_UNUSED(region);
- Q_UNUSED(offset);
-}
-
-QImage PvrEglWindowSurface::image() const
-{
- if (drawable) {
- PvrQwsRect pvrRect;
- pvrQwsGetGeometry(drawable, &pvrRect);
- void *data = pvrQwsGetRenderBuffer(drawable);
- if (data) {
- return QImage((uchar *)data, pvrRect.width, pvrRect.height,
- pvrQwsGetStride(drawable), screen->pixelFormat());
- }
- }
- return QImage(16, 16, screen->pixelFormat());
-}
-
-QPaintDevice *PvrEglWindowSurface::paintDevice()
-{
- return widget;
-}
-
-void PvrEglWindowSurface::setDirectRegion(const QRegion &r, int id)
-{
- QWSGLWindowSurface::setDirectRegion(r, id);
-
- if (!drawable)
- return;
-
- // Clip the region to the window boundaries in case the child
- // is partially outside the geometry of the parent.
- QWidget *window = widget->window();
- QRegion region = r;
- if (widget != window) {
- QRect rect = window->geometry();
- rect.moveTo(window->mapToGlobal(QPoint(0, 0)));
- region = region.intersect(rect);
- }
-
- if (region.isEmpty()) {
- pvrQwsClearVisibleRegion(drawable);
- } else if (region.rectCount() == 1) {
- QRect rect = region.boundingRect();
- PvrQwsRect pvrRect;
- pvrRect.x = rect.x();
- pvrRect.y = rect.y();
- pvrRect.width = rect.width();
- pvrRect.height = rect.height();
- transformRects(&pvrRect, 1);
- pvrQwsSetVisibleRegion(drawable, &pvrRect, 1);
- pvrQwsSetRotation(drawable, screen->transformation());
- if (!pvrQwsSwapBuffers(drawable, 1))
- screen->solidFill(QColor(0, 0, 0), region);
- } else {
- QVector<QRect> rects = region.rects();
- PvrQwsRect *pvrRects = new PvrQwsRect [rects.size()];
- for (int index = 0; index < rects.size(); ++index) {
- QRect rect = rects[index];
- pvrRects[index].x = rect.x();
- pvrRects[index].y = rect.y();
- pvrRects[index].width = rect.width();
- pvrRects[index].height = rect.height();
- }
- transformRects(pvrRects, rects.size());
- pvrQwsSetVisibleRegion(drawable, pvrRects, rects.size());
- pvrQwsSetRotation(drawable, screen->transformation());
- if (!pvrQwsSwapBuffers(drawable, 1))
- screen->solidFill(QColor(0, 0, 0), region);
- delete [] pvrRects;
- }
-}
-
-void PvrEglWindowSurface::transformRects(PvrQwsRect *rects, int count) const
-{
- switch (screen->transformation()) {
- case 0: break;
-
- case 90:
- {
- for (int index = 0; index < count; ++index) {
- int x = rects[index].y;
- int y = screen->height() - (rects[index].x + rects[index].width);
- rects[index].x = x;
- rects[index].y = y;
- qSwap(rects[index].width, rects[index].height);
- }
- }
- break;
-
- case 180:
- {
- for (int index = 0; index < count; ++index) {
- int x = screen->width() - (rects[index].x + rects[index].width);
- int y = screen->height() - (rects[index].y + rects[index].height);
- rects[index].x = x;
- rects[index].y = y;
- }
- }
- break;
-
- case 270:
- {
- for (int index = 0; index < count; ++index) {
- int x = screen->width() - (rects[index].y + rects[index].height);
- int y = rects[index].x;
- rects[index].x = x;
- rects[index].y = y;
- qSwap(rects[index].width, rects[index].height);
- }
- }
- break;
- }
-}
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h
deleted file mode 100644
index 365fed9170..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef PVREGLWINDOWSURFACE_H
-#define PVREGLWINDOWSURFACE_H
-
-#include <private/qglwindowsurface_qws_p.h>
-#include "pvrqwsdrawable.h"
-
-class PvrEglScreen;
-
-class PvrEglWindowSurface : public QWSGLWindowSurface
-{
-public:
- PvrEglWindowSurface(QWidget *widget, PvrEglScreen *screen, int screenNum);
- PvrEglWindowSurface();
- ~PvrEglWindowSurface();
-
- QString key() const { return QLatin1String("PvrEgl"); }
-
- bool isValid() const;
-
- void setGeometry(const QRect &rect);
- bool move(const QPoint &offset);
-
- QByteArray permanentState() const;
- void setPermanentState(const QByteArray &state);
-
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
- QImage image() const;
- QPaintDevice *paintDevice();
-
- void setDirectRegion(const QRegion &region, int id);
-
- long nativeDrawable() const { return (long)widget; }
-
-private:
- QWidget *widget;
- PvrQwsDrawable *drawable;
- PvrEglScreen *screen;
- QPaintDevice *pdevice;
-
- void transformRects(PvrQwsRect *rects, int count) const;
-};
-
-#endif
diff --git a/src/plugins/gfxdrivers/qvfb/main.cpp b/src/plugins/gfxdrivers/qvfb/main.cpp
deleted file mode 100644
index 98661b61b9..0000000000
--- a/src/plugins/gfxdrivers/qvfb/main.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreendriverplugin_qws.h>
-#include <qscreenvfb_qws.h>
-#include <qstringlist.h>
-
-#ifndef QT_NO_LIBRARY
-QT_BEGIN_NAMESPACE
-
-class ScreenVfbDriver : public QScreenDriverPlugin
-{
-public:
- ScreenVfbDriver();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-ScreenVfbDriver::ScreenVfbDriver()
-: QScreenDriverPlugin()
-{
-}
-
-QStringList ScreenVfbDriver::keys() const
-{
- QStringList list;
- list << "QVFb";
- return list;
-}
-
-QScreen* ScreenVfbDriver::create(const QString& driver, int displayId)
-{
- if (driver.toLower() == "qvfb")
- return new QVFbScreen(displayId);
-
- return 0;
-}
-
-Q_EXPORT_STATIC_PLUGIN(ScreenVfbDriver)
-Q_EXPORT_PLUGIN2(qscreenvfb, ScreenVfbDriver)
-
-QT_END_NAMESPACE
-#endif //QT_NO_LIBRARY
diff --git a/src/plugins/gfxdrivers/qvfb/qvfb.pro b/src/plugins/gfxdrivers/qvfb/qvfb.pro
deleted file mode 100644
index 99376be81c..0000000000
--- a/src/plugins/gfxdrivers/qvfb/qvfb.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TARGET = qscreenvfb
-load(qt_plugin)
-
-DEFINES += QT_QWS_QVFB QT_QWS_MOUSE_QVFB QT_QWS_KBD_QVFB
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-HEADERS = \
- $$QT_SOURCE_TREE/src/gui/embedded/qscreenvfb_qws.h \
- $$QT_SOURCE_TREE/src/gui/embedded/qkbdvfb_qws.h \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousevfb_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qscreenvfb_qws.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qkbdvfb_qws.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousevfb_qws.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
diff --git a/src/plugins/gfxdrivers/transformed/main.cpp b/src/plugins/gfxdrivers/transformed/main.cpp
deleted file mode 100644
index 612068e3a6..0000000000
--- a/src/plugins/gfxdrivers/transformed/main.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreendriverplugin_qws.h>
-#include <qscreentransformed_qws.h>
-#include <qstringlist.h>
-#ifndef QT_NO_LIBRARY
-QT_BEGIN_NAMESPACE
-
-class GfxTransformedDriver : public QScreenDriverPlugin
-{
-public:
- GfxTransformedDriver();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-GfxTransformedDriver::GfxTransformedDriver()
-: QScreenDriverPlugin()
-{
-}
-
-QStringList GfxTransformedDriver::keys() const
-{
- QStringList list;
- list << "Transformed";
- return list;
-}
-
-QScreen* GfxTransformedDriver::create(const QString& driver, int displayId)
-{
-#ifndef QT_NO_QWS_TRANSFORMED
- if (driver.toLower() == "transformed")
- return new QTransformedScreen(displayId);
-#else //QT_NO_QWS_TRANSFORMED
- printf("QT buildt with QT_NO_QWS_TRANSFORMED. No screen driver returned\n");
-#endif //QT_NO_QWS_TRANSFORMED
- return 0;
-}
-
-Q_EXPORT_STATIC_PLUGIN(GfxTransformedDriver)
-Q_EXPORT_PLUGIN2(qgfxtransformed, GfxTransformedDriver)
-
-QT_END_NAMESPACE
-#endif //QT_NO_LIBRARY
diff --git a/src/plugins/gfxdrivers/transformed/transformed.pro b/src/plugins/gfxdrivers/transformed/transformed.pro
deleted file mode 100644
index f97713fc38..0000000000
--- a/src/plugins/gfxdrivers/transformed/transformed.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qgfxtransformed
-load(qt_plugin)
-
-DEFINES += QT_QWS_TRANSFORMED
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qscreentransformed_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qscreentransformed_qws.cpp
-
-target.path=$$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
diff --git a/src/plugins/gfxdrivers/vnc/main.cpp b/src/plugins/gfxdrivers/vnc/main.cpp
deleted file mode 100644
index 0a7ae592e0..0000000000
--- a/src/plugins/gfxdrivers/vnc/main.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreendriverplugin_qws.h>
-#include <qscreenvnc_qws.h>
-#include <qstringlist.h>
-
-#ifndef QT_NO_LIBRARY
-QT_BEGIN_NAMESPACE
-
-class GfxVncDriver : public QScreenDriverPlugin
-{
-public:
- GfxVncDriver();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-GfxVncDriver::GfxVncDriver()
-: QScreenDriverPlugin()
-{
-}
-
-QStringList GfxVncDriver::keys() const
-{
- QStringList list;
- list << "VNC";
- return list;
-}
-
-QScreen* GfxVncDriver::create(const QString& driver, int displayId)
-{
-#ifndef QT_NO_QWS_VNC
- if (driver.toLower() == "vnc")
- return new QVNCScreen(displayId);
-#else //QT_NO_QWS_VNC
- printf("QT buildt with QT_NO_QWS_VNC. No screen driver returned\n");
-#endif //QT_NO_QWS_VNC
- return 0;
-}
-
-Q_EXPORT_STATIC_PLUGIN(GfxVncDriver)
-Q_EXPORT_PLUGIN2(qgfxvnc, GfxVncDriver)
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_LIBRARY
diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h b/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h
deleted file mode 100644
index e64393a8c9..0000000000
--- a/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h
+++ /dev/null
@@ -1,524 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENVNC_P_H
-#define QSCREENVNC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qscreenvnc_qws.h"
-
-#ifndef QT_NO_QWS_VNC
-
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qsharedmemory.h>
-#include <QtNetwork/qtcpsocket.h>
-#include <QtNetwork/qtcpserver.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVNCServer;
-
-#ifndef QT_NO_QWS_CURSOR
-class QVNCCursor : public QProxyScreenCursor
-{
-public:
- QVNCCursor(QVNCScreen *s);
- ~QVNCCursor();
-
- void hide();
- void show();
- void set(const QImage &image, int hotx, int hoty);
- void move(int x, int y);
-
-private:
- void setDirty(const QRect &r) const;
- QVNCScreen *screen;
-};
-
-class QVNCClientCursor : public QProxyScreenCursor
-{
-public:
- QVNCClientCursor(QVNCServer *s);
- ~QVNCClientCursor();
-
- void set(const QImage &image, int hotx, int hoty);
- void write() const;
-
-private:
- QVNCServer *server;
-};
-#endif // QT_NO_QWS_CURSOR
-
-#define MAP_TILE_SIZE 16
-#define MAP_WIDTH 1280 / MAP_TILE_SIZE
-#define MAP_HEIGHT 1024 / MAP_TILE_SIZE
-
-class QVNCDirtyMap
-{
-public:
- QVNCDirtyMap(QScreen *screen);
- virtual ~QVNCDirtyMap();
-
- void reset();
- bool dirty(int x, int y) const;
- virtual void setDirty(int x, int y, bool force = false) = 0;
- void setClean(int x, int y);
-
- int bytesPerPixel;
-
- int numDirty;
- int mapWidth;
- int mapHeight;
-
-protected:
- uchar *map;
- QScreen *screen;
- uchar *buffer;
- int bufferWidth;
- int bufferHeight;
- int bufferStride;
- int numTiles;
-};
-
-template <class T>
-class QVNCDirtyMapOptimized : public QVNCDirtyMap
-{
-public:
- QVNCDirtyMapOptimized(QScreen *screen) : QVNCDirtyMap(screen) {}
- ~QVNCDirtyMapOptimized() {}
-
- void setDirty(int x, int y, bool force = false);
-};
-
-class QRfbRect
-{
-public:
- QRfbRect() {}
- QRfbRect(quint16 _x, quint16 _y, quint16 _w, quint16 _h) {
- x = _x; y = _y; w = _w; h = _h;
- }
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s) const;
-
- quint16 x;
- quint16 y;
- quint16 w;
- quint16 h;
-};
-
-class QRfbPixelFormat
-{
-public:
- static int size() { return 16; }
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s);
-
- int bitsPerPixel;
- int depth;
- bool bigEndian;
- bool trueColor;
- int redBits;
- int greenBits;
- int blueBits;
- int redShift;
- int greenShift;
- int blueShift;
-};
-
-class QRfbServerInit
-{
-public:
- QRfbServerInit() { name = 0; }
- ~QRfbServerInit() { delete[] name; }
-
- int size() const { return QRfbPixelFormat::size() + 8 + strlen(name); }
- void setName(const char *n);
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s);
-
- quint16 width;
- quint16 height;
- QRfbPixelFormat format;
- char *name;
-};
-
-class QRfbSetEncodings
-{
-public:
- bool read(QTcpSocket *s);
-
- quint16 count;
-};
-
-class QRfbFrameBufferUpdateRequest
-{
-public:
- bool read(QTcpSocket *s);
-
- char incremental;
- QRfbRect rect;
-};
-
-class QRfbKeyEvent
-{
-public:
- bool read(QTcpSocket *s);
-
- char down;
- int keycode;
- int unicode;
-};
-
-class QRfbPointerEvent
-{
-public:
- bool read(QTcpSocket *s);
-
- uint buttons;
- quint16 x;
- quint16 y;
-};
-
-class QRfbClientCutText
-{
-public:
- bool read(QTcpSocket *s);
-
- quint32 length;
-};
-
-class QVNCScreenPrivate : public QObject
-{
-public:
- QVNCScreenPrivate(QVNCScreen *parent);
- ~QVNCScreenPrivate();
-
- void setDirty(const QRect &rect, bool force = false);
- void configure();
-
- qreal dpiX;
- qreal dpiY;
- bool doOnScreenSurface;
- QVNCDirtyMap *dirty;
- int refreshRate;
- QVNCServer *vncServer;
-
-#if !defined(QT_NO_QWS_MULTIPROCESS) && !defined(QT_NO_SHAREDMEMORY)
- QSharedMemory shm;
-#endif
-
- QVNCScreen *q_ptr;
-
- bool noDisablePainting;
-};
-
-class QRfbEncoder
-{
-public:
- QRfbEncoder(QVNCServer *s) : server(s) {}
- virtual ~QRfbEncoder() {}
-
- virtual void write() = 0;
-
-protected:
- QVNCServer *server;
-};
-
-class QRfbRawEncoder : public QRfbEncoder
-{
-public:
- QRfbRawEncoder(QVNCServer *s) : QRfbEncoder(s) {}
-
- void write();
-
-private:
- QByteArray buffer;
-};
-
-template <class SRC> class QRfbHextileEncoder;
-
-template <class SRC>
-class QRfbSingleColorHextile
-{
-public:
- QRfbSingleColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- QRfbHextileEncoder<SRC> *encoder;
-};
-
-template <class SRC>
-class QRfbDualColorHextile
-{
-public:
- QRfbDualColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- struct Rect {
- quint8 xy;
- quint8 wh;
- } Q_PACKED rects[8 * 16];
-
- quint8 numRects;
- QRfbHextileEncoder<SRC> *encoder;
-
-private:
- inline int lastx() const { return rectx(numRects); }
- inline int lasty() const { return recty(numRects); }
- inline int rectx(int r) const { return rects[r].xy >> 4; }
- inline int recty(int r) const { return rects[r].xy & 0x0f; }
- inline int width(int r) const { return (rects[r].wh >> 4) + 1; }
- inline int height(int r) const { return (rects[r].wh & 0x0f) + 1; }
-
- inline void setX(int r, int x) {
- rects[r].xy = (x << 4) | (rects[r].xy & 0x0f);
- }
- inline void setY(int r, int y) {
- rects[r].xy = (rects[r].xy & 0xf0) | y;
- }
- inline void setWidth(int r, int width) {
- rects[r].wh = ((width - 1) << 4) | (rects[r].wh & 0x0f);
- }
- inline void setHeight(int r, int height) {
- rects[r].wh = (rects[r].wh & 0xf0) | (height - 1);
- }
-
- inline void setWidth(int width) { setWidth(numRects, width); }
- inline void setHeight(int height) { setHeight(numRects, height); }
- inline void setX(int x) { setX(numRects, x); }
- inline void setY(int y) { setY(numRects, y); }
- void next();
-};
-
-template <class SRC>
-class QRfbMultiColorHextile
-{
-public:
- QRfbMultiColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- inline quint8* rect(int r) {
- return rects.data() + r * (bpp + 2);
- }
- inline const quint8* rect(int r) const {
- return rects.constData() + r * (bpp + 2);
- }
- inline void setX(int r, int x) {
- quint8 *ptr = rect(r) + bpp;
- *ptr = (x << 4) | (*ptr & 0x0f);
- }
- inline void setY(int r, int y) {
- quint8 *ptr = rect(r) + bpp;
- *ptr = (*ptr & 0xf0) | y;
- }
- void setColor(SRC color);
- inline int rectx(int r) const {
- const quint8 *ptr = rect(r) + bpp;
- return *ptr >> 4;
- }
- inline int recty(int r) const {
- const quint8 *ptr = rect(r) + bpp;
- return *ptr & 0x0f;
- }
- inline void setWidth(int r, int width) {
- quint8 *ptr = rect(r) + bpp + 1;
- *ptr = ((width - 1) << 4) | (*ptr & 0x0f);
- }
- inline void setHeight(int r, int height) {
- quint8 *ptr = rect(r) + bpp + 1;
- *ptr = (*ptr & 0xf0) | (height - 1);
- }
-
- bool beginRect();
- void endRect();
-
- static const int maxRectsSize = 16 * 16;
- QVarLengthArray<quint8, maxRectsSize> rects;
-
- quint8 bpp;
- quint8 numRects;
- QRfbHextileEncoder<SRC> *encoder;
-};
-
-template <class SRC>
-class QRfbHextileEncoder : public QRfbEncoder
-{
-public:
- QRfbHextileEncoder(QVNCServer *s);
- void write();
-
-private:
- enum SubEncoding {
- Raw = 1,
- BackgroundSpecified = 2,
- ForegroundSpecified = 4,
- AnySubrects = 8,
- SubrectsColoured = 16
- };
-
- QByteArray buffer;
- QRfbSingleColorHextile<SRC> singleColorHextile;
- QRfbDualColorHextile<SRC> dualColorHextile;
- QRfbMultiColorHextile<SRC> multiColorHextile;
-
- SRC bg;
- SRC fg;
- bool newBg;
- bool newFg;
-
- friend class QRfbSingleColorHextile<SRC>;
- friend class QRfbDualColorHextile<SRC>;
- friend class QRfbMultiColorHextile<SRC>;
-};
-
-class QVNCServer : public QObject
-{
- Q_OBJECT
-public:
- QVNCServer(QVNCScreen *screen);
- QVNCServer(QVNCScreen *screen, int id);
- ~QVNCServer();
-
- void setDirty();
- void setDirtyCursor() { dirtyCursor = true; setDirty(); }
- inline bool isConnected() const { return state == Connected; }
- inline void setRefreshRate(int rate) { refreshRate = rate; }
-
- enum ClientMsg { SetPixelFormat = 0,
- FixColourMapEntries = 1,
- SetEncodings = 2,
- FramebufferUpdateRequest = 3,
- KeyEvent = 4,
- PointerEvent = 5,
- ClientCutText = 6 };
-
- enum ServerMsg { FramebufferUpdate = 0,
- SetColourMapEntries = 1 };
-
- void convertPixels(char *dst, const char *src, int count) const;
-
- inline int clientBytesPerPixel() const {
- return pixelFormat.bitsPerPixel / 8;
- }
-
- inline QVNCScreen* screen() const { return qvnc_screen; }
- inline QVNCDirtyMap* dirtyMap() const { return qvnc_screen->d_ptr->dirty; }
- inline QTcpSocket* clientSocket() const { return client; }
- QImage screenImage() const;
- inline bool doPixelConversion() const { return needConversion; }
-#ifndef QT_NO_QWS_CURSOR
- inline bool hasClientCursor() const { return qvnc_cursor != 0; }
-#endif
-
-private:
- void setPixelFormat();
- void setEncodings();
- void frameBufferUpdateRequest();
- void pointerEvent();
- void keyEvent();
- void clientCutText();
- bool pixelConversionNeeded() const;
-
-private slots:
- void newConnection();
- void readClient();
- void checkUpdate();
- void discardClient();
-
-private:
- void init(uint port);
- enum ClientState { Unconnected, Protocol, Init, Connected };
- QTimer *timer;
- QTcpServer *serverSocket;
- QTcpSocket *client;
- ClientState state;
- quint8 msgType;
- bool handleMsg;
- QRfbPixelFormat pixelFormat;
- Qt::KeyboardModifiers keymod;
- int encodingsPending;
- int cutTextPending;
- uint supportCopyRect : 1;
- uint supportRRE : 1;
- uint supportCoRRE : 1;
- uint supportHextile : 1;
- uint supportZRLE : 1;
- uint supportCursor : 1;
- uint supportDesktopSize : 1;
- bool wantUpdate;
- bool sameEndian;
- bool needConversion;
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- bool swapBytes;
-#endif
- bool dirtyCursor;
- int refreshRate;
- QVNCScreen *qvnc_screen;
-#ifndef QT_NO_QWS_CURSOR
- QVNCClientCursor *qvnc_cursor;
-#endif
-
- QRfbEncoder *encoder;
-};
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_QWS_VNC
-#endif // QSCREENVNC_P_H
diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp b/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp
deleted file mode 100644
index 3ddedc63ea..0000000000
--- a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp
+++ /dev/null
@@ -1,2338 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreenvnc_qws.h"
-
-#ifndef QT_NO_QWS_VNC
-
-#include "qscreenvnc_p.h"
-#include "qwindowsystem_qws.h"
-#include "qwsdisplay_qws.h"
-#include "qscreendriverfactory_qws.h"
-#include <QtCore/qtimer.h>
-#include <QtCore/qregexp.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/qpolygon.h>
-#include <QtGui/qpainter.h>
-#include <qdebug.h>
-#include <private/qwindowsurface_qws_p.h>
-#include <private/qwssignalhandler_p.h>
-#include <private/qwidget_p.h>
-#include <private/qdrawhelper_p.h>
-
-#include <stdlib.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define QT_QWS_VNC_DEBUG
-
-extern QString qws_qtePipeFilename();
-
-#ifndef QT_NO_QWS_CURSOR
-
-QVNCCursor::QVNCCursor(QVNCScreen *s)
- : screen(s)
-{
- if (qt_screencursor)
- setScreenCursor(qt_screencursor);
- else
- hwaccel = true;
-}
-
-QVNCCursor::~QVNCCursor()
-{
- if (screenCursor())
- qt_screencursor = screenCursor();
-}
-
-void QVNCCursor::setDirty(const QRect &r) const
-{
- screen->d_ptr->setDirty(r, true);
-}
-
-void QVNCCursor::hide()
-{
- QProxyScreenCursor::hide();
- if (enable)
- setDirty(boundingRect());
-}
-
-void QVNCCursor::show()
-{
- QProxyScreenCursor::show();
- if (enable)
- setDirty(boundingRect());
-}
-
-void QVNCCursor::set(const QImage &image, int hotx, int hoty)
-{
- QRegion dirty = boundingRect();
- QProxyScreenCursor::set(image, hotx, hoty);
- dirty |= boundingRect();
- if (enable && hwaccel && !screen->d_ptr->vncServer->hasClientCursor()) {
- const QVector<QRect> rects = dirty.rects();
- for (int i = 0; i < rects.size(); ++i)
- setDirty(rects.at(i));
- }
-}
-
-void QVNCCursor::move(int x, int y)
-{
- if (enable && hwaccel && !screen->d_ptr->vncServer->hasClientCursor()) {
- QRegion dirty = boundingRect();
- QProxyScreenCursor::move(x, y);
- dirty |= boundingRect();
- if (enable) {
- const QVector<QRect> rects = dirty.rects();
- for (int i = 0; i < rects.size(); ++i)
- setDirty(rects.at(i));
- }
- } else {
- QProxyScreenCursor::move(x, y);
- }
-}
-
-QVNCClientCursor::QVNCClientCursor(QVNCServer *s)
- : server(s)
-{
- setScreenCursor(qt_screencursor);
- Q_ASSERT(hwaccel);
- qt_screencursor = this; // hw: XXX
-
- set(image(), hotspot.x(), hotspot.y());
-}
-
-QVNCClientCursor::~QVNCClientCursor()
-{
- qt_screencursor = screenCursor();
-}
-
-void QVNCClientCursor::set(const QImage &image, int hotx, int hoty)
-{
- QScreenCursor::set(image, hotx, hoty);
- server->setDirtyCursor();
-}
-
-void QVNCClientCursor::write() const
-{
- QTcpSocket *socket = server->clientSocket();
-
- // FramebufferUpdate header
- {
- const quint16 tmp[6] = { htons(0),
- htons(1),
- htons(hotspot.x()), htons(hotspot.y()),
- htons(cursor.width()),
- htons(cursor.height()) };
- socket->write((char*)tmp, sizeof(tmp));
-
- const quint32 encoding = htonl(-239);
- socket->write((char*)(&encoding), sizeof(encoding));
- }
-
- if (cursor.isNull())
- return;
-
- // write pixels
- Q_ASSERT(cursor.hasAlphaChannel());
- const QImage img = cursor.convertToFormat(server->screen()->pixelFormat());
- const int n = server->clientBytesPerPixel() * img.width();
- char *buffer = new char[n];
- for (int i = 0; i < img.height(); ++i) {
- server->convertPixels(buffer, (const char*)img.scanLine(i), img.width());
- socket->write(buffer, n);
- }
- delete[] buffer;
-
- // write mask
- const QImage bitmap = cursor.createAlphaMask().convertToFormat(QImage::Format_Mono);
- Q_ASSERT(bitmap.depth() == 1);
- Q_ASSERT(bitmap.size() == img.size());
- const int width = (bitmap.width() + 7) / 8;
- for (int i = 0; i < bitmap.height(); ++i)
- socket->write((const char*)bitmap.scanLine(i), width);
-}
-
-#endif // QT_NO_QWS_CURSOR
-
-QVNCScreenPrivate::QVNCScreenPrivate(QVNCScreen *parent)
- : dpiX(72), dpiY(72), doOnScreenSurface(false), refreshRate(25),
- vncServer(0), q_ptr(parent), noDisablePainting(false)
-{
-#ifdef QT_BUILD_INTERNAL
- noDisablePainting = (qgetenv("QT_VNC_NO_DISABLEPAINTING").toInt() > 0);
-#endif
-#ifndef QT_NO_QWS_SIGNALHANDLER
- QWSSignalHandler::instance()->addObject(this);
-#endif
-}
-
-QVNCScreenPrivate::~QVNCScreenPrivate()
-{
-#if defined(QT_NO_QWS_MULTIPROCESS) || defined(QT_NO_SHAREDMEMORY)
- if (q_ptr->screen())
- return;
-
- delete[] q_ptr->data;
- q_ptr->data = 0;
-#else
- shm.detach();
-#endif
-}
-
-void QVNCScreenPrivate::configure()
-{
- if (q_ptr->screen())
- return;
-
- q_ptr->lstep = q_ptr->dw * ((q_ptr->d + 7) / 8);
- q_ptr->size = q_ptr->h * q_ptr->lstep;
- q_ptr->mapsize = q_ptr->size;
- q_ptr->physWidth = qRound(q_ptr->dw * qreal(25.4) / dpiX);
- q_ptr->physHeight = qRound(q_ptr->dh * qreal(25.4) / dpiY);
-
- switch (q_ptr->d) {
- case 1:
- q_ptr->setPixelFormat(QImage::Format_Mono); //### LSB???
- break;
- case 8:
- q_ptr->setPixelFormat(QImage::Format_Indexed8);
- break;
- case 12:
- q_ptr->setPixelFormat(QImage::Format_RGB444);
- break;
- case 15:
- q_ptr->setPixelFormat(QImage::Format_RGB555);
- break;
- case 16:
- q_ptr->setPixelFormat(QImage::Format_RGB16);
- break;
- case 18:
- q_ptr->setPixelFormat(QImage::Format_RGB666);
- break;
- case 24:
- q_ptr->setPixelFormat(QImage::Format_RGB888);
- break;
- case 32:
- q_ptr->setPixelFormat(QImage::Format_ARGB32_Premultiplied);
- break;
- }
-
-#if !defined(QT_NO_QWS_MULTIPROCESS) && !defined(QT_NO_SHAREDMEMORY)
- if (q_ptr->size != shm.size()) {
- shm.detach();
- const QString key = qws_qtePipeFilename() +
- QString().sprintf("_vnc_%d_%d",
- q_ptr->displayId, q_ptr->size);
- shm.setKey(key);
- if (QApplication::type() == QApplication::GuiServer) {
- if (!shm.create(q_ptr->size)) {
- qWarning() << "QVNCScreen could not create shared memory:"
- << shm.errorString();
- if (!shm.attach()) {
- qWarning() << "QVNCScreen could not attach to shared memory:"
- << shm.errorString();
- }
- }
- } else if (!shm.attach()) {
- qWarning() << "QVNCScreen could not attach to shared memory:"
- << shm.errorString();
- }
- q_ptr->data = reinterpret_cast<uchar*>(shm.data());
- }
-#else
- if (q_ptr->data)
- delete[] q_ptr->data;
- q_ptr->data = new uchar[q_ptr->size];
-#endif
-}
-
-//===========================================================================
-
-static const struct {
- int keysym;
- int keycode;
-} keyMap[] = {
- { 0xff08, Qt::Key_Backspace },
- { 0xff09, Qt::Key_Tab },
- { 0xff0d, Qt::Key_Return },
- { 0xff1b, Qt::Key_Escape },
- { 0xff63, Qt::Key_Insert },
- { 0xffff, Qt::Key_Delete },
- { 0xff50, Qt::Key_Home },
- { 0xff57, Qt::Key_End },
- { 0xff55, Qt::Key_PageUp },
- { 0xff56, Qt::Key_PageDown },
- { 0xff51, Qt::Key_Left },
- { 0xff52, Qt::Key_Up },
- { 0xff53, Qt::Key_Right },
- { 0xff54, Qt::Key_Down },
- { 0xffbe, Qt::Key_F1 },
- { 0xffbf, Qt::Key_F2 },
- { 0xffc0, Qt::Key_F3 },
- { 0xffc1, Qt::Key_F4 },
- { 0xffc2, Qt::Key_F5 },
- { 0xffc3, Qt::Key_F6 },
- { 0xffc4, Qt::Key_F7 },
- { 0xffc5, Qt::Key_F8 },
- { 0xffc6, Qt::Key_F9 },
- { 0xffc7, Qt::Key_F10 },
- { 0xffc8, Qt::Key_F11 },
- { 0xffc9, Qt::Key_F12 },
- { 0xffe1, Qt::Key_Shift },
- { 0xffe2, Qt::Key_Shift },
- { 0xffe3, Qt::Key_Control },
- { 0xffe4, Qt::Key_Control },
- { 0xffe7, Qt::Key_Meta },
- { 0xffe8, Qt::Key_Meta },
- { 0xffe9, Qt::Key_Alt },
- { 0xffea, Qt::Key_Alt },
-
- { 0xffb0, Qt::Key_0 },
- { 0xffb1, Qt::Key_1 },
- { 0xffb2, Qt::Key_2 },
- { 0xffb3, Qt::Key_3 },
- { 0xffb4, Qt::Key_4 },
- { 0xffb5, Qt::Key_5 },
- { 0xffb6, Qt::Key_6 },
- { 0xffb7, Qt::Key_7 },
- { 0xffb8, Qt::Key_8 },
- { 0xffb9, Qt::Key_9 },
-
- { 0xff8d, Qt::Key_Return },
- { 0xffaa, Qt::Key_Asterisk },
- { 0xffab, Qt::Key_Plus },
- { 0xffad, Qt::Key_Minus },
- { 0xffae, Qt::Key_Period },
- { 0xffaf, Qt::Key_Slash },
-
- { 0xff95, Qt::Key_Home },
- { 0xff96, Qt::Key_Left },
- { 0xff97, Qt::Key_Up },
- { 0xff98, Qt::Key_Right },
- { 0xff99, Qt::Key_Down },
- { 0xff9a, Qt::Key_PageUp },
- { 0xff9b, Qt::Key_PageDown },
- { 0xff9c, Qt::Key_End },
- { 0xff9e, Qt::Key_Insert },
- { 0xff9f, Qt::Key_Delete },
-
- { 0, 0 }
-};
-
-void QRfbRect::read(QTcpSocket *s)
-{
- quint16 buf[4];
- s->read((char*)buf, 8);
- x = ntohs(buf[0]);
- y = ntohs(buf[1]);
- w = ntohs(buf[2]);
- h = ntohs(buf[3]);
-}
-
-void QRfbRect::write(QTcpSocket *s) const
-{
- quint16 buf[4];
- buf[0] = htons(x);
- buf[1] = htons(y);
- buf[2] = htons(w);
- buf[3] = htons(h);
- s->write((char*)buf, 8);
-}
-
-void QRfbPixelFormat::read(QTcpSocket *s)
-{
- char buf[16];
- s->read(buf, 16);
- bitsPerPixel = buf[0];
- depth = buf[1];
- bigEndian = buf[2];
- trueColor = buf[3];
-
- quint16 a = ntohs(*(quint16 *)(buf + 4));
- redBits = 0;
- while (a) { a >>= 1; redBits++; }
-
- a = ntohs(*(quint16 *)(buf + 6));
- greenBits = 0;
- while (a) { a >>= 1; greenBits++; }
-
- a = ntohs(*(quint16 *)(buf + 8));
- blueBits = 0;
- while (a) { a >>= 1; blueBits++; }
-
- redShift = buf[10];
- greenShift = buf[11];
- blueShift = buf[12];
-}
-
-void QRfbPixelFormat::write(QTcpSocket *s)
-{
- char buf[16];
- buf[0] = bitsPerPixel;
- buf[1] = depth;
- buf[2] = bigEndian;
- buf[3] = trueColor;
-
- quint16 a = 0;
- for (int i = 0; i < redBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 4) = htons(a);
-
- a = 0;
- for (int i = 0; i < greenBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 6) = htons(a);
-
- a = 0;
- for (int i = 0; i < blueBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 8) = htons(a);
-
- buf[10] = redShift;
- buf[11] = greenShift;
- buf[12] = blueShift;
- s->write(buf, 16);
-}
-
-
-void QRfbServerInit::setName(const char *n)
-{
- delete[] name;
- name = new char [strlen(n) + 1];
- strcpy(name, n);
-}
-
-void QRfbServerInit::read(QTcpSocket *s)
-{
- s->read((char *)&width, 2);
- width = ntohs(width);
- s->read((char *)&height, 2);
- height = ntohs(height);
- format.read(s);
-
- quint32 len;
- s->read((char *)&len, 4);
- len = ntohl(len);
-
- name = new char [len + 1];
- s->read(name, len);
- name[len] = '\0';
-}
-
-void QRfbServerInit::write(QTcpSocket *s)
-{
- quint16 t = htons(width);
- s->write((char *)&t, 2);
- t = htons(height);
- s->write((char *)&t, 2);
- format.write(s);
- quint32 len = strlen(name);
- len = htonl(len);
- s->write((char *)&len, 4);
- s->write(name, strlen(name));
-}
-
-bool QRfbSetEncodings::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 3)
- return false;
-
- char tmp;
- s->read(&tmp, 1); // padding
- s->read((char *)&count, 2);
- count = ntohs(count);
-
- return true;
-}
-
-bool QRfbFrameBufferUpdateRequest::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 9)
- return false;
-
- s->read(&incremental, 1);
- rect.read(s);
-
- return true;
-}
-
-bool QRfbKeyEvent::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 7)
- return false;
-
- s->read(&down, 1);
- quint16 tmp;
- s->read((char *)&tmp, 2); // padding
-
- quint32 key;
- s->read((char *)&key, 4);
- key = ntohl(key);
-
- unicode = 0;
- keycode = 0;
- int i = 0;
- while (keyMap[i].keysym && !keycode) {
- if (keyMap[i].keysym == (int)key)
- keycode = keyMap[i].keycode;
- i++;
- }
-
- if (keycode >= ' ' && keycode <= '~')
- unicode = keycode;
-
- if (!keycode) {
- if (key <= 0xff) {
- unicode = key;
- if (key >= 'a' && key <= 'z')
- keycode = Qt::Key_A + key - 'a';
- else if (key >= ' ' && key <= '~')
- keycode = Qt::Key_Space + key - ' ';
- }
- }
-
- return true;
-}
-
-bool QRfbPointerEvent::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 5)
- return false;
-
- char buttonMask;
- s->read(&buttonMask, 1);
- buttons = 0;
- if (buttonMask & 1)
- buttons |= Qt::LeftButton;
- if (buttonMask & 2)
- buttons |= Qt::MidButton;
- if (buttonMask & 4)
- buttons |= Qt::RightButton;
-
- quint16 tmp;
- s->read((char *)&tmp, 2);
- x = ntohs(tmp);
- s->read((char *)&tmp, 2);
- y = ntohs(tmp);
-
- return true;
-}
-
-bool QRfbClientCutText::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 7)
- return false;
-
- char tmp[3];
- s->read(tmp, 3); // padding
- s->read((char *)&length, 4);
- length = ntohl(length);
-
- return true;
-}
-
-//===========================================================================
-
-QVNCServer::QVNCServer(QVNCScreen *screen)
- : qvnc_screen(screen)
-{
- init(5900);
-}
-
-QVNCServer::QVNCServer(QVNCScreen *screen, int id)
- : qvnc_screen(screen)
-{
- init(5900 + id);
-}
-
-void QVNCServer::init(uint port)
-{
- handleMsg = false;
- client = 0;
- encodingsPending = 0;
- cutTextPending = 0;
- keymod = 0;
- state = Unconnected;
- dirtyCursor = false;
-
- refreshRate = 25;
- timer = new QTimer(this);
- timer->setSingleShot(true);
- connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
-
- serverSocket = new QTcpServer(this);
- if (!serverSocket->listen(QHostAddress::Any, port))
- qDebug() << "QVNCServer could not connect:" << serverSocket->errorString();
- else
- qDebug("QVNCServer created on port %d", port);
-
- connect(serverSocket, SIGNAL(newConnection()), this, SLOT(newConnection()));
-
-#ifndef QT_NO_QWS_CURSOR
- qvnc_cursor = 0;
-#endif
- encoder = 0;
-}
-
-QVNCServer::~QVNCServer()
-{
- delete encoder;
- encoder = 0;
- delete client;
- client = 0;
-#ifndef QT_NO_QWS_CURSOR
- delete qvnc_cursor;
- qvnc_cursor = 0;
-#endif
-}
-
-void QVNCServer::setDirty()
-{
- if (state == Connected && !timer->isActive() &&
- ((dirtyMap()->numDirty > 0) || dirtyCursor)) {
- timer->start();
- }
-}
-
-void QVNCServer::newConnection()
-{
- if (client)
- delete client;
-
- client = serverSocket->nextPendingConnection();
- connect(client,SIGNAL(readyRead()),this,SLOT(readClient()));
- connect(client,SIGNAL(disconnected()),this,SLOT(discardClient()));
- handleMsg = false;
- encodingsPending = 0;
- cutTextPending = 0;
- supportHextile = false;
- wantUpdate = false;
-
- timer->start(1000 / refreshRate);
- dirtyMap()->reset();
-
- // send protocol version
- const char *proto = "RFB 003.003\n";
- client->write(proto, 12);
- state = Protocol;
-
- if (!qvnc_screen->screen() && !qvnc_screen->d_ptr->noDisablePainting)
- QWSServer::instance()->enablePainting(true);
-}
-
-void QVNCServer::readClient()
-{
- switch (state) {
- case Protocol:
- if (client->bytesAvailable() >= 12) {
- char proto[13];
- client->read(proto, 12);
- proto[12] = '\0';
- qDebug("Client protocol version %s", proto);
- // No authentication
- quint32 auth = htonl(1);
- client->write((char *) &auth, sizeof(auth));
- state = Init;
- }
- break;
-
- case Init:
- if (client->bytesAvailable() >= 1) {
- quint8 shared;
- client->read((char *) &shared, 1);
-
- // Server Init msg
- QRfbServerInit sim;
- QRfbPixelFormat &format = sim.format;
- switch (qvnc_screen->depth()) {
- case 32:
- format.bitsPerPixel = 32;
- format.depth = 32;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 8;
- format.greenBits = 8;
- format.blueBits = 8;
- format.redShift = 16;
- format.greenShift = 8;
- format.blueShift = 0;
- break;
-
- case 24:
- format.bitsPerPixel = 24;
- format.depth = 24;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 8;
- format.greenBits = 8;
- format.blueBits = 8;
- format.redShift = 16;
- format.greenShift = 8;
- format.blueShift = 0;
- break;
-
- case 18:
- format.bitsPerPixel = 24;
- format.depth = 18;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 6;
- format.greenBits = 6;
- format.blueBits = 6;
- format.redShift = 12;
- format.greenShift = 6;
- format.blueShift = 0;
- break;
-
- case 16:
- format.bitsPerPixel = 16;
- format.depth = 16;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 5;
- format.greenBits = 6;
- format.blueBits = 5;
- format.redShift = 11;
- format.greenShift = 5;
- format.blueShift = 0;
- break;
-
- case 15:
- format.bitsPerPixel = 16;
- format.depth = 15;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 5;
- format.greenBits = 5;
- format.blueBits = 5;
- format.redShift = 10;
- format.greenShift = 5;
- format.blueShift = 0;
- break;
-
- case 12:
- format.bitsPerPixel = 16;
- format.depth = 12;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 4;
- format.greenBits = 4;
- format.blueBits = 4;
- format.redShift = 8;
- format.greenShift = 4;
- format.blueShift = 0;
- break;
-
- case 8:
- case 4:
- format.bitsPerPixel = 8;
- format.depth = 8;
- format.bigEndian = 0;
- format.trueColor = false;
- format.redBits = 0;
- format.greenBits = 0;
- format.blueBits = 0;
- format.redShift = 0;
- format.greenShift = 0;
- format.blueShift = 0;
- break;
-
- default:
- qDebug("QVNC cannot drive depth %d", qvnc_screen->depth());
- discardClient();
- return;
- }
- sim.width = qvnc_screen->deviceWidth();
- sim.height = qvnc_screen->deviceHeight();
- sim.setName("Qt for Embedded Linux VNC Server");
- sim.write(client);
- state = Connected;
- }
- break;
-
- case Connected:
- do {
- if (!handleMsg) {
- client->read((char *)&msgType, 1);
- handleMsg = true;
- }
- if (handleMsg) {
- switch (msgType ) {
- case SetPixelFormat:
- setPixelFormat();
- break;
- case FixColourMapEntries:
- qDebug("Not supported: FixColourMapEntries");
- handleMsg = false;
- break;
- case SetEncodings:
- setEncodings();
- break;
- case FramebufferUpdateRequest:
- frameBufferUpdateRequest();
- break;
- case KeyEvent:
- keyEvent();
- break;
- case PointerEvent:
- pointerEvent();
- break;
- case ClientCutText:
- clientCutText();
- break;
- default:
- qDebug("Unknown message type: %d", (int)msgType);
- handleMsg = false;
- }
- }
- } while (!handleMsg && client->bytesAvailable());
- break;
- default:
- break;
- }
-}
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-bool QVNCScreen::swapBytes() const
-{
- if (depth() != 16)
- return false;
-
- if (screen())
- return screen()->frameBufferLittleEndian();
- return frameBufferLittleEndian();
-}
-#endif
-
-void QVNCServer::setPixelFormat()
-{
- if (client->bytesAvailable() >= 19) {
- char buf[3];
- client->read(buf, 3); // just padding
- pixelFormat.read(client);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("Want format: %d %d %d %d %d %d %d %d %d %d",
- int(pixelFormat.bitsPerPixel),
- int(pixelFormat.depth),
- int(pixelFormat.bigEndian),
- int(pixelFormat.trueColor),
- int(pixelFormat.redBits),
- int(pixelFormat.greenBits),
- int(pixelFormat.blueBits),
- int(pixelFormat.redShift),
- int(pixelFormat.greenShift),
- int(pixelFormat.blueShift));
-#endif
- if (!pixelFormat.trueColor) {
- qDebug("Can only handle true color clients");
- discardClient();
- }
- handleMsg = false;
- sameEndian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) == !!pixelFormat.bigEndian;
- needConversion = pixelConversionNeeded();
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- swapBytes = qvnc_screen->swapBytes();
-#endif
- }
-}
-
-void QVNCServer::setEncodings()
-{
- QRfbSetEncodings enc;
-
- if (!encodingsPending && enc.read(client)) {
- encodingsPending = enc.count;
- if (!encodingsPending)
- handleMsg = false;
- }
-
- if (encoder) {
- delete encoder;
- encoder = 0;
- }
-
- enum Encodings {
- Raw = 0,
- CopyRect = 1,
- RRE = 2,
- CoRRE = 4,
- Hextile = 5,
- ZRLE = 16,
- Cursor = -239,
- DesktopSize = -223
- };
-
- if (encodingsPending && (unsigned)client->bytesAvailable() >=
- encodingsPending * sizeof(quint32)) {
- for (int i = 0; i < encodingsPending; ++i) {
- qint32 enc;
- client->read((char *)&enc, sizeof(qint32));
- enc = ntohl(enc);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: %d", enc);
-#endif
- switch (enc) {
- case Raw:
- if (!encoder) {
- encoder = new QRfbRawEncoder(this);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: using raw");
-#endif
- }
- break;
- case CopyRect:
- supportCopyRect = true;
- break;
- case RRE:
- supportRRE = true;
- break;
- case CoRRE:
- supportCoRRE = true;
- break;
- case Hextile:
- supportHextile = true;
- if (encoder)
- break;
- switch (qvnc_screen->depth()) {
-#ifdef QT_QWS_DEPTH_8
- case 8:
- encoder = new QRfbHextileEncoder<quint8>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_12
- case 12:
- encoder = new QRfbHextileEncoder<qrgb444>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15:
- encoder = new QRfbHextileEncoder<qrgb555>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_16
- case 16:
- encoder = new QRfbHextileEncoder<quint16>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_18
- case 18:
- encoder = new QRfbHextileEncoder<qrgb666>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24:
- encoder = new QRfbHextileEncoder<qrgb888>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_32
- case 32:
- encoder = new QRfbHextileEncoder<quint32>(this);
- break;
-#endif
- default:
- break;
- }
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: using hextile");
-#endif
- break;
- case ZRLE:
- supportZRLE = true;
- break;
- case Cursor:
- supportCursor = true;
-#ifndef QT_NO_QWS_CURSOR
- if (!qvnc_screen->screen() || qt_screencursor->isAccelerated()) {
- delete qvnc_cursor;
- qvnc_cursor = new QVNCClientCursor(this);
- }
-#endif
- break;
- case DesktopSize:
- supportDesktopSize = true;
- break;
- default:
- break;
- }
- }
- handleMsg = false;
- encodingsPending = 0;
- }
-
- if (!encoder) {
- encoder = new QRfbRawEncoder(this);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: fallback using raw");
-#endif
- }
-}
-
-void QVNCServer::frameBufferUpdateRequest()
-{
- QRfbFrameBufferUpdateRequest ev;
-
- if (ev.read(client)) {
- if (!ev.incremental) {
- QRect r(ev.rect.x, ev.rect.y, ev.rect.w, ev.rect.h);
- r.translate(qvnc_screen->offset());
- qvnc_screen->d_ptr->setDirty(r, true);
- }
- wantUpdate = true;
- checkUpdate();
- handleMsg = false;
- }
-}
-
-void QVNCServer::pointerEvent()
-{
- QRfbPointerEvent ev;
- if (ev.read(client)) {
- const QPoint offset = qvnc_screen->offset();
- QWSServer::sendMouseEvent(offset + QPoint(ev.x, ev.y), ev.buttons);
- handleMsg = false;
- }
-}
-
-void QVNCServer::keyEvent()
-{
- QRfbKeyEvent ev;
-
- if (ev.read(client)) {
- if (ev.keycode == Qt::Key_Shift)
- keymod = ev.down ? keymod | Qt::ShiftModifier :
- keymod & ~Qt::ShiftModifier;
- else if (ev.keycode == Qt::Key_Control)
- keymod = ev.down ? keymod | Qt::ControlModifier :
- keymod & ~Qt::ControlModifier;
- else if (ev.keycode == Qt::Key_Alt)
- keymod = ev.down ? keymod | Qt::AltModifier :
- keymod & ~Qt::AltModifier;
- if (ev.unicode || ev.keycode)
- QWSServer::sendKeyEvent(ev.unicode, ev.keycode, keymod, ev.down, false);
- handleMsg = false;
- }
-}
-
-void QVNCServer::clientCutText()
-{
- QRfbClientCutText ev;
-
- if (cutTextPending == 0 && ev.read(client)) {
- cutTextPending = ev.length;
- if (!cutTextPending)
- handleMsg = false;
- }
-
- if (cutTextPending && client->bytesAvailable() >= cutTextPending) {
- char *text = new char [cutTextPending+1];
- client->read(text, cutTextPending);
- delete [] text;
- cutTextPending = 0;
- handleMsg = false;
- }
-}
-
-// stride in bytes
-template <class SRC>
-bool QRfbSingleColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const int depth = encoder->server->screen()->depth();
- if (width % (depth / 8)) // hw: should rather fallback to simple loop
- return false;
-
- static int alwaysFalse = qgetenv("QT_VNC_NOCHECKFILL").toInt();
- if (alwaysFalse)
- return false;
-
- switch (depth) {
- case 4: {
- const quint8 *data8 = reinterpret_cast<const quint8*>(data);
- if ((data8[0] & 0xf) != (data8[0] >> 4))
- return false;
- width /= 2;
- } // fallthrough
- case 8: {
- const quint8 *data8 = reinterpret_cast<const quint8*>(data);
- if (data8[0] != data8[1])
- return false;
- width /= 2;
- } // fallthrough
- case 12:
- case 15:
- case 16: {
- const quint16 *data16 = reinterpret_cast<const quint16*>(data);
- if (data16[0] != data16[1])
- return false;
- width /= 2;
- } // fallthrough
- case 18:
- case 24:
- case 32: {
- const quint32 *data32 = reinterpret_cast<const quint32*>(data);
- const quint32 first = data32[0];
- const int linestep = (stride / sizeof(quint32)) - width;
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- if (*(data32++) != first)
- return false;
- }
- data32 += linestep;
- }
- break;
- }
- default:
- return false;
- }
-
- SRC color = reinterpret_cast<const SRC*>(data)[0];
- encoder->newBg |= (color != encoder->bg);
- encoder->bg = color;
- return true;
-}
-
-template <class SRC>
-void QRfbSingleColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- if (true || encoder->newBg) {
- const int bpp = encoder->server->clientBytesPerPixel();
- const int padding = 3;
- QVarLengthArray<char> buffer(padding + 1 + bpp);
- buffer[padding] = 2; // BackgroundSpecified
- encoder->server->convertPixels(buffer.data() + padding + 1,
- reinterpret_cast<char*>(&encoder->bg),
- 1);
- socket->write(buffer.data() + padding, bpp + 1);
-// encoder->newBg = false;
- } else {
- char subenc = 0;
- socket->write(&subenc, 1);
- }
-}
-
-template <class SRC>
-bool QRfbDualColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const SRC *ptr = reinterpret_cast<const SRC*>(data);
- const int linestep = (stride / sizeof(SRC)) - width;
-
- SRC c1;
- SRC c2 = 0;
- int n1 = 0;
- int n2 = 0;
- int x = 0;
- int y = 0;
-
- c1 = *ptr;
-
- // find second color
- while (y < height) {
- while (x < width) {
- if (*ptr == c1) {
- ++n1;
- } else {
- c2 = *ptr;
- goto found_second_color;
- }
- ++ptr;
- ++x;
- }
- x = 0;
- ptr += linestep;
- ++y;
- }
-
-found_second_color:
- // finish counting
- while (y < height) {
- while (x < width) {
- if (*ptr == c1) {
- ++n1;
- } else if (*ptr == c2) {
- ++n2;
- } else {
- return false;
- }
- ++ptr;
- ++x;
- }
- x = 0;
- ptr += linestep;
- ++y;
- }
-
- if (n2 > n1) {
- const quint32 tmpC = c1;
- c1 = c2;
- c2 = tmpC;
- }
-
- encoder->newBg |= (c1 != encoder->bg);
- encoder->newFg |= (c2 != encoder->fg);
-
- encoder->bg = c1;
- encoder->fg = c2;
-
- // create map
- bool inRect = false;
- numRects = 0;
- ptr = reinterpret_cast<const SRC*>(data);
- for (y = 0; y < height; ++y) {
- for (x = 0; x < width; ++x) {
- if (inRect && *ptr == encoder->bg) {
- // rect finished
- setWidth(x - lastx());
- next();
- inRect = false;
- } else if (!inRect && *ptr == encoder->fg) {
- // rect start
- setX(x);
- setY(y);
- setHeight(1);
- inRect = true;
- }
- ++ptr;
- }
- if (inRect) {
- // finish rect
- setWidth(width - lastx());
- next();
- inRect = false;
- }
- ptr += linestep;
- }
-
- return true;
-}
-
-template <class SRC>
-void QRfbDualColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- const int bpp = encoder->server->clientBytesPerPixel();
- const int padding = 3;
- QVarLengthArray<char> buffer(padding + 2 * bpp + sizeof(char) + sizeof(numRects));
- char &subenc = buffer[padding];
- int n = padding + sizeof(subenc);
-
- subenc = 0x8; // AnySubrects
-
- if (encoder->newBg) {
- subenc |= 0x2; // Background
- encoder->server->convertPixels(buffer.data() + n, (char*)&encoder->bg, 1);
- n += bpp;
-// encoder->newBg = false;
- }
-
- if (encoder->newFg) {
- subenc |= 0x4; // Foreground
- encoder->server->convertPixels(buffer.data() + n, (char*)&encoder->fg, 1);
- n += bpp;
-// encoder->newFg = false;
- }
- buffer[n] = numRects;
- n += sizeof(numRects);
-
- socket->write(buffer.data() + padding, n - padding);
- socket->write((char*)rects, numRects * sizeof(Rect));
-}
-
-template <class SRC>
-void QRfbDualColorHextile<SRC>::next()
-{
- for (int r = numRects - 1; r >= 0; --r) {
- if (recty(r) == lasty())
- continue;
- if (recty(r) < lasty() - 1) // only search previous scanline
- break;
- if (rectx(r) == lastx() && width(r) == width(numRects)) {
- ++rects[r].wh;
- return;
- }
- }
- ++numRects;
-}
-
-template <class SRC>
-inline void QRfbMultiColorHextile<SRC>::setColor(SRC color)
-{
- encoder->server->convertPixels(reinterpret_cast<char*>(rect(numRects)),
- (const char*)&color, 1);
-}
-
-template <class SRC>
-inline bool QRfbMultiColorHextile<SRC>::beginRect()
-{
- if ((rects.size() + bpp + 2) > maxRectsSize)
- return false;
- rects.resize(rects.size() + bpp + 2);
- return true;
-}
-
-template <class SRC>
-inline void QRfbMultiColorHextile<SRC>::endRect()
-{
- setHeight(numRects, 1);
- ++numRects;
-}
-
-template <class SRC>
-bool QRfbMultiColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const SRC *ptr = reinterpret_cast<const SRC*>(data);
- const int linestep = (stride / sizeof(SRC)) - width;
-
- bpp = encoder->server->clientBytesPerPixel();
-
- if (encoder->newBg)
- encoder->bg = ptr[0];
-
- const SRC bg = encoder->bg;
- SRC color = bg;
- bool inRect = false;
-
- numRects = 0;
- rects.clear();
-
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- if (inRect && *ptr != color) { // end rect
- setWidth(numRects, x - rectx(numRects));
- endRect();
- inRect = false;
- }
-
- if (!inRect && *ptr != bg) { // begin rect
- if (!beginRect())
- return false;
- inRect = true;
- color = *ptr;
- setColor(color);
- setX(numRects, x);
- setY(numRects, y);
- }
- ++ptr;
- }
- if (inRect) { // end rect
- setWidth(numRects, width - rectx(numRects));
- endRect();
- inRect = false;
- }
- ptr += linestep;
- }
-
- return true;
-}
-
-template <class SRC>
-void QRfbMultiColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- const int padding = 3;
- QVarLengthArray<quint8> buffer(bpp + padding + sizeof(quint8) + sizeof(numRects));
-
- quint8 &subenc = buffer[padding];
- int n = padding + sizeof(quint8);
-
- subenc = 8 | 16; // AnySubrects | SubrectsColoured
-
- if (encoder->newBg) {
- subenc |= 0x2; // Background
- encoder->server->convertPixels(reinterpret_cast<char*>(buffer.data() + n),
- reinterpret_cast<const char*>(&encoder->bg),
- 1);
- n += bpp;
-// encoder->newBg = false;
- }
-
- buffer[n] = numRects;
- n += sizeof(numRects);
-
- socket->write(reinterpret_cast<const char*>(buffer.data() + padding),
- n - padding);
- socket->write(reinterpret_cast<const char*>(rects.constData()),
- rects.size());
-}
-
-bool QVNCServer::pixelConversionNeeded() const
-{
- if (!sameEndian)
- return true;
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (qvnc_screen->swapBytes())
- return true;
-#endif
-
- const int screendepth = qvnc_screen->depth();
- if (screendepth != pixelFormat.bitsPerPixel)
- return true;
-
- switch (screendepth) {
- case 32:
- case 24:
- return false;
- case 18:
- return (pixelFormat.redBits == 6
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 6);
- case 16:
- return (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 5);
- case 15:
- return (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 5
- && pixelFormat.blueBits == 5);
- case 12:
- return (pixelFormat.redBits == 4
- && pixelFormat.greenBits == 4
- && pixelFormat.blueBits == 4);
- }
- return true;
-}
-
-// count: number of pixels
-void QVNCServer::convertPixels(char *dst, const char *src, int count) const
-{
- const int screendepth = qvnc_screen->depth();
- const bool isBgr = qvnc_screen->pixelType() == QScreen::BGRPixel;
-
- // cutoffs
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (!swapBytes)
-#endif
- if (sameEndian) {
- if (screendepth == pixelFormat.bitsPerPixel) { // memcpy cutoffs
-
- switch (screendepth) {
- case 32:
- memcpy(dst, src, count * sizeof(quint32));
- return;
- case 16:
- if (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 5)
- {
- memcpy(dst, src, count * sizeof(quint16));
- return;
- }
- }
- } else if (screendepth == 16 && pixelFormat.bitsPerPixel == 32) {
-#if defined(__i386__) // Currently fails on ARM if dst is not 4 byte aligned
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- quint32 *dst32 = reinterpret_cast<quint32*>(dst);
- int count32 = count * sizeof(quint16) / sizeof(quint32);
- while (count32--) {
- const quint32 s = *src32++;
- quint32 result1;
- quint32 result2;
-
- // red
- result1 = ((s & 0xf8000000) | ((s & 0xe0000000) >> 5)) >> 8;
- result2 = ((s & 0x0000f800) | ((s & 0x0000e000) >> 5)) << 8;
-
- // green
- result1 |= ((s & 0x07e00000) | ((s & 0x06000000) >> 6)) >> 11;
- result2 |= ((s & 0x000007e0) | ((s & 0x00000600) >> 6)) << 5;
-
- // blue
- result1 |= ((s & 0x001f0000) | ((s & 0x001c0000) >> 5)) >> 13;
- result2 |= ((s & 0x0000001f) | ((s & 0x0000001c) >> 5)) << 3;
-
- *dst32++ = result2;
- *dst32++ = result1;
- }
- if (count & 0x1) {
- const quint16 *src16 = reinterpret_cast<const quint16*>(src);
- *dst32 = qt_conv16ToRgb(src16[count - 1]);
- }
- return;
-#endif
- }
- }
-
- const int bytesPerPixel = (pixelFormat.bitsPerPixel + 7) / 8;
-
-// nibble = 0;
-
- for (int i = 0; i < count; ++i) {
- int r, g, b;
-
- switch (screendepth) {
-#if 0
- case 4: {
- if (!nibble) {
- r = ((*src) & 0x0f) << 4;
- } else {
- r = (*src) & 0xf0;
- src++;
- }
- nibble = !nibble;
- g = b = r;
- break;
- }
-#endif
- case 8: {
- QRgb rgb = qvnc_screen->clut()[int(*src)];
- r = qRed(rgb);
- g = qGreen(rgb);
- b = qBlue(rgb);
- src++;
- break;
- }
-#ifdef QT_QWS_DEPTH_12
- case 12: {
- quint32 p = quint32(*reinterpret_cast<const qrgb444*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb444);
- break;
- }
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15: {
- quint32 p = quint32(*reinterpret_cast<const qrgb555*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb555);
- break;
- }
-#endif
- case 16: {
- quint16 p = *reinterpret_cast<const quint16*>(src);
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (swapBytes)
- p = ((p & 0xff) << 8) | ((p & 0xff00) >> 8);
-#endif
- r = (p >> 11) & 0x1f;
- g = (p >> 5) & 0x3f;
- b = p & 0x1f;
- r <<= 3;
- g <<= 2;
- b <<= 3;
- src += sizeof(quint16);
- break;
- }
-#ifdef QT_QWS_DEPTH_18
- case 18: {
- quint32 p = quint32(*reinterpret_cast<const qrgb666*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb666);
- break;
- }
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24: {
- quint32 p = quint32(*reinterpret_cast<const qrgb888*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb888);
- break;
- }
-#endif
- case 32: {
- quint32 p = *reinterpret_cast<const quint32*>(src);
- r = (p >> 16) & 0xff;
- g = (p >> 8) & 0xff;
- b = p & 0xff;
- src += sizeof(quint32);
- break;
- }
- default: {
- r = g = b = 0;
- qDebug("QVNCServer: don't support %dbpp display", screendepth);
- return;
- }
- }
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (swapBytes ^ isBgr)
-#else
- if (isBgr)
-#endif
- qSwap(r, b);
-
- r >>= (8 - pixelFormat.redBits);
- g >>= (8 - pixelFormat.greenBits);
- b >>= (8 - pixelFormat.blueBits);
-
- int pixel = (r << pixelFormat.redShift) |
- (g << pixelFormat.greenShift) |
- (b << pixelFormat.blueShift);
-
- if (sameEndian || pixelFormat.bitsPerPixel == 8) {
- memcpy(dst, &pixel, bytesPerPixel); // XXX: do a simple for-loop instead?
- dst += bytesPerPixel;
- continue;
- }
-
-
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- switch (pixelFormat.bitsPerPixel) {
- case 16:
- pixel = (((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- case 32:
- pixel = (((pixel & 0xff000000) >> 24) |
- ((pixel & 0x00ff0000) >> 8) |
- ((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- default:
- qDebug("Cannot handle %d bpp client", pixelFormat.bitsPerPixel);
- }
- } else { // QSysInfo::ByteOrder == QSysInfo::LittleEndian
- switch (pixelFormat.bitsPerPixel) {
- case 16:
- pixel = (((pixel & 0xff000000) >> 8) |
- ((pixel & 0x00ff0000) << 8));
- break;
- case 32:
- pixel = (((pixel & 0xff000000) >> 24) |
- ((pixel & 0x00ff0000) >> 8) |
- ((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- default:
- qDebug("Cannot handle %d bpp client",
- pixelFormat.bitsPerPixel);
- break;
- }
- }
- memcpy(dst, &pixel, bytesPerPixel); // XXX: simple for-loop instead?
- dst += bytesPerPixel;
- }
-}
-
-#ifndef QT_NO_QWS_CURSOR
-static void blendCursor(QImage &image, const QRect &imageRect)
-{
- const QRect cursorRect = qt_screencursor->boundingRect();
- const QRect intersection = (cursorRect & imageRect);
- const QRect destRect = intersection.translated(-imageRect.topLeft());
- const QRect srcRect = intersection.translated(-cursorRect.topLeft());
-
- QPainter painter(&image);
- painter.drawImage(destRect, qt_screencursor->image(), srcRect);
- painter.end();
-}
-#endif // QT_NO_QWS_CURSOR
-
-QVNCDirtyMap::QVNCDirtyMap(QScreen *s)
- : bytesPerPixel(0), numDirty(0), screen(s)
-{
- bytesPerPixel = (screen->depth() + 7) / 8;
- bufferWidth = screen->deviceWidth();
- bufferHeight = screen->deviceHeight();
- bufferStride = bufferWidth * bytesPerPixel;
- buffer = new uchar[bufferHeight * bufferStride];
-
- mapWidth = (bufferWidth + MAP_TILE_SIZE - 1) / MAP_TILE_SIZE;
- mapHeight = (bufferHeight + MAP_TILE_SIZE - 1) / MAP_TILE_SIZE;
- numTiles = mapWidth * mapHeight;
- map = new uchar[numTiles];
-}
-
-QVNCDirtyMap::~QVNCDirtyMap()
-{
- delete[] map;
- delete[] buffer;
-}
-
-void QVNCDirtyMap::reset()
-{
- memset(map, 1, numTiles);
- memset(buffer, 0, bufferHeight * bufferStride);
- numDirty = numTiles;
-}
-
-inline bool QVNCDirtyMap::dirty(int x, int y) const
-{
- return map[y * mapWidth + x];
-}
-
-inline void QVNCDirtyMap::setClean(int x, int y)
-{
- map[y * mapWidth + x] = 0;
- --numDirty;
-}
-
-template <class T>
-void QVNCDirtyMapOptimized<T>::setDirty(int tileX, int tileY, bool force)
-{
- static bool alwaysForce = qgetenv("QT_VNC_NO_COMPAREBUFFER").toInt();
- if (alwaysForce)
- force = true;
-
- bool changed = false;
-
- if (!force) {
- const int lstep = screen->linestep();
- const int startX = tileX * MAP_TILE_SIZE;
- const int startY = tileY * MAP_TILE_SIZE;
- const uchar *scrn = screen->base()
- + startY * lstep + startX * bytesPerPixel;
- uchar *old = buffer + startY * bufferStride + startX * sizeof(T);
-
- const int tileHeight = (startY + MAP_TILE_SIZE > bufferHeight ?
- bufferHeight - startY : MAP_TILE_SIZE);
- const int tileWidth = (startX + MAP_TILE_SIZE > bufferWidth ?
- bufferWidth - startX : MAP_TILE_SIZE);
- const bool doInlines = (tileWidth == MAP_TILE_SIZE);
-
- int y = tileHeight;
-
- if (doInlines) { // hw: memcmp/memcpy is inlined when using constants
- while (y) {
- if (memcmp(old, scrn, sizeof(T) * MAP_TILE_SIZE)) {
- changed = true;
- break;
- }
- scrn += lstep;
- old += bufferStride;
- --y;
- }
-
- while (y) {
- memcpy(old, scrn, sizeof(T) * MAP_TILE_SIZE);
- scrn += lstep;
- old += bufferStride;
- --y;
- }
- } else {
- while (y) {
- if (memcmp(old, scrn, sizeof(T) * tileWidth)) {
- changed = true;
- break;
- }
- scrn += lstep;
- old += bufferStride;
- --y;
- }
-
- while (y) {
- memcpy(old, scrn, sizeof(T) * tileWidth);
- scrn += lstep;
- old += bufferStride;
- --y;
- }
- }
- }
-
- const int mapIndex = tileY * mapWidth + tileX;
- if ((force || changed) && !map[mapIndex]) {
- map[mapIndex] = 1;
- ++numDirty;
- }
-}
-
-template <class SRC>
-QRfbHextileEncoder<SRC>::QRfbHextileEncoder(QVNCServer *s)
- : QRfbEncoder(s),
- singleColorHextile(this), dualColorHextile(this), multiColorHextile(this)
-{
-}
-
-/*
- \internal
- Send dirty rects using hextile encoding.
-*/
-template <class SRC>
-void QRfbHextileEncoder<SRC>::write()
-{
- QWSDisplay::grab(true);
-
- QVNCDirtyMap *map = server->dirtyMap();
- QTcpSocket *socket = server->clientSocket();
-
- const quint32 encoding = htonl(5); // hextile encoding
- const int bytesPerPixel = server->clientBytesPerPixel();
-
- {
- const char tmp[2] = { 0, 0 }; // msg type, padding
- socket->write(tmp, sizeof(tmp));
- }
- {
- const quint16 count = htons(map->numDirty);
- socket->write((char *)&count, sizeof(count));
- }
-
- if (map->numDirty <= 0) {
- QWSDisplay::ungrab();
- return;
- }
-
- newBg = true;
- newFg = true;
-
- const QImage screenImage = server->screenImage();
- QRfbRect rect(0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE);
-
- for (int y = 0; y < map->mapHeight; ++y) {
- if (rect.y + MAP_TILE_SIZE > server->screen()->height())
- rect.h = server->screen()->height() - rect.y;
- rect.w = MAP_TILE_SIZE;
- for (int x = 0; x < map->mapWidth; ++x) {
- if (!map->dirty(x, y))
- continue;
- map->setClean(x, y);
-
- rect.x = x * MAP_TILE_SIZE;
- if (rect.x + MAP_TILE_SIZE > server->screen()->deviceWidth())
- rect.w = server->screen()->deviceWidth() - rect.x;
- rect.write(socket);
-
- socket->write((char *)&encoding, sizeof(encoding));
-
- const uchar *screendata = screenImage.scanLine(rect.y)
- + rect.x * screenImage.depth() / 8;
- int linestep = screenImage.bytesPerLine();
-
-#ifndef QT_NO_QWS_CURSOR
- // hardware cursors must be blended with the screen memory
- const bool doBlendCursor = qt_screencursor
- && !server->hasClientCursor()
- && qt_screencursor->isAccelerated();
- QImage tileImage;
- if (doBlendCursor) {
- const QRect tileRect(rect.x, rect.y, rect.w, rect.h);
- const QRect cursorRect = qt_screencursor->boundingRect()
- .translated(-server->screen()->offset());
- if (tileRect.intersects(cursorRect)) {
- tileImage = screenImage.copy(tileRect);
- blendCursor(tileImage,
- tileRect.translated(server->screen()->offset()));
- screendata = tileImage.bits();
- linestep = tileImage.bytesPerLine();
- }
- }
-#endif // QT_NO_QWS_CURSOR
-
- if (singleColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- singleColorHextile.write(socket);
- } else if (dualColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- dualColorHextile.write(socket);
- } else if (multiColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- multiColorHextile.write(socket);
- } else if (server->doPixelConversion()) {
- const int bufferSize = rect.w * rect.h * bytesPerPixel + 1;
- const int padding = sizeof(quint32) - sizeof(char);
- buffer.resize(bufferSize + padding);
-
- buffer[padding] = 1; // Raw subencoding
-
- // convert pixels
- char *b = buffer.data() + padding + 1;
- const int bstep = rect.w * bytesPerPixel;
- for (int i = 0; i < rect.h; ++i) {
- server->convertPixels(b, (const char*)screendata, rect.w);
- screendata += linestep;
- b += bstep;
- }
- socket->write(buffer.constData() + padding, bufferSize);
- } else {
- quint8 subenc = 1; // Raw subencoding
- socket->write((char *)&subenc, 1);
-
- // send pixels
- for (int i = 0; i < rect.h; ++i) {
- socket->write((const char*)screendata,
- rect.w * bytesPerPixel);
- screendata += linestep;
- }
- }
- }
- if (socket->state() == QAbstractSocket::UnconnectedState)
- break;
- rect.y += MAP_TILE_SIZE;
- }
- socket->flush();
- Q_ASSERT(map->numDirty == 0);
-
- QWSDisplay::ungrab();
-}
-
-void QRfbRawEncoder::write()
-{
- QWSDisplay::grab(false);
-
- QVNCDirtyMap *map = server->dirtyMap();
- QTcpSocket *socket = server->clientSocket();
-
- const int bytesPerPixel = server->clientBytesPerPixel();
-
- // create a region from the dirty rects and send the region's merged rects.
- QRegion rgn;
- if (map) {
- for (int y = 0; y < map->mapHeight; ++y) {
- for (int x = 0; x < map->mapWidth; ++x) {
- if (!map->dirty(x, y))
- continue;
- rgn += QRect(x * MAP_TILE_SIZE, y * MAP_TILE_SIZE,
- MAP_TILE_SIZE, MAP_TILE_SIZE);
- map->setClean(x, y);
- }
- }
-
- rgn &= QRect(0, 0, server->screen()->deviceWidth(),
- server->screen()->deviceHeight());
- }
- const QVector<QRect> rects = rgn.rects();
-
- {
- const char tmp[2] = { 0, 0 }; // msg type, padding
- socket->write(tmp, sizeof(tmp));
- }
-
- {
- const quint16 count = htons(rects.size());
- socket->write((char *)&count, sizeof(count));
- }
-
- if (rects.size() <= 0) {
- QWSDisplay::ungrab();
- return;
- }
-
- const QImage screenImage = server->screenImage();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect tileRect = rects.at(i);
- const QRfbRect rect(tileRect.x(), tileRect.y(),
- tileRect.width(), tileRect.height());
- rect.write(socket);
-
- const quint32 encoding = htonl(0); // raw encoding
- socket->write((char *)&encoding, sizeof(encoding));
-
- int linestep = screenImage.bytesPerLine();
- const uchar *screendata = screenImage.scanLine(rect.y)
- + rect.x * screenImage.depth() / 8;
-
-#ifndef QT_NO_QWS_CURSOR
- // hardware cursors must be blended with the screen memory
- const bool doBlendCursor = qt_screencursor
- && !server->hasClientCursor()
- && qt_screencursor->isAccelerated();
- QImage tileImage;
- if (doBlendCursor) {
- const QRect cursorRect = qt_screencursor->boundingRect()
- .translated(-server->screen()->offset());
- if (tileRect.intersects(cursorRect)) {
- tileImage = screenImage.copy(tileRect);
- blendCursor(tileImage,
- tileRect.translated(server->screen()->offset()));
- screendata = tileImage.bits();
- linestep = tileImage.bytesPerLine();
- }
- }
-#endif // QT_NO_QWS_CURSOR
-
- if (server->doPixelConversion()) {
- const int bufferSize = rect.w * rect.h * bytesPerPixel;
- if (bufferSize > buffer.size())
- buffer.resize(bufferSize);
-
- // convert pixels
- char *b = buffer.data();
- const int bstep = rect.w * bytesPerPixel;
- for (int i = 0; i < rect.h; ++i) {
- server->convertPixels(b, (const char*)screendata, rect.w);
- screendata += linestep;
- b += bstep;
- }
- socket->write(buffer.constData(), bufferSize);
- } else {
- for (int i = 0; i < rect.h; ++i) {
- socket->write((const char*)screendata, rect.w * bytesPerPixel);
- screendata += linestep;
- }
- }
- if (socket->state() == QAbstractSocket::UnconnectedState)
- break;
- }
- socket->flush();
-
- QWSDisplay::ungrab();
-}
-
-inline QImage QVNCServer::screenImage() const
-{
- return QImage(qvnc_screen->base(), qvnc_screen->deviceWidth(),
- qvnc_screen->deviceHeight(), qvnc_screen->linestep(),
- qvnc_screen->pixelFormat());
-}
-
-void QVNCServer::checkUpdate()
-{
- if (!wantUpdate)
- return;
-
- if (dirtyCursor) {
-#ifndef QT_NO_QWS_CURSOR
- Q_ASSERT(qvnc_cursor);
- qvnc_cursor->write();
-#endif
- dirtyCursor = false;
- wantUpdate = false;
- return;
- }
-
- if (dirtyMap()->numDirty > 0) {
- if (encoder)
- encoder->write();
- wantUpdate = false;
- }
-}
-
-void QVNCServer::discardClient()
-{
- timer->stop();
- state = Unconnected;
- delete encoder;
- encoder = 0;
-#ifndef QT_NO_QWS_CURSOR
- delete qvnc_cursor;
- qvnc_cursor = 0;
-#endif
- if (!qvnc_screen->screen() && !qvnc_screen->d_ptr->noDisablePainting && QWSServer::instance())
- QWSServer::instance()->enablePainting(false);
-}
-
-
-//===========================================================================
-
-/*!
- \class QVNCScreen
- \internal
- \ingroup qws
-
- \brief The QVNCScreen class implements a screen driver for VNC
- servers.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
- Custom screen drivers can be added by subclassing the QScreen
- class, using the QScreenDriverFactory class to dynamically load
- the driver into the application.
-
- The VNC protocol allows you to view and interact with the
- computer's display from anywhere on the network. See the
- \l{The VNC Protocol and Qt for Embedded Linux}{VNC protocol}
- documentation for more details.
-
- The default implementation of QVNCScreen inherits QLinuxFbScreen,
- but any QScreen subclass, or QScreen itself, can serve as its base
- class. This is easily achieved by manipulating the \c
- VNCSCREEN_BASE definition in the header file.
-
- \sa QScreen, {Running Applications}
-*/
-
-/*!
- \fn QVNCScreen::QVNCScreen(int displayId)
-
- Constructs a QVNCScreen object. The \a displayId argument
- identifies the Qt for Embedded Linux server to connect to.
-*/
-QVNCScreen::QVNCScreen(int display_id)
- : QProxyScreen(display_id, VNCClass)
-{
- d_ptr = new QVNCScreenPrivate(this);
-}
-
-/*!
- Destroys this QVNCScreen object.
-*/
-QVNCScreen::~QVNCScreen()
-{
- delete d_ptr;
-}
-
-/*!
- \reimp
-*/
-void QVNCScreen::setDirty(const QRect &rect)
-{
- d_ptr->setDirty(rect);
-}
-
-void QVNCScreenPrivate::setDirty(const QRect& rect, bool force)
-{
- if (rect.isEmpty())
- return;
-
- if (q_ptr->screen())
- q_ptr->screen()->setDirty(rect);
-
- if (!vncServer || !vncServer->isConnected())
- return;
-
- const QRect r = rect.translated(-q_ptr->offset());
- const int x1 = r.x() / MAP_TILE_SIZE;
- int y = r.y() / MAP_TILE_SIZE;
- for (; (y <= r.bottom() / MAP_TILE_SIZE) && y < dirty->mapHeight; y++)
- for (int x = x1; (x <= r.right() / MAP_TILE_SIZE) && x < dirty->mapWidth; x++)
- dirty->setDirty(x, y, force);
-
- vncServer->setDirty();
-}
-
-static int getDisplayId(const QString &spec)
-{
- QRegExp regexp(QLatin1String(":(\\d+)\\b"));
- if (regexp.lastIndexIn(spec) != -1) {
- const QString capture = regexp.cap(1);
- return capture.toInt();
- }
- return 0;
-}
-
-/*!
- \reimp
-*/
-bool QVNCScreen::connect(const QString &displaySpec)
-{
- QString dspec = displaySpec;
- if (dspec.startsWith(QLatin1String("vnc:"), Qt::CaseInsensitive))
- dspec = dspec.mid(QString::fromLatin1("vnc:").size());
- else if (dspec.compare(QLatin1String("vnc"), Qt::CaseInsensitive) == 0)
- dspec = QString();
-
- const QString displayIdSpec = QString::fromLatin1(" :%1").arg(displayId);
- if (dspec.endsWith(displayIdSpec))
- dspec = dspec.left(dspec.size() - displayIdSpec.size());
-
- QStringList args = dspec.split(QLatin1Char(':'),
- QString::SkipEmptyParts);
- QRegExp refreshRegexp(QLatin1String("^refreshrate=(\\d+)$"));
- int index = args.indexOf(refreshRegexp);
- if (index >= 0) {
- d_ptr->refreshRate = refreshRegexp.cap(1).toInt();
- args.removeAt(index);
- dspec = args.join(QLatin1String(":"));
- }
-
- QString driver = dspec;
- int colon = driver.indexOf(QLatin1Char(':'));
- if (colon >= 0)
- driver.truncate(colon);
-
- if (QScreenDriverFactory::keys().contains(driver, Qt::CaseInsensitive)) {
- const int id = getDisplayId(dspec);
- QScreen *s = qt_get_screen(id, dspec.toLatin1().constData());
- if (s->pixelFormat() == QImage::Format_Indexed8
- || s->pixelFormat() == QImage::Format_Invalid && s->depth() == 8)
- qFatal("QVNCScreen: unsupported screen format");
- setScreen(s);
- } else { // create virtual screen
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- QScreen::setFrameBufferLittleEndian(false);
-#endif
-
- d = qgetenv("QWS_DEPTH").toInt();
- if (!d)
- d = 16;
-
- QByteArray str = qgetenv("QWS_SIZE");
- if(!str.isEmpty()) {
- sscanf(str.constData(), "%dx%d", &w, &h);
- dw = w;
- dh = h;
- } else {
- dw = w = 640;
- dh = h = 480;
- }
-
- const QStringList args = displaySpec.split(QLatin1Char(':'),
- QString::SkipEmptyParts);
-
- if (args.contains(QLatin1String("paintonscreen"), Qt::CaseInsensitive))
- d_ptr->doOnScreenSurface = true;
-
- QRegExp depthRegexp(QLatin1String("^depth=(\\d+)$"));
- if (args.indexOf(depthRegexp) != -1)
- d = depthRegexp.cap(1).toInt();
-
- QRegExp sizeRegexp(QLatin1String("^size=(\\d+)x(\\d+)$"));
- if (args.indexOf(sizeRegexp) != -1) {
- dw = w = sizeRegexp.cap(1).toInt();
- dh = h = sizeRegexp.cap(2).toInt();
- }
-
- // Handle display physical size spec.
- QRegExp mmWidthRegexp(QLatin1String("^mmWidth=?(\\d+)$"));
- if (args.indexOf(mmWidthRegexp) != -1) {
- const int mmWidth = mmWidthRegexp.cap(1).toInt();
- if (mmWidth > 0)
- d_ptr->dpiX = dw * 25.4 / mmWidth;
- }
- QRegExp mmHeightRegexp(QLatin1String("^mmHeight=?(\\d+)$"));
- if (args.indexOf(mmHeightRegexp) != -1) {
- const int mmHeight = mmHeightRegexp.cap(1).toInt();
- if (mmHeight > 0)
- d_ptr->dpiY = dh * 25.4 / mmHeight;
- }
- QRegExp dpiRegexp(QLatin1String("^dpi=(\\d+)(?:,(\\d+))?$"));
- if (args.indexOf(dpiRegexp) != -1) {
- const qreal dpiX = dpiRegexp.cap(1).toFloat();
- const qreal dpiY = dpiRegexp.cap(2).toFloat();
- if (dpiX > 0)
- d_ptr->dpiX = dpiX;
- d_ptr->dpiY = (dpiY > 0 ? dpiY : dpiX);
- }
-
- if (args.contains(QLatin1String("noDisablePainting")))
- d_ptr->noDisablePainting = true;
-
- QWSServer::setDefaultMouse("None");
- QWSServer::setDefaultKeyboard("None");
-
- d_ptr->configure();
- }
-
- // XXX
- qt_screen = this;
-
- return true;
-}
-
-/*!
- \reimp
-*/
-void QVNCScreen::disconnect()
-{
- QProxyScreen::disconnect();
-#if !defined(QT_NO_QWS_MULTIPROCESS) && !defined(QT_NO_SHAREDMEMORY)
- d_ptr->shm.detach();
-#endif
-}
-
-/*!
- \reimp
-*/
-bool QVNCScreen::initDevice()
-{
- if (!QProxyScreen::screen() && d == 4) {
- screencols = 16;
- int val = 0;
- for (int idx = 0; idx < 16; idx++, val += 17) {
- screenclut[idx] = qRgb(val, val, val);
- }
- }
- d_ptr->vncServer = new QVNCServer(this, displayId);
- d_ptr->vncServer->setRefreshRate(d_ptr->refreshRate);
-
- switch (depth()) {
-#ifdef QT_QWS_DEPTH_32
- case 32:
- d_ptr->dirty = new QVNCDirtyMapOptimized<quint32>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24:
- d_ptr->dirty = new QVNCDirtyMapOptimized<qrgb888>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_18
- case 18:
- d_ptr->dirty = new QVNCDirtyMapOptimized<qrgb666>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_16
- case 16:
- d_ptr->dirty = new QVNCDirtyMapOptimized<quint16>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15:
- d_ptr->dirty = new QVNCDirtyMapOptimized<qrgb555>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_12
- case 12:
- d_ptr->dirty = new QVNCDirtyMapOptimized<qrgb444>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_8
- case 8:
- d_ptr->dirty = new QVNCDirtyMapOptimized<quint8>(this);
- break;
-#endif
- default:
- qWarning("QVNCScreen::initDevice: No support for screen depth %d",
- depth());
- d_ptr->dirty = 0;
- return false;
- }
-
-
- const bool ok = QProxyScreen::initDevice();
-#ifndef QT_NO_QWS_CURSOR
- qt_screencursor = new QVNCCursor(this);
-#endif
- if (QProxyScreen::screen())
- return ok;
-
- // Disable painting if there is only 1 display and nothing is attached to the VNC server
- if (!d_ptr->noDisablePainting)
- QWSServer::instance()->enablePainting(false);
-
- return true;
-}
-
-/*!
- \reimp
-*/
-void QVNCScreen::shutdownDevice()
-{
- QProxyScreen::shutdownDevice();
- delete d_ptr->vncServer;
- delete d_ptr->dirty;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_VNC
diff --git a/src/plugins/gfxdrivers/vnc/vnc.pro b/src/plugins/gfxdrivers/vnc/vnc.pro
deleted file mode 100644
index 95e2ba7cf8..0000000000
--- a/src/plugins/gfxdrivers/vnc/vnc.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-TARGET = qgfxvnc
-load(qt_plugin)
-
-DEFINES += QT_QWS_VNC
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-HEADERS = \
- qscreenvnc_qws.h \
- qscreenvnc_p.h
-
-SOURCES = main.cpp \
- qscreenvnc_qws.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
diff --git a/src/plugins/graphicssystems/graphicssystems.pro b/src/plugins/graphicssystems/graphicssystems.pro
deleted file mode 100644
index 5c99291047..0000000000
--- a/src/plugins/graphicssystems/graphicssystems.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS += trace
-!wince*:contains(QT_CONFIG, opengl):SUBDIRS += opengl
-contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl) {
- SUBDIRS += openvg
-}
-
-contains(QT_CONFIG, shivavg) {
- # Only works under X11 at present
- !win32:!embedded:!mac:SUBDIRS += shivavg
-}
-
-!win32:!embedded:!mac:!symbian:CONFIG += x11
-
-x11:contains(QT_CONFIG, opengles2):contains(QT_CONFIG, egl):SUBDIRS += meego
diff --git a/src/plugins/graphicssystems/meego/dithering.cpp b/src/plugins/graphicssystems/meego/dithering.cpp
deleted file mode 100644
index 6e4b61c754..0000000000
--- a/src/plugins/graphicssystems/meego/dithering.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// Implements two dithering methods:
-//
-// * convertRGBA32_to_RGB565
-//
-// This is implemented using Ordered Bayer Dithering. The code has been adapted
-// from QX11PixmapData::fromImage. This method was originally implemented using
-// Floyd-Steinberg dithering but was later changed to Ordered Dithering because
-// of the better quality of the results.
-//
-// * convertRGBA32_to_RGBA4444
-//
-// This is implemented using Floyd-Steinberg dithering.
-//
-// The alghorithm used here is not the fastest possible but it's prolly fast enough:
-// uses look-up tables, integer-only arthmetics and works in one pass on two lines
-// at a time. It's a high-quality dithering using 1/8 diffusion precission.
-// Each channel (RGBA) is diffused independently and alpha is dithered too.
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <QVarLengthArray>
-
-// Gets a component (red = 1, green = 2...) from a RGBA data structure.
-// data is unsigned char. stride is the number of bytes per line.
-#define GET_RGBA_COMPONENT(data, x, y, stride, c) (data[(y * stride) + (x << 2) + c])
-
-// Writes a new pixel with r, g, b to data in 565 16bit format. Data is a short.
-#define PUT_565(data, x, y, width, r, g, b) (data[(y * width) + x] = (r << 11) | (g << 5) | b)
-
-// Writes a new pixel with r, g, b, a to data in 4444 RGBA 16bit format. Data is a short.
-#define PUT_4444(data, x, y, width, r, g, b, a) (data[(y * width) + x] = (r << 12) | (g << 8) | (b << 4) | a)
-
-// Writes(ads) a new value to the diffusion accumulator. accumulator is a short.
-// x, y is a position in the accumulation buffer. y can be 0 or 1 -- we operate on two lines at time.
-#define ACCUMULATE(accumulator, x, y, width, v) if (x < width && x >= 0) accumulator[(y * width) + x] += v
-
-// Clamps a value to be in 0..255 range.
-#define CLAMP_256(v) if (v > 255) v = 255; if (v < 0) v = 0;
-
-// Converts incoming RGB32 (QImage::Format_RGB32) to RGB565. Returns the newly allocated data.
-unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int height, int stride)
-{
- static bool thresholdMapInitialized = false;
- static int thresholdMap[16][16];
-
- if (!thresholdMapInitialized) {
- int i;
- int j;
- int n;
-
- thresholdMap[0][0] = 0;
- thresholdMap[1][0] = 2;
- thresholdMap[0][1] = 3;
- thresholdMap[1][1] = 1;
-
- for (n=2; n<16; n*=2) {
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) {
- thresholdMap[i][j] *= 4;
- thresholdMap[i+n][j] = thresholdMap[i][j] + 2;
- thresholdMap[i][j+n] = thresholdMap[i][j] + 3;
- thresholdMap[i+n][j+n] = thresholdMap[i][j] + 1;
- }
- }
- }
-
- thresholdMapInitialized = true;
- }
-
- // Output line stride. Aligned to 4 bytes.
- int alignedWidth = width;
- if (alignedWidth % 2 > 0)
- alignedWidth++;
-
- // Will store output
- unsigned short *out = (unsigned short *)malloc (alignedWidth * height * 2);
-
- int x;
- int y;
- int threshold;
-
- // For each line...
- for (y = 0; y < height; y++) {
-
- // For each column....
- for (x = 0; x < width; x++) {
-
- int r = GET_RGBA_COMPONENT(in, x, y, stride, 0);
- int g = GET_RGBA_COMPONENT(in, x, y, stride, 1);
- int b = GET_RGBA_COMPONENT(in, x, y, stride, 2);
-
- threshold = thresholdMap[x%16][y%16];
-
- if (r <= (255-(1<<3)) && ((r<<5) & 255) > threshold) r += (1<<3);
- if (g <= (255-(1<<2)) && ((g<<6) & 255) > threshold) g += (1<<2);
- if (b <= (255-(1<<3)) && ((b<<5) & 255) > threshold) b += (1<<3);
-
- // Write the newly produced pixel
- PUT_565(out, x, y, alignedWidth, ((b >> 3) & 0x1f), ((g >> 2) & 0x3f), ((r >> 3) & 0x1f));
- }
- }
-
- return out;
-}
-
-// Converts incoming RGBA32 (QImage::Format_ARGB32_Premultiplied) to RGB565. Returns the newly allocated data.
-// This function is similar (yet different) to the _565 variant but it makes sense to duplicate it here for simplicity.
-// The output has each scan line aligned to 4 bytes (as expected by GL by default).
-unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, int height, int stride)
-{
- // Output line stride. Aligned to 4 bytes.
- int alignedWidth = width;
- if (alignedWidth % 2 > 0)
- alignedWidth++;
-
- // Will store output
- unsigned short *out = (unsigned short *) malloc(alignedWidth * 2 * height);
-
- // Lookup tables for the 8bit => 4bit conversion
- unsigned char lookup_8bit_to_4bit[256];
- short lookup_8bit_to_4bit_diff[256];
-
- // Macros for the conversion using the lookup table.
- #define CONVERT_8BIT_TO_4BIT(v) (lookup_8bit_to_4bit[v])
- #define DIFF_8BIT_TO_4BIT(v) (lookup_8bit_to_4bit_diff[v])
-
- int i;
- int x, y, c; // Pixel we're processing. c is component number (0, 1, 2, 3 for r, b, b, a)
- short component[4]; // Stores the new components (r, g, b, a) for pixel produced during conversion
- short diff; // The difference between the converted value and the original one. To be accumulated.
- QVarLengthArray <short> accumulatorData(4 * width * 2); // Data for three acumulators for r, g, b. Each accumulator is two lines.
- short *accumulator[4]; // Helper for accessing the accumulator on a per-channel basis more easily.
- accumulator[0] = accumulatorData.data();
- accumulator[1] = accumulatorData.data() + width;
- accumulator[2] = accumulatorData.data() + (width * 2);
- accumulator[3] = accumulatorData.data() + (width * 3);
-
- // Produce the conversion lookup tables.
- for (i = 0; i < 256; i++) {
- lookup_8bit_to_4bit[i] = round(i / 16.0);
- // Before bitshifts: (i * 8) - (... * 16 * 8)
- lookup_8bit_to_4bit_diff[i] = (i << 3) - (lookup_8bit_to_4bit[i] << 7);
-
- if (lookup_8bit_to_4bit[i] > 15)
- lookup_8bit_to_4bit[i] = 15;
- }
-
- // Clear the accumulators
- memset(accumulator[0], 0, width * 4);
- memset(accumulator[1], 0, width * 4);
- memset(accumulator[2], 0, width * 4);
- memset(accumulator[3], 0, width * 4);
-
- // For each line...
- for (y = 0; y < height; y++) {
-
- // For each component (r, g, b, a)...
- memcpy(accumulator[0], accumulator[0] + width, width * 2);
- memset(accumulator[0] + width, 0, width * 2);
-
- memcpy(accumulator[1], accumulator[1] + width, width * 2);
- memset(accumulator[1] + width, 0, width * 2);
-
- memcpy(accumulator[2], accumulator[2] + width, width * 2);
- memset(accumulator[2] + width, 0, width * 2);
-
- memcpy(accumulator[3], accumulator[3] + width, width * 2);
- memset(accumulator[3] + width, 0, width * 2);
-
- // For each column....
- for (x = 0; x < width; x++) {
-
- // For each component (r, g, b, a)...
- for (c = 0; c < 4; c++) {
-
- // Get the 8bit value from the original image
- component[c] = GET_RGBA_COMPONENT(in, x, y, stride, c);
-
- // Add the diffusion for this pixel we stored in the accumulator.
- // >> 7 because the values in accumulator are stored * 128
- component[c] += accumulator[c][x] >> 7;
-
- // Make sure we're not over the boundaries.
- CLAMP_256(component[c]);
-
- // Store the difference from converting 8bit => 4bit and the orig pixel.
- // Convert 8bit => 4bit.
- diff = DIFF_8BIT_TO_4BIT(component[c]);
- component[c] = CONVERT_8BIT_TO_4BIT(component[c]);
-
- // Distribute the difference according to the matrix in the
- // accumulation bufffer.
- ACCUMULATE(accumulator[c], x + 1, 0, width, diff * 7);
- ACCUMULATE(accumulator[c], x - 1, 1, width, diff * 3);
- ACCUMULATE(accumulator[c], x, 1, width, diff * 5);
- ACCUMULATE(accumulator[c], x + 1, 1, width, diff * 1);
- }
-
- // Write the newly produced pixel
- PUT_4444(out, x, y, alignedWidth, component[0], component[1], component[2], component[3]);
- }
- }
-
- return out;
-}
-
-unsigned char* convertBGRA32_to_RGBA32(const unsigned char *in, int width, int height, int stride)
-{
- unsigned char *out = (unsigned char *) malloc(stride * height);
-
- // For each line...
- for (int y = 0; y < height; y++) {
- // For each column
- for (int x = 0; x < width; x++) {
- out[(stride * y) + (x * 4) + 0] = in[(stride * y) + (x * 4) + 2];
- out[(stride * y) + (x * 4) + 1] = in[(stride * y) + (x * 4) + 1];
- out[(stride * y) + (x * 4) + 2] = in[(stride * y) + (x * 4) + 0];
- out[(stride * y) + (x * 4) + 3] = in[(stride * y) + (x * 4) + 3];
- }
- }
-
- return out;
-}
diff --git a/src/plugins/graphicssystems/meego/meego.pro b/src/plugins/graphicssystems/meego/meego.pro
deleted file mode 100644
index 6432825888..0000000000
--- a/src/plugins/graphicssystems/meego/meego.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qmeegographicssystem
-load(qt_plugin)
-
-QT += core-private gui-private opengl-private
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-HEADERS = qmeegographicssystem.h qmeegopixmapdata.h qmeegoextensions.h qmeegorasterpixmapdata.h qmeegolivepixmapdata.h
-SOURCES = qmeegographicssystem.cpp qmeegographicssystem.h qmeegographicssystemplugin.h qmeegographicssystemplugin.cpp qmeegopixmapdata.h qmeegopixmapdata.cpp qmeegoextensions.h qmeegoextensions.cpp qmeegorasterpixmapdata.h qmeegorasterpixmapdata.cpp qmeegolivepixmapdata.cpp qmeegolivepixmapdata.h dithering.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
-
diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp
deleted file mode 100644
index c1a8eb7028..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmeegoextensions.h"
-#include <private/qeglcontext_p.h>
-#include <private/qpixmapdata_gl_p.h>
-
-bool QMeeGoExtensions::initialized = false;
-bool QMeeGoExtensions::hasImageShared = false;
-bool QMeeGoExtensions::hasSurfaceScaling = false;
-bool QMeeGoExtensions::hasLockSurface = false;
-bool QMeeGoExtensions::hasFenceSync = false;
-
-/* Extension funcs */
-
-typedef EGLBoolean (EGLAPIENTRY *eglQueryImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint, EGLint*);
-typedef EGLNativeSharedImageTypeNOK (EGLAPIENTRY *eglCreateSharedImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint*);
-typedef EGLBoolean (EGLAPIENTRY *eglDestroySharedImageNOKFunc)(EGLDisplay, EGLNativeSharedImageTypeNOK);
-typedef EGLBoolean (EGLAPIENTRY *eglSetSurfaceScalingNOKFunc)(EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint);
-typedef EGLBoolean (EGLAPIENTRY *eglLockSurfaceKHRFunc)(EGLDisplay, EGLSurface, const EGLint*);
-typedef EGLBoolean (EGLAPIENTRY *eglUnlockSurfaceKHRFunc)(EGLDisplay, EGLSurface);
-typedef EGLSyncKHR (EGLAPIENTRY *eglCreateSyncKHRFunc)(EGLDisplay, EGLenum, const EGLint*);
-typedef EGLBoolean (EGLAPIENTRY *eglDestroySyncKHRFunc)(EGLDisplay, EGLSyncKHR);
-typedef EGLint (EGLAPIENTRY *eglClientWaitSyncKHRFunc)(EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR);
-typedef EGLBoolean (EGLAPIENTRY *eglGetSyncAttribKHRFunc)(EGLDisplay, EGLSyncKHR, EGLint, EGLint*);
-
-static eglQueryImageNOKFunc _eglQueryImageNOK = 0;
-static eglCreateSharedImageNOKFunc _eglCreateSharedImageNOK = 0;
-static eglDestroySharedImageNOKFunc _eglDestroySharedImageNOK = 0;
-static eglSetSurfaceScalingNOKFunc _eglSetSurfaceScalingNOK = 0;
-static eglLockSurfaceKHRFunc _eglLockSurfaceKHR = 0;
-static eglUnlockSurfaceKHRFunc _eglUnlockSurfaceKHR = 0;
-static eglCreateSyncKHRFunc _eglCreateSyncKHR = 0;
-static eglDestroySyncKHRFunc _eglDestroySyncKHR = 0;
-static eglClientWaitSyncKHRFunc _eglClientWaitSyncKHR = 0;
-static eglGetSyncAttribKHRFunc _eglGetSyncAttribKHR = 0;
-
-/* Public */
-
-void QMeeGoExtensions::ensureInitialized()
-{
- if (!initialized)
- initialize();
-
- initialized = true;
-}
-
-EGLNativeSharedImageTypeNOK QMeeGoExtensions::eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props)
-{
- if (!hasImageShared)
- qFatal("EGL_NOK_image_shared not found but trying to use capability!");
-
- return _eglCreateSharedImageNOK(dpy, image, props);
-}
-
-bool QMeeGoExtensions::eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v)
-{
- if (!hasImageShared)
- qFatal("EGL_NOK_image_shared not found but trying to use capability!");
-
- return _eglQueryImageNOK(dpy, image, prop, v);
-}
-
-bool QMeeGoExtensions::eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img)
-{
- if (!hasImageShared)
- qFatal("EGL_NOK_image_shared not found but trying to use capability!");
-
- return _eglDestroySharedImageNOK(dpy, img);
-}
-
-bool QMeeGoExtensions::eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height)
-{
- if (!hasSurfaceScaling)
- qFatal("EGL_NOK_surface_scaling not found but trying to use capability!");
-
- return _eglSetSurfaceScalingNOK(dpy, surface, x, y, width, height);
-}
-
-bool QMeeGoExtensions::eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
-{
- if (!hasLockSurface)
- qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!");
-
- return _eglLockSurfaceKHR(display, surface, attrib_list);
-}
-
-bool QMeeGoExtensions::eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
-{
- if (!hasLockSurface)
- qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!");
-
- return _eglUnlockSurfaceKHR(display, surface);
-}
-
-EGLSyncKHR QMeeGoExtensions::eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
-{
- if (!hasFenceSync)
- qFatal("EGL_KHR_fence_sync not found but trying to use capability!");
-
- return _eglCreateSyncKHR(dpy, type, attrib_list);
-}
-
-bool QMeeGoExtensions::eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
-{
- if (!hasFenceSync)
- qFatal("EGL_KHR_fence_sync not found but trying to use capability!");
-
- return _eglDestroySyncKHR(dpy, sync);
-}
-
-EGLint QMeeGoExtensions::eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
-{
- if (!hasFenceSync)
- qFatal("EGL_KHR_fence_sync not found but trying to use capability!");
-
- return _eglClientWaitSyncKHR(dpy, sync, flags, timeout);
-}
-
-EGLBoolean QMeeGoExtensions::eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
-{
- if (!hasFenceSync)
- qFatal("EGL_KHR_fence_sync not found but trying to use capability!");
-
- return _eglGetSyncAttribKHR(dpy, sync, attribute, value);
-}
-
-/* Private */
-
-void QMeeGoExtensions::initialize()
-{
- QGLContext *ctx = (QGLContext *) QGLContext::currentContext();
- qt_resolve_eglimage_gl_extensions(ctx);
-
- if (QEgl::hasExtension("EGL_NOK_image_shared")) {
- qDebug("MeegoGraphics: found EGL_NOK_image_shared");
- _eglQueryImageNOK = (eglQueryImageNOKFunc) eglGetProcAddress("eglQueryImageNOK");
- _eglCreateSharedImageNOK = (eglCreateSharedImageNOKFunc) eglGetProcAddress("eglCreateSharedImageNOK");
- _eglDestroySharedImageNOK = (eglDestroySharedImageNOKFunc) eglGetProcAddress("eglDestroySharedImageNOK");
- _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR");
- _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR");
-
- Q_ASSERT(_eglQueryImageNOK && _eglCreateSharedImageNOK && _eglDestroySharedImageNOK);
- hasImageShared = true;
- }
-
- if (QEgl::hasExtension("EGL_NOK_surface_scaling")) {
- qDebug("MeegoGraphics: found EGL_NOK_surface_scaling");
- _eglSetSurfaceScalingNOK = (eglSetSurfaceScalingNOKFunc) eglGetProcAddress("eglSetSurfaceScalingNOK");
-
- Q_ASSERT(_eglSetSurfaceScalingNOK);
- hasSurfaceScaling = true;
- }
-
- if (QEgl::hasExtension("EGL_KHR_lock_surface2")) {
- qDebug("MeegoGraphics: found EGL_KHR_lock_surface2");
- _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR");
- _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR");
-
- Q_ASSERT(_eglLockSurfaceKHR && _eglUnlockSurfaceKHR);
- hasLockSurface = true;
- }
-
- if (QEgl::hasExtension("EGL_KHR_fence_sync")) {
- qDebug("MeegoGraphics: found EGL_KHR_fence_sync");
- _eglCreateSyncKHR = (eglCreateSyncKHRFunc) eglGetProcAddress("eglCreateSyncKHR");
- _eglDestroySyncKHR = (eglDestroySyncKHRFunc) eglGetProcAddress("eglDestroySyncKHR");
- _eglClientWaitSyncKHR = (eglClientWaitSyncKHRFunc) eglGetProcAddress("eglClientWaitSyncKHR");
- _eglGetSyncAttribKHR = (eglGetSyncAttribKHRFunc) eglGetProcAddress("eglGetSyncAttribKHR");
-
- Q_ASSERT(_eglCreateSyncKHR && _eglDestroySyncKHR && _eglClientWaitSyncKHR && _eglGetSyncAttribKHR);
- hasFenceSync = true;
- }
-}
-
diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.h b/src/plugins/graphicssystems/meego/qmeegoextensions.h
deleted file mode 100644
index e4ceed3a31..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegoextensions.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MEXTENSIONS_H
-#define MEXTENSIONS_H
-
-#include <private/qgl_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qpixmapdata_gl_p.h>
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-/* Extensions decls */
-
-#ifndef EGL_SHARED_IMAGE_NOK
-#define EGL_SHARED_IMAGE_NOK 0x30DA
-typedef void* EGLNativeSharedImageTypeNOK;
-#endif
-
-#ifndef EGL_GL_TEXTURE_2D_KHR
-#define EGL_GL_TEXTURE_2D_KHR 0x30B1
-#endif
-
-#ifndef EGL_FIXED_WIDTH_NOK
-#define EGL_FIXED_WIDTH_NOK 0x30DB
-#define EGL_FIXED_HEIGHT_NOK 0x30DC
-#endif
-
-#ifndef EGL_BITMAP_POINTER_KHR
-#define EGL_BITMAP_POINTER_KHR 0x30C6
-#define EGL_BITMAP_PITCH_KHR 0x30C7
-#endif
-
-#ifndef EGL_MAP_PRESERVE_PIXELS_KHR
-#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
-#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
-#define EGL_READ_SURFACE_BIT_KHR 0x0001
-#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
-#endif
-
-#ifndef EGL_SYNC_FENCE_KHR
-#define EGL_SYNC_FENCE_KHR 0x30F9
-#define EGL_SYNC_TYPE_KHR 0x30F7
-#define EGL_SYNC_STATUS_KHR 0x30F1
-#define EGL_SYNC_CONDITION_KHR 0x30F8
-#define EGL_SIGNALED_KHR 0x30F2
-#define EGL_UNSIGNALED_KHR 0x30F3
-#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
-#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
-#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
-#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
-#define EGL_CONDITION_SATISFIED_KHR 0x30F6
-#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
-typedef void* EGLSyncKHR;
-typedef khronos_utime_nanoseconds_t EGLTimeKHR;
-#endif
-
-/* Class */
-
-class QMeeGoExtensions
-{
-public:
- static void ensureInitialized();
-
- static EGLNativeSharedImageTypeNOK eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props);
- static bool eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v);
- static bool eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img);
- static bool eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height);
- static bool eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
- static bool eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface);
- static EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
- static bool eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
- static EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
- static EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
-
-private:
- static void initialize();
-
- static bool initialized;
- static bool hasImageShared;
- static bool hasSurfaceScaling;
- static bool hasLockSurface;
- static bool hasFenceSync;
-};
-
-#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
deleted file mode 100644
index ab403797df..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
+++ /dev/null
@@ -1,534 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QDebug>
-#include <private/qpixmap_raster_p.h>
-#include <private/qwindowsurface_gl_p.h>
-#include <private/qwindowsurface_raster_p.h>
-#include <private/qegl_p.h>
-#include <private/qglextensions_p.h>
-#include <private/qgl_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_runtime_p.h>
-#include <private/qimage_p.h>
-#include <private/qeglproperties_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qpixmap_x11_p.h>
-
-#include "qmeegopixmapdata.h"
-#include "qmeegolivepixmapdata.h"
-#include "qmeegographicssystem.h"
-#include "qmeegoextensions.h"
-
-#include <QTimer>
-
-bool QMeeGoGraphicsSystem::surfaceWasCreated = false;
-
-QHash <Qt::HANDLE, QPixmap*> QMeeGoGraphicsSystem::liveTexturePixmaps;
-
-QList<QMeeGoSwitchCallback> QMeeGoGraphicsSystem::switchCallbacks;
-
-QMeeGoGraphicsSystem::SwitchPolicy QMeeGoGraphicsSystem::switchPolicy = QMeeGoGraphicsSystem::AutomaticSwitch;
-
-QMeeGoGraphicsSystem::QMeeGoGraphicsSystem()
-{
- qDebug("Using the meego graphics system");
-}
-
-QMeeGoGraphicsSystem::~QMeeGoGraphicsSystem()
-{
- qDebug("Meego graphics system destroyed");
- qt_destroy_gl_share_widget();
-}
-
-class QMeeGoGraphicsSystemSwitchHandler : public QObject
-{
- Q_OBJECT
-public:
- QMeeGoGraphicsSystemSwitchHandler();
-
- void addWidget(QWidget *widget);
- bool eventFilter(QObject *, QEvent *);
-
- void handleMapNotify();
-
-private slots:
- void removeWidget(QObject *object);
- void switchToRaster();
- void switchToMeeGo();
-
-private:
- int visibleWidgets() const;
-
-private:
- QList<QWidget *> m_widgets;
-};
-
-typedef bool(*QX11FilterFunction)(XEvent *event);
-Q_GUI_EXPORT void qt_installX11EventFilter(QX11FilterFunction func);
-
-static bool x11EventFilter(XEvent *event);
-
-QMeeGoGraphicsSystemSwitchHandler::QMeeGoGraphicsSystemSwitchHandler()
-{
- qt_installX11EventFilter(x11EventFilter);
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::addWidget(QWidget *widget)
-{
- if (widget != qt_gl_share_widget() && !m_widgets.contains(widget)) {
- widget->installEventFilter(this);
- connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(removeWidget(QObject *)));
- m_widgets << widget;
- }
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::handleMapNotify()
-{
- if (m_widgets.isEmpty() && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
- QTimer::singleShot(0, this, SLOT(switchToMeeGo()));
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::removeWidget(QObject *object)
-{
- m_widgets.removeOne(static_cast<QWidget *>(object));
- if (m_widgets.isEmpty() && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
- QTimer::singleShot(0, this, SLOT(switchToRaster()));
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::switchToRaster()
-{
- QMeeGoGraphicsSystem::switchToRaster();
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::switchToMeeGo()
-{
- QMeeGoGraphicsSystem::switchToMeeGo();
-}
-
-int QMeeGoGraphicsSystemSwitchHandler::visibleWidgets() const
-{
- int count = 0;
- for (int i = 0; i < m_widgets.size(); ++i)
- count += m_widgets.at(i)->isVisible() && !(m_widgets.at(i)->windowState() & Qt::WindowMinimized);
- return count;
-}
-
-bool QMeeGoGraphicsSystemSwitchHandler::eventFilter(QObject *object, QEvent *event)
-{
- if (event->type() == QEvent::WindowStateChange
- && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
- {
- QWindowStateChangeEvent *change = static_cast<QWindowStateChangeEvent *>(event);
- QWidget *widget = static_cast<QWidget *>(object);
-
- Qt::WindowStates current = widget->windowState();
- Qt::WindowStates old = change->oldState();
-
- // did minimized flag change?
- if ((current ^ old) & Qt::WindowMinimized) {
- if (current & Qt::WindowMinimized) {
- if (visibleWidgets() == 0)
- QMeeGoGraphicsSystem::switchToRaster();
- } else {
- if (visibleWidgets() > 0)
- QMeeGoGraphicsSystem::switchToMeeGo();
- }
- }
- }
-
- // resume processing of event
- return false;
-}
-
-Q_GLOBAL_STATIC(QMeeGoGraphicsSystemSwitchHandler, switch_handler)
-
-bool x11EventFilter(XEvent *event)
-{
- if (event->type == MapNotify)
- switch_handler()->handleMapNotify();
- return false;
-}
-
-QWindowSurface* QMeeGoGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- QGLWidget *shareWidget = qt_gl_share_widget();
-
- if (!shareWidget)
- return new QRasterWindowSurface(widget);
-
- QGLShareContextScope ctx(shareWidget->context());
-
- if (QApplicationPrivate::instance()->graphics_system_name == QLatin1String("runtime"))
- switch_handler()->addWidget(widget);
-
- QMeeGoGraphicsSystem::surfaceWasCreated = true;
- QWindowSurface *surface = new QGLWindowSurface(widget);
- return surface;
-}
-
-QPixmapData *QMeeGoGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- return new QRasterPixmapData(type);
-}
-
-QPixmapData *QMeeGoGraphicsSystem::createPixmapData(QPixmapData *origin)
-{
- // If the pixmap is a raster type...
- // and if the pixmap pointer matches our mapping...
- // create a shared image instead with the given handle.
-
- if (!origin->isNull() && origin->classId() == QPixmapData::RasterClass) {
- QRasterPixmapData *rasterClass = static_cast <QRasterPixmapData *> (origin);
- void *rawResource = static_cast <void *> (rasterClass->buffer()->data_ptr()->data);
-
- if (QMeeGoPixmapData::sharedImagesMap.contains(rawResource))
- return new QMeeGoPixmapData();
- }
-
- return new QRasterPixmapData(origin->pixelType());
-}
-
-QPixmapData* QMeeGoGraphicsSystem::wrapPixmapData(QPixmapData *pmd)
-{
- QString name = QApplicationPrivate::instance()->graphics_system_name;
- if (name == "runtime") {
- QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
- QRuntimePixmapData *rt = new QRuntimePixmapData(rsystem, pmd->pixelType());;
- rt->m_data = pmd;
- rt->readBackInfo();
- rsystem->m_pixmapDatas << rt;
- return rt;
- } else
- return pmd;
-}
-
-void QMeeGoGraphicsSystem::setSurfaceFixedSize(int /*width*/, int /*height*/)
-{
- if (QMeeGoGraphicsSystem::surfaceWasCreated) {
- qWarning("Trying to set surface fixed size but surface already created!");
- return;
- }
-
-#ifdef QT_WAS_PATCHED
- QEglProperties *properties = new QEglProperties();
- properties->setValue(EGL_FIXED_WIDTH_NOK, width);
- properties->setValue(EGL_FIXED_HEIGHT_NOK, height);
- QGLContextPrivate::setExtraWindowSurfaceCreationProps(properties);
-#endif
-}
-
-void QMeeGoGraphicsSystem::setSurfaceScaling(int x, int y, int width, int height)
-{
- QMeeGoExtensions::ensureInitialized();
- QMeeGoExtensions::eglSetSurfaceScalingNOK(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->currentSurface, x, y, width, height);
-}
-
-void QMeeGoGraphicsSystem::setTranslucent(bool translucent)
-{
- if (QMeeGoGraphicsSystem::surfaceWasCreated) {
- qWarning("Trying to set translucency but surface already created!");
- return;
- }
-
- QGLWindowSurface::surfaceFormat.setSampleBuffers(false);
- QGLWindowSurface::surfaceFormat.setSamples(0);
- QGLWindowSurface::surfaceFormat.setAlpha(translucent);
-}
-
-QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage)
-{
- if (softImage.format() != QImage::Format_ARGB32_Premultiplied &&
- softImage.format() != QImage::Format_RGB32) {
- qFatal("For egl shared images, the soft image has to be ARGB32_Premultiplied or RGB32");
- return NULL;
- }
-
- if (QMeeGoGraphicsSystem::meeGoRunning()) {
- QMeeGoPixmapData *pmd = new QMeeGoPixmapData;
- pmd->fromEGLSharedImage(handle, softImage);
- return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
- } else {
- QRasterPixmapData *pmd = new QRasterPixmapData(QPixmapData::PixmapType);
- pmd->fromImage(softImage, Qt::NoFormatConversion);
-
- // Make sure that the image was not converted in any way
- if (pmd->buffer()->data_ptr()->data !=
- const_cast<QImage &>(softImage).data_ptr()->data)
- qFatal("Iternal misalignment of raster data detected. Prolly a QImage copy fail.");
-
- QMeeGoPixmapData::registerSharedImage(handle, softImage);
- return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
- }
-}
-
-void QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(QPixmap *pixmap)
-{
- QMeeGoPixmapData *pmd = (QMeeGoPixmapData *) pixmap->pixmapData();
-
- // Basic sanity check to make sure this is really a QMeeGoPixmapData...
- if (pmd->classId() != QPixmapData::OpenGLClass)
- qFatal("Trying to updated EGLSharedImage pixmap but it's not really a shared image pixmap!");
-
- pmd->updateFromSoftImage();
-}
-
-QPixmapData *QMeeGoGraphicsSystem::pixmapDataWithGLTexture(int w, int h)
-{
- QGLPixmapData *pmd = new QGLPixmapData(QPixmapData::PixmapType);
- pmd->resize(w, h);
- return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
-}
-
-bool QMeeGoGraphicsSystem::meeGoRunning()
-{
- return runningGraphicsSystemName() == "meego";
-}
-
-QPixmapData* QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format)
-{
- return new QMeeGoLivePixmapData(w, h, format);
-}
-
-QPixmapData* QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(Qt::HANDLE handle)
-{
- return new QMeeGoLivePixmapData(handle);
-}
-
-QImage* QMeeGoGraphicsSystem::lockLiveTexture(QPixmap* pixmap, void* fenceSync)
-{
- QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
- return pixmapData->lock(fenceSync);
-}
-
-bool QMeeGoGraphicsSystem::releaseLiveTexture(QPixmap *pixmap, QImage *image)
-{
- QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
- return pixmapData->release(image);
-}
-
-Qt::HANDLE QMeeGoGraphicsSystem::getLiveTextureHandle(QPixmap *pixmap)
-{
- QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
- return pixmapData->handle();
-}
-
-void* QMeeGoGraphicsSystem::createFenceSync()
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
- return QMeeGoExtensions::eglCreateSyncKHR(QEgl::display(), EGL_SYNC_FENCE_KHR, NULL);
-}
-
-void QMeeGoGraphicsSystem::destroyFenceSync(void *fenceSync)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
- QMeeGoExtensions::eglDestroySyncKHR(QEgl::display(), fenceSync);
-}
-
-QString QMeeGoGraphicsSystem::runningGraphicsSystemName()
-{
- if (!QApplicationPrivate::instance()) {
- qWarning("Querying graphics system but application not running yet!");
- return QString();
- }
-
- QString name = QApplicationPrivate::instance()->graphics_system_name;
- if (name == QLatin1String("runtime")) {
- QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
- name = rsystem->graphicsSystemName();
- }
-
- return name;
-}
-
-void QMeeGoGraphicsSystem::switchToMeeGo()
-{
- if (switchPolicy == NoSwitch || meeGoRunning())
- return;
-
- if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime"))
- qWarning("Can't switch to meego - switching only supported with 'runtime' graphics system.");
- else {
- triggerSwitchCallbacks(0, "meego");
-
- QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
- app->setGraphicsSystem(QLatin1String("meego"));
-
- triggerSwitchCallbacks(1, "meego");
- }
-}
-
-void QMeeGoGraphicsSystem::switchToRaster()
-{
- if (switchPolicy == NoSwitch || runningGraphicsSystemName() == QLatin1String("raster"))
- return;
-
- if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime"))
- qWarning("Can't switch to raster - switching only supported with 'runtime' graphics system.");
- else {
- triggerSwitchCallbacks(0, "raster");
-
- QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
- app->setGraphicsSystem(QLatin1String("raster"));
-
- QMeeGoLivePixmapData::invalidateSurfaces();
-
- triggerSwitchCallbacks(1, "raster");
- }
-}
-
-void QMeeGoGraphicsSystem::registerSwitchCallback(QMeeGoSwitchCallback callback)
-{
- switchCallbacks << callback;
-}
-
-void QMeeGoGraphicsSystem::triggerSwitchCallbacks(int type, const char *name)
-{
- for (int i = 0; i < switchCallbacks.size(); ++i)
- switchCallbacks.at(i)(type, name);
-}
-
-/* C API */
-
-int qt_meego_image_to_egl_shared_image(const QImage &image)
-{
- return QMeeGoPixmapData::imageToEGLSharedImage(image);
-}
-
-QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage)
-{
- return QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(handle, softImage);
-}
-
-QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h)
-{
- return QMeeGoGraphicsSystem::pixmapDataWithGLTexture(w, h);
-}
-
-bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle)
-{
- return QMeeGoPixmapData::destroyEGLSharedImage(handle);
-}
-
-void qt_meego_set_surface_fixed_size(int width, int height)
-{
- QMeeGoGraphicsSystem::setSurfaceFixedSize(width, height);
-}
-
-void qt_meego_set_surface_scaling(int x, int y, int width, int height)
-{
- QMeeGoGraphicsSystem::setSurfaceScaling(x, y, width, height);
-}
-
-void qt_meego_set_translucent(bool translucent)
-{
- QMeeGoGraphicsSystem::setTranslucent(translucent);
-}
-
-void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap)
-{
- QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(pixmap);
-}
-
-QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format)
-{
- return QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(w, h, format);
-}
-
-QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle)
-{
- return QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(handle);
-}
-
-QImage* qt_meego_live_texture_lock(QPixmap *pixmap, void *fenceSync)
-{
- return QMeeGoGraphicsSystem::lockLiveTexture(pixmap, fenceSync);
-}
-
-bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image)
-{
- return QMeeGoGraphicsSystem::releaseLiveTexture(pixmap, image);
-}
-
-Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap)
-{
- return QMeeGoGraphicsSystem::getLiveTextureHandle(pixmap);
-}
-
-void* qt_meego_create_fence_sync(void)
-{
- return QMeeGoGraphicsSystem::createFenceSync();
-}
-
-void qt_meego_destroy_fence_sync(void* fs)
-{
- return QMeeGoGraphicsSystem::destroyFenceSync(fs);
-}
-
-void qt_meego_invalidate_live_surfaces(void)
-{
- return QMeeGoLivePixmapData::invalidateSurfaces();
-}
-
-void qt_meego_switch_to_raster(void)
-{
- QMeeGoGraphicsSystem::switchToRaster();
-}
-
-void qt_meego_switch_to_meego(void)
-{
- QMeeGoGraphicsSystem::switchToMeeGo();
-}
-
-void qt_meego_register_switch_callback(QMeeGoSwitchCallback callback)
-{
- QMeeGoGraphicsSystem::registerSwitchCallback(callback);
-}
-
-void qt_meego_set_switch_policy(int policy)
-{
- QMeeGoGraphicsSystem::switchPolicy = QMeeGoGraphicsSystem::SwitchPolicy(policy);
-}
-
-#include "qmeegographicssystem.moc"
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
deleted file mode 100644
index 7299af56be..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MGRAPHICSSYSTEM_H
-#define MGRAPHICSSYSTEM_H
-
-#include <private/qgraphicssystem_p.h>
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-extern "C" typedef void (*QMeeGoSwitchCallback)(int type, const char *name);
-
-class QMeeGoGraphicsSystem : public QGraphicsSystem
-{
-public:
- enum SwitchPolicy { AutomaticSwitch, ManualSwitch, NoSwitch };
-
- QMeeGoGraphicsSystem();
- ~QMeeGoGraphicsSystem();
-
- virtual QWindowSurface *createWindowSurface(QWidget *widget) const;
- virtual QPixmapData *createPixmapData(QPixmapData::PixelType) const;
- virtual QPixmapData *createPixmapData(QPixmapData *origin);
-
- static QPixmapData *wrapPixmapData(QPixmapData *pmd);
- static void setSurfaceFixedSize(int width, int height);
- static void setSurfaceScaling(int x, int y, int width, int height);
- static void setTranslucent(bool translucent);
-
- static QPixmapData *pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
- static QPixmapData *pixmapDataFromEGLImage(Qt::HANDLE handle);
- static QPixmapData *pixmapDataWithGLTexture(int w, int h);
- static void updateEGLSharedImagePixmap(QPixmap *pixmap);
-
- static QPixmapData *pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format);
- static QPixmapData *pixmapDataFromLiveTextureHandle(Qt::HANDLE handle);
- static QImage *lockLiveTexture(QPixmap* pixmap, void* fenceSync);
- static bool releaseLiveTexture(QPixmap *pixmap, QImage *image);
- static Qt::HANDLE getLiveTextureHandle(QPixmap *pixmap);
-
- static void* createFenceSync();
- static void destroyFenceSync(void* fenceSync);
-
- static void switchToRaster();
- static void switchToMeeGo();
- static QString runningGraphicsSystemName();
-
- static void registerSwitchCallback(QMeeGoSwitchCallback callback);
-
- static SwitchPolicy switchPolicy;
-
-private:
- static bool meeGoRunning();
- static EGLSurface getSurfaceForLiveTexturePixmap(QPixmap *pixmap);
- static void destroySurfaceForLiveTexturePixmap(QPixmapData* pmd);
- static void triggerSwitchCallbacks(int type, const char *name);
-
- static bool surfaceWasCreated;
- static QHash<Qt::HANDLE, QPixmap*> liveTexturePixmaps;
- static QList<QMeeGoSwitchCallback> switchCallbacks;
-};
-
-/* C api */
-
-extern "C" {
- Q_DECL_EXPORT int qt_meego_image_to_egl_shared_image(const QImage &image);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h);
- Q_DECL_EXPORT void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap);
- Q_DECL_EXPORT bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle);
- Q_DECL_EXPORT void qt_meego_set_surface_fixed_size(int width, int height);
- Q_DECL_EXPORT void qt_meego_set_surface_scaling(int x, int y, int width, int height);
- Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle);
- Q_DECL_EXPORT QImage* qt_meego_live_texture_lock(QPixmap *pixmap, void *fenceSync);
- Q_DECL_EXPORT bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image);
- Q_DECL_EXPORT Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap);
- Q_DECL_EXPORT void* qt_meego_create_fence_sync(void);
- Q_DECL_EXPORT void qt_meego_destroy_fence_sync(void* fs);
- Q_DECL_EXPORT void qt_meego_invalidate_live_surfaces(void);
- Q_DECL_EXPORT void qt_meego_switch_to_raster(void);
- Q_DECL_EXPORT void qt_meego_switch_to_meego(void);
- Q_DECL_EXPORT void qt_meego_register_switch_callback(QMeeGoSwitchCallback callback);
- Q_DECL_EXPORT void qt_meego_set_switch_policy(int policy);
-}
-
-#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
deleted file mode 100644
index 40421bc8f0..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmeegolivepixmapdata.h"
-#include "qmeegorasterpixmapdata.h"
-#include <private/qimage_p.h>
-#include <private/qwindowsurface_gl_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_runtime_p.h>
-#include <private/qpixmap_x11_p.h>
-#include <stdio.h>
-
-static QMeeGoLivePixmapDataList all_live_pixmaps;
-
-static EGLint lock_attribs[] = {
- EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE,
- EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR,
- EGL_NONE
-};
-
-static EGLint preserved_attribs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_NONE
-};
-
-// as copied from qwindowsurface.cpp
-void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
-{
- // make sure we don't detach
- uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits());
-
- int lineskip = img.bytesPerLine();
- int depth = img.depth() >> 3;
-
- const QRect imageRect(0, 0, img.width(), img.height());
- const QRect r = rect & imageRect & imageRect.translated(-offset);
- const QPoint p = rect.topLeft() + offset;
-
- if (r.isEmpty())
- return;
-
- const uchar *src;
- uchar *dest;
-
- if (r.top() < p.y()) {
- src = mem + r.bottom() * lineskip + r.left() * depth;
- dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth;
- lineskip = -lineskip;
- } else {
- src = mem + r.top() * lineskip + r.left() * depth;
- dest = mem + p.y() * lineskip + p.x() * depth;
- }
-
- const int w = r.width();
- int h = r.height();
- const int bytes = w * depth;
-
- // overlapping segments?
- if (offset.y() == 0 && qAbs(offset.x()) < w) {
- do {
- ::memmove(dest, src, bytes);
- dest += lineskip;
- src += lineskip;
- } while (--h);
- } else {
- do {
- ::memcpy(dest, src, bytes);
- dest += lineskip;
- src += lineskip;
- } while (--h);
- }
-}
-
-/* Public */
-
-QMeeGoLivePixmapData::QMeeGoLivePixmapData(int w, int h, QImage::Format format) : QGLPixmapData(QPixmapData::PixmapType)
-{
- QImage image(w, h, format);
- QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
- pmd->fromImage(image, Qt::NoOpaqueDetection);
- backingX11Pixmap = new QPixmap(pmd);
-
- initializeThroughEGLImage();
-
- pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
-}
-
-QMeeGoLivePixmapData::QMeeGoLivePixmapData(Qt::HANDLE h) : QGLPixmapData(QPixmapData::PixmapType)
-{
- backingX11Pixmap = new QPixmap(QPixmap::fromX11Pixmap(h));
- initializeThroughEGLImage();
-
- pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
-}
-
-QMeeGoLivePixmapData::~QMeeGoLivePixmapData()
-{
- delete backingX11Pixmap;
- all_live_pixmaps.erase(pos);
-}
-
-void QMeeGoLivePixmapData::initializeThroughEGLImage()
-{
- if (texture()->id != 0)
- return;
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- EGLImageKHR eglImage = EGL_NO_IMAGE_KHR;
- GLuint newTextureId = 0;
-
- eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer) backingX11Pixmap->handle(), preserved_attribs);
-
- if (eglImage == EGL_NO_IMAGE_KHR) {
- qWarning("eglCreateImageKHR failed (live texture)!");
- return;
- }
-
- glGenTextures(1, &newTextureId);
- glBindTexture(GL_TEXTURE_2D, newTextureId);
-
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (EGLImageKHR) eglImage);
- if (glGetError() == GL_NO_ERROR) {
- resize(backingX11Pixmap->width(), backingX11Pixmap->height());
- texture()->id = newTextureId;
- texture()->options &= ~QGLContext::InvertedYBindOption;
- m_hasAlpha = backingX11Pixmap->hasAlphaChannel();
- } else {
- qWarning("Failed to create a texture from an egl image (live texture)!");
- glDeleteTextures(1, &newTextureId);
- }
-
- QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
-}
-
-QPixmapData *QMeeGoLivePixmapData::createCompatiblePixmapData() const
-{
- qWarning("Create compatible called on live pixmap! Expect fail soon...");
- return new QMeeGoRasterPixmapData(pixelType());
-}
-
-QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- if (fenceSync) {
- QMeeGoExtensions::eglClientWaitSyncKHR(QEgl::display(),
- fenceSync,
- EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
- EGL_FOREVER_KHR);
- }
-
- void *data = 0;
- int pitch = 0;
- int surfaceWidth = 0;
- int surfaceHeight = 0;
- EGLSurface surface = 0;
- QImage::Format format;
- lockedImage = QImage();
-
- surface = getSurfaceForBackingPixmap();
- if (! QMeeGoExtensions::eglLockSurfaceKHR(QEgl::display(), surface, lock_attribs)) {
- qWarning("Failed to lock surface (live texture)!");
- return &lockedImage;
- }
-
- eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) &data);
- eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) &pitch);
- eglQuerySurface(QEgl::display(), surface, EGL_WIDTH, (EGLint*) &surfaceWidth);
- eglQuerySurface(QEgl::display(), surface, EGL_HEIGHT, (EGLint*) &surfaceHeight);
-
- // Ok, here we know we just support those two formats. Real solution would be:
- // query also the format.
- if (backingX11Pixmap->depth() > 16)
- format = QImage::Format_ARGB32_Premultiplied;
- else
- format = QImage::Format_RGB16;
-
- if (data == NULL || pitch == 0) {
- qWarning("Failed to query the live texture!");
- return &lockedImage;
- }
-
- if (width() != surfaceWidth || height() != surfaceHeight) {
- qWarning("Live texture dimensions don't match!");
- QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface);
- return &lockedImage;
- }
-
- lockedImage = QImage((uchar *) data, width(), height(), pitch, format);
- return &lockedImage;
-}
-
-bool QMeeGoLivePixmapData::release(QImage* /*img*/)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- if (QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), getSurfaceForBackingPixmap())) {
- lockedImage = QImage();
- return true;
- } else {
- lockedImage = QImage();
- return false;
- }
-}
-
-Qt::HANDLE QMeeGoLivePixmapData::handle()
-{
- return backingX11Pixmap->handle();
-}
-
-bool QMeeGoLivePixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- lock(NULL);
-
- if (!lockedImage.isNull())
- qt_scrollRectInImage(lockedImage, rect, QPoint(dx, dy));
-
- release(&lockedImage);
- return true;
-}
-
-EGLSurface QMeeGoLivePixmapData::getSurfaceForBackingPixmap()
-{
- initializeThroughEGLImage();
-
- // This code is a crative remix of the stuff that can be found in the
- // Qt's TFP implementation in /src/opengl/qgl_x11egl.cpp ::bindiTextureFromNativePixmap
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(backingX11Pixmap->data_ptr().data());
- Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
- bool hasAlpha = pixmapData->hasAlphaChannel();
-
- if (pixmapData->gl_surface &&
- hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- return pixmapData->gl_surface;
-
- // Check to see if the surface is still valid
- if (pixmapData->gl_surface &&
- hasAlpha != ((pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha) > 0)) {
- // Surface is invalid!
- destroySurfaceForPixmapData(pixmapData);
- }
-
- if (pixmapData->gl_surface == 0) {
- EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
- QEgl::OpenGL,
- hasAlpha ? QEgl::Translucent : QEgl::NoOptions);
-
- pixmapData->gl_surface = (void*)QEgl::createSurface(backingX11Pixmap, config);
-
- if (hasAlpha)
- pixmapData->flags |= QX11PixmapData::GlSurfaceCreatedWithAlpha;
- else
- pixmapData->flags &= ~QX11PixmapData::GlSurfaceCreatedWithAlpha;
-
- if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE)
- return NULL;
- }
-
- return pixmapData->gl_surface;
-}
-
-void QMeeGoLivePixmapData::destroySurfaceForPixmapData(QPixmapData* pmd)
-{
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- pixmapData->gl_surface = 0;
- }
-}
-
-void QMeeGoLivePixmapData::invalidateSurfaces()
-{
- foreach (QMeeGoLivePixmapData *data, all_live_pixmaps) {
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(data->backingX11Pixmap->data_ptr().data());
- *data->texture() = QGLTexture();
- pixmapData->gl_surface = 0;
- }
-}
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
deleted file mode 100644
index 73f75143e3..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MLIVEPIXMAPDATA_H
-#define MLIVEPIXMAPDATA_H
-
-#include <QLinkedList>
-#include <private/qpixmapdata_gl_p.h>
-#include "qmeegoextensions.h"
-
-class QMeeGoLivePixmapData;
-typedef QLinkedList<QMeeGoLivePixmapData *> QMeeGoLivePixmapDataList;
-
-class QMeeGoLivePixmapData : public QGLPixmapData
-{
-public:
- QMeeGoLivePixmapData(int w, int h, QImage::Format format);
- QMeeGoLivePixmapData(Qt::HANDLE h);
- ~QMeeGoLivePixmapData();
-
- QPixmapData *createCompatiblePixmapData() const;
- bool scroll(int dx, int dy, const QRect &rect);
-
- void initializeThroughEGLImage();
-
- QImage* lock(EGLSyncKHR fenceSync);
- bool release(QImage *img);
- Qt::HANDLE handle();
-
- EGLSurface getSurfaceForBackingPixmap();
- void destroySurfaceForPixmapData(QPixmapData* pmd);
-
- QPixmap *backingX11Pixmap;
- QImage lockedImage;
- QMeeGoLivePixmapDataList::Iterator pos;
-
- static void invalidateSurfaces();
-};
-
-#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
deleted file mode 100644
index ec6c33fa07..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmeegopixmapdata.h"
-#include "qmeegoextensions.h"
-#include "qmeegorasterpixmapdata.h"
-#include <private/qimage_p.h>
-#include <private/qwindowsurface_gl_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_runtime_p.h>
-
-// from dithering.cpp
-extern unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int height, int stride);
-extern unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, int height, int stride);
-extern unsigned char* convertBGRA32_to_RGBA32(const unsigned char *in, int width, int height, int stride);
-
-static EGLint preserved_image_attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
-
-QHash <void*, QMeeGoImageInfo*> QMeeGoPixmapData::sharedImagesMap;
-
-/* Public */
-
-QMeeGoPixmapData::QMeeGoPixmapData() : QGLPixmapData(QPixmapData::PixmapType)
-{
-}
-
-void QMeeGoPixmapData::fromTexture(GLuint textureId, int w, int h, bool alpha)
-{
- resize(w, h);
- texture()->id = textureId;
- m_hasAlpha = alpha;
- softImage = QImage();
-}
-
-QImage QMeeGoPixmapData::toImage() const
-{
- return softImage;
-}
-
-void QMeeGoPixmapData::fromImage(const QImage &image,
- Qt::ImageConversionFlags flags)
-{
- void *rawResource = static_cast <void *> (((QImage &) image).data_ptr()->data);
-
- if (sharedImagesMap.contains(rawResource)) {
- QMeeGoImageInfo *info = sharedImagesMap.value(rawResource);
- fromEGLSharedImage(info->handle, image);
- } else {
- // This should *never* happen since the graphics system should never
- // create a QMeeGoPixmapData for an origin that doesn't contain a raster
- // image we know about. But...
- qWarning("QMeeGoPixmapData::fromImage called on non-know resource. Falling back...");
- QGLPixmapData::fromImage(image, flags);
- }
-}
-
-void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si)
-{
- if (si.isNull())
- qFatal("Trying to build pixmap with an empty/null softimage!");
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
-
- QMeeGoExtensions::ensureInitialized();
-
- bool textureIsBound = false;
- GLuint newTextureId;
- GLint newWidth, newHeight;
-
- glGenTextures(1, &newTextureId);
- glBindTexture(GL_TEXTURE_2D, newTextureId);
-
- EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_SHARED_IMAGE_NOK,
- (EGLClientBuffer)handle, preserved_image_attribs);
-
- if (image != EGL_NO_IMAGE_KHR) {
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
- GLint err = glGetError();
- if (err == GL_NO_ERROR)
- textureIsBound = true;
-
- QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_WIDTH, &newWidth);
- QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_HEIGHT, &newHeight);
-
- QEgl::eglDestroyImageKHR(QEgl::display(), image);
- }
-
- if (textureIsBound) {
- fromTexture(newTextureId, newWidth, newHeight,
- (si.hasAlphaChannel() && const_cast<QImage &>(si).data_ptr()->checkForAlphaPixels()));
- texture()->options &= ~QGLContext::InvertedYBindOption;
- softImage = si;
- QMeeGoPixmapData::registerSharedImage(handle, softImage);
- } else {
- qWarning("Failed to create a texture from a shared image!");
- glDeleteTextures(1, &newTextureId);
- }
-}
-
-Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
-
- QMeeGoExtensions::ensureInitialized();
-
- GLuint textureId;
-
- glGenTextures(1, &textureId);
- glBindTexture(GL_TEXTURE_2D, textureId);
- if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) {
- void *converted = convertBGRA32_to_RGBA32(image.bits(), image.width(), image.height(), image.bytesPerLine());
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, converted);
- free(converted);
- } else {
- void *converted = convertRGB32_to_RGB565(image.bits(), image.width(), image.height(), image.bytesPerLine());
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, converted);
- free(converted);
- }
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- glBindTexture(GL_TEXTURE_2D, textureId);
- EGLImageKHR eglimage = QEgl::eglCreateImageKHR(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->context(),
- EGL_GL_TEXTURE_2D_KHR,
- (EGLClientBuffer) textureId,
- preserved_image_attribs);
- glDeleteTextures(1, &textureId);
- if (eglimage) {
- EGLNativeSharedImageTypeNOK handle = QMeeGoExtensions::eglCreateSharedImageNOK(QEgl::display(), eglimage, NULL);
- QEgl::eglDestroyImageKHR(QEgl::display(), eglimage);
- return (Qt::HANDLE) handle;
- } else {
- qWarning("Failed to create shared image from pixmap/texture!");
- return 0;
- }
-}
-
-void QMeeGoPixmapData::updateFromSoftImage()
-{
- // FIXME That's broken with recent 16bit textures changes.
- m_dirty = true;
- m_source = softImage;
- ensureCreated();
-
- if (softImage.width() != w || softImage.height() != h)
- qWarning("Ooops, looks like softImage changed dimensions since last updated! Corruption ahead?!");
-}
-
-bool QMeeGoPixmapData::destroyEGLSharedImage(Qt::HANDLE h)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- QMutableHashIterator <void*, QMeeGoImageInfo*> i(sharedImagesMap);
- while (i.hasNext()) {
- i.next();
- if (i.value()->handle == h)
- i.remove();
- }
-
- return QMeeGoExtensions::eglDestroySharedImageNOK(QEgl::display(), (EGLNativeSharedImageTypeNOK) h);
-}
-
-void QMeeGoPixmapData::registerSharedImage(Qt::HANDLE handle, const QImage &si)
-{
- void *raw = static_cast <void *> (((QImage) si).data_ptr()->data);
- QMeeGoImageInfo *info;
-
- if (! sharedImagesMap.contains(raw)) {
- info = new QMeeGoImageInfo;
- info->handle = handle;
- info->rawFormat = si.format();
- sharedImagesMap.insert(raw, info);
- } else {
- info = sharedImagesMap.value(raw);
- if (info->handle != handle || info->rawFormat != si.format())
- qWarning("Inconsistency detected: overwriting entry in sharedImagesMap but handle/format different");
- }
-}
-
-QPixmapData *QMeeGoPixmapData::createCompatiblePixmapData() const
-{
- return new QMeeGoRasterPixmapData(pixelType());
-}
diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
deleted file mode 100644
index f1ff255b08..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MPIXMAPDATA_H
-#define MPIXMAPDATA_H
-
-#include <private/qpixmapdata_gl_p.h>
-
-struct QMeeGoImageInfo
-{
- Qt::HANDLE handle;
- QImage::Format rawFormat;
-};
-
-class QMeeGoPixmapData : public QGLPixmapData
-{
-public:
- QMeeGoPixmapData();
- void fromTexture(GLuint textureId, int w, int h, bool alpha);
- QPixmapData *createCompatiblePixmapData() const;
-
- virtual void fromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
- virtual void fromImage (const QImage &image, Qt::ImageConversionFlags flags);
- virtual QImage toImage() const;
- virtual void updateFromSoftImage();
-
- QImage softImage;
-
- static QHash <void*, QMeeGoImageInfo*> sharedImagesMap;
-
- static Qt::HANDLE imageToEGLSharedImage(const QImage &image);
- static bool destroyEGLSharedImage(Qt::HANDLE h);
- static void registerSharedImage(Qt::HANDLE handle, const QImage &si);
-};
-
-#endif
diff --git a/src/plugins/graphicssystems/opengl/opengl.pro b/src/plugins/graphicssystems/opengl/opengl.pro
deleted file mode 100644
index fd3542ecf0..0000000000
--- a/src/plugins/graphicssystems/opengl/opengl.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qglgraphicssystem
-load(qt_plugin)
-
-QT += core-private gui-private opengl-private
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-SOURCES = main.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
-
-symbian: TARGET.UID3 = 0x2002131B
diff --git a/src/plugins/graphicssystems/openvg/openvg.pro b/src/plugins/graphicssystems/openvg/openvg.pro
deleted file mode 100644
index 6a737790a2..0000000000
--- a/src/plugins/graphicssystems/openvg/openvg.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qvggraphicssystem
-load(qt_plugin)
-
-QT += openvg
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-SOURCES = main.cpp qgraphicssystem_vg.cpp
-HEADERS = qgraphicssystem_vg_p.h
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
-
-symbian: TARGET.UID3 = 0x2001E62C
diff --git a/src/plugins/graphicssystems/shivavg/README b/src/plugins/graphicssystems/shivavg/README
deleted file mode 100644
index 15ee7101e8..0000000000
--- a/src/plugins/graphicssystems/shivavg/README
+++ /dev/null
@@ -1,8 +0,0 @@
-
-This graphics system uses ShivaVG (http://sourceforge.net/projects/shivavg)
-to perform OpenVG rendering on X11 systems. The graphics system name for
-the "-graphicssystem" command-line option is "ShivaVG".
-
-ShivaVG support is experimental, mostly to demonstrate how to integrate
-non-EGL OpenVG engines into the system. It will probably not produce
-good output.
diff --git a/src/plugins/graphicssystems/shivavg/shivavg.pro b/src/plugins/graphicssystems/shivavg/shivavg.pro
deleted file mode 100644
index 1d934cd685..0000000000
--- a/src/plugins/graphicssystems/shivavg/shivavg.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-TARGET = qshivavggraphicssystem
-load(qt_plugin)
-
-QT += openvg
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-SOURCES = main.cpp shivavggraphicssystem.cpp shivavgwindowsurface.cpp
-HEADERS = shivavggraphicssystem.h shivavgwindowsurface.h
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
diff --git a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp b/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp
deleted file mode 100644
index 448532ae92..0000000000
--- a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define GL_GLEXT_PROTOTYPES
-#include "shivavgwindowsurface.h"
-#include <QtOpenVG/private/qpaintengine_vg_p.h>
-#if defined(Q_WS_X11)
-#include "private/qt_x11_p.h"
-#include "qx11info_x11.h"
-#include <GL/glx.h>
-
-extern QX11Info *qt_x11Info(const QPaintDevice *pd);
-#endif
-
-// Define this to use framebuffer objects.
-//#define QVG_USE_FBO 1
-
-#include <vg/openvg.h>
-
-QT_BEGIN_NAMESPACE
-
-class QShivaContext
-{
-public:
- QShivaContext();
- ~QShivaContext();
-
- bool makeCurrent(ShivaVGWindowSurfacePrivate *surface);
- void doneCurrent();
-
- bool initialized;
- QSize currentSize;
- ShivaVGWindowSurfacePrivate *currentSurface;
-};
-
-Q_GLOBAL_STATIC(QShivaContext, shivaContext);
-
-class ShivaVGWindowSurfacePrivate
-{
-public:
- ShivaVGWindowSurfacePrivate()
- : isCurrent(false)
- , needsResize(true)
- , engine(0)
-#if defined(QVG_USE_FBO)
- , fbo(0)
- , texture(0)
-#endif
-#if defined(Q_WS_X11)
- , drawable(0)
- , context(0)
-#endif
- {
- }
- ~ShivaVGWindowSurfacePrivate();
-
- void ensureContext(QWidget *widget);
-
- QSize size;
- bool isCurrent;
- bool needsResize;
- QVGPaintEngine *engine;
-#if defined(QVG_USE_FBO)
- GLuint fbo;
- GLuint texture;
-#endif
-#if defined(Q_WS_X11)
- GLXDrawable drawable;
- GLXContext context;
-#endif
-};
-
-QShivaContext::QShivaContext()
- : initialized(false)
- , currentSurface(0)
-{
-}
-
-QShivaContext::~QShivaContext()
-{
- if (initialized)
- vgDestroyContextSH();
-}
-
-bool QShivaContext::makeCurrent(ShivaVGWindowSurfacePrivate *surface)
-{
- if (currentSurface)
- currentSurface->isCurrent = false;
- surface->isCurrent = true;
- currentSurface = surface;
- currentSize = surface->size;
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, surface->drawable, surface->context);
-#endif
- if (!initialized) {
- if (!vgCreateContextSH(currentSize.width(), currentSize.height())) {
- qWarning("vgCreateContextSH(%d, %d): could not create context", currentSize.width(), currentSize.height());
- return false;
- }
- initialized = true;
- } else {
- vgResizeSurfaceSH(currentSize.width(), currentSize.height());
- }
-#if defined(QVG_USE_FBO)
- if (surface->fbo)
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surface->fbo);
- else
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-#endif
- return true;
-}
-
-void QShivaContext::doneCurrent()
-{
- if (currentSurface) {
- currentSurface->isCurrent = false;
- currentSurface = 0;
- }
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, 0, 0);
-#endif
-}
-
-ShivaVGWindowSurfacePrivate::~ShivaVGWindowSurfacePrivate()
-{
-#if defined(QVG_USE_FBO)
- if (fbo) {
- glDeleteTextures(1, &texture);
- glDeleteFramebuffersEXT(1, &fbo);
- }
-#endif
-}
-
-void ShivaVGWindowSurfacePrivate::ensureContext(QWidget *widget)
-{
-#if defined(Q_WS_X11)
- Window win = widget->winId();
- if (win != drawable) {
- if (context)
- glXDestroyContext(X11->display, context);
- drawable = win;
- }
- if (context == 0) {
- const QX11Info *xinfo = qt_x11Info(widget);
- int spec[64];
- int i = 0;
- spec[i++] = GLX_DOUBLEBUFFER;
- spec[i++] = GLX_DEPTH_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_STENCIL_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_RGBA;
- spec[i++] = GLX_RED_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_GREEN_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_BLUE_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = 4;
- spec[i] = XNone;
- XVisualInfo *visual = glXChooseVisual
- (xinfo->display(), xinfo->screen(), spec);
- context = glXCreateContext(X11->display, visual, 0, True);
- if (!context)
- qWarning("glXCreateContext: could not create GL context for VG rendering");
- }
-#else
- Q_UNUSED(widget);
-#endif
-#if defined(QVG_USE_FBO)
- if (needsResize && fbo) {
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, drawable, context);
-#endif
- glDeleteTextures(1, &texture);
- glDeleteFramebuffersEXT(1, &fbo);
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, 0, 0);
-#endif
- fbo = 0;
- texture = 0;
- }
- if (!fbo) {
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, drawable, context);
-#endif
- glGenFramebuffersEXT(1, &fbo);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
-
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size.width(), size.height(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2DEXT
- (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
- texture, 0);
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, 0, 0);
-#endif
- }
-#endif
- needsResize = false;
-}
-
-ShivaVGWindowSurface::ShivaVGWindowSurface(QWidget *window)
- : QWindowSurface(window), d_ptr(new ShivaVGWindowSurfacePrivate)
-{
-}
-
-ShivaVGWindowSurface::~ShivaVGWindowSurface()
-{
- if (d_ptr->isCurrent) {
- shivaContext()->doneCurrent();
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
-#if defined(Q_WS_X11)
- if (d_ptr->context)
- glXDestroyContext(X11->display, d_ptr->context);
-#endif
- delete d_ptr;
-}
-
-QPaintDevice *ShivaVGWindowSurface::paintDevice()
-{
- d_ptr->ensureContext(window());
- shivaContext()->makeCurrent(d_ptr);
- glClearDepth(0.0f);
- glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- return this;
-}
-
-void ShivaVGWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(region);
- Q_UNUSED(offset);
- QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
- d_ptr->ensureContext(parent);
- QShivaContext *context = shivaContext();
- if (!d_ptr->isCurrent)
- context->makeCurrent(d_ptr);
-#if defined(QVG_USE_FBO)
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- if (d_ptr->fbo) {
- static GLfloat const vertices[][2] = {
- {-1, -1}, {1, -1}, {1, 1}, {-1, 1}
- };
- static GLfloat const texCoords[][2] = {
- {0, 0}, {1, 0}, {1, 1}, {0, 1}
- };
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
- glBindTexture(GL_TEXTURE_2D, d_ptr->texture);
- glEnable(GL_TEXTURE_2D);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-#endif
-#if defined(Q_WS_X11)
- glXSwapBuffers(X11->display, d_ptr->drawable);
-#endif
- context->doneCurrent();
-}
-
-void ShivaVGWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
- d_ptr->needsResize = true;
- d_ptr->size = rect.size();
-}
-
-bool ShivaVGWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- return QWindowSurface::scroll(area, dx, dy);
-}
-
-void ShivaVGWindowSurface::beginPaint(const QRegion &region)
-{
- // Nothing to do here.
- Q_UNUSED(region);
-}
-
-void ShivaVGWindowSurface::endPaint(const QRegion &region)
-{
- // Nothing to do here.
- Q_UNUSED(region);
-}
-
-Q_GLOBAL_STATIC(QVGPaintEngine, sharedPaintEngine);
-
-QPaintEngine *ShivaVGWindowSurface::paintEngine() const
-{
- if (!d_ptr->engine)
- d_ptr->engine = sharedPaintEngine();
- return d_ptr->engine;
-}
-
-int ShivaVGWindowSurface::metric(PaintDeviceMetric met) const
-{
- return qt_paint_device_metric(window(), met);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/trace/main.cpp b/src/plugins/graphicssystems/trace/main.cpp
deleted file mode 100644
index c0043a2cdd..0000000000
--- a/src/plugins/graphicssystems/trace/main.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qgraphicssystemplugin_p.h>
-#include "qgraphicssystem_trace_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QTraceGraphicsSystemPlugin : public QGraphicsSystemPlugin
-{
-public:
- QStringList keys() const;
- QGraphicsSystem *create(const QString&);
-};
-
-QStringList QTraceGraphicsSystemPlugin::keys() const
-{
- return QStringList(QLatin1String("Trace"));
-}
-
-QGraphicsSystem* QTraceGraphicsSystemPlugin::create(const QString& system)
-{
- if (system.toLower() == QLatin1String("trace"))
- return new QTraceGraphicsSystem;
-
- return 0;
-}
-
-Q_EXPORT_PLUGIN2(trace, QTraceGraphicsSystemPlugin)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp b/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp
deleted file mode 100644
index 502a198099..0000000000
--- a/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystem_trace_p.h"
-#include <private/qpixmap_raster_p.h>
-#include <private/qpaintbuffer_p.h>
-#include <private/qwindowsurface_raster_p.h>
-
-#include <QFile>
-#include <QPainter>
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-class QTraceWindowSurface : public QRasterWindowSurface
-{
-public:
- QTraceWindowSurface(QWidget *widget);
- ~QTraceWindowSurface();
-
- QPaintDevice *paintDevice();
- void beginPaint(const QRegion &rgn);
- void endPaint(const QRegion &rgn);
-
- bool scroll(const QRegion &area, int dx, int dy);
-
-private:
- QPaintBuffer *buffer;
- QList<QRegion> updates;
-
- qulonglong winId;
-};
-
-QTraceWindowSurface::QTraceWindowSurface(QWidget *widget)
- : QRasterWindowSurface(widget)
- , buffer(0)
- , winId(0)
-{
-}
-
-QTraceWindowSurface::~QTraceWindowSurface()
-{
- if (buffer) {
- QFile outputFile(QString(QLatin1String("qtgraphics-%0.trace")).arg(winId));
- if (outputFile.open(QIODevice::WriteOnly)) {
- QDataStream out(&outputFile);
- out.setFloatingPointPrecision(QDataStream::SinglePrecision);
-
- out.writeBytes("qttraceV2", 9);
-
- uint version = 1;
-
- out << version << *buffer << updates;
- }
- delete buffer;
- }
-}
-
-QPaintDevice *QTraceWindowSurface::paintDevice()
-{
- if (!buffer) {
- buffer = new QPaintBuffer;
-#ifdef Q_WS_QPA
- buffer->setBoundingRect(QRect(QPoint(), size()));
-#else
- buffer->setBoundingRect(geometry());
-#endif
- }
- return buffer;
-}
-
-void QTraceWindowSurface::beginPaint(const QRegion &rgn)
-{
- // ensure paint buffer is created
- paintDevice();
- buffer->beginNewFrame();
-
- QRasterWindowSurface::beginPaint(rgn);
-}
-
-void QTraceWindowSurface::endPaint(const QRegion &rgn)
-{
- QPainter p(QRasterWindowSurface::paintDevice());
- buffer->draw(&p, buffer->numFrames()-1);
- p.end();
-
- winId = (qulonglong)window()->winId();
-
- updates << rgn;
-
- QRasterWindowSurface::endPaint(rgn);
-}
-
-bool QTraceWindowSurface::scroll(const QRegion &, int, int)
-{
- // TODO: scrolling should also be streamed and replayed
- // to test scrolling performance
- return false;
-}
-
-QTraceGraphicsSystem::QTraceGraphicsSystem()
-{
-}
-
-QPixmapData *QTraceGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- return new QRasterPixmapData(type);
-}
-
-QWindowSurface *QTraceGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- return new QTraceWindowSurface(widget);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/trace/trace.pro b/src/plugins/graphicssystems/trace/trace.pro
deleted file mode 100644
index f44bb3211e..0000000000
--- a/src/plugins/graphicssystems/trace/trace.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qtracegraphicssystem
-load(qt_plugin)
-
-QT += core-private gui-private network
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-symbian:TARGET.UID3 = 0x2002130E
-
-SOURCES = main.cpp qgraphicssystem_trace.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
-INCLUDEPATH += ../../../3rdparty/harfbuzz/src
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index 5e1f16bad4..da6b8a75bc 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -589,7 +589,6 @@ QImage ICOReader::iconAt(int index)
mask.setColor(1, qRgba(0 ,0 ,0 ,0xff));
read1BitBMP(mask);
if (!mask.isNull()) {
- img = QImage(image.width(), image.height(), QImage::Format_ARGB32 );
img = image;
img.setAlphaChannel(mask);
// (Luckily, it seems that setAlphaChannel() does not ruin the alpha values
diff --git a/src/plugins/inputmethods/imsw-multi/imsw-multi.pro b/src/plugins/inputmethods/imsw-multi/imsw-multi.pro
deleted file mode 100644
index 4c7b9b96d8..0000000000
--- a/src/plugins/inputmethods/imsw-multi/imsw-multi.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qimsw-multi
-load(qt_plugin)
-CONFIG += warn_on
-
-DESTDIR = $$QT.gui.plugins/inputmethods
-
-HEADERS += qmultiinputcontext.h \
- qmultiinputcontextplugin.h
-SOURCES += qmultiinputcontext.cpp \
- qmultiinputcontextplugin.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/inputmethods
-INSTALLS += target
diff --git a/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp b/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp
deleted file mode 100644
index 258d586564..0000000000
--- a/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Implementation of QMultiInputContext class
-**
-** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** licence. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QT_NO_IM
-#include "qmultiinputcontext.h"
-#include <qinputcontextfactory.h>
-#include <qstringlist.h>
-#include <qaction.h>
-#include <qsettings.h>
-#include <qmenu.h>
-
-#include <stdlib.h>
-
-QT_BEGIN_NAMESPACE
-
-QMultiInputContext::QMultiInputContext()
- : QInputContext(), current(-1)
-{
- keys = QInputContextFactory::keys();
- for (int i = keys.size()-1; i >= 0; --i)
- if (keys.at(i).contains(QLatin1String("imsw")))
- keys.removeAt(i);
-
- QString def = QLatin1String(getenv("QT4_IM_MODULE"));
- if (def.isEmpty())
- def = QLatin1String(getenv("QT_IM_MODULE"));
- if (def.isEmpty()) {
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
- def = settings.value(QLatin1String("DefaultInputMethod"), QLatin1String("xim")).toString();
- }
- current = keys.indexOf(def);
- if (current < 0)
- current = 0;
-
- menu = new QMenu(tr("Select IM"));
- separator = new QAction(this);
- separator->setSeparator(true);
-
- QActionGroup *group = new QActionGroup(this);
- for (int i = 0; i < keys.size(); ++i) {
- slaves.append(0);
- const QString key = keys.at(i);
- QAction *a = menu->addAction(QInputContextFactory::displayName(key));
- a->setData(key);
- a->setCheckable(true);
- group->addAction(a);
- if (i == current) {
- slaves.replace(current, QInputContextFactory::create(key, this));
- a->setChecked(true);
- }
- }
- connect(group, SIGNAL(triggered(QAction*)), this, SLOT(changeSlave(QAction*)));
-}
-
-QMultiInputContext::~QMultiInputContext()
-{
- delete menu;
-}
-
-
-QString QMultiInputContext::identifierName()
-{
- return (slave()) ? slave()->identifierName() : QLatin1String("");
-}
-
-QString QMultiInputContext::language()
-{
- return (slave()) ? slave()->language() : QLatin1String("");
-}
-
-
-#if defined(Q_WS_X11)
-bool QMultiInputContext::x11FilterEvent(QWidget *keywidget, XEvent *event)
-{
- return (slave()) ? slave()->x11FilterEvent(keywidget, event) : false;
-}
-#endif // Q_WS_X11
-
-
-bool QMultiInputContext::filterEvent(const QEvent *event)
-{
- return (slave()) ? slave()->filterEvent(event) : false;
-}
-
-void QMultiInputContext::reset()
-{
- if (slave())
- slave()->reset();
-}
-
-void QMultiInputContext::update()
-{
- if (slave())
- slave()->update();
-}
-
-void QMultiInputContext::mouseHandler(int x, QMouseEvent *event)
-{
- if (slave())
- slave()->mouseHandler(x, event);
-}
-
-QFont QMultiInputContext::font() const
-{
- return (slave()) ? slave()->font() : QInputContext::font();
-}
-
-void QMultiInputContext::setFocusWidget(QWidget *w)
-{
- QInputContext::setFocusWidget(w);
- if (slave())
- slave()->setFocusWidget(w);
-}
-
-QWidget *QMultiInputContext::focusWidget() const
-{
- return QInputContext::focusWidget();
-}
-
-void QMultiInputContext::widgetDestroyed(QWidget *w)
-{
- if (slave())
- slave()->widgetDestroyed(w);
-}
-
-bool QMultiInputContext::isComposing() const
-{
- return (slave()) ? slave()->isComposing() : false;
-}
-
-QList<QAction *> QMultiInputContext::actions()
-{
- QList<QAction *> a = slave()->actions();
- a.append(separator);
- a.append(menu->menuAction());
- return a;
-}
-
-void QMultiInputContext::changeSlave(QAction *a)
-{
- for (int i = 0; i < slaves.size(); ++i) {
- if (keys.at(i) == a->data().toString()) {
- if (slaves.at(i) == 0)
- slaves.replace(i, QInputContextFactory::create(keys.at(i), this));
- QInputContext *qic = slaves.at(current);
- QWidget *oldWidget = qic->focusWidget();
- qic->reset();
- qic->setFocusWidget(0);
- current = i;
- qic = slaves.at(current);
- qic->setFocusWidget(oldWidget);
- return;
- }
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_IM
diff --git a/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.h b/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.h
deleted file mode 100644
index 5d311b3f4b..0000000000
--- a/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QMultiInputContext class
-**
-** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** licence. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QMULTIINPUTCONTEXT_H
-#define QMULTIINPUTCONTEXT_H
-
-#ifndef QT_NO_IM
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qinputcontext.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qnamespace.h>
-#include <QtCore/qmap.h>
-#include <QtCore/qpointer.h>
-#include <QtCore/qlist.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMultiInputContext : public QInputContext
-{
- Q_OBJECT
-public:
- QMultiInputContext();
- ~QMultiInputContext();
-
- QString identifierName();
- QString language();
-
-#if defined(Q_WS_X11)
- bool x11FilterEvent( QWidget *keywidget, XEvent *event );
-#endif // Q_WS_X11
- bool filterEvent( const QEvent *event );
-
- void reset();
- void update();
- void mouseHandler( int x, QMouseEvent *event );
- QFont font() const;
- bool isComposing() const;
-
- QList<QAction *> actions();
-
- QWidget *focusWidget() const;
- void setFocusWidget(QWidget *w);
-
- void widgetDestroyed( QWidget *w );
-
- QInputContext *slave() { return slaves.at(current); }
- const QInputContext *slave() const { return slaves.at(current); }
-
-protected Q_SLOTS:
- void changeSlave(QAction *);
-private:
- void *unused;
- int current;
- QList<QInputContext *> slaves;
- QMenu *menu;
- QAction *separator;
- QStringList keys;
-};
-
-#endif // Q_NO_IM
-
-QT_END_NAMESPACE
-
-#endif // QMULTIINPUTCONTEXT_H
diff --git a/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp b/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp
deleted file mode 100644
index 1f56e2350b..0000000000
--- a/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Implementation of QMultiInputContextPlugin class
-**
-** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QT_NO_IM
-#include "qmultiinputcontext.h"
-#include "qmultiinputcontextplugin.h"
-#include <qinputcontextplugin.h>
-#include <qstringlist.h>
-
-QT_BEGIN_NAMESPACE
-
-QMultiInputContextPlugin::QMultiInputContextPlugin()
-{
-}
-
-QMultiInputContextPlugin::~QMultiInputContextPlugin()
-{
-}
-
-QStringList QMultiInputContextPlugin::keys() const
-{
- // input method switcher should named with "imsw-" prefix to
- // prevent to be listed in ordinary input method list.
- return QStringList( QLatin1String("imsw-multi") );
-}
-
-QInputContext *QMultiInputContextPlugin::create( const QString &key )
-{
- if (key != QLatin1String("imsw-multi"))
- return 0;
- return new QMultiInputContext;
-}
-
-QStringList QMultiInputContextPlugin::languages( const QString & )
-{
- return QStringList();
-}
-
-QString QMultiInputContextPlugin::displayName( const QString &key )
-{
- if (key != QLatin1String("imsw-multi"))
- return QString();
- return tr( "Multiple input method switcher" );
-}
-
-QString QMultiInputContextPlugin::description( const QString &key )
-{
- if (key != QLatin1String("imsw-multi"))
- return QString();
- return tr( "Multiple input method switcher that uses the context menu of the text widgets" );
-}
-
-
-Q_EXPORT_STATIC_PLUGIN(QMultiInputContextPlugin)
-Q_EXPORT_PLUGIN2(qimsw_multi, QMultiInputContextPlugin)
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.h b/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.h
deleted file mode 100644
index c18112ff8b..0000000000
--- a/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QMultiInputContextPlugin class
-**
-** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QMULTIINPUTCONTEXTPLUGIN_H
-#define QMULTIINPUTCONTEXTPLUGIN_H
-
-#ifndef QT_NO_IM
-
-#include "qmultiinputcontext.h"
-#include <QtGui/qinputcontextplugin.h>
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMultiInputContextPlugin : public QInputContextPlugin
-{
- Q_OBJECT
-public:
- QMultiInputContextPlugin();
- ~QMultiInputContextPlugin();
-
- QStringList keys() const;
- QInputContext *create( const QString &key );
- QStringList languages( const QString &key );
- QString displayName( const QString &key );
- QString description( const QString &key );
-};
-
-#endif // QT_NO_IM
-
-QT_END_NAMESPACE
-
-#endif // QMULTIINPUTCONTEXTPLUGIN_H
diff --git a/src/plugins/inputmethods/inputmethods.pro b/src/plugins/inputmethods/inputmethods.pro
deleted file mode 100644
index e1ca847519..0000000000
--- a/src/plugins/inputmethods/inputmethods.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS = imsw-multi
diff --git a/src/plugins/kbddrivers/kbddrivers.pro b/src/plugins/kbddrivers/kbddrivers.pro
deleted file mode 100644
index dbab47b366..0000000000
--- a/src/plugins/kbddrivers/kbddrivers.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-TEMPLATE = subdirs
-contains(kbd-plugins, linuxinput): SUBDIRS += linuxinput
diff --git a/src/plugins/kbddrivers/linuxinput/linuxinput.pro b/src/plugins/kbddrivers/linuxinput/linuxinput.pro
deleted file mode 100644
index 8eaa786ce0..0000000000
--- a/src/plugins/kbddrivers/linuxinput/linuxinput.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qlinuxinputkbddriver
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/kbddrivers
-target.path = $$[QT_INSTALL_PLUGINS]/kbddrivers
-INSTALLS += target
-
-DEFINES += QT_QWS_KBD_LINUXINPUT
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qkbdlinuxinput_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qkbdlinuxinput_qws.cpp
-
diff --git a/src/plugins/kbddrivers/linuxinput/main.cpp b/src/plugins/kbddrivers/linuxinput/main.cpp
deleted file mode 100644
index 9affaa67ea..0000000000
--- a/src/plugins/kbddrivers/linuxinput/main.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qkbddriverplugin_qws.h>
-#include <qkbdlinuxinput_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class QLinuxInputKbdDriver : public QKbdDriverPlugin
-{
-public:
- QLinuxInputKbdDriver();
-
- QStringList keys() const;
- QWSKeyboardHandler* create(const QString &driver, const QString &device);
-};
-
-QLinuxInputKbdDriver::QLinuxInputKbdDriver()
- : QKbdDriverPlugin()
-{
-}
-
-QStringList QLinuxInputKbdDriver::keys() const
-{
- return (QStringList() << QLatin1String("LinuxInput"));
-}
-
-QWSKeyboardHandler* QLinuxInputKbdDriver::create(const QString &driver,
- const QString &device)
-{
- Q_UNUSED(device);
- if (driver.compare(QLatin1String("LinuxInput"), Qt::CaseInsensitive))
- return 0;
- return new QWSLinuxInputKeyboardHandler(device);
-}
-
-Q_EXPORT_PLUGIN2(qwslinuxinputkbddriver, QLinuxInputKbdDriver)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/mousedrivers/linuxtp/linuxtp.pro b/src/plugins/mousedrivers/linuxtp/linuxtp.pro
deleted file mode 100644
index e5d274a0b7..0000000000
--- a/src/plugins/mousedrivers/linuxtp/linuxtp.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qlinuxtpmousedriver
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/mousedrivers
-target.path = $$[QT_INSTALL_PLUGINS]/mousedrivers
-INSTALLS += target
-
-DEFINES += QT_QWS_MOUSE_LINUXTP
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qmouselinuxtp_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qmouselinuxtp_qws.cpp
-
diff --git a/src/plugins/mousedrivers/linuxtp/main.cpp b/src/plugins/mousedrivers/linuxtp/main.cpp
deleted file mode 100644
index 64a69ef7f1..0000000000
--- a/src/plugins/mousedrivers/linuxtp/main.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qmousedriverplugin_qws.h>
-#include <qmouselinuxtp_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class QLinuxTPMouseDriver : public QMouseDriverPlugin
-{
-public:
- QLinuxTPMouseDriver();
-
- QStringList keys() const;
- QWSMouseHandler* create(const QString &driver, const QString &device);
-};
-
-QLinuxTPMouseDriver::QLinuxTPMouseDriver()
- : QMouseDriverPlugin()
-{
-}
-
-QStringList QLinuxTPMouseDriver::keys() const
-{
- return (QStringList() << "LinuxTP");
-}
-
-QWSMouseHandler* QLinuxTPMouseDriver::create(const QString &driver,
- const QString &device)
-{
- if (driver.compare(QLatin1String("LinuxTP"), Qt::CaseInsensitive))
- return 0;
- return new QWSLinuxTPMouseHandler(driver, device);
-}
-
-Q_EXPORT_PLUGIN2(qwslinuxtpmousehandler, QLinuxTPMouseDriver)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/mousedrivers/mousedrivers.pro b/src/plugins/mousedrivers/mousedrivers.pro
deleted file mode 100644
index f89682b880..0000000000
--- a/src/plugins/mousedrivers/mousedrivers.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE = subdirs
-contains(mouse-plugins, linuxtp): SUBDIRS += linuxtp
-contains(mouse-plugins, pc): SUBDIRS += pc
-contains(mouse-plugins, tslib): SUBDIRS += tslib
-contains(mouse-plugins, linuxinput): SUBDIRS += linuxinput
diff --git a/src/plugins/mousedrivers/pc/main.cpp b/src/plugins/mousedrivers/pc/main.cpp
deleted file mode 100644
index fbd23dab0f..0000000000
--- a/src/plugins/mousedrivers/pc/main.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qmousedriverplugin_qws.h>
-#include <qmousepc_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPcMouseDriver : public QMouseDriverPlugin
-{
-public:
- QPcMouseDriver();
-
- QStringList keys() const;
- QWSMouseHandler* create(const QString &driver, const QString &device);
-};
-
-QPcMouseDriver::QPcMouseDriver()
- : QMouseDriverPlugin()
-{
-}
-
-QStringList QPcMouseDriver::keys() const
-{
- return (QStringList()
- << QLatin1String("Auto")
- << QLatin1String("IntelliMouse")
- << QLatin1String("Microsoft")
- << QLatin1String("MouseSystems")
- << QLatin1String("MouseMan"));
-}
-
-QWSMouseHandler* QPcMouseDriver::create(const QString &driver,
- const QString &device)
-{
- if (!keys().contains(driver, Qt::CaseInsensitive))
- return 0;
- return new QWSPcMouseHandler(driver, device);
-}
-
-Q_EXPORT_PLUGIN2(qwspcmousehandler, QPcMouseDriver)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/mousedrivers/pc/pc.pro b/src/plugins/mousedrivers/pc/pc.pro
deleted file mode 100644
index 04d7b0f06f..0000000000
--- a/src/plugins/mousedrivers/pc/pc.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qpcmousedriver
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/mousedrivers
-target.path = $$[QT_INSTALL_PLUGINS]/mousedrivers
-INSTALLS += target
-
-DEFINES += QT_QWS_MOUSE_PC
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qmousepc_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousepc_qws.cpp
-
diff --git a/src/plugins/mousedrivers/tslib/main.cpp b/src/plugins/mousedrivers/tslib/main.cpp
deleted file mode 100644
index 1d6f8535ba..0000000000
--- a/src/plugins/mousedrivers/tslib/main.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qmousedriverplugin_qws.h>
-#include <qmousetslib_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class TslibMouseDriver : public QMouseDriverPlugin
-{
-public:
- TslibMouseDriver();
-
- QStringList keys() const;
- QWSMouseHandler* create(const QString &driver, const QString &device);
-};
-
-TslibMouseDriver::TslibMouseDriver()
- : QMouseDriverPlugin()
-{
-}
-
-QStringList TslibMouseDriver::keys() const
-{
- return (QStringList() << "tslib");
-}
-
-QWSMouseHandler* TslibMouseDriver::create(const QString &driver,
- const QString &device)
-{
- if (driver.toLower() != "tslib")
- return 0;
- return new QWSTslibMouseHandler(driver, device);
-}
-
-Q_EXPORT_STATIC_PLUGIN(TslibMouseDriver)
-Q_EXPORT_PLUGIN2(qwstslibmousehandler, TslibMouseDriver)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/mousedrivers/tslib/tslib.pro b/src/plugins/mousedrivers/tslib/tslib.pro
deleted file mode 100644
index 552a2e7173..0000000000
--- a/src/plugins/mousedrivers/tslib/tslib.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-TARGET = qtslibmousedriver
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/mousedrivers
-
-HEADERS = \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousedriverplugin_qws.h \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousetslib_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousetslib_qws.cpp
-
-LIBS += -lts
-
-target.path += $$[QT_INSTALL_PLUGINS]/mousedrivers
-INSTALLS += target
-
diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro
new file mode 100644
index 0000000000..193dad0018
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/ibus.pro
@@ -0,0 +1,19 @@
+TARGET = ibusplatforminputcontextplugin
+load(qt_plugin)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforminputcontexts
+
+QT += dbus platformsupport-private
+SOURCES += $$PWD/qibusplatforminputcontext.cpp \
+ $$PWD/qibusproxy.cpp \
+ $$PWD/qibusinputcontextproxy.cpp \
+ $$PWD/qibustypes.cpp \
+ $$PWD/main.cpp
+
+HEADERS += $$PWD/qibusplatforminputcontext.h \
+ $$PWD/qibusproxy.h \
+ $$PWD/qibusinputcontextproxy.h \
+ $$PWD/qibustypes.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforminputcontexts
+INSTALLS += target
diff --git a/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.InputContext.xml b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.InputContext.xml
new file mode 100644
index 0000000000..dbc79c178b
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.InputContext.xml
@@ -0,0 +1,80 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.IBus.InputContext">
+ <method name="ProcessKeyEvent">
+ <arg name="keyval" direction="in" type="u"/>
+ <arg name="keycode" direction="in" type="u"/>
+ <arg name="state" direction="in" type="u"/>
+ <arg name="handled" direction="out" type="b"/>
+ </method>
+ <method name="SetCursorLocation">
+ <arg name="x" direction="in" type="i"/>
+ <arg name="y" direction="in" type="i"/>
+ <arg name="w" direction="in" type="i"/>
+ <arg name="h" direction="in" type="i"/>
+ </method>
+ <method name="FocusIn"/>
+ <method name="FocusOut"/>
+ <method name="Reset"/>
+ <method name="Enable"/>
+ <method name="Disable"/>
+ <method name="IsEnabled">
+ <arg name="enable" direction="out" type="b"/>
+ </method>
+ <method name="SetCapabilities">
+ <arg name="caps" direction="in" type="u"/>
+ </method>
+ <method name="PropertyActivate">
+ <arg name="name" direction="in" type="s"/>
+ <arg name="state" direction="in" type="i"/>
+ </method>
+ <method name="SetEngine">
+ <arg name="name" direction="in" type="s"/>
+ </method>
+ <method name="GetEngine">
+ <arg name="desc" direction="out" type="v"/>
+ </method>
+ <method name="Destroy"/>
+ <signal name="CommitText">
+ <arg name="text" type="v"/>
+ </signal>
+ <signal name="Enabled"/>
+ <signal name="Disabled"/>
+ <signal name="ForwardKeyEvent">
+ <arg name="keyval" type="u"/>
+ <arg name="keycode" type="u"/>
+ <arg name="state" type="u"/>
+ </signal>
+ <signal name="UpdatePreeditText">
+ <arg name="text" type="v"/>
+ <arg name="cursor_pos" type="u"/>
+ <arg name="visible" type="b"/>
+ </signal>
+ <signal name="ShowPreeditText"/>
+ <signal name="HidePreeditText"/>
+ <signal name="UpdateAuxiliaryText">
+ <arg name="text" type="v"/>
+ <arg name="visible" type="b"/>
+ </signal>
+ <signal name="ShowAuxiliaryText"/>
+ <signal name="HideAuxiliaryText"/>
+ <signal name="UpdateLookupTable">
+ <arg name="table" type="v"/>
+ <arg name="visible" type="b"/>
+ </signal>
+ <signal name="ShowLookupTable"/>
+ <signal name="HideLookupTable"/>
+ <signal name="PageUpLookupTable"/>
+ <signal name="PageDownLookupTable"/>
+ <signal name="CursorUpLookupTable"/>
+ <signal name="CursorDownLookupTable"/>
+ <signal name="RegisterProperties">
+ <arg name="props" type="v"/>
+ </signal>
+ <signal name="UpdateProperty">
+ <arg name="prop" type="v"/>
+ </signal>
+ </interface>
+</node>
+
diff --git a/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.xml b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.xml
new file mode 100644
index 0000000000..6ac4891771
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.xml
@@ -0,0 +1,30 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.IBus">
+ <method name="GetAddress">
+ <arg name="address" direction="out" type="s"/>
+ </method>
+ <method name="CreateInputContext">
+ <arg name="name" direction="in" type="s"/>
+ <arg name="context" direction="out" type="o"/>
+ </method>
+ <method name="RegisterComponent">
+ <arg name="components" direction="in" type="v"/>
+ </method>
+ <method name="ListEngines">
+ <arg name="engines" direction="out" type="av"/>
+ </method>
+ <method name="ListActiveEngines">
+ <arg name="engines" direction="out" type="av"/>
+ </method>
+ <method name="Exit">
+ <arg name="restart" direction="in" type="b"/>
+ </method>
+ <method name="Ping">
+ <arg name="data" direction="in" type="v"/>
+ <arg name="data" direction="out" type="v"/>
+ </method>
+ </interface>
+</node>
+
diff --git a/src/plugins/gfxdrivers/linuxfb/main.cpp b/src/plugins/platforminputcontexts/ibus/main.cpp
index 187237f042..eb773c8856 100644
--- a/src/plugins/gfxdrivers/linuxfb/main.cpp
+++ b/src/plugins/platforminputcontexts/ibus/main.cpp
@@ -2,7 +2,7 @@
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: Nokia Corporation (info@qt.nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
@@ -39,41 +39,33 @@
**
****************************************************************************/
-#include <qscreendriverplugin_qws.h>
-#include <qscreenlinuxfb_qws.h>
-#include <qstringlist.h>
+#include <private/qplatforminputcontextplugin_qpa_p.h>
+#include <QtCore/QStringList>
+#include "qibusplatforminputcontext.h"
QT_BEGIN_NAMESPACE
-class QScreenLinuxFbPlugin : public QScreenDriverPlugin
+class QIbusPlatformInputContextPlugin : public QPlatformInputContextPlugin
{
public:
- QScreenLinuxFbPlugin();
-
QStringList keys() const;
- QScreen *create(const QString&, int displayId);
+ QIBusPlatformInputContext *create(const QString&, const QStringList&);
};
-QScreenLinuxFbPlugin::QScreenLinuxFbPlugin()
- : QScreenDriverPlugin()
-{
-}
-
-QStringList QScreenLinuxFbPlugin::keys() const
+QStringList QIbusPlatformInputContextPlugin::keys() const
{
- QStringList list;
- list << QLatin1String("LinuxFb");
- return list;
+ return QStringList(QStringLiteral("ibus"));
}
-QScreen* QScreenLinuxFbPlugin::create(const QString& driver, int displayId)
+QIBusPlatformInputContext *QIbusPlatformInputContextPlugin::create(const QString& system, const QStringList& paramList)
{
- if (driver.toLower() == QLatin1String("linuxfb"))
- return new QLinuxFbScreen(displayId);
+ Q_UNUSED(paramList);
+ if (system.compare(system, QStringLiteral("ibus"), Qt::CaseInsensitive) == 0)
+ return new QIBusPlatformInputContext;
return 0;
}
-Q_EXPORT_PLUGIN2(qscreenlinuxfb, QScreenLinuxFbPlugin)
+Q_EXPORT_PLUGIN2(ibusplatforminputcontextplugin, QIbusPlatformInputContextPlugin)
QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.cpp b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.cpp
new file mode 100644
index 0000000000..7adffbc2e2
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -p qibusinputcontextproxy -c QIBusInputContextProxy interfaces/org.freedesktop.IBus.InputContext.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "qibusinputcontextproxy.h"
+
+/*
+ * Implementation of interface class QIBusInputContextProxy
+ */
+
+QIBusInputContextProxy::QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+QIBusInputContextProxy::~QIBusInputContextProxy()
+{
+}
+
diff --git a/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h
new file mode 100644
index 0000000000..9a91c4e484
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h
@@ -0,0 +1,144 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -p qibusinputcontextproxy -c QIBusInputContextProxy interfaces/org.freedesktop.IBus.InputContext.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef QIBUSINPUTCONTEXTPROXY_H_1308831153
+#define QIBUSINPUTCONTEXTPROXY_H_1308831153
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface org.freedesktop.IBus.InputContext
+ */
+class QIBusInputContextProxy: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "org.freedesktop.IBus.InputContext"; }
+
+public:
+ QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~QIBusInputContextProxy();
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<> Destroy()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Destroy"), argumentList);
+ }
+
+ inline QDBusPendingReply<> Disable()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Disable"), argumentList);
+ }
+
+ inline QDBusPendingReply<> Enable()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Enable"), argumentList);
+ }
+
+ inline QDBusPendingReply<> FocusIn()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("FocusIn"), argumentList);
+ }
+
+ inline QDBusPendingReply<> FocusOut()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("FocusOut"), argumentList);
+ }
+
+ inline QDBusPendingReply<QDBusVariant> GetEngine()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("GetEngine"), argumentList);
+ }
+
+ inline QDBusPendingReply<bool> IsEnabled()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("IsEnabled"), argumentList);
+ }
+
+ inline QDBusPendingReply<bool> ProcessKeyEvent(uint keyval, uint keycode, uint state)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(keyval) << QVariant::fromValue(keycode) << QVariant::fromValue(state);
+ return asyncCallWithArgumentList(QLatin1String("ProcessKeyEvent"), argumentList);
+ }
+
+ inline QDBusPendingReply<> PropertyActivate(const QString &name, int state)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(name) << QVariant::fromValue(state);
+ return asyncCallWithArgumentList(QLatin1String("PropertyActivate"), argumentList);
+ }
+
+ inline QDBusPendingReply<> Reset()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Reset"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetCapabilities(uint caps)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(caps);
+ return asyncCallWithArgumentList(QLatin1String("SetCapabilities"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetCursorLocation(int x, int y, int w, int h)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(x) << QVariant::fromValue(y) << QVariant::fromValue(w) << QVariant::fromValue(h);
+ return asyncCallWithArgumentList(QLatin1String("SetCursorLocation"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetEngine(const QString &name)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(name);
+ return asyncCallWithArgumentList(QLatin1String("SetEngine"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+ void CommitText(const QDBusVariant &text);
+ void CursorDownLookupTable();
+ void CursorUpLookupTable();
+ void Disabled();
+ void Enabled();
+ void ForwardKeyEvent(uint keyval, uint keycode, uint state);
+ void HideAuxiliaryText();
+ void HideLookupTable();
+ void HidePreeditText();
+ void PageDownLookupTable();
+ void PageUpLookupTable();
+ void RegisterProperties(const QDBusVariant &props);
+ void ShowAuxiliaryText();
+ void ShowLookupTable();
+ void ShowPreeditText();
+ void UpdateAuxiliaryText(const QDBusVariant &text, bool visible);
+ void UpdateLookupTable(const QDBusVariant &table, bool visible);
+ void UpdatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible);
+ void UpdateProperty(const QDBusVariant &prop);
+};
+
+#endif
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
new file mode 100644
index 0000000000..af8fd5a1f1
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -0,0 +1,329 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qibusplatforminputcontext.h"
+
+#include <QtDebug>
+#include <QTextCharFormat>
+#include <QGuiApplication>
+#include <qwindow.h>
+#include <qevent.h>
+
+#include "qibusproxy.h"
+#include "qibusinputcontextproxy.h"
+#include "qibustypes.h"
+
+#include <sys/types.h>
+#include <signal.h>
+
+#include <QtDBus>
+
+enum { debug = 0 };
+
+class QIBusPlatformInputContextPrivate
+{
+public:
+ QIBusPlatformInputContextPrivate();
+ ~QIBusPlatformInputContextPrivate()
+ {
+ delete context;
+ delete bus;
+ delete connection;
+ }
+
+ static QDBusConnection *createConnection();
+
+ QDBusConnection *connection;
+ QIBusProxy *bus;
+ QIBusInputContextProxy *context;
+
+ bool valid;
+};
+
+
+QIBusPlatformInputContext::QIBusPlatformInputContext ()
+ : d(new QIBusPlatformInputContextPrivate())
+{
+ if (d->context) {
+ connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant)));
+ connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool)));
+ }
+ QInputPanel *p = qApp->inputPanel();
+ connect(p, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged()));
+ connect(p, SIGNAL(cursorRectangleChanged()), this, SLOT(cursorRectChanged()));
+}
+
+QIBusPlatformInputContext::~QIBusPlatformInputContext (void)
+{
+ delete d;
+}
+
+bool QIBusPlatformInputContext::isValid() const
+{
+ return d->valid;
+}
+
+void QIBusPlatformInputContext::invokeAction(QInputPanel::Action a, int x)
+{
+ QPlatformInputContext::invokeAction(a, x);
+
+ if (!d->valid)
+ return;
+}
+
+void QIBusPlatformInputContext::reset()
+{
+ QPlatformInputContext::reset();
+
+ if (!d->valid)
+ return;
+
+ d->context->Reset();
+}
+
+void QIBusPlatformInputContext::update(Qt::InputMethodQueries q)
+{
+ QPlatformInputContext::update(q);
+}
+
+void QIBusPlatformInputContext::cursorRectChanged()
+{
+ if (!d->valid)
+ return;
+
+ QRect r = qApp->inputPanel()->cursorRectangle().toRect();
+ if(!r.isValid())
+ return;
+
+ QWindow *inputWindow = qApp->inputPanel()->inputWindow();
+ r.moveTopLeft(inputWindow->mapToGlobal(r.topLeft()));
+ if (debug)
+ qDebug() << "microFocus" << r;
+ d->context->SetCursorLocation(r.x(), r.y(), r.width(), r.height());
+}
+
+void QIBusPlatformInputContext::inputItemChanged()
+{
+ if (!d->valid)
+ return;
+
+ QObject *input = qApp->inputPanel()->inputItem();
+ if (debug)
+ qDebug() << "setFocusObject" << input;
+ if (input)
+ d->context->FocusIn();
+ else
+ d->context->FocusOut();
+}
+
+
+void QIBusPlatformInputContext::commitText(const QDBusVariant &text)
+{
+ QObject *input = qApp->inputPanel()->inputItem();
+ if (!input)
+ return;
+
+ const QDBusArgument arg = text.variant().value<QDBusArgument>();
+
+ QIBusText t;
+ if (debug)
+ qDebug() << arg.currentSignature();
+ t.fromDBusArgument(arg);
+ if (debug)
+ qDebug() << "commit text:" << t.text;
+
+ QInputMethodEvent event;
+ event.setCommitString(t.text);
+ QCoreApplication::sendEvent(input, &event);
+}
+
+void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint cursorPos, bool visible)
+{
+ QObject *input = qApp->inputPanel()->inputItem();
+ if (!input)
+ return;
+
+ const QDBusArgument arg = text.variant().value<QDBusArgument>();
+
+ QIBusText t;
+ t.fromDBusArgument(arg);
+ if (debug)
+ qDebug() << "preedit text:" << t.text;
+
+ QList<QInputMethodEvent::Attribute> attributes = t.attributes.imAttributes();
+ attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, visible ? 1 : 0, QVariant());
+
+ QInputMethodEvent event(t.text, attributes);
+ QCoreApplication::sendEvent(input, &event);
+}
+
+
+/* Kernel keycode -> X keycode table */
+static const unsigned int keycode_table[256] = {
+ 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 76, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 111, 221, 94, 95, 96, 211, 128, 127, 129, 208, 131, 126,
+ 108, 109, 112, 111, 113, 181, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107,
+ 239, 160, 174, 176, 222, 157, 123, 110, 139, 134, 209, 210, 133, 115, 116, 117,
+ 232, 133, 134, 135, 140, 248, 191, 192, 122, 188, 245, 158, 161, 193, 223, 227,
+ 198, 199, 200, 147, 159, 151, 178, 201, 146, 203, 166, 236, 230, 235, 234, 233,
+ 163, 204, 253, 153, 162, 144, 164, 177, 152, 190, 208, 129, 130, 231, 209, 210,
+ 136, 220, 143, 246, 251, 137, 138, 182, 183, 184, 93, 184, 247, 132, 170, 219,
+ 249, 205, 207, 149, 150, 154, 155, 167, 168, 169, 171, 172, 173, 165, 175, 179,
+ 180, 0, 185, 186, 187, 118, 119, 120, 121, 229, 194, 195, 196, 197, 148, 202,
+ 101, 212, 237, 214, 215, 216, 217, 218, 228, 142, 213, 240, 241, 242, 243, 244,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+bool
+QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, bool press)
+{
+ if (!d->valid)
+ return false;
+
+ if (!press)
+ return false;
+
+ keycode -= 8; // ###
+ QDBusReply<bool> reply = d->context->ProcessKeyEvent(keyval, keycode, state);
+
+// qDebug() << "x11FilterEvent return" << reply.value();
+
+ return reply.value();
+}
+
+QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
+ : connection(createConnection()),
+ bus(0),
+ context(0),
+ valid(false)
+{
+ if (!connection || !connection->isConnected()) {
+ qDebug("QIBusPlatformInputContext: not connected.");
+ return;
+ }
+
+ bus = new QIBusProxy(QLatin1String("org.freedesktop.IBus"),
+ QLatin1String("/org/freedesktop/IBus"),
+ *connection);
+ if (!bus->isValid()) {
+ qWarning("QIBusPlatformInputContext: invalid bus.");
+ return;
+ }
+
+ QDBusReply<QDBusObjectPath> ic = bus->CreateInputContext(QLatin1String("QIBusInputContext"));
+ if (!ic.isValid()) {
+ qWarning("QIBusPlatformInputContext: CreateInputContext failed.");
+ return;
+ }
+
+ context = new QIBusInputContextProxy(QLatin1String("org.freedesktop.IBus"), ic.value().path(), *connection);
+
+ if (!context->isValid()) {
+ qWarning("QIBusPlatformInputContext: invalid input context.");
+ return;
+ }
+
+ enum Capabilities {
+ IBUS_CAP_PREEDIT_TEXT = 1 << 0,
+ IBUS_CAP_AUXILIARY_TEXT = 1 << 1,
+ IBUS_CAP_LOOKUP_TABLE = 1 << 2,
+ IBUS_CAP_FOCUS = 1 << 3,
+ IBUS_CAP_PROPERTY = 1 << 4,
+ IBUS_CAP_SURROUNDING_TEXT = 1 << 5
+ };
+ context->SetCapabilities(IBUS_CAP_PREEDIT_TEXT|IBUS_CAP_FOCUS);
+
+ if (debug)
+ qDebug(">>>> valid!");
+ valid = true;
+}
+
+QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
+{
+ QByteArray display(getenv("DISPLAY"));
+ QByteArray host = "unix";
+ QByteArray displayNumber = "0";
+
+ int pos = display.indexOf(':');
+ if (pos > 0)
+ host = display.left(pos);
+ ++pos;
+ int pos2 = display.indexOf('.', pos);
+ if (pos2 > 0)
+ displayNumber = display.mid(pos, pos2 - pos);
+ if (debug)
+ qDebug() << "host=" << host << "displayNumber" << displayNumber;
+
+ QFile file(QDir::homePath() + QLatin1String("/.config/ibus/bus/") +
+ QLatin1String(QDBusConnection::localMachineId()) +
+ QLatin1Char('-') + QString::fromLocal8Bit(host) + QLatin1Char('-') + QString::fromLocal8Bit(displayNumber));
+
+ if (!file.exists()) {
+ qWarning("QIBusPlatformInputContext: ibus config file '%s' does not exist.", qPrintable(file.fileName()));
+ return 0;
+ }
+
+ file.open(QFile::ReadOnly);
+
+ QByteArray address;
+ int pid = -1;
+
+ while (!file.atEnd()) {
+ QByteArray line = file.readLine().trimmed();
+ if (line.startsWith('#'))
+ continue;
+
+ if (line.startsWith("IBUS_ADDRESS="))
+ address = line.mid(sizeof("IBUS_ADDRESS=") - 1);
+ if (line.startsWith("IBUS_DAEMON_PID="))
+ pid = line.mid(sizeof("IBUS_DAEMON_PID=") - 1).toInt();
+ }
+
+ if (debug)
+ qDebug() << "IBUS_ADDRESS=" << address << "PID=" << pid;
+ if (address.isEmpty() || pid < 0 || kill(pid, 0) != 0)
+ return 0;
+
+ return new QDBusConnection(QDBusConnection::connectToBus(QString::fromLatin1(address), QLatin1String("QIBusProxy")));
+}
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
new file mode 100644
index 0000000000..84b578db16
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QIBUSPLATFORMINPUTCONTEXT_H
+#define QIBUSPLATFORMINPUTCONTEXT_H
+
+#include <QPlatformInputContext>
+
+class QIBusPlatformInputContextPrivate;
+class QDBusVariant;
+
+class QIBusPlatformInputContext : public QPlatformInputContext
+{
+ Q_OBJECT
+public:
+ QIBusPlatformInputContext();
+ ~QIBusPlatformInputContext();
+
+ bool isValid() const;
+
+ void invokeAction(QInputPanel::Action a, int x);
+ void reset(void);
+ void update(Qt::InputMethodQueries);
+
+ Q_INVOKABLE bool x11FilterEvent(uint keyval, uint keycode, uint state, bool press);
+
+public Q_SLOTS:
+ void commitText(const QDBusVariant &text);
+ void updatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible);
+ void inputItemChanged();
+ void cursorRectChanged();
+
+private:
+ QIBusPlatformInputContextPrivate *d;
+};
+
+#endif
diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp
new file mode 100644
index 0000000000..9d64b603f3
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -p qibusproxy -c QIBusProxy interfaces/org.freedesktop.IBus.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "qibusproxy.h"
+
+/*
+ * Implementation of interface class QIBusProxy
+ */
+
+QIBusProxy::QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+QIBusProxy::~QIBusProxy()
+{
+}
+
diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.h b/src/plugins/platforminputcontexts/ibus/qibusproxy.h
new file mode 100644
index 0000000000..389eec3175
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.h
@@ -0,0 +1,88 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -p qibusproxy -c QIBusProxy interfaces/org.freedesktop.IBus.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef QIBUSPROXY_H_1308831142
+#define QIBUSPROXY_H_1308831142
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface org.freedesktop.IBus
+ */
+class QIBusProxy: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "org.freedesktop.IBus"; }
+
+public:
+ QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~QIBusProxy();
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<QDBusObjectPath> CreateInputContext(const QString &name)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(name);
+ return asyncCallWithArgumentList(QLatin1String("CreateInputContext"), argumentList);
+ }
+
+ inline QDBusPendingReply<> Exit(bool restart)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(restart);
+ return asyncCallWithArgumentList(QLatin1String("Exit"), argumentList);
+ }
+
+ inline QDBusPendingReply<QString> GetAddress()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("GetAddress"), argumentList);
+ }
+
+ inline QDBusPendingReply<QVariantList> ListActiveEngines()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("ListActiveEngines"), argumentList);
+ }
+
+ inline QDBusPendingReply<QVariantList> ListEngines()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("ListEngines"), argumentList);
+ }
+
+ inline QDBusPendingReply<QDBusVariant> Ping(const QDBusVariant &data)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(data);
+ return asyncCallWithArgumentList(QLatin1String("Ping"), argumentList);
+ }
+
+ inline QDBusPendingReply<> RegisterComponent(const QDBusVariant &components)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(components);
+ return asyncCallWithArgumentList(QLatin1String("RegisterComponent"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+};
+
+#endif
diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
new file mode 100644
index 0000000000..8d8c61afb7
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qibustypes.h"
+#include <qtextformat.h>
+#include <QtDBus>
+
+QIBusSerializable::QIBusSerializable()
+{
+}
+
+QIBusSerializable::~QIBusSerializable()
+{
+}
+
+void QIBusSerializable::fromDBusArgument(const QDBusArgument &arg)
+{
+ arg >> name;
+ arg.beginMap();
+ while (!arg.atEnd()) {
+ arg.beginMapEntry();
+ QString key;
+ QDBusVariant value;
+ arg >> key;
+ arg >> value;
+ arg.endMapEntry();
+ attachments[key] = value.variant().value<QDBusArgument>();
+ }
+ arg.endMap();
+}
+
+
+
+QIBusAttribute::QIBusAttribute()
+ : type(Invalid),
+ value(0),
+ start(0),
+ end(0)
+{
+}
+
+QIBusAttribute::~QIBusAttribute()
+{
+
+}
+
+void QIBusAttribute::fromDBusArgument(const QDBusArgument &arg)
+{
+// qDebug() << "QIBusAttribute::fromDBusArgument()" << arg.currentSignature();
+ arg.beginStructure();
+
+ QIBusSerializable::fromDBusArgument(arg);
+
+ quint32 t;
+ arg >> t;
+ type = (Type)t;
+ arg >> value;
+ arg >> start;
+ arg >> end;
+
+ arg.endStructure();
+}
+
+QTextFormat QIBusAttribute::format() const
+{
+ QTextCharFormat fmt;
+ switch (type) {
+ case Invalid:
+ break;
+ case Underline: {
+ QTextCharFormat::UnderlineStyle style = QTextCharFormat::NoUnderline;
+
+ switch (value) {
+ case UnderlineNone:
+ break;
+ case UnderlineSingle:
+ style = QTextCharFormat::SingleUnderline;
+ break;
+ case UnderlineDouble:
+ style = QTextCharFormat::DashUnderline;
+ break;
+ case UnderlineLow:
+ style = QTextCharFormat::DashDotLine;
+ break;
+ case UnderlineError:
+ style = QTextCharFormat::WaveUnderline;
+ fmt.setUnderlineColor(Qt::red);
+ break;
+ }
+
+ fmt.setUnderlineStyle(style);
+ break;
+ }
+ case Foreground:
+ fmt.setForeground(QColor(value));
+ break;
+ case Background:
+ fmt.setBackground(QColor(value));
+ break;
+ }
+ return fmt;
+}
+
+
+QIBusAttributeList::QIBusAttributeList()
+{
+
+}
+
+QIBusAttributeList::~QIBusAttributeList()
+{
+
+}
+
+void QIBusAttributeList::fromDBusArgument(const QDBusArgument &arg)
+{
+// qDebug() << "QIBusAttributeList::fromDBusArgument()" << arg.currentSignature();
+ arg.beginStructure();
+
+ QIBusSerializable::fromDBusArgument(arg);
+
+ arg.beginArray();
+ while(!arg.atEnd()) {
+ QDBusVariant var;
+ arg >> var;
+
+ QIBusAttribute attr;
+ attr.fromDBusArgument(var.variant().value<QDBusArgument>());
+ attributes.append(attr);
+ }
+ arg.endArray();
+
+ arg.endStructure();
+}
+
+QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const
+{
+ QList<QInputMethodEvent::Attribute> imAttrs;
+ for (int i = 0; i < attributes.size(); ++i) {
+ const QIBusAttribute &attr = attributes.at(i);
+ imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, attr.start, attr.end - attr.start, attr.format());
+ }
+ return imAttrs;
+}
+
+
+QIBusText::QIBusText()
+{
+
+}
+
+QIBusText::~QIBusText()
+{
+
+}
+
+void QIBusText::fromDBusArgument(const QDBusArgument &arg)
+{
+// qDebug() << "QIBusText::fromDBusArgument()" << arg.currentSignature();
+ arg.beginStructure();
+
+ QIBusSerializable::fromDBusArgument(arg);
+
+ arg >> text;
+ QDBusVariant variant;
+ arg >> variant;
+ attributes.fromDBusArgument(variant.variant().value<QDBusArgument>());
+
+ arg.endStructure();
+}
+
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h b/src/plugins/platforminputcontexts/ibus/qibustypes.h
index f1893e3e96..c426ff7eda 100644
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h
+++ b/src/plugins/platforminputcontexts/ibus/qibustypes.h
@@ -38,62 +38,79 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef QIBUSTYPES_H
+#define QIBUSTYPES_H
-#ifndef PVREGLSCREEN_H
-#define PVREGLSCREEN_H
+#include <qvector.h>
+#include <qevent.h>
-#include <QScreen>
-#include <QGLScreen>
-#include "pvrqwsdrawable.h"
+class QDBusArgument;
-class PvrEglScreen;
-
-class PvrEglScreenSurfaceFunctions : public QGLScreenSurfaceFunctions
+class QIBusSerializable
{
public:
- PvrEglScreenSurfaceFunctions(PvrEglScreen *s, int screenNum)
- : screen(s), displayId(screenNum) {}
+ QIBusSerializable();
+ virtual ~QIBusSerializable();
- bool createNativeWindow(QWidget *widget, EGLNativeWindowType *native);
+ virtual void fromDBusArgument(const QDBusArgument &arg);
-private:
- PvrEglScreen *screen;
- int displayId;
+ QString name;
+ QHash<QString, QDBusArgument> attachments;
};
-class PvrEglScreen : public QGLScreen
+class QIBusAttribute : public QIBusSerializable
{
public:
- PvrEglScreen(int displayId);
- ~PvrEglScreen();
+ enum Type {
+ Invalid = 0,
+ Underline = 1,
+ Foreground = 2,
+ Background = 3,
+ };
+
+ enum Underline {
+ UnderlineNone = 0,
+ UnderlineSingle = 1,
+ UnderlineDouble = 2,
+ UnderlineLow = 3,
+ UnderlineError = 4,
+ };
+
+ QIBusAttribute();
+ ~QIBusAttribute();
- bool initDevice();
- bool connect(const QString &displaySpec);
- void disconnect();
- void shutdownDevice();
- void setMode(int, int, int) {}
+ void fromDBusArgument(const QDBusArgument &arg);
+ QTextFormat format() const;
- void blit(const QImage &img, const QPoint &topLeft, const QRegion &region);
- void solidFill(const QColor &color, const QRegion &region);
+ Type type;
+ quint32 value;
+ quint32 start;
+ quint32 end;
+};
- bool chooseContext(QGLContext *context, const QGLContext *shareContext);
- bool hasOpenGL();
+class QIBusAttributeList : public QIBusSerializable
+{
+public:
+ QIBusAttributeList();
+ ~QIBusAttributeList();
- QWSWindowSurface* createSurface(QWidget *widget) const;
- QWSWindowSurface* createSurface(const QString &key) const;
+ void fromDBusArgument(const QDBusArgument &arg);
- int transformation() const;
+ QList<QInputMethodEvent::Attribute> imAttributes() const;
+
+ QVector<QIBusAttribute> attributes;
+};
+
+class QIBusText : public QIBusSerializable
+{
+public:
+ QIBusText();
+ ~QIBusText();
-private:
- void sync();
- void openTty();
- void closeTty();
+ void fromDBusArgument(const QDBusArgument &arg);
- int fd;
- int ttyfd, oldKdMode;
- QString ttyDevice;
- bool doGraphicsMode;
- mutable const QScreen *parent;
+ QString text;
+ QIBusAttributeList attributes;
};
#endif
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
new file mode 100644
index 0000000000..b6e2b6e775
--- /dev/null
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+!macx:!win:SUBDIRS += ibus
+
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index bfa147f948..d6801e0bed 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -2,28 +2,46 @@ TARGET = qcocoa
load(qt_plugin)
DESTDIR = $$QT.gui.plugins/platforms
-OBJECTIVE_SOURCES = main.mm \
+OBJECTIVE_SOURCES += main.mm \
qcocoaintegration.mm \
- qcocoawindowsurface.mm \
+ qcocoabackingstore.mm \
qcocoawindow.mm \
qnsview.mm \
- qcocoaeventloopintegration.mm \
qcocoaautoreleasepool.mm \
- qnswindowdelegate.mm
+ qnswindowdelegate.mm \
+ qcocoaglcontext.mm \
+ qcocoanativeinterface.mm \
+ qcocoaeventdispatcher.mm \
+ qcocoamenuloader.mm \
+ qcocoaapplicationdelegate.mm \
+ qcocoaapplication.mm \
+ qcocoamenu.mm \
+ qmenu_mac.mm \
+ qcocoahelpers.mm \
-OBJECTIVE_HEADERS = qcocoaintegration.h \
- qcocoawindowsurface.h \
+HEADERS += qcocoaintegration.h \
+ qcocoabackingstore.h \
qcocoawindow.h \
qnsview.h \
- qcocoaeventloopintegration.h \
qcocoaautoreleasepool.h \
- qnswindowdelegate.h
+ qnswindowdelegate.h \
+ qcocoaglcontext.h \
+ qcocoanativeinterface.h \
+ qcocoaeventdispatcher.h \
+ qcocoamenuloader.h \
+ qcocoaapplicationdelegate.h \
+ qcocoaapplication.h \
+ qcocoamenu.h \
+ qmenu_mac.h \
+ qcocoahelpers.h \
+
+RESOURCES += qcocoaresources.qrc
#add libz for freetype.
-LIBS += -lz
-LIBS += -framework cocoa
+LIBS += -lz -framework Cocoa
+
+QT += core-private gui-private widgets-private platformsupport-private
-include(../fontdatabases/coretext/coretext.pri)
+CONFIG += qpa/basicunixfontdatabase
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
-
diff --git a/src/plugins/platforms/cocoa/images/copyarrowcursor.png b/src/plugins/platforms/cocoa/images/copyarrowcursor.png
new file mode 100644
index 0000000000..13dfca95bc
--- /dev/null
+++ b/src/plugins/platforms/cocoa/images/copyarrowcursor.png
Binary files differ
diff --git a/src/plugins/platforms/cocoa/images/forbiddencursor.png b/src/plugins/platforms/cocoa/images/forbiddencursor.png
new file mode 100644
index 0000000000..a9f21b4a5e
--- /dev/null
+++ b/src/plugins/platforms/cocoa/images/forbiddencursor.png
Binary files differ
diff --git a/src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png b/src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png
new file mode 100644
index 0000000000..6716597046
--- /dev/null
+++ b/src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png
Binary files differ
diff --git a/src/plugins/platforms/cocoa/images/pluscursor.png b/src/plugins/platforms/cocoa/images/pluscursor.png
new file mode 100644
index 0000000000..c583c088c9
--- /dev/null
+++ b/src/plugins/platforms/cocoa/images/pluscursor.png
Binary files differ
diff --git a/src/plugins/platforms/cocoa/images/spincursor.png b/src/plugins/platforms/cocoa/images/spincursor.png
new file mode 100644
index 0000000000..ca44ab50fd
--- /dev/null
+++ b/src/plugins/platforms/cocoa/images/spincursor.png
Binary files differ
diff --git a/src/plugins/platforms/cocoa/images/waitcursor.png b/src/plugins/platforms/cocoa/images/waitcursor.png
new file mode 100644
index 0000000000..a9abe61320
--- /dev/null
+++ b/src/plugins/platforms/cocoa/images/waitcursor.png
Binary files differ
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h
new file mode 100644
index 0000000000..5b6b2f48f2
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
+// and many other. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+/*
+ Cocoa Application Categories
+*/
+#include "qglobal.h"
+
+#import <AppKit/AppKit.h>
+QT_FORWARD_DECLARE_CLASS(QApplicationPrivate)
+@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
+
+@interface NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
+- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu;
+- (QApplicationPrivate *)QT_MANGLE_NAMESPACE(qt_qappPrivate);
+- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader);
+- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel;
+
+- (void)qt_sendPostedMessage:(NSEvent *)event;
+- (BOOL)qt_filterEvent:(NSEvent *)event;
+@end
+
+@interface QNSApplication : NSApplication {
+}
+@end
+
+QT_BEGIN_NAMESPACE
+
+void qt_redirectNSApplicationSendEvent();
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
new file mode 100644
index 0000000000..2adf6a57f0
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include <qcocoaapplication.h>
+
+#include <qcocoaapplicationdelegate.h>
+#include <qcocoahelpers.h>
+#include <qguiapplication.h>
+#include <qdebug.h>
+
+QT_USE_NAMESPACE
+
+@implementation NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
+
+- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu
+{
+ [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] setDockMenu:newMenu];
+}
+
+- (QApplicationPrivate *)QT_MANGLE_NAMESPACE(qt_qappPrivate)
+{
+ return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] qAppPrivate];
+}
+
+- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)
+{
+ return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader];
+}
+
+- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel
+{
+ Q_UNUSED(fontPanel);
+ // only display those things that QFont can handle
+ return NSFontPanelFaceModeMask
+ | NSFontPanelSizeModeMask
+ | NSFontPanelCollectionModeMask
+ | NSFontPanelUnderlineEffectModeMask
+ | NSFontPanelStrikethroughEffectModeMask;
+}
+
+- (void)qt_sendPostedMessage:(NSEvent *)event
+{
+/*
+ // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5!
+ // That is why we need to split the address in two parts:
+ quint64 lower = [event data1];
+ quint64 upper = [event data2];
+ QCocoaPostMessageArgs *args = reinterpret_cast<QCocoaPostMessageArgs *>(lower | (upper << 32));
+ // Special case for convenience: if the argument is an NSNumber, we unbox it directly.
+ // Use NSValue instead if this behaviour is unwanted.
+ id a1 = ([args->arg1 isKindOfClass:[NSNumber class]]) ? (id)[args->arg1 intValue] : args->arg1;
+ id a2 = ([args->arg2 isKindOfClass:[NSNumber class]]) ? (id)[args->arg2 intValue] : args->arg2;
+ switch (args->argCount) {
+ case 0:
+ [args->target performSelector:args->selector];
+ break;
+ case 1:
+ [args->target performSelector:args->selector withObject:a1];
+ break;
+ case 3:
+ [args->target performSelector:args->selector withObject:a1 withObject:a2];
+ break;
+ }
+
+ delete args;
+*/
+}
+
+- (BOOL)qt_filterEvent:(NSEvent *)event
+{
+/*
+ if (qApp->macEventFilter(0, reinterpret_cast<EventRef>(event)))
+ return true;
+
+ if ([event type] == NSApplicationDefined) {
+ switch ([event subtype]) {
+ case QtCocoaEventSubTypePostMessage:
+ [NSApp qt_sendPostedMessage:event];
+ return true;
+ default:
+ break;
+ }
+ }
+*/
+ return false;
+}
+
+@end
+
+@implementation QNSApplication
+
+- (void)qt_sendEvent_original:(NSEvent *)event
+{
+ Q_UNUSED(event);
+ // This method will only be used as a signature
+ // template for the method we add into NSApplication
+ // containing the original [NSApplication sendEvent:] implementation
+}
+
+- (void)qt_sendEvent_replacement:(NSEvent *)event
+{
+ // This method (or its implementation to be precise) will
+ // be called instead of sendEvent if redirection occurs.
+ // 'self' will then be an instance of NSApplication
+ // (and not QNSApplication)
+ if (![NSApp qt_filterEvent:event])
+ [self qt_sendEvent_original:event];
+}
+
+- (void)sendEvent:(NSEvent *)event
+{
+ // This method will be called if
+ // no redirection occurs
+ if (![NSApp qt_filterEvent:event])
+ [super sendEvent:event];
+}
+
+- (void)qtDispatcherToQAction:(id)sender
+{
+ // Forward actions sendt from the menu bar (e.g. quit) to the menu loader.
+ // Having this method here means that we are the last stop in the responder
+ // chain, and that we are able to handle menu actions even when no window is
+ // visible on screen. Note: If Qt is used as a plugin, Qt will not use a
+ // native menu bar. Hence, we will also not need to do any redirection etc. as
+ // we do with sendEvent.
+ [[NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)] qtDispatcherToQAction:sender];
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+
+void qt_redirectNSApplicationSendEvent()
+{
+/*
+ if ([NSApp isMemberOfClass:[QNSApplication class]]) {
+ // No need to change implementation since Qt
+ // already controls a subclass of NSApplication
+ return;
+ }
+
+ // Change the implementation of [NSApplication sendEvent] to the
+ // implementation of qt_sendEvent_replacement found in QNSApplication.
+ // And keep the old implementation that gets overwritten inside a new
+ // method 'qt_sendEvent_original' that we add to NSApplication
+ qt_cocoa_change_implementation(
+ [NSApplication class],
+ @selector(sendEvent:),
+ [QNSApplication class],
+ @selector(qt_sendEvent_replacement:),
+ @selector(qt_sendEvent_original:));
+ */
+ }
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
new file mode 100644
index 0000000000..7f8d1dfacd
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+/****************************************************************************
+ **
+ ** Copyright (c) 2007-2008, Apple, Inc.
+ **
+ ** All rights reserved.
+ **
+ ** Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are met:
+ **
+ ** * Redistributions of source code must retain the above copyright notice,
+ ** this list of conditions and the following disclaimer.
+ **
+ ** * Redistributions in binary form must reproduce the above copyright notice,
+ ** this list of conditions and the following disclaimer in the documentation
+ ** and/or other materials provided with the distribution.
+ **
+ ** * Neither the name of Apple, Inc. nor the names of its contributors
+ ** may be used to endorse or promote products derived from this software
+ ** without specific prior written permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ **
+ ****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
+// and many other. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#import <Cocoa/Cocoa.h>
+
+#include <qglobal.h>
+
+QT_FORWARD_DECLARE_CLASS(QApplicationPrivate);
+
+@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+
+@protocol NSApplicationDelegate <NSObject>
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames;
+- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
+- (void)applicationDidBecomeActive:(NSNotification *)notification;
+- (void)applicationDidResignActive:(NSNotification *)notification;
+@end
+
+#endif
+
+@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate> {
+ bool startedQuit;
+ QApplicationPrivate *qtPrivate;
+ NSMenu *dockMenu;
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader;
+ NSObject <NSApplicationDelegate> *reflectionDelegate;
+ bool inLaunch;
+}
++ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate;
+- (void)setDockMenu:(NSMenu *)newMenu;
+- (void)setQtPrivate:(QApplicationPrivate *)value;
+- (QApplicationPrivate *)qAppPrivate;
+- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader)*)menuLoader;
+- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader;
+- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate;
+- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
+@end
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
new file mode 100644
index 0000000000..6a2508359b
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -0,0 +1,354 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+ **
+ ** Copyright (c) 2007-2008, Apple, Inc.
+ **
+ ** All rights reserved.
+ **
+ ** Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are met:
+ **
+ ** * Redistributions of source code must retain the above copyright notice,
+ ** this list of conditions and the following disclaimer.
+ **
+ ** * Redistributions in binary form must reproduce the above copyright notice,
+ ** this list of conditions and the following disclaimer in the documentation
+ ** and/or other materials provided with the distribution.
+ **
+ ** * Neither the name of Apple, Inc. nor the names of its contributors
+ ** may be used to endorse or promote products derived from this software
+ ** without specific prior written permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ **
+ ****************************************************************************/
+
+
+#import "qcocoaapplicationdelegate.h"
+#import "qnswindowdelegate.h"
+#include <qevent.h>
+#include <qurl.h>
+#include <qdebug.h>
+#include <qguiapplication.h>
+
+QT_USE_NAMESPACE
+
+static QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *sharedCocoaApplicationDelegate = nil;
+
+static void cleanupCocoaApplicationDelegate()
+{
+ [sharedCocoaApplicationDelegate release];
+}
+
+@implementation QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)
+
+- (id)init
+{
+ self = [super init];
+ if (self)
+ inLaunch = true;
+ return self;
+}
+
+- (void)dealloc
+{
+ sharedCocoaApplicationDelegate = nil;
+ [dockMenu release];
+ [qtMenuLoader release];
+ if (reflectionDelegate) {
+ [NSApp setDelegate:reflectionDelegate];
+ [reflectionDelegate release];
+ }
+ [super dealloc];
+}
+
++ (id)allocWithZone:(NSZone *)zone
+{
+ @synchronized(self) {
+ if (sharedCocoaApplicationDelegate == nil) {
+ sharedCocoaApplicationDelegate = [super allocWithZone:zone];
+ return sharedCocoaApplicationDelegate;
+ qAddPostRoutine(cleanupCocoaApplicationDelegate);
+ }
+ }
+ return nil;
+}
+
++ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate
+{
+ @synchronized(self) {
+ if (sharedCocoaApplicationDelegate == nil)
+ [[self alloc] init];
+ }
+ return [[sharedCocoaApplicationDelegate retain] autorelease];
+}
+
+- (void)setDockMenu:(NSMenu*)newMenu
+{
+ [newMenu retain];
+ [dockMenu release];
+ dockMenu = newMenu;
+}
+
+- (NSMenu *)applicationDockMenu
+{
+ return [[dockMenu retain] autorelease];
+}
+
+- (QApplicationPrivate *)qAppPrivate
+{
+ return qtPrivate;
+}
+
+- (void)setQtPrivate:(QApplicationPrivate *)value
+{
+ qtPrivate = value;
+}
+
+- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
+{
+ [menuLoader retain];
+ [qtMenuLoader release];
+ qtMenuLoader = menuLoader;
+}
+
+- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
+{
+ return [[qtMenuLoader retain] autorelease];
+}
+
+// This function will only be called when NSApp is actually running. Before
+// that, the kAEQuitApplication Apple event will be sent to
+// QApplicationPrivate::globalAppleEventProcessor in qapplication_mac.mm
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+/*
+ Q_UNUSED(sender);
+ // The reflection delegate gets precedence
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)]) {
+ return [reflectionDelegate applicationShouldTerminate:sender];
+ }
+
+ if (qtPrivate->canQuit()) {
+ if (!startedQuit) {
+ startedQuit = true;
+ qAppInstance()->quit();
+ startedQuit = false;
+ }
+ }
+
+ if (qtPrivate->threadData->eventLoops.size() == 0) {
+ // INVARIANT: No event loop is executing. This probably
+ // means that Qt is used as a plugin, or as a part of a native
+ // Cocoa application. In any case it should be fine to
+ // terminate now:
+ return NSTerminateNow;
+ }
+
+ return NSTerminateCancel;
+*/
+ return NSTerminateNow;
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+ Q_UNUSED(aNotification);
+ inLaunch = false;
+ // qt_release_apple_event_handler();
+
+
+ // Insert code here to initialize your application
+}
+
+
+
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
+{
+/*
+ for (NSString *fileName in filenames) {
+ QString qtFileName = qt_mac_NSStringToQString(fileName);
+ if (inLaunch) {
+ // We need to be careful because Cocoa will be nice enough to take
+ // command line arguments and send them to us as events. Given the history
+ // of Qt Applications, this will result in behavior people don't want, as
+ // they might be doing the opening themselves with the command line parsing.
+ if (qApp->arguments().contains(qtFileName))
+ continue;
+ }
+ QFileOpenEvent foe(qtFileName);
+ qt_sendSpontaneousEvent(qAppInstance(), &foe);
+ }
+
+ if (reflectionDelegate &&
+ [reflectionDelegate respondsToSelector:@selector(application:openFiles:)])
+ [reflectionDelegate application:sender openFiles:filenames];
+*/
+}
+
+- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
+{
+ // If we have a reflection delegate, that will get to call the shots.
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:
+ @selector(applicationShouldTerminateAfterLastWindowClosed:)])
+ return [reflectionDelegate applicationShouldTerminateAfterLastWindowClosed:sender];
+ return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together.
+}
+
+
+- (void)applicationDidBecomeActive:(NSNotification *)notification
+{
+/*
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationDidBecomeActive:)])
+ [reflectionDelegate applicationDidBecomeActive:notification];
+
+ onApplicationChangedActivation(true);
+
+ if (!QWidget::mouseGrabber()){
+ // Update enter/leave immidiatly, don't wait for a move event. But only
+ // if no grab exists (even if the grab points to this widget, it seems, ref X11)
+ QPoint qlocal, qglobal;
+ QWidget *widgetUnderMouse = 0;
+ qt_mac_getTargetForMouseEvent(0, QEvent::Enter, qlocal, qglobal, 0, &widgetUnderMouse);
+ QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, 0);
+ qt_last_mouse_receiver = widgetUnderMouse;
+ qt_last_native_mouse_receiver = widgetUnderMouse ?
+ (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0;
+ }
+*/
+}
+
+- (void)applicationDidResignActive:(NSNotification *)notification
+{
+/*
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationDidResignActive:)])
+ [reflectionDelegate applicationDidResignActive:notification];
+
+ onApplicationChangedActivation(false);
+
+ if (!QWidget::mouseGrabber())
+ QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
+ qt_last_mouse_receiver = 0;
+ qt_last_native_mouse_receiver = 0;
+ qt_button_down = 0;
+*/
+}
+
+- (void)applicationDidChangeScreenParameters:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ //QDesktopWidgetImplementation::instance()->onResize();
+}
+
+- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate
+{
+ [oldDelegate retain];
+ [reflectionDelegate release];
+ reflectionDelegate = oldDelegate;
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
+{
+ NSMethodSignature *result = [super methodSignatureForSelector:aSelector];
+ if (!result && reflectionDelegate) {
+ result = [reflectionDelegate methodSignatureForSelector:aSelector];
+ }
+ return result;
+}
+
+- (BOOL)respondsToSelector:(SEL)aSelector
+{
+ BOOL result = [super respondsToSelector:aSelector];
+ if (!result && reflectionDelegate)
+ result = [reflectionDelegate respondsToSelector:aSelector];
+ return result;
+}
+
+- (void)forwardInvocation:(NSInvocation *)invocation
+{
+ SEL invocationSelector = [invocation selector];
+ if (reflectionDelegate && [reflectionDelegate respondsToSelector:invocationSelector])
+ [invocation invokeWithTarget:reflectionDelegate];
+ else
+ [self doesNotRecognizeSelector:invocationSelector];
+}
+
+- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
+{
+ Q_UNUSED(replyEvent);
+/*
+ NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
+ QUrl url(qt_mac_NSStringToQString(urlString));
+ QFileOpenEvent qtEvent(url);
+ qt_sendSpontaneousEvent(qAppInstance(), &qtEvent);
+*/
+}
+
+- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
+{
+ Q_UNUSED(event);
+ Q_UNUSED(replyEvent);
+ qDebug() << "appleEventQuit";
+
+ [NSApp terminate:self];
+}
+
+- (void)qtDispatcherToQAction:(id)sender
+{
+ //[[NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)] qtDispatcherToQAction:sender];
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
index 862bc27f9d..359b5d34d0 100644
--- a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
+++ b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
@@ -42,6 +42,8 @@
#ifndef QCOCOAAUTORELEASEPOOL_H
#define QCOCOAAUTORELEASEPOOL_H
+#undef slots
+
#include <Cocoa/Cocoa.h>
class QCocoaAutoReleasePool
diff --git a/src/plugins/platforms/cocoa/qcocoawindowsurface.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 95eea2b7ea..938e27347c 100644
--- a/src/plugins/platforms/cocoa/qcocoawindowsurface.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -39,33 +39,31 @@
**
****************************************************************************/
-#ifndef QWINDOWSURFACE_COCOA_H
-#define QWINDOWSURFACE_COCOA_H
+#ifndef QBACKINGSTORE_COCOA_H
+#define QBACKINGSTORE_COCOA_H
#include <Cocoa/Cocoa.h>
#include "qcocoawindow.h"
#include "qnsview.h"
-#include <QtGui/private/qwindowsurface_p.h>
+#include <QPlatformBackingStore>
QT_BEGIN_NAMESPACE
-class QCocoaWindowSurface : public QWindowSurface
+class QCocoaBackingStore : public QPlatformBackingStore
{
public:
- QCocoaWindowSurface(QWidget *window, WId wid);
- ~QCocoaWindowSurface();
+ QCocoaBackingStore(QWindow *window);
+ ~QCocoaBackingStore();
QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize (const QSize &size);
+ void flush(QWindow *widget, const QRegion &region, const QPoint &offset);
+ void resize (const QSize &size, const QRegion &);
private:
-
QCocoaWindow *m_cocoaWindow;
QImage *m_image;
- QNSView *m_contentView;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindowsurface.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 16bb327196..5a59fb5c49 100644
--- a/src/plugins/platforms/cocoa/qcocoawindowsurface.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -39,10 +39,9 @@
**
****************************************************************************/
-#include "qcocoawindowsurface.h"
+#include "qcocoabackingstore.h"
#include <QtCore/qdebug.h>
-
#include <QtGui/QPainter>
QT_BEGIN_NAMESPACE
@@ -56,30 +55,28 @@ QRect flipedRect(const QRect &sourceRect,int height)
return flippedRect;
}
-QCocoaWindowSurface::QCocoaWindowSurface(QWidget *window, WId wId)
- : QWindowSurface(window)
+QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
{
- m_cocoaWindow = static_cast<QCocoaWindow *>(window->platformWindow());
+ m_cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
const QRect geo = window->geometry();
NSRect rect = NSMakeRect(geo.x(),geo.y(),geo.width(),geo.height());
- m_contentView = [[QNSView alloc] initWithWidget:window];
- m_cocoaWindow->setContentView(m_contentView);
- m_image = new QImage(window->size(),QImage::Format_ARGB32);
+ m_image = new QImage(window->geometry().size(),QImage::Format_ARGB32);
}
-QCocoaWindowSurface::~QCocoaWindowSurface()
+QCocoaBackingStore::~QCocoaBackingStore()
{
delete m_image;
}
-QPaintDevice *QCocoaWindowSurface::paintDevice()
+QPaintDevice *QCocoaBackingStore::paintDevice()
{
return m_image;
}
-void QCocoaWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QCocoaBackingStore::flush(QWindow *widget, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(widget);
Q_UNUSED(offset);
@@ -87,17 +84,15 @@ void QCocoaWindowSurface::flush(QWidget *widget, const QRegion &region, const QP
QRect geo = region.boundingRect();
NSRect rect = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height());
- [m_contentView displayRect:rect];
+ [m_cocoaWindow->m_contentView displayRect:rect];
}
-void QCocoaWindowSurface::resize(const QSize &size)
+void QCocoaBackingStore::resize(const QSize &size, const QRegion &)
{
- QWindowSurface::resize(size);
delete m_image;
m_image = new QImage(size,QImage::Format_ARGB32_Premultiplied);
NSSize newSize = NSMakeSize(size.width(),size.height());
- [m_contentView setImage:m_image];
-
+ [static_cast<QNSView *>(m_cocoaWindow->m_contentView) setImage:m_image];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
new file mode 100644
index 0000000000..7184db84fa
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#ifndef QEVENTDISPATCHER_MAC_P_H
+#define QEVENTDISPATCHER_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qhash.h>
+#include <QtCore/qstack.h>
+#include <QtGui/qwindowdefs.h>
+#include <QtCore/private/qeventdispatcher_unix_p.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef struct _NSModalSession *NSModalSession;
+typedef struct _QCocoaModalSessionInfo {
+ QPointer<QWindow> window;
+ NSModalSession session;
+ void *nswindow;
+} QCocoaModalSessionInfo;
+
+class QCocoaEventDispatcherPrivate;
+class QCocoaEventDispatcher : public QEventDispatcherUNIX
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QCocoaEventDispatcher)
+
+public:
+ QCocoaEventDispatcher(QAbstractEventDispatcherPrivate &priv, QObject *parent = 0);
+ explicit QCocoaEventDispatcher(QObject *parent = 0);
+ ~QCocoaEventDispatcher();
+
+
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
+ bool hasPendingEvents();
+
+ void registerSocketNotifier(QSocketNotifier *notifier);
+ void unregisterSocketNotifier(QSocketNotifier *notifier);
+
+ void registerTimer(int timerId, int interval, QObject *object);
+ bool unregisterTimer(int timerId);
+ bool unregisterTimers(QObject *object);
+ QList<TimerInfo> registeredTimers(QObject *object) const;
+
+ void wakeUp();
+ void interrupt();
+
+private:
+ //friend void qt_mac_select_timer_callbk(__EventLoopTimer*, void*);
+ friend class QApplicationPrivate;
+};
+
+struct MacTimerInfo {
+ int id;
+ int interval;
+ QObject *obj;
+ bool pending;
+ CFRunLoopTimerRef runLoopTimer;
+ bool operator==(const MacTimerInfo &other)
+ {
+ return (id == other.id);
+ }
+};
+typedef QHash<int, MacTimerInfo *> MacTimerHash;
+
+struct MacSocketInfo {
+ MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {}
+ CFSocketRef socket;
+ CFRunLoopSourceRef runloop;
+ QObject *readNotifier;
+ QObject *writeNotifier;
+};
+typedef QHash<int, MacSocketInfo *> MacSocketHash;
+
+class QCocoaEventDispatcherPrivate : public QEventDispatcherUNIXPrivate
+{
+ Q_DECLARE_PUBLIC(QCocoaEventDispatcher)
+
+public:
+ QCocoaEventDispatcherPrivate();
+
+ static MacTimerHash macTimerHash;
+ // Set 'blockSendPostedEvents' to true if you _really_ need
+ // to make sure that qt events are not posted while calling
+ // low-level cocoa functions (like beginModalForWindow). And
+ // use a QBoolBlocker to be safe:
+ static bool blockSendPostedEvents;
+ // The following variables help organizing modal sessions:
+ static QStack<QCocoaModalSessionInfo> cocoaModalSessionStack;
+ static bool currentExecIsNSAppRun;
+ static bool nsAppRunCalledByQt;
+ static bool cleanupModalSessionsNeeded;
+ static NSModalSession currentModalSessionCached;
+ static NSModalSession currentModalSession();
+ static void updateChildrenWorksWhenModal();
+ static void temporarilyStopAllModalSessions();
+ static void beginModalSession(QWindow *widget);
+ static void endModalSession(QWindow *widget);
+ static void cancelWaitForMoreEvents();
+ static void cleanupModalSessions();
+ static void ensureNSAppInitialized();
+
+ MacSocketHash macSockets;
+ QList<void *> queuedUserInputEvents; // NSEvent *
+ CFRunLoopSourceRef postedEventsSource;
+ CFRunLoopObserverRef waitingObserver;
+ CFRunLoopObserverRef firstTimeObserver;
+ QAtomicInt serialNumber;
+ int lastSerial;
+ static bool interrupt;
+private:
+ static Boolean postedEventSourceEqualCallback(const void *info1, const void *info2);
+ static void postedEventsSourcePerformCallback(void *info);
+ static void activateTimer(CFRunLoopTimerRef, void *info);
+ static void waitingObserverCallback(CFRunLoopObserverRef observer,
+ CFRunLoopActivity activity, void *info);
+ static void firstLoopEntry(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info);
+ friend void processPostedEvents(QCocoaEventDispatcherPrivate *const d, const bool blockSendPostedEvents);
+};
+
+class QtCocoaInterruptDispatcher : public QObject
+{
+ static QtCocoaInterruptDispatcher *instance;
+ bool cancelled;
+
+ QtCocoaInterruptDispatcher();
+ ~QtCocoaInterruptDispatcher();
+
+ public:
+ static void interruptLater();
+ static void cancelInterruptLater();
+};
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_MAC_P_H
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
new file mode 100644
index 0000000000..9525b47c65
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -0,0 +1,1123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include "qcocoaeventdispatcher.h"
+#include "qcocoaautoreleasepool.h"
+
+#include "qguiapplication.h"
+#include "qevent.h"
+#include "qhash.h"
+#include "qmutex.h"
+#include "qsocketnotifier.h"
+#include <qplatformwindow_qpa.h>
+#include "private/qthread_p.h"
+#include "private/qguiapplication_p.h"
+#include <qdebug.h>
+
+#undef slots
+#include <Cocoa/Cocoa.h>
+#include <Carbon/Carbon.h>
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+enum {
+ QtCocoaEventSubTypeWakeup = SHRT_MAX,
+ QtCocoaEventSubTypePostMessage = SHRT_MAX-1
+};
+
+static inline CFRunLoopRef mainRunLoop()
+{
+ return CFRunLoopGetMain();
+}
+
+/*****************************************************************************
+ Timers stuff
+ *****************************************************************************/
+
+/* timer call back */
+void QCocoaEventDispatcherPrivate::activateTimer(CFRunLoopTimerRef, void *info)
+{
+ int timerID =
+#ifdef Q_OS_MAC64
+ qint64(info);
+#else
+ int(info);
+#endif
+
+ MacTimerInfo *tmr;
+ tmr = macTimerHash.value(timerID);
+ if (tmr == 0 || tmr->pending == true)
+ return; // Can't send another timer event if it's pending.
+
+
+ if (blockSendPostedEvents) {
+ QCoreApplication::postEvent(tmr->obj, new QTimerEvent(tmr->id));
+ } else {
+ tmr->pending = true;
+ QTimerEvent e(tmr->id);
+
+ QCoreApplication::sendSpontaneousEvent(tmr->obj, &e);
+ // Get the value again in case the timer gets unregistered during the sendEvent.
+ tmr = macTimerHash.value(timerID);
+ if (tmr != 0)
+ tmr->pending = false;
+ }
+
+}
+
+void QCocoaEventDispatcher::registerTimer(int timerId, int interval, QObject *obj)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1 || interval < 0 || !obj) {
+ qWarning("QEventDispatcherMac::registerTimer: invalid arguments");
+ return;
+ } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QObject::startTimer: timers cannot be started from another thread");
+ return;
+ }
+#endif
+
+ MacTimerInfo *t = new MacTimerInfo();
+ t->id = timerId;
+ t->interval = interval;
+ t->obj = obj;
+ t->runLoopTimer = 0;
+ t->pending = false;
+
+ CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent();
+ CFTimeInterval cfinterval = qMax(CFTimeInterval(interval) / 1000, 0.0000001);
+ fireDate += cfinterval;
+ QCocoaEventDispatcherPrivate::macTimerHash.insert(timerId, t);
+ CFRunLoopTimerContext info = { 0, (void *)timerId, 0, 0, 0 };
+ t->runLoopTimer = CFRunLoopTimerCreate(0, fireDate, cfinterval, 0, 0,
+ QCocoaEventDispatcherPrivate::activateTimer, &info);
+ if (t->runLoopTimer == 0) {
+ qFatal("QEventDispatcherMac::registerTimer: Cannot create timer");
+ }
+ CFRunLoopAddTimer(mainRunLoop(), t->runLoopTimer, kCFRunLoopCommonModes);
+}
+
+bool QCocoaEventDispatcher::unregisterTimer(int identifier)
+{
+#ifndef QT_NO_DEBUG
+ if (identifier < 1) {
+ qWarning("QEventDispatcherMac::unregisterTimer: invalid argument");
+ return false;
+ } else if (thread() != QThread::currentThread()) {
+ qWarning("QObject::killTimer: timers cannot be stopped from another thread");
+ return false;
+ }
+#endif
+ if (identifier <= 0)
+ return false; // not init'd or invalid timer
+
+ MacTimerInfo *timerInfo = QCocoaEventDispatcherPrivate::macTimerHash.take(identifier);
+ if (timerInfo == 0)
+ return false;
+
+ if (!QObjectPrivate::get(timerInfo->obj)->inThreadChangeEvent)
+ QAbstractEventDispatcherPrivate::releaseTimerId(identifier);
+ CFRunLoopTimerInvalidate(timerInfo->runLoopTimer);
+ CFRelease(timerInfo->runLoopTimer);
+ delete timerInfo;
+
+ return true;
+}
+
+bool QCocoaEventDispatcher::unregisterTimers(QObject *obj)
+{
+#ifndef QT_NO_DEBUG
+ if (!obj) {
+ qWarning("QEventDispatcherMac::unregisterTimers: invalid argument");
+ return false;
+ } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QObject::killTimers: timers cannot be stopped from another thread");
+ return false;
+ }
+#endif
+
+ MacTimerHash::iterator it = QCocoaEventDispatcherPrivate::macTimerHash.begin();
+ while (it != QCocoaEventDispatcherPrivate::macTimerHash.end()) {
+ MacTimerInfo *timerInfo = it.value();
+ if (timerInfo->obj != obj) {
+ ++it;
+ } else {
+ if (!QObjectPrivate::get(timerInfo->obj)->inThreadChangeEvent)
+ QAbstractEventDispatcherPrivate::releaseTimerId(timerInfo->id);
+ CFRunLoopTimerInvalidate(timerInfo->runLoopTimer);
+ CFRelease(timerInfo->runLoopTimer);
+ delete timerInfo;
+ it = QCocoaEventDispatcherPrivate::macTimerHash.erase(it);
+ }
+ }
+ return true;
+}
+
+QList<QCocoaEventDispatcher::TimerInfo>
+QCocoaEventDispatcher::registeredTimers(QObject *object) const
+{
+ if (!object) {
+ qWarning("QEventDispatcherMac:registeredTimers: invalid argument");
+ return QList<TimerInfo>();
+ }
+
+ QList<TimerInfo> list;
+
+ MacTimerHash::const_iterator it = QCocoaEventDispatcherPrivate::macTimerHash.constBegin();
+ while (it != QCocoaEventDispatcherPrivate::macTimerHash.constEnd()) {
+ MacTimerInfo *t = it.value();
+ if (t->obj == object)
+ list << TimerInfo(t->id, t->interval);
+ ++it;
+ }
+ return list;
+}
+
+/**************************************************************************
+ Socket Notifiers
+ *************************************************************************/
+void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef,
+ const void *, void *info) {
+ QCocoaEventDispatcherPrivate *const eventDispatcher
+ = static_cast<QCocoaEventDispatcherPrivate *>(info);
+ int nativeSocket = CFSocketGetNative(s);
+ MacSocketInfo *socketInfo = eventDispatcher->macSockets.value(nativeSocket);
+ QEvent notifierEvent(QEvent::SockAct);
+
+ // There is a race condition that happen where we disable the notifier and
+ // the kernel still has a notification to pass on. We then get this
+ // notification after we've successfully disabled the CFSocket, but our Qt
+ // notifier is now gone. The upshot is we have to check the notifier
+ // everytime.
+ if (callbackType == kCFSocketReadCallBack) {
+ if (socketInfo->readNotifier)
+ QGuiApplication::sendEvent(socketInfo->readNotifier, &notifierEvent);
+ } else if (callbackType == kCFSocketWriteCallBack) {
+ if (socketInfo->writeNotifier)
+ QGuiApplication::sendEvent(socketInfo->writeNotifier, &notifierEvent);
+ }
+}
+
+/*
+ Adds a loop source for the given socket to the current run loop.
+*/
+CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket)
+{
+ CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
+ if (!loopSource)
+ return 0;
+
+ CFRunLoopAddSource(mainRunLoop(), loopSource, kCFRunLoopCommonModes);
+ return loopSource;
+}
+
+/*
+ Removes the loop source for the given socket from the current run loop.
+*/
+void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop)
+{
+ Q_ASSERT(runloop);
+ CFRunLoopRemoveSource(mainRunLoop(), runloop, kCFRunLoopCommonModes);
+ CFSocketDisableCallBacks(socket, kCFSocketReadCallBack);
+ CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack);
+ CFRunLoopSourceInvalidate(runloop);
+}
+
+/*
+ Register a QSocketNotifier with the mac event system by creating a CFSocket with
+ with a read/write callback.
+
+ Qt has separate socket notifiers for reading and writing, but on the mac there is
+ a limitation of one CFSocket object for each native socket.
+*/
+void QCocoaEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_ASSERT(notifier);
+ int nativeSocket = notifier->socket();
+ int type = notifier->type();
+#ifndef QT_NO_DEBUG
+ if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
+ qWarning("QSocketNotifier: Internal error");
+ return;
+ } else if (notifier->thread() != thread()
+ || thread() != QThread::currentThread()) {
+ qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
+ return;
+ }
+#endif
+
+ Q_D(QCocoaEventDispatcher);
+
+ if (type == QSocketNotifier::Exception) {
+ qWarning("QSocketNotifier::Exception is not supported on Mac OS X");
+ return;
+ }
+
+ // Check if we have a CFSocket for the native socket, create one if not.
+ MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket);
+ if (!socketInfo) {
+ socketInfo = new MacSocketInfo();
+
+ // Create CFSocket, specify that we want both read and write callbacks (the callbacks
+ // are enabled/disabled later on).
+ const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack;
+ CFSocketContext context = {0, d, 0, 0, 0};
+ socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context);
+ if (CFSocketIsValid(socketInfo->socket) == false) {
+ qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket");
+ return;
+ }
+
+ CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket);
+ flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write
+ flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation
+ CFSocketSetSocketFlags(socketInfo->socket, flags);
+
+ // Add CFSocket to runloop.
+ if(!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) {
+ qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop");
+ CFSocketInvalidate(socketInfo->socket);
+ CFRelease(socketInfo->socket);
+ return;
+ }
+
+ // Disable both callback types by default. This must be done after
+ // we add the CFSocket to the runloop, or else these calls will have
+ // no effect.
+ CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
+ CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
+
+ d->macSockets.insert(nativeSocket, socketInfo);
+ }
+
+ // Increment read/write counters and select enable callbacks if necessary.
+ if (type == QSocketNotifier::Read) {
+ Q_ASSERT(socketInfo->readNotifier == 0);
+ socketInfo->readNotifier = notifier;
+ CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
+ } else if (type == QSocketNotifier::Write) {
+ Q_ASSERT(socketInfo->writeNotifier == 0);
+ socketInfo->writeNotifier = notifier;
+ CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
+ }
+}
+
+/*
+ Unregister QSocketNotifer. The CFSocket correspoding to this notifier is
+ removed from the runloop of this is the last notifier that users
+ that CFSocket.
+*/
+void QCocoaEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_ASSERT(notifier);
+ int nativeSocket = notifier->socket();
+ int type = notifier->type();
+#ifndef QT_NO_DEBUG
+ if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
+ qWarning("QSocketNotifier: Internal error");
+ return;
+ } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
+ return;
+ }
+#endif
+
+ Q_D(QCocoaEventDispatcher);
+
+ if (type == QSocketNotifier::Exception) {
+ qWarning("QSocketNotifier::Exception is not supported on Mac OS X");
+ return;
+ }
+ MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket);
+ if (!socketInfo) {
+ qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier");
+ return;
+ }
+
+ // Decrement read/write counters and disable callbacks if necessary.
+ if (type == QSocketNotifier::Read) {
+ Q_ASSERT(notifier == socketInfo->readNotifier);
+ socketInfo->readNotifier = 0;
+ CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
+ } else if (type == QSocketNotifier::Write) {
+ Q_ASSERT(notifier == socketInfo->writeNotifier);
+ socketInfo->writeNotifier = 0;
+ CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
+ }
+
+ // Remove CFSocket from runloop if this was the last QSocketNotifier.
+ if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) {
+ if (CFSocketIsValid(socketInfo->socket))
+ qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop);
+ CFRunLoopSourceInvalidate(socketInfo->runloop);
+ CFRelease(socketInfo->runloop);
+ CFSocketInvalidate(socketInfo->socket);
+ CFRelease(socketInfo->socket);
+ delete socketInfo;
+ d->macSockets.remove(nativeSocket);
+ }
+}
+
+bool QCocoaEventDispatcher::hasPendingEvents()
+{
+ extern uint qGlobalPostedEventsCount();
+ extern bool qt_is_gui_used; //qapplication.cpp
+ return qGlobalPostedEventsCount() || (qt_is_gui_used && GetNumEventsInQueue(GetMainEventQueue()));
+}
+
+static bool IsMouseOrKeyEvent( NSEvent* event )
+{
+ bool result = false;
+
+ switch( [event type] )
+ {
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSMouseMoved: // ??
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSMouseEntered:
+ case NSMouseExited:
+ case NSKeyDown:
+ case NSKeyUp:
+ case NSFlagsChanged: // key modifiers changed?
+ case NSCursorUpdate: // ??
+ case NSScrollWheel:
+ case NSTabletPoint:
+ case NSTabletProximity:
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+ case NSOtherMouseDragged:
+#ifndef QT_NO_GESTURES
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ case NSEventTypeGesture: // touch events
+ case NSEventTypeMagnify:
+ case NSEventTypeSwipe:
+ case NSEventTypeRotate:
+ case NSEventTypeBeginGesture:
+ case NSEventTypeEndGesture:
+#endif
+#endif // QT_NO_GESTURES
+ result = true;
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+static inline void qt_mac_waitForMoreEvents()
+{
+ // If no event exist in the cocoa event que, wait
+ // (and free up cpu time) until at least one event occur.
+ // This implementation is a bit on the edge, but seems to
+ // work fine:
+ NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantFuture]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ if (event)
+ [NSApp postEvent:event atStart:YES];
+}
+
+static inline void qt_mac_waitForMoreModalSessionEvents()
+{
+ // If no event exist in the cocoa event que, wait
+ // (and free up cpu time) until at least one event occur.
+ // This implementation is a bit on the edge, but seems to
+ // work fine:
+ NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantFuture]
+ inMode:NSModalPanelRunLoopMode
+ dequeue:YES];
+ if (event)
+ [NSApp postEvent:event atStart:YES];
+}
+
+bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ Q_D(QCocoaEventDispatcher);
+ d->interrupt = false;
+
+ bool interruptLater = false;
+ QtCocoaInterruptDispatcher::cancelInterruptLater();
+
+ // In case we end up recursing while we now process events, make sure
+ // that we send remaining posted Qt events before this call returns:
+ wakeUp();
+ emit awake();
+
+ bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents;
+ bool retVal = false;
+ forever {
+ if (d->interrupt)
+ break;
+
+ QCocoaAutoReleasePool pool;
+ NSEvent* event = 0;
+
+ // First, send all previously excluded input events, if any:
+ if (!excludeUserEvents) {
+ while (!d->queuedUserInputEvents.isEmpty()) {
+ event = static_cast<NSEvent *>(d->queuedUserInputEvents.takeFirst());
+ if (!filterEvent(event)) {
+ [NSApp sendEvent:event];
+ retVal = true;
+ }
+ [event release];
+ }
+ }
+
+ // If Qt is used as a plugin, or as an extension in a native cocoa
+ // application, we should not run or stop NSApplication; This will be
+ // done from the application itself. And if processEvents is called
+ // manually (rather than from a QEventLoop), we cannot enter a tight
+ // loop and block this call, but instead we need to return after one flush.
+ // Finally, if we are to exclude user input events, we cannot call [NSApp run]
+ // as we then loose control over which events gets dispatched:
+ const bool canExec_3rdParty = d->nsAppRunCalledByQt || ![NSApp isRunning];
+ const bool canExec_Qt = !excludeUserEvents &&
+ (flags & QEventLoop::DialogExec || flags & QEventLoop::EventLoopExec) ;
+
+ if (canExec_Qt && canExec_3rdParty) {
+ // We can use exec-mode, meaning that we can stay in a tight loop until
+ // interrupted. This is mostly an optimization, but it allow us to use
+ // [NSApp run], which is the normal code path for cocoa applications.
+ if (NSModalSession session = d->currentModalSession()) {
+ QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
+ while ([NSApp runModalSession:session] == NSRunContinuesResponse && !d->interrupt)
+ qt_mac_waitForMoreModalSessionEvents();
+
+ if (!d->interrupt && session == d->currentModalSessionCached) {
+ // Someone called [NSApp stopModal:] from outside the event
+ // dispatcher (e.g to stop a native dialog). But that call wrongly stopped
+ // 'session' as well. As a result, we need to restart all internal sessions:
+ d->temporarilyStopAllModalSessions();
+ }
+ } else {
+ d->nsAppRunCalledByQt = true;
+ QBoolBlocker execGuard(d->currentExecIsNSAppRun, true);
+ [NSApp run];
+ }
+ retVal = true;
+ } else {
+ // We cannot block the thread (and run in a tight loop).
+ // Instead we will process all current pending events and return.
+ d->ensureNSAppInitialized();
+ if (NSModalSession session = d->currentModalSession()) {
+ // INVARIANT: a modal window is executing.
+ if (!excludeUserEvents) {
+ // Since we can dispatch all kinds of events, we choose
+ // to use cocoa's native way of running modal sessions:
+ if (flags & QEventLoop::WaitForMoreEvents)
+ qt_mac_waitForMoreModalSessionEvents();
+ NSInteger status = [NSApp runModalSession:session];
+ if (status != NSRunContinuesResponse && session == d->currentModalSessionCached) {
+ // INVARIANT: Someone called [NSApp stopModal:] from outside the event
+ // dispatcher (e.g to stop a native dialog). But that call wrongly stopped
+ // 'session' as well. As a result, we need to restart all internal sessions:
+ d->temporarilyStopAllModalSessions();
+ }
+ retVal = true;
+ } else do {
+ // Dispatch all non-user events (but que non-user events up for later). In
+ // this case, we need more control over which events gets dispatched, and
+ // cannot use [NSApp runModalSession:session]:
+ event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:nil
+ inMode:NSModalPanelRunLoopMode
+ dequeue: YES];
+
+ if (event) {
+ if (IsMouseOrKeyEvent(event)) {
+ [event retain];
+ d->queuedUserInputEvents.append(event);
+ continue;
+ }
+ if (!filterEvent(event)) {
+ [NSApp sendEvent:event];
+ retVal = true;
+ }
+ }
+ } while (!d->interrupt && event != nil);
+ } else do {
+ // INVARIANT: No modal window is executing.
+ event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:nil
+ inMode:NSDefaultRunLoopMode
+ dequeue: YES];
+
+ if (event) {
+ if (flags & QEventLoop::ExcludeUserInputEvents) {
+ if (IsMouseOrKeyEvent(event)) {
+ [event retain];
+ d->queuedUserInputEvents.append(event);
+ continue;
+ }
+ }
+ if (!filterEvent(event)) {
+ [NSApp sendEvent:event];
+ retVal = true;
+ }
+ }
+ } while (!d->interrupt && event != nil);
+
+ // Be sure to flush the Qt posted events when not using exec mode
+ // (exec mode will always do this call from the event loop source):
+ if (!d->interrupt)
+ QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
+
+ // Since the window that holds modality might have changed while processing
+ // events, we we need to interrupt when we return back the previous process
+ // event recursion to ensure that we spin the correct modal session.
+ // We do the interruptLater at the end of the function to ensure that we don't
+ // disturb the 'wait for more events' below (as deleteLater will post an event):
+ interruptLater = true;
+ }
+ bool canWait = (d->threadData->canWait
+ && !retVal
+ && !d->interrupt
+ && (flags & QEventLoop::WaitForMoreEvents));
+ if (canWait) {
+ // INVARIANT: We haven't processed any events yet. And we're told
+ // to stay inside this function until at least one event is processed.
+ qt_mac_waitForMoreEvents();
+ flags &= ~QEventLoop::WaitForMoreEvents;
+ } else {
+ // Done with event processing for now.
+ // Leave the function:
+ break;
+ }
+ }
+
+ // If we're interrupted, we need to interrupt the _current_
+ // recursion as well to check if it is still supposed to be
+ // executing. This way we wind down the stack until we land
+ // on a recursion that again calls processEvents (typically
+ // from QEventLoop), and set interrupt to false:
+ if (d->interrupt)
+ interrupt();
+
+ if (interruptLater)
+ QtCocoaInterruptDispatcher::interruptLater();
+
+ return retVal;
+}
+
+void QCocoaEventDispatcher::wakeUp()
+{
+ Q_D(QCocoaEventDispatcher);
+ d->serialNumber.ref();
+ CFRunLoopSourceSignal(d->postedEventsSource);
+ CFRunLoopWakeUp(mainRunLoop());
+}
+
+/*****************************************************************************
+ QEventDispatcherMac Implementation
+ *****************************************************************************/
+MacTimerHash QCocoaEventDispatcherPrivate::macTimerHash;
+bool QCocoaEventDispatcherPrivate::blockSendPostedEvents = false;
+bool QCocoaEventDispatcherPrivate::interrupt = false;
+
+
+QStack<QCocoaModalSessionInfo> QCocoaEventDispatcherPrivate::cocoaModalSessionStack;
+bool QCocoaEventDispatcherPrivate::currentExecIsNSAppRun = false;
+bool QCocoaEventDispatcherPrivate::nsAppRunCalledByQt = false;
+bool QCocoaEventDispatcherPrivate::cleanupModalSessionsNeeded = false;
+NSModalSession QCocoaEventDispatcherPrivate::currentModalSessionCached = 0;
+
+void QCocoaEventDispatcherPrivate::ensureNSAppInitialized()
+{
+ // Some elements in Cocoa require NSApplication to be running before
+ // they get fully initialized, in particular the menu bar. This
+ // function is intended for cases where a dialog is told to execute before
+ // QGuiApplication::exec is called, or the application spins the events loop
+ // manually rather than calling QGuiApplication:exec.
+ // The function makes sure that NSApplication starts running, but stops
+ // it again as soon as the send posted events callback is called. That way
+ // we let Cocoa finish the initialization it seems to need. We'll only
+ // apply this trick at most once for any application, and we avoid doing it
+ // for the common case where main just starts QGuiApplication::exec.
+ if (nsAppRunCalledByQt || [NSApp isRunning])
+ return;
+ nsAppRunCalledByQt = true;
+ QBoolBlocker block1(interrupt, true);
+ QBoolBlocker block2(currentExecIsNSAppRun, true);
+ [NSApp run];
+}
+
+void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions()
+{
+ // Flush, and Stop, all created modal session, and as
+ // such, make them pending again. The next call to
+ // currentModalSession will recreate them again. The
+ // reason to stop all session like this is that otherwise
+ // a call [NSApp stop] would not stop NSApp, but rather
+ // the current modal session. So if we need to stop NSApp
+ // we need to stop all the modal session first. To avoid changing
+ // the stacking order of the windows while doing so, we put
+ // up a block that is used in QCocoaWindow and QCocoaPanel:
+ int stackSize = cocoaModalSessionStack.size();
+ for (int i=0; i<stackSize; ++i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (info.session) {
+ [NSApp endModalSession:info.session];
+ info.session = 0;
+ }
+ }
+ currentModalSessionCached = 0;
+}
+
+NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
+{
+ // If we have one or more modal windows, this function will create
+ // a session for each of those, and return the one for the top.
+ if (currentModalSessionCached)
+ return currentModalSessionCached;
+
+ if (cocoaModalSessionStack.isEmpty())
+ return 0;
+
+ int sessionCount = cocoaModalSessionStack.size();
+ for (int i=0; i<sessionCount; ++i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (!info.window)
+ continue;
+// ### port
+// if (info.window->testAttribute(Qt::WA_DontShowOnScreen))
+// continue;
+
+ if (!info.session) {
+ QCocoaAutoReleasePool pool;
+ NSWindow *window = reinterpret_cast<NSWindow *>(info.window->handle()->winId());
+ if (!window)
+ continue;
+
+ ensureNSAppInitialized();
+ QBoolBlocker block1(blockSendPostedEvents, true);
+ info.nswindow = window;
+ [(NSWindow*) info.nswindow retain];
+ int levelBeforeEnterModal = [window level];
+ info.session = [NSApp beginModalSessionForWindow:window];
+ // Make sure we don't stack the window lower that it was before
+ // entering modal, in case it e.g. had the stays-on-top flag set:
+ if (levelBeforeEnterModal > [window level])
+ [window setLevel:levelBeforeEnterModal];
+ }
+ currentModalSessionCached = info.session;
+ cleanupModalSessionsNeeded = false;
+ }
+ return currentModalSessionCached;
+}
+
+static void setChildrenWorksWhenModal(QWindow *window, bool worksWhenModal)
+{
+ // For NSPanels (but not NSWindows, sadly), we can set the flag
+ // worksWhenModal, so that they are active even when they are not modal.
+/*
+ ### not ported
+ QList<QDialog *> dialogs = window->findChildren<QDialog *>();
+ for (int i=0; i<dialogs.size(); ++i){
+ NSWindow *window = qt_mac_window_for(dialogs[i]);
+ if (window && [window isKindOfClass:[NSPanel class]]) {
+ [static_cast<NSPanel *>(window) setWorksWhenModal:worksWhenModal];
+ if (worksWhenModal && [window isVisible]){
+ [window orderFront:window];
+ }
+ }
+ }
+*/
+}
+
+void QCocoaEventDispatcherPrivate::updateChildrenWorksWhenModal()
+{
+ // Make the dialog children of the window
+ // active. And make the dialog children of
+ // the previous modal dialog unactive again:
+ QCocoaAutoReleasePool pool;
+ int size = cocoaModalSessionStack.size();
+ if (size > 0){
+ if (QWindow *prevModal = cocoaModalSessionStack[size-1].window)
+ setChildrenWorksWhenModal(prevModal, true);
+ if (size > 1){
+ if (QWindow *prevModal = cocoaModalSessionStack[size-2].window)
+ setChildrenWorksWhenModal(prevModal, false);
+ }
+ }
+}
+
+void QCocoaEventDispatcherPrivate::cleanupModalSessions()
+{
+ // Go through the list of modal sessions, and end those
+ // that no longer has a window assosiated; no window means
+ // the the session has logically ended. The reason we wait like
+ // this to actually end the sessions for real (rather than at the
+ // point they were marked as stopped), is that ending a session
+ // when no other session runs below it on the stack will make cocoa
+ // drop some events on the floor.
+ QCocoaAutoReleasePool pool;
+ int stackSize = cocoaModalSessionStack.size();
+
+ for (int i=stackSize-1; i>=0; --i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (info.window) {
+ // This session has a window, and is therefore not marked
+ // as stopped. So just make it current. There might still be other
+ // stopped sessions on the stack, but those will be stopped on
+ // a later "cleanup" call.
+ currentModalSessionCached = info.session;
+ break;
+ }
+ cocoaModalSessionStack.remove(i);
+ currentModalSessionCached = 0;
+ if (info.session) {
+ [NSApp endModalSession:info.session];
+ [(NSWindow *)info.nswindow release];
+ }
+ }
+
+ updateChildrenWorksWhenModal();
+ cleanupModalSessionsNeeded = false;
+}
+
+void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
+{
+ // Add a new, empty (null), NSModalSession to the stack.
+ // It will become active the next time QEventDispatcher::processEvents is called.
+ // A QCocoaModalSessionInfo is considered pending to become active if the window pointer
+ // is non-zero, and the session pointer is zero (it will become active upon a call to
+ // currentModalSession). A QCocoaModalSessionInfo is considered pending to be stopped if
+ // the window pointer is zero, and the session pointer is non-zero (it will be fully
+ // stopped in cleanupModalSessions()).
+ QCocoaModalSessionInfo info = {window, 0, 0};
+ cocoaModalSessionStack.push(info);
+ updateChildrenWorksWhenModal();
+ currentModalSessionCached = 0;
+}
+
+void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
+{
+ // Mark all sessions attached to window as pending to be stopped. We do this
+ // by setting the window pointer to zero, but leave the session pointer.
+ // We don't tell cocoa to stop any sessions just yet, because cocoa only understands
+ // when we stop the _current_ modal session (which is the session on top of
+ // the stack, and might not belong to 'window').
+ int stackSize = cocoaModalSessionStack.size();
+ for (int i=stackSize-1; i>=0; --i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (info.window == window) {
+ info.window = 0;
+ if (i == stackSize-1) {
+ // The top sessions ended. Interrupt the event dispatcher
+ // to start spinning the correct session immidiatly:
+ currentModalSessionCached = 0;
+ cleanupModalSessionsNeeded = true;
+ QCocoaEventDispatcher::instance()->interrupt();
+ }
+ }
+ }
+}
+
+QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
+{
+}
+
+QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent)
+ : QEventDispatcherUNIX(*new QCocoaEventDispatcherPrivate, parent)
+{
+ Q_D(QCocoaEventDispatcher);
+ CFRunLoopSourceContext context;
+ bzero(&context, sizeof(CFRunLoopSourceContext));
+ context.info = d;
+ context.equal = QCocoaEventDispatcherPrivate::postedEventSourceEqualCallback;
+ context.perform = QCocoaEventDispatcherPrivate::postedEventsSourcePerformCallback;
+ d->postedEventsSource = CFRunLoopSourceCreate(0, 0, &context);
+ Q_ASSERT(d->postedEventsSource);
+ CFRunLoopAddSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes);
+
+ CFRunLoopObserverContext observerContext;
+ bzero(&observerContext, sizeof(CFRunLoopObserverContext));
+ observerContext.info = this;
+ d->waitingObserver = CFRunLoopObserverCreate(kCFAllocatorDefault,
+ kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting,
+ true, 0,
+ QCocoaEventDispatcherPrivate::waitingObserverCallback,
+ &observerContext);
+ CFRunLoopAddObserver(mainRunLoop(), d->waitingObserver, kCFRunLoopCommonModes);
+
+ /* The first cycle in the loop adds the source and the events of the source
+ are not processed.
+ We use an observer to process the posted events for the first
+ execution of the loop. */
+ CFRunLoopObserverContext firstTimeObserverContext;
+ bzero(&firstTimeObserverContext, sizeof(CFRunLoopObserverContext));
+ firstTimeObserverContext.info = d;
+ d->firstTimeObserver = CFRunLoopObserverCreate(kCFAllocatorDefault,
+ kCFRunLoopEntry,
+ /* repeats = */ false,
+ 0,
+ QCocoaEventDispatcherPrivate::firstLoopEntry,
+ &firstTimeObserverContext);
+ CFRunLoopAddObserver(mainRunLoop(), d->firstTimeObserver, kCFRunLoopCommonModes);
+}
+
+void QCocoaEventDispatcherPrivate::waitingObserverCallback(CFRunLoopObserverRef,
+ CFRunLoopActivity activity, void *info)
+{
+ if (activity == kCFRunLoopBeforeWaiting)
+ emit static_cast<QCocoaEventDispatcher*>(info)->aboutToBlock();
+ else
+ emit static_cast<QCocoaEventDispatcher*>(info)->awake();
+}
+
+Boolean QCocoaEventDispatcherPrivate::postedEventSourceEqualCallback(const void *info1, const void *info2)
+{
+ return info1 == info2;
+}
+
+void processPostedEvents(QCocoaEventDispatcherPrivate *const d, const bool blockSendPostedEvents)
+{
+ if (blockSendPostedEvents) {
+ // We're told to not send posted events (because the event dispatcher
+ // is currently working on setting up the correct session to run). But
+ // we still need to make sure that we don't fall asleep until pending events
+ // are sendt, so we just signal this need, and return:
+ CFRunLoopSourceSignal(d->postedEventsSource);
+ return;
+ }
+
+ if (d->cleanupModalSessionsNeeded)
+ d->cleanupModalSessions();
+
+ if (d->interrupt) {
+ if (d->currentExecIsNSAppRun) {
+ // The event dispatcher has been interrupted. But since
+ // [NSApplication run] is running the event loop, we
+ // delayed stopping it until now (to let cocoa process
+ // pending cocoa events first).
+ if (d->currentModalSessionCached)
+ d->temporarilyStopAllModalSessions();
+ [NSApp stop:NSApp];
+ d->cancelWaitForMoreEvents();
+ }
+ return;
+ }
+
+ if (!d->threadData->canWait || (d->serialNumber != d->lastSerial)) {
+ d->lastSerial = d->serialNumber;
+ QWindowSystemInterface::sendWindowSystemEvents(d->q_func(), QEventLoop::AllEvents);
+ }
+}
+
+void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref,
+ CFRunLoopActivity activity,
+ void *info)
+{
+ Q_UNUSED(ref);
+ Q_UNUSED(activity);
+/*
+ // This function is called when NSApplication has finished initialization,
+ // which appears to be just after [NSApplication run] has started to execute.
+ // By setting up our apple events handlers this late, we override the ones
+ // set up by NSApplication.
+
+ // If Qt is used as a plugin, we let the 3rd party application handle events
+ // like quit and open file events. Otherwise, if we install our own handlers, we
+ // easily end up breaking functionallity the 3rd party application depend on:
+ if (QGuiApplication::testAttribute(Qt::AA_MacPluginApplication))
+ return;
+
+ QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
+ [eventManager setEventHandler:newDelegate andSelector:@selector(appleEventQuit:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
+ [eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
+ forEventClass:kInternetEventClass andEventID:kAEGetURL];
+*/
+
+ processPostedEvents(static_cast<QCocoaEventDispatcherPrivate *>(info), blockSendPostedEvents);
+}
+
+void QCocoaEventDispatcherPrivate::postedEventsSourcePerformCallback(void *info)
+{
+ processPostedEvents(static_cast<QCocoaEventDispatcherPrivate *>(info), blockSendPostedEvents);
+}
+
+void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents()
+{
+ // In case the event dispatcher is waiting for more
+ // events somewhere, we post a dummy event to wake it up:
+ QCocoaAutoReleasePool pool;
+ [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint
+ modifierFlags:0 timestamp:0. windowNumber:0 context:0
+ subtype:QtCocoaEventSubTypeWakeup data1:0 data2:0] atStart:NO];
+}
+
+void QCocoaEventDispatcher::interrupt()
+{
+ Q_D(QCocoaEventDispatcher);
+ d->interrupt = true;
+ wakeUp();
+
+ // We do nothing more here than setting d->interrupt = true, and
+ // poke the event loop if it is sleeping. Actually stopping
+ // NSApp, or the current modal session, is done inside the send
+ // posted events callback. We do this to ensure that all current pending
+ // cocoa events gets delivered before we stop. Otherwise, if we now stop
+ // the last event loop recursion, cocoa will just drop pending posted
+ // events on the floor before we get a chance to reestablish a new session.
+ d->cancelWaitForMoreEvents();
+}
+
+QCocoaEventDispatcher::~QCocoaEventDispatcher()
+{
+ Q_D(QCocoaEventDispatcher);
+ //timer cleanup
+ MacTimerHash::iterator it = QCocoaEventDispatcherPrivate::macTimerHash.begin();
+ while (it != QCocoaEventDispatcherPrivate::macTimerHash.end()) {
+ MacTimerInfo *t = it.value();
+ if (t->runLoopTimer) {
+ CFRunLoopTimerInvalidate(t->runLoopTimer);
+ CFRelease(t->runLoopTimer);
+ }
+ delete t;
+ ++it;
+ }
+ QCocoaEventDispatcherPrivate::macTimerHash.clear();
+
+ // Remove CFSockets from the runloop.
+ for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) {
+ MacSocketInfo *socketInfo = (*it);
+ if (CFSocketIsValid(socketInfo->socket)) {
+ qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop);
+ CFRunLoopSourceInvalidate(socketInfo->runloop);
+ CFRelease(socketInfo->runloop);
+ CFSocketInvalidate(socketInfo->socket);
+ CFRelease(socketInfo->socket);
+ }
+ }
+ CFRunLoopRemoveSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes);
+ CFRelease(d->postedEventsSource);
+
+ CFRunLoopObserverInvalidate(d->waitingObserver);
+ CFRelease(d->waitingObserver);
+
+ CFRunLoopObserverInvalidate(d->firstTimeObserver);
+ CFRelease(d->firstTimeObserver);
+}
+
+QtCocoaInterruptDispatcher* QtCocoaInterruptDispatcher::instance = 0;
+
+QtCocoaInterruptDispatcher::QtCocoaInterruptDispatcher() : cancelled(false)
+{
+ // The whole point of this class is that we enable a way to interrupt
+ // the event dispatcher when returning back to a lower recursion level
+ // than where interruptLater was called. This is needed to detect if
+ // [NSApp run] should still be running at the recursion level it is at.
+ // Since the interrupt is canceled if processEvents is called before
+ // this object gets deleted, we also avoid interrupting unnecessary.
+ deleteLater();
+}
+
+QtCocoaInterruptDispatcher::~QtCocoaInterruptDispatcher()
+{
+ if (cancelled)
+ return;
+ instance = 0;
+ QCocoaEventDispatcher::instance()->interrupt();
+}
+
+void QtCocoaInterruptDispatcher::cancelInterruptLater()
+{
+ if (!instance)
+ return;
+ instance->cancelled = true;
+ delete instance;
+ instance = 0;
+}
+
+void QtCocoaInterruptDispatcher::interruptLater()
+{
+ cancelInterruptLater();
+ instance = new QtCocoaInterruptDispatcher;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm
deleted file mode 100644
index ac0b75e9ea..0000000000
--- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcocoaeventloopintegration.h"
-
-#import <Cocoa/Cocoa.h>
-
-#include "qcocoaautoreleasepool.h"
-
-#include <QtCore/QElapsedTimer>
-
-#include <QDebug>
-#include <QApplication>
-
-void wakeupCallback ( void * ) {
- QPlatformEventLoopIntegration::processEvents();
-}
-
-void timerCallback( CFRunLoopTimerRef timer, void *info)
-{
- QPlatformEventLoopIntegration::processEvents();
- QCocoaEventLoopIntegration *eventLoopIntegration =
- static_cast<QCocoaEventLoopIntegration *>(info);
- qint64 nextTime = eventLoopIntegration->nextTimerEvent();
- CFAbsoluteTime nexttime = CFAbsoluteTimeGetCurrent();
- nexttime = nexttime + (double(nextTime)/1000);
- CFRunLoopTimerSetNextFireDate(timer,nexttime);
-}
-
-QCocoaEventLoopIntegration::QCocoaEventLoopIntegration() :
- QPlatformEventLoopIntegration()
-{
- [NSApplication sharedApplication];
- m_sourceContext.version = 0;
- m_sourceContext.info = this;
- m_sourceContext.retain = 0;
- m_sourceContext.release = 0;
- m_sourceContext.copyDescription = 0;
- m_sourceContext.equal = 0;
- m_sourceContext.hash = 0;
- m_sourceContext.schedule = 0;
- m_sourceContext.cancel = 0;
- m_sourceContext.perform = wakeupCallback;
-
- m_source = CFRunLoopSourceCreate(0,0,&m_sourceContext);
- CFRunLoopAddSource(CFRunLoopGetMain(),m_source,kCFRunLoopCommonModes);
-
- m_timerContext.version = 0;
- m_timerContext.info = this;
- m_timerContext.retain = 0;
- m_timerContext.release = 0;
- m_timerContext.copyDescription = 0;
- CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent ();
- CFTimeInterval interval = 30;
-
- CFRunLoopTimerRef m_timerSource = CFRunLoopTimerCreate(0,fireDate,interval,0,0,timerCallback,&m_timerContext);
- CFRunLoopAddTimer(CFRunLoopGetMain(),m_timerSource,kCFRunLoopCommonModes);
-}
-
-void QCocoaEventLoopIntegration::startEventLoop()
-{
- [[NSApplication sharedApplication] run];
-}
-
-void QCocoaEventLoopIntegration::quitEventLoop()
-{
- [[NSApplication sharedApplication] terminate:nil];
-}
-
-void QCocoaEventLoopIntegration::qtNeedsToProcessEvents()
-{
- CFRunLoopSourceSignal(m_source);
-}
-
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
new file mode 100644
index 0000000000..1b84e7b305
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -0,0 +1,43 @@
+#ifndef QCOCOAGLCONTEXT_H
+#define QCOCOAGLCONTEXT_H
+
+#include <QtCore/QWeakPointer>
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QWindow>
+
+#undef slots
+#include <Cocoa/Cocoa.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaGLContext : public QPlatformOpenGLContext
+{
+public:
+ QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share);
+
+ QSurfaceFormat format() const;
+
+ void swapBuffers(QPlatformSurface *surface);
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ void update();
+
+ static NSOpenGLPixelFormat *createNSOpenGLPixelFormat();
+ NSOpenGLContext *nsOpenGLContext() const;
+
+private:
+ void setActiveWindow(QWindow *window);
+
+ NSOpenGLContext *m_context;
+ QSurfaceFormat m_format;
+ QWeakPointer<QWindow> m_currentWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOCOAGLCONTEXT_H
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
new file mode 100644
index 0000000000..8b07315378
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -0,0 +1,99 @@
+#include "qcocoaglcontext.h"
+#include "qcocoawindow.h"
+#include "qcocoaautoreleasepool.h"
+#include <qdebug.h>
+#include <QtCore/private/qcore_mac_p.h>
+#include <QtPlatformSupport/private/cglconvenience_p.h>
+
+#import <Cocoa/Cocoa.h>
+
+QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : m_format(format)
+{
+ QCocoaAutoReleasePool pool; // For the SG Canvas render thread.
+
+ NSOpenGLPixelFormat *pixelFormat = static_cast <NSOpenGLPixelFormat *>(qcgl_createNSOpenGLPixelFormat());
+ NSOpenGLContext *actualShare = share ? static_cast<QCocoaGLContext *>(share)->m_context : 0;
+
+ m_context = [NSOpenGLContext alloc];
+ [m_context initWithFormat:pixelFormat shareContext:actualShare];
+
+ const GLint interval = 1;
+ [m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
+
+}
+
+// Match up with createNSOpenGLPixelFormat!
+QSurfaceFormat QCocoaGLContext::format() const
+{
+ return m_format;
+}
+
+void QCocoaGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
+ setActiveWindow(window);
+
+ [m_context flushBuffer];
+}
+
+bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
+{
+ QCocoaAutoReleasePool pool;
+
+ QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
+ setActiveWindow(window);
+
+ [m_context makeCurrentContext];
+ return true;
+}
+
+void QCocoaGLContext::setActiveWindow(QWindow *window)
+{
+ if (window == m_currentWindow.data())
+ return;
+
+ if (m_currentWindow)
+ static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+
+ Q_ASSERT(window->handle());
+
+ m_currentWindow = window;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ cocoaWindow->setCurrentContext(this);
+
+ NSView *view = cocoaWindow->contentView();
+ [m_context setView:view];
+}
+
+void QCocoaGLContext::doneCurrent()
+{
+ if (m_currentWindow)
+ static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+
+ m_currentWindow.clear();
+
+ [NSOpenGLContext clearCurrentContext];
+}
+
+void (*QCocoaGLContext::getProcAddress(const QByteArray &procName))()
+{
+ return qcgl_getProcAddress(procName);
+}
+
+void QCocoaGLContext::update()
+{
+ [m_context update];
+}
+
+NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat()
+{
+ return static_cast<NSOpenGLPixelFormat *>(qcgl_createNSOpenGLPixelFormat());
+}
+
+NSOpenGLContext *QCocoaGLContext::nsOpenGLContext() const
+{
+ return m_context;
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
new file mode 100644
index 0000000000..8e807cc288
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the plugins of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** 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, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia 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.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef QCOCOAHELPERS_H
+#define QCOCOAHELPERS_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It provides helper functions
+// for the Cocoa lighthouse plugin. This header file may
+// change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qt_mac_p.h>
+
+class QPixmap;
+class QString;
+
+// Conversion functions
+QStringList qt_mac_NSArrayToQStringList(void *nsarray);
+void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list);
+
+inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist)
+{ return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); }
+
+inline QString qt_mac_NSStringToQString(const NSString *nsstr)
+{ return QCFString::toQString(reinterpret_cast<const CFStringRef>(nsstr)); }
+
+inline NSString *qt_mac_QStringToNSString(const QString &qstr)
+{ return [const_cast<NSString *>(reinterpret_cast<const NSString *>(QCFString::toCFStringRef(qstr))) autorelease]; }
+
+CGImageRef qt_mac_image_to_cgimage(const QImage &image);
+NSImage *qt_mac_cgimage_to_nsimage(CGImageRef iamge);
+NSImage *qt_mac_create_nsimage(const QPixmap &pm);
+
+QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
+Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
+
+// Misc
+void qt_mac_transformProccessToForegroundApplication();
+QString qt_mac_removeMnemonics(const QString &original);
+CGColorSpaceRef qt_mac_genericColorSpace();
+CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget);
+QString qt_mac_applicationName();
+
+
+#endif //QCOCOAHELPERS_H
+
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
new file mode 100644
index 0000000000..03e83f1130
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -0,0 +1,448 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the plugins of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** 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, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia 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.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include "qcocoahelpers.h"
+
+#include "qcocoaautoreleasepool.h"
+
+#include <QtCore>
+#include <QtGui>
+
+//
+// Conversion Functions
+//
+
+QStringList qt_mac_NSArrayToQStringList(void *nsarray)
+{
+ QStringList result;
+ NSArray *array = static_cast<NSArray *>(nsarray);
+ for (NSUInteger i=0; i<[array count]; ++i)
+ result << qt_mac_NSStringToQString([array objectAtIndex:i]);
+ return result;
+}
+
+void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
+{
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()];
+ for (int i=0; i<list.size(); ++i){
+ [result addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(list[i]))];
+ }
+ return result;
+}
+
+static void drawImageReleaseData (void *info, const void *, size_t)
+{
+ delete static_cast<QImage *>(info);
+}
+
+CGImageRef qt_mac_image_to_cgimage(const QImage &img)
+{
+ QImage *image;
+ if (img.depth() != 32)
+ image = new QImage(img.convertToFormat(QImage::Format_ARGB32_Premultiplied));
+ else
+ image = new QImage(img);
+
+ uint cgflags = kCGImageAlphaNone;
+ switch (image->format()) {
+ case QImage::Format_ARGB32_Premultiplied:
+ cgflags = kCGImageAlphaPremultipliedFirst;
+ break;
+ case QImage::Format_ARGB32:
+ cgflags = kCGImageAlphaFirst;
+ break;
+ case QImage::Format_RGB32:
+ cgflags = kCGImageAlphaNoneSkipFirst;
+ default:
+ break;
+ }
+ cgflags |= kCGBitmapByteOrder32Host;
+ QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(image,
+ static_cast<const QImage *>(image)->bits(),
+ image->byteCount(),
+ drawImageReleaseData);
+
+ return CGImageCreate(image->width(), image->height(), 8, 32,
+ image->bytesPerLine(),
+ qt_mac_genericColorSpace(),
+ cgflags, dataProvider, 0, false, kCGRenderingIntentDefault);
+
+}
+
+NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image)
+{
+ QCocoaAutoReleasePool pool;
+ NSImage *newImage = 0;
+ NSRect imageRect = NSMakeRect(0.0, 0.0, CGImageGetWidth(image), CGImageGetHeight(image));
+ newImage = [[NSImage alloc] initWithSize:imageRect.size];
+ [newImage lockFocus];
+ {
+ CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+ CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
+ }
+ [newImage unlockFocus];
+ return newImage;
+}
+
+NSImage *qt_mac_create_nsimage(const QPixmap &pm)
+{
+ QImage image = pm.toImage();
+ return qt_mac_cgimage_to_nsimage(qt_mac_image_to_cgimage(image));
+}
+
+
+// Use this method to keep all the information in the TextSegment. As long as it is ordered
+// we are in OK shape, and we can influence that ourselves.
+struct KeyPair
+{
+ QChar cocoaKey;
+ Qt::Key qtKey;
+};
+
+bool operator==(const KeyPair &entry, QChar qchar)
+{
+ return entry.cocoaKey == qchar;
+}
+
+bool operator<(const KeyPair &entry, QChar qchar)
+{
+ return entry.cocoaKey < qchar;
+}
+
+bool operator<(QChar qchar, const KeyPair &entry)
+{
+ return qchar < entry.cocoaKey;
+}
+
+bool operator<(const Qt::Key &key, const KeyPair &entry)
+{
+ return key < entry.qtKey;
+}
+
+bool operator<(const KeyPair &entry, const Qt::Key &key)
+{
+ return entry.qtKey < key;
+}
+
+static bool qtKey2CocoaKeySortLessThan(const KeyPair &entry1, const KeyPair &entry2)
+{
+ return entry1.qtKey < entry2.qtKey;
+}
+
+static const int NumEntries = 59;
+static const KeyPair entries[NumEntries] = {
+ { NSEnterCharacter, Qt::Key_Enter },
+ { NSBackspaceCharacter, Qt::Key_Backspace },
+ { NSTabCharacter, Qt::Key_Tab },
+ { NSNewlineCharacter, Qt::Key_Return },
+ { NSCarriageReturnCharacter, Qt::Key_Return },
+ { NSBackTabCharacter, Qt::Key_Backtab },
+ { kEscapeCharCode, Qt::Key_Escape },
+ // Cocoa sends us delete when pressing backspace!
+ // (NB when we reverse this list in qtKey2CocoaKey, there
+ // will be two indices of Qt::Key_Backspace. But is seems to work
+ // ok for menu shortcuts (which uses that function):
+ { NSDeleteCharacter, Qt::Key_Backspace },
+ { NSUpArrowFunctionKey, Qt::Key_Up },
+ { NSDownArrowFunctionKey, Qt::Key_Down },
+ { NSLeftArrowFunctionKey, Qt::Key_Left },
+ { NSRightArrowFunctionKey, Qt::Key_Right },
+ { NSF1FunctionKey, Qt::Key_F1 },
+ { NSF2FunctionKey, Qt::Key_F2 },
+ { NSF3FunctionKey, Qt::Key_F3 },
+ { NSF4FunctionKey, Qt::Key_F4 },
+ { NSF5FunctionKey, Qt::Key_F5 },
+ { NSF6FunctionKey, Qt::Key_F6 },
+ { NSF7FunctionKey, Qt::Key_F7 },
+ { NSF8FunctionKey, Qt::Key_F8 },
+ { NSF9FunctionKey, Qt::Key_F8 },
+ { NSF10FunctionKey, Qt::Key_F10 },
+ { NSF11FunctionKey, Qt::Key_F11 },
+ { NSF12FunctionKey, Qt::Key_F12 },
+ { NSF13FunctionKey, Qt::Key_F13 },
+ { NSF14FunctionKey, Qt::Key_F14 },
+ { NSF15FunctionKey, Qt::Key_F15 },
+ { NSF16FunctionKey, Qt::Key_F16 },
+ { NSF17FunctionKey, Qt::Key_F17 },
+ { NSF18FunctionKey, Qt::Key_F18 },
+ { NSF19FunctionKey, Qt::Key_F19 },
+ { NSF20FunctionKey, Qt::Key_F20 },
+ { NSF21FunctionKey, Qt::Key_F21 },
+ { NSF22FunctionKey, Qt::Key_F22 },
+ { NSF23FunctionKey, Qt::Key_F23 },
+ { NSF24FunctionKey, Qt::Key_F24 },
+ { NSF25FunctionKey, Qt::Key_F25 },
+ { NSF26FunctionKey, Qt::Key_F26 },
+ { NSF27FunctionKey, Qt::Key_F27 },
+ { NSF28FunctionKey, Qt::Key_F28 },
+ { NSF29FunctionKey, Qt::Key_F29 },
+ { NSF30FunctionKey, Qt::Key_F30 },
+ { NSF31FunctionKey, Qt::Key_F31 },
+ { NSF32FunctionKey, Qt::Key_F32 },
+ { NSF33FunctionKey, Qt::Key_F33 },
+ { NSF34FunctionKey, Qt::Key_F34 },
+ { NSF35FunctionKey, Qt::Key_F35 },
+ { NSInsertFunctionKey, Qt::Key_Insert },
+ { NSDeleteFunctionKey, Qt::Key_Delete },
+ { NSHomeFunctionKey, Qt::Key_Home },
+ { NSEndFunctionKey, Qt::Key_End },
+ { NSPageUpFunctionKey, Qt::Key_PageUp },
+ { NSPageDownFunctionKey, Qt::Key_PageDown },
+ { NSPrintScreenFunctionKey, Qt::Key_Print },
+ { NSScrollLockFunctionKey, Qt::Key_ScrollLock },
+ { NSPauseFunctionKey, Qt::Key_Pause },
+ { NSSysReqFunctionKey, Qt::Key_SysReq },
+ { NSMenuFunctionKey, Qt::Key_Menu },
+ { NSHelpFunctionKey, Qt::Key_Help },
+};
+static const KeyPair * const end = entries + NumEntries;
+
+QChar qt_mac_qtKey2CocoaKey(Qt::Key key)
+{
+ // The first time this function is called, create a reverse
+ // looup table sorted on Qt Key rather than Cocoa key:
+ static QVector<KeyPair> rev_entries(NumEntries);
+ static bool mustInit = true;
+ if (mustInit){
+ mustInit = false;
+ for (int i=0; i<NumEntries; ++i)
+ rev_entries[i] = entries[i];
+ qSort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan);
+ }
+ const QVector<KeyPair>::iterator i
+ = qBinaryFind(rev_entries.begin(), rev_entries.end(), key);
+ if (i == rev_entries.end())
+ return QChar();
+ return i->cocoaKey;
+}
+
+Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode)
+{
+ const KeyPair *i = qBinaryFind(entries, end, keyCode);
+ if (i == end)
+ return Qt::Key(keyCode.unicode());
+ return i->qtKey;
+}
+
+//
+// Misc
+//
+
+// Changes the process type for this process to kProcessTransformToForegroundApplication,
+// unless either LSUIElement or LSBackgroundOnly is set in the Info.plist.
+void qt_mac_transformProccessToForegroundApplication()
+{
+ ProcessSerialNumber psn;
+ if (GetCurrentProcess(&psn) == noErr) {
+ bool forceTransform = true;
+ CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
+ CFSTR("LSUIElement"));
+ if (value) {
+ CFTypeID valueType = CFGetTypeID(value);
+ // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
+ // A number less so, but OK.
+ if (valueType == CFStringGetTypeID())
+ forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
+ else if (valueType == CFBooleanGetTypeID())
+ forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
+ else if (valueType == CFNumberGetTypeID()) {
+ int valueAsInt;
+ CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
+ forceTransform = !valueAsInt;
+ }
+ }
+
+ if (forceTransform) {
+ value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
+ CFSTR("LSBackgroundOnly"));
+ if (value) {
+ CFTypeID valueType = CFGetTypeID(value);
+ if (valueType == CFBooleanGetTypeID())
+ forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
+ else if (valueType == CFStringGetTypeID())
+ forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
+ else if (valueType == CFNumberGetTypeID()) {
+ int valueAsInt;
+ CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
+ forceTransform = !valueAsInt;
+ }
+ }
+ }
+
+ if (forceTransform) {
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ }
+ }
+}
+
+QString qt_mac_removeMnemonics(const QString &original)
+{
+ QString returnText(original.size(), 0);
+ int finalDest = 0;
+ int currPos = 0;
+ int l = original.length();
+ while (l) {
+ if (original.at(currPos) == QLatin1Char('&')
+ && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
+ ++currPos;
+ --l;
+ if (l == 0)
+ break;
+ }
+ returnText[finalDest] = original.at(currPos);
+ ++currPos;
+ ++finalDest;
+ --l;
+ }
+ returnText.truncate(finalDest);
+ return returnText;
+}
+
+
+CGColorSpaceRef m_genericColorSpace = 0;
+QHash<CGDirectDisplayID, CGColorSpaceRef> m_displayColorSpaceHash;
+bool m_postRoutineRegistered = false;
+
+CGColorSpaceRef qt_mac_genericColorSpace()
+{
+#if 0
+ if (!m_genericColorSpace) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ } else
+#endif
+ {
+ m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
+ }
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
+ }
+ }
+ return m_genericColorSpace;
+#else
+ // Just return the main display colorspace for the moment.
+ return qt_mac_displayColorSpace(0);
+#endif
+}
+
+/*
+ Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc.
+ to support multiple displays correctly.
+*/
+CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget)
+{
+ CGColorSpaceRef colorSpace;
+
+ CGDirectDisplayID displayID;
+ CMProfileRef displayProfile = 0;
+ if (widget == 0) {
+ displayID = CGMainDisplayID();
+ } else {
+ displayID = CGMainDisplayID();
+ /*
+ ### get correct display
+ const QRect &qrect = widget->window()->geometry();
+ CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height());
+ CGDisplayCount throwAway;
+ CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway);
+ if (dErr != kCGErrorSuccess)
+ return macDisplayColorSpace(0); // fall back on main display
+ */
+ }
+ if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
+ return colorSpace;
+
+ CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
+ if (err == noErr) {
+ colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
+ } else if (widget) {
+ return qt_mac_displayColorSpace(0); // fall back on main display
+ }
+
+ if (colorSpace == 0)
+ colorSpace = CGColorSpaceCreateDeviceRGB();
+
+ m_displayColorSpaceHash.insert(displayID, colorSpace);
+ CMCloseProfile(displayProfile);
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ void qt_mac_cleanUpMacColorSpaces();
+ qAddPostRoutine(qt_mac_cleanUpMacColorSpaces);
+ }
+ return colorSpace;
+}
+
+void qt_mac_cleanUpMacColorSpaces()
+{
+ if (m_genericColorSpace) {
+ CFRelease(m_genericColorSpace);
+ m_genericColorSpace = 0;
+ }
+ QHash<CGDirectDisplayID, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin();
+ while (it != m_displayColorSpaceHash.constEnd()) {
+ if (it.value())
+ CFRelease(it.value());
+ ++it;
+ }
+ m_displayColorSpaceHash.clear();
+}
+
+QString qt_mac_applicationName()
+{
+ QString appName;
+ CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleName"));
+ if (string)
+ appName = QCFString::toQString(static_cast<CFStringRef>(string));
+
+ if (appName.isEmpty()) {
+ QString arg0 = qApp->arguments().at(0);
+ if (arg0.contains("/")) {
+ QStringList parts = arg0.split("/");
+ appName = parts.at(parts.count() - 1);
+ } else {
+ appName = arg0;
+ }
+ }
+ return appName;
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 120bee46b7..a253a6bea3 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -76,19 +76,19 @@ public:
~QCocoaIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
-
- QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
QPlatformFontDatabase *fontDatabase() const;
+ QPlatformMenu *createPlatformMenu(QMenu *menu = 0) const;
+ QPlatformMenuBar *createPlatformMenuBar(QMenuBar *menuBar = 0) const;
- QPlatformEventLoopIntegration *createEventLoopIntegration() const;
-
+ QPlatformNativeInterface *nativeInterface() const;
private:
- QList<QPlatformScreen *> mScreens;
QPlatformFontDatabase *mFontDb;
+ QAbstractEventDispatcher *mEventDispatcher;
QCocoaAutoReleasePool *mPool;
};
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 086f7b62e9..e3e204226f 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -42,14 +42,18 @@
#include "qcocoaintegration.h"
#include "qcocoawindow.h"
-#include "qcocoawindowsurface.h"
-#include "qcocoaeventloopintegration.h"
+#include "qcocoabackingstore.h"
+#include "qcocoanativeinterface.h"
+#include "qcocoamenuloader.h"
+#include "qcocoaeventdispatcher.h"
+#include "qcocoahelpers.h"
+#include "qcocoaapplication.h"
+#include "qcocoaapplicationdelegate.h"
+#include "qmenu_mac.h"
-#include "qcoretextfontdatabase.h"
+#include <QtCore/qcoreapplication.h>
-#include <QtGui/QApplication>
-
-#include <private/qpixmap_raster_p.h>
+#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h>
QT_BEGIN_NAMESPACE
@@ -74,18 +78,47 @@ QCocoaScreen::~QCocoaScreen()
}
QCocoaIntegration::QCocoaIntegration()
- : mFontDb(new QCoreTextFontDatabase())
+ : mFontDb(new QBasicUnixFontDatabase())
+ , mEventDispatcher(new QCocoaEventDispatcher())
{
mPool = new QCocoaAutoReleasePool;
- //Make sure we have a nsapplication :)
- [NSApplication sharedApplication];
-// [[OurApplication alloc] init];
+ QNSApplication *cocoaApplication = [QNSApplication sharedApplication];
+
+ // Applications launched from plain executables (without an app
+ // bundle) are "background" applications that does not take keybaord
+ // focus or have a dock icon or task switcher entry. Qt Gui apps generally
+ // wants to be foreground applications so change the process type. (But
+ // see the function implementation for exceptions.)
+ qt_mac_transformProccessToForegroundApplication();
+
+ // Move the application window to front to avoid launching behind the terminal.
+ // Ignoring other apps is neccessary (we must ignore the terminal), but makes
+ // Qt apps play slightly less nice with other apps when lanching from Finder
+ // (See the activateIgnoringOtherApps docs.)
+ [cocoaApplication activateIgnoringOtherApps : YES];
+
+ // ### For AA_MacPluginApplication we don't want to load the menu nib.
+ // Qt 4 also does not set the application delegate, so that behavior
+ // is matched here.
+ if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
+
+ // Set app delegate, link to the current delegate (if any)
+ QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ [newDelegate setReflectionDelegate:[cocoaApplication delegate]];
+ [cocoaApplication setDelegate:newDelegate];
+
+ // Load the application menu. This menu contains Preferences, Hide, Quit.
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
+ qt_mac_loadMenuNib(qtMenuLoader);
+ [cocoaApplication setMenu:[qtMenuLoader menu]];
+ [newDelegate setMenuLoader:qtMenuLoader];
+ }
NSArray *screens = [NSScreen screens];
for (uint i = 0; i < [screens count]; i++) {
QCocoaScreen *screen = new QCocoaScreen(i);
- mScreens.append(screen);
+ screenAdded(screen);
}
}
@@ -98,26 +131,32 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case OpenGL : return true;
+ case ThreadedOpenGL : return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
-QPixmapData *QCocoaIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QCocoaWindow(window);
+}
+
+QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- return new QRasterPixmapData(type);
+ return new QCocoaGLContext(context->format(), context->shareHandle());
}
-QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
- return new QCocoaWindow(widget);
+ return new QCocoaBackingStore(window);
}
-QWindowSurface *QCocoaIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QAbstractEventDispatcher *QCocoaIntegration::guiThreadEventDispatcher() const
{
- return new QCocoaWindowSurface(widget,winId);
+ return mEventDispatcher;
}
QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const
@@ -125,8 +164,21 @@ QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const
return mFontDb;
}
-QPlatformEventLoopIntegration *QCocoaIntegration::createEventLoopIntegration() const
+QPlatformMenu *QCocoaIntegration::createPlatformMenu(QMenu *menu) const
+{
+ // return new QCocoaMenu(menu);
+ return 0;
+}
+
+QPlatformMenuBar *QCocoaIntegration::createPlatformMenuBar(QMenuBar *menuBar) const
+{
+ //return new QCocoaMenuBar(menuBar);
+ return 0;
+}
+
+QPlatformNativeInterface *QCocoaIntegration::nativeInterface() const
{
- return new QCocoaEventLoopIntegration();
+ return new QCocoaNativeInterface();
}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp b/src/plugins/platforms/cocoa/qcocoamenu.h
index 228e7b8dea..4e8ce20580 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,40 +39,42 @@
**
****************************************************************************/
-#include "qdirectfbscreen.h"
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
-#include <QtGui/qscreendriverplugin_qws.h>
-#include <QtCore/qstringlist.h>
-#ifndef QT_NO_QWS_DIRECTFB
+#include "qmacdefines_mac.h"
+#import <Cocoa/Cocoa.h>
-class DirectFBScreenDriverPlugin : public QScreenDriverPlugin
-{
-public:
- DirectFBScreenDriverPlugin();
+QT_FORWARD_DECLARE_CLASS(QMenu)
+QT_FORWARD_DECLARE_CLASS(QAction)
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
-DirectFBScreenDriverPlugin::DirectFBScreenDriverPlugin()
- : QScreenDriverPlugin()
-{
-}
+@protocol NSMenuDelegate <NSObject>
+- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item;
+- (void)menuWillOpen:(NSMenu*)menu;
+- (void)menuDidClose:(NSMenu*)menu;
+- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier
+ whichItem:(NSMenuItem**)outItem;
+@end
-QStringList DirectFBScreenDriverPlugin::keys() const
-{
- return (QStringList() << "directfb");
-}
+#endif
-QScreen* DirectFBScreenDriverPlugin::create(const QString& driver,
- int displayId)
+@interface QT_MANGLE_NAMESPACE(QNativeCocoaMenu) : NSMenu <NSMenuDelegate>
{
- if (driver.toLower() != "directfb")
- return 0;
-
- return new QDirectFBScreen(displayId);
+ QMenu *qmenu;
+ QAction *previousAction;
}
+- (id)initWithQMenu:(QMenu*)menu;
+- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action;
+- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector;
+@end
-Q_EXPORT_PLUGIN2(qdirectfbscreen, DirectFBScreenDriverPlugin)
-
-#endif
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
new file mode 100644
index 0000000000..1bb5f45a94
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -0,0 +1,267 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qapplication.h"
+#include "qvarlengtharray.h"
+#import "qcocoamenu.h"
+#import "qcocoamenuloader.h"
+#import "qcocoaapplication.h"
+#include "qcocoahelpers.h"
+#include <private/qapplication_p.h>
+#include <private/qaction_p.h>
+
+QT_FORWARD_DECLARE_CLASS(QAction)
+QT_FORWARD_DECLARE_CLASS(QWidget)
+QT_FORWARD_DECLARE_CLASS(QApplication)
+QT_FORWARD_DECLARE_CLASS(QCoreApplication)
+QT_FORWARD_DECLARE_CLASS(QApplicationPrivate)
+QT_FORWARD_DECLARE_CLASS(QKeyEvent)
+QT_FORWARD_DECLARE_CLASS(QEvent)
+
+QT_BEGIN_NAMESPACE
+extern void qt_mac_menu_collapseSeparators(NSMenu *menu, bool collapse);
+void qt_mac_clear_status_text(QAction *action);
+extern void qt_mac_emit_menuSignals(QMenu *menu, bool show);
+extern void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action);
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+@implementation QT_MANGLE_NAMESPACE(QNativeCocoaMenu)
+
+- (id)initWithQMenu:(QMenu*)menu
+{
+ self = [super init];
+ if (self) {
+ qmenu = menu;
+ previousAction = 0;
+ [self setAutoenablesItems:NO];
+ [self setDelegate:self];
+ }
+ return self;
+}
+
+- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item
+{
+ Q_UNUSED(menu);
+
+ if (!item) {
+ if (previousAction) {
+ qt_mac_clear_status_text(previousAction);
+ previousAction = 0;
+ }
+ return;
+ }
+
+ if (QAction *action = reinterpret_cast<QAction *>([item tag])) {
+ QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QNativeCocoaMenu) *>(menu)->qmenu;
+ previousAction = action;
+ action->activate(QAction::Hover);
+ qt_mac_menu_emit_hovered(qtmenu, action);
+ action->showStatusText(0); // 0 widget -> action's parent
+ }
+}
+
+- (void)menuWillOpen:(NSMenu*)menu
+{
+ while (QWidget *popup
+ = QApplication::activePopupWidget())
+ popup->close();
+ QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QNativeCocoaMenu) *>(menu)->qmenu;
+ qt_mac_emit_menuSignals(qtmenu, true);
+ qt_mac_menu_collapseSeparators(menu, qtmenu->separatorsCollapsible());
+}
+
+- (void)menuDidClose:(NSMenu*)menu
+{
+ qt_mac_emit_menuSignals(((QT_MANGLE_NAMESPACE(QNativeCocoaMenu) *)menu)->qmenu, false);
+ if (previousAction) {
+ qt_mac_clear_status_text(previousAction);
+ previousAction = 0;
+ }
+}
+
+- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier
+ whichItem:(NSMenuItem**)outItem
+{
+ for (NSMenuItem *item in [menu itemArray]) {
+ if (![item isEnabled] || [item isHidden] || [item isSeparatorItem])
+ continue;
+ if ([item hasSubmenu]) {
+ if ([self hasShortcut:[item submenu]
+ forKey:key
+ forModifiers:modifier whichItem:outItem]) {
+ if (outItem)
+ *outItem = item;
+ return YES;
+ }
+ }
+ NSString *menuKey = [item keyEquivalent];
+ if (menuKey && NSOrderedSame == [menuKey compare:key]
+ && (modifier == [item keyEquivalentModifierMask])) {
+ if (outItem)
+ *outItem = item;
+ return YES;
+ }
+ }
+ if (outItem)
+ *outItem = 0;
+ return NO;
+}
+
+NSString *qt_mac_removePrivateUnicode(NSString* string)
+{
+ int len = [string length];
+ if (len) {
+ QVarLengthArray <unichar, 10> characters(len);
+ bool changed = false;
+ for (int i = 0; i<len; i++) {
+ characters[i] = [string characterAtIndex:i];
+ // check if they belong to key codes in private unicode range
+ // currently we need to handle only the NSDeleteFunctionKey
+ if (characters[i] == NSDeleteFunctionKey) {
+ characters[i] = NSDeleteCharacter;
+ changed = true;
+ }
+ }
+ if (changed)
+ return [NSString stringWithCharacters:characters.data() length:len];
+ }
+ return string;
+}
+
+- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action
+{
+ // Check if the menu actually has a keysequence defined for this key event.
+ // If it does, then we will first send the key sequence to the QWidget that has focus
+ // since (in Qt's eyes) it needs to a chance at the key event first. If the widget
+ // accepts the key event, we then return YES, but set the target and action to be nil,
+ // which means that the action should not be triggered, and instead dispatch the event ourselves.
+ // In every other case we return NO, which means that Cocoa can do as it pleases
+ // (i.e., fire the menu action).
+ NSMenuItem *whichItem;
+ // Change the private unicode keys to the ones used in setting the "Key Equivalents"
+ NSString *characters = qt_mac_removePrivateUnicode([event characters]);
+ if ([self hasShortcut:menu
+ forKey:characters
+ // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ...
+ forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask))
+ whichItem:&whichItem]) {
+ QWidget *widget = 0;
+ QAction *qaction = 0;
+ if (whichItem && [whichItem tag]) {
+ qaction = reinterpret_cast<QAction *>([whichItem tag]);
+ }
+ if (qApp->activePopupWidget())
+ widget = (qApp->activePopupWidget()->focusWidget() ?
+ qApp->activePopupWidget()->focusWidget() : qApp->activePopupWidget());
+ else if (QApplicationPrivate::focus_widget)
+ widget = QApplicationPrivate::focus_widget;
+ // If we could not find any receivers, pass it to the active window
+ if (!widget)
+ widget = qApp->activeWindow();
+ if (qaction && widget) {
+ int key = qaction->shortcut();
+ QKeyEvent accel_ev(QEvent::ShortcutOverride, (key & (~Qt::KeyboardModifierMask)),
+ Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask));
+ accel_ev.ignore();
+
+// ### qt_sendSpontaneousEvent(widget, &accel_ev);
+
+ if (accel_ev.isAccepted()) {
+ qWarning("Unimplemented: qt_dispatchKeyEvent");
+#if 0
+ qt_dispatchKeyEvent(event, widget);
+#endif
+ *target = nil;
+ *action = nil;
+ return YES;
+ }
+ }
+ }
+ return NO;
+}
+
+- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector
+{
+ NSInteger index = [super indexOfItemWithTarget:anObject andAction:actionSelector];
+ static SEL selForOFCP = NSSelectorFromString(@"orderFrontCharacterPalette:");
+ if (index == -1 && selForOFCP == actionSelector) {
+ // Check if the 'orderFrontCharacterPalette' SEL exists for QNativeCocoaMenuLoader object
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
+ return [super indexOfItemWithTarget:loader andAction:actionSelector];
+ }
+ return index;
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+extern int qt_mac_menus_open_count; // qmenu_mac.mm
+
+void qt_mac_emit_menuSignals(QMenu *menu, bool show)
+{
+ if (!menu)
+ return;
+ int delta;
+ if (show) {
+ emit menu->aboutToShow();
+ delta = 1;
+ } else {
+ emit menu->aboutToHide();
+ delta = -1;
+ }
+ qt_mac_menus_open_count += delta;
+}
+
+void qt_mac_clear_status_text(QAction *action)
+{
+ action->d_func()->showStatusText(0, QString());
+}
+
+void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action)
+{
+ emit menu->hovered(action);
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/decorations/styled/main.cpp b/src/plugins/platforms/cocoa/qcocoamenuloader.h
index 69c339843a..2fcda512f0 100644
--- a/src/plugins/decorations/styled/main.cpp
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h
@@ -39,39 +39,57 @@
**
****************************************************************************/
-#include <qdecorationplugin_qws.h>
-#include <qdecorationstyled_qws.h>
+#ifndef QCOCOAMENULOADER_P_H
+#define QCOCOAMENULOADER_P_H
-QT_BEGIN_NAMESPACE
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
-class DecorationStyled : public QDecorationPlugin
-{
-public:
- DecorationStyled();
-
- QStringList keys() const;
- QDecoration *create(const QString&);
-};
-
-DecorationStyled::DecorationStyled() : QDecorationPlugin()
-{
-}
+#import <Cocoa/Cocoa.h>
+#include <QtCore/private/qcore_mac_p.h>
-QStringList DecorationStyled::keys() const
+@interface QT_MANGLE_NAMESPACE(QCocoaMenuLoader) : NSResponder
{
- return (QStringList() << QLatin1String("Styled"));
-}
-
-QDecoration* DecorationStyled::create(const QString& s)
-{
- if (s.toLower() != QLatin1String("styled"))
- return 0;
-
- qDebug("creatign styled decoration");
-
- return new QDecorationStyled;
+ IBOutlet NSMenu *theMenu;
+ IBOutlet NSMenu *appMenu;
+ IBOutlet NSMenuItem *quitItem;
+ IBOutlet NSMenuItem *preferencesItem;
+ IBOutlet NSMenuItem *aboutItem;
+ IBOutlet NSMenuItem *aboutQtItem;
+ IBOutlet NSMenuItem *hideItem;
+ NSMenuItem *lastAppSpecificItem;
+ NSMenuItem *servicesItem;
+ NSMenuItem *hideAllOthersItem;
+ NSMenuItem *showAllItem;
}
+- (void)ensureAppMenuInMenu:(NSMenu *)menu;
+- (void)removeActionsFromAppMenu;
+- (NSMenu *)applicationMenu;
+- (NSMenu *)menu;
+- (NSMenuItem *)quitMenuItem;
+- (NSMenuItem *)preferencesMenuItem;
+- (NSMenuItem *)aboutMenuItem;
+- (NSMenuItem *)aboutQtMenuItem;
+- (NSMenuItem *)hideMenuItem;
+- (NSMenuItem *)appSpecificMenuItem;
+- (IBAction)terminate:(id)sender;
+- (IBAction)orderFrontStandardAboutPanel:(id)sender;
+- (IBAction)hideOtherApplications:(id)sender;
+- (IBAction)unhideAllApplications:(id)sender;
+- (IBAction)hide:(id)sender;
+- (IBAction)qtDispatcherToQAction:(id)sender;
+- (void)qtUpdateMenubar;
+- (void)orderFrontCharacterPalette:(id)sender;
+@end
-Q_EXPORT_PLUGIN2(qdecorationstyled, DecorationStyled)
+void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader);
-QT_END_NAMESPACE
+#endif // QCOCOAMENULOADER_P_H
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
new file mode 100644
index 0000000000..353808655f
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -0,0 +1,314 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoamenuloader.h"
+
+#include "qmenu_mac.h"
+#include "qcocoahelpers.h"
+
+#include <QtCore/private/qcore_mac_p.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qdebug.h>
+
+QT_FORWARD_DECLARE_CLASS(QCFString)
+QT_FORWARD_DECLARE_CLASS(QString)
+
+#ifndef QT_NO_TRANSLATION
+ QT_BEGIN_NAMESPACE
+ extern QString qt_mac_applicationmenu_string(int type);
+ QT_END_NAMESPACE
+#endif
+
+QT_USE_NAMESPACE
+
+/*
+ Loads and instantiates the main app menu from the menu nib file(s).
+
+ The main app menu contains the Quit, Hide About, Preferences entries, and
+ The reason for having the nib file is that those can not be created
+ programmatically. To ease deployment the nib files are stored in Qt resources
+ and written to QDir::temp() before loading. (Earlier Qt versions used
+ to require having the nib file in the QtGui framework.)
+*/
+void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader)
+{
+ // Create qt_menu.nib dir in temp.
+ QDir temp = QDir::temp();
+ temp.mkdir("qt_menu.nib");
+ QString nibDir = temp.canonicalPath() + QLatin1String("/") + QLatin1String("qt_menu.nib/");
+ if (!QDir(nibDir).exists()) {
+ qWarning("qt_mac_loadMenuNib: could not create nib directory in temp");
+ return;
+ }
+
+ // Copy nib files from resources to temp.
+ QDir nibResource(":/trolltech/mac/qt_menu.nib/");
+ if (!nibResource.exists()) {
+ qWarning("qt_mac_loadMenuNib: could not load nib from resources");
+ return;
+ }
+ foreach (const QFileInfo &file, nibResource.entryInfoList()) {
+ QFile::copy(file.absoluteFilePath(), nibDir + QLatin1String("/") + file.fileName());
+ }
+
+ // Load and instantiate nib file from temp
+ NSURL *nibUrl = [NSURL fileURLWithPath : const_cast<NSString *>(reinterpret_cast<const NSString *>(QCFString::toCFStringRef(nibDir)))];
+ [nibUrl autorelease];
+ NSNib *nib = [[NSNib alloc] initWithContentsOfURL : nibUrl];
+ [nib autorelease];
+ if(!nib) {
+ qWarning("qt_mac_loadMenuNib: could not load nib from temp");
+ return;
+ }
+ bool ok = [nib instantiateNibWithOwner : qtMenuLoader topLevelObjects : nil];
+ if (!ok) {
+ qWarning("qt_mac_loadMenuNib: could not instantiate nib");
+ }
+}
+
+
+
+@implementation QT_MANGLE_NAMESPACE(QCocoaMenuLoader)
+
+- (void)awakeFromNib
+{
+ servicesItem = [[appMenu itemWithTitle:@"Services"] retain];
+ hideAllOthersItem = [[appMenu itemWithTitle:@"Hide Others"] retain];
+ showAllItem = [[appMenu itemWithTitle:@"Show All"] retain];
+
+ // Get the names in the nib to match the app name set by Qt.
+ const NSString *appName = reinterpret_cast<const NSString*>(QCFString::toCFStringRef(qt_mac_applicationName()));
+ [quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
+ withString:const_cast<NSString *>(appName)]];
+ [hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
+ withString:const_cast<NSString *>(appName)]];
+ [aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
+ withString:const_cast<NSString *>(appName)]];
+ [appName release];
+ // Disable the items that don't do anything. If someone associates a QAction with them
+ // They should get synced back in.
+ [preferencesItem setEnabled:NO];
+ [preferencesItem setHidden:YES];
+ [aboutItem setEnabled:NO];
+ [aboutItem setHidden:YES];
+}
+
+- (void)ensureAppMenuInMenu:(NSMenu *)menu
+{
+ // The application menu is the menu in the menu bar that contains the
+ // 'Quit' item. When changing menu bar (e.g when switching between
+ // windows with different menu bars), we never recreate this menu, but
+ // instead pull it out the current menu bar and place into the new one:
+ NSMenu *mainMenu = [NSApp mainMenu];
+ if ([NSApp mainMenu] == menu)
+ return; // nothing to do (menu is the current menu bar)!
+
+#ifndef QT_NAMESPACE
+ Q_ASSERT(mainMenu);
+#endif
+ // Grab the app menu out of the current menu.
+ int numItems = [mainMenu numberOfItems];
+ NSMenuItem *oldAppMenuItem = 0;
+ for (int i = 0; i < numItems; ++i) {
+ NSMenuItem *item = [mainMenu itemAtIndex:i];
+ if ([item submenu] == appMenu) {
+ oldAppMenuItem = item;
+ [oldAppMenuItem retain];
+ [mainMenu removeItemAtIndex:i];
+ break;
+ }
+ }
+
+ if (oldAppMenuItem) {
+ [oldAppMenuItem setSubmenu:nil];
+ [oldAppMenuItem release];
+ NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
+ action:nil keyEquivalent:@""];
+ [appMenuItem setSubmenu:appMenu];
+ [menu insertItem:appMenuItem atIndex:0];
+ }
+}
+
+- (void)removeActionsFromAppMenu
+{
+ for (NSMenuItem *item in [appMenu itemArray])
+ [item setTag:nil];
+}
+
+- (void)dealloc
+{
+ [servicesItem release];
+ [hideAllOthersItem release];
+ [showAllItem release];
+
+ [lastAppSpecificItem release];
+ [theMenu release];
+ [appMenu release];
+ [super dealloc];
+}
+
+- (NSMenu *)menu
+{
+ return [[theMenu retain] autorelease];
+}
+
+- (NSMenu *)applicationMenu
+{
+ return [[appMenu retain] autorelease];
+}
+
+- (NSMenuItem *)quitMenuItem
+{
+ return [[quitItem retain] autorelease];
+}
+
+- (NSMenuItem *)preferencesMenuItem
+{
+ return [[preferencesItem retain] autorelease];
+}
+
+- (NSMenuItem *)aboutMenuItem
+{
+ return [[aboutItem retain] autorelease];
+}
+
+- (NSMenuItem *)aboutQtMenuItem
+{
+ return [[aboutQtItem retain] autorelease];
+}
+
+- (NSMenuItem *)hideMenuItem
+{
+ return [[hideItem retain] autorelease];
+}
+
+- (NSMenuItem *)appSpecificMenuItem
+{
+ // Create an App-Specific menu item, insert it into the menu and return
+ // it as an autorelease item.
+ NSMenuItem *item = [[NSMenuItem alloc] init];
+
+ NSInteger location;
+ if (lastAppSpecificItem == nil) {
+ location = [appMenu indexOfItem:aboutQtItem];
+ } else {
+ location = [appMenu indexOfItem:lastAppSpecificItem];
+ [lastAppSpecificItem release];
+ }
+ lastAppSpecificItem = item; // Keep track of this for later (i.e., don't release it)
+ [appMenu insertItem:item atIndex:location + 1];
+
+ return [[item retain] autorelease];
+}
+
+- (BOOL) acceptsFirstResponder
+{
+ return YES;
+}
+
+- (void)terminate:(id)sender
+{
+ [NSApp terminate:sender];
+}
+
+- (void)orderFrontStandardAboutPanel:(id)sender
+{
+ [NSApp orderFrontStandardAboutPanel:sender];
+}
+
+- (void)hideOtherApplications:(id)sender
+{
+ [NSApp hideOtherApplications:sender];
+}
+
+- (void)unhideAllApplications:(id)sender
+{
+ [NSApp unhideAllApplications:sender];
+}
+
+- (void)hide:(id)sender
+{
+ [NSApp hide:sender];
+}
+
+- (void)qtUpdateMenubar
+{
+ QCocoaMenuBar::macUpdateMenuBarImmediatly();
+}
+
+- (void)qtTranslateApplicationMenu
+{
+
+ qDebug() << "qtTranslateApplicationMenu";
+
+#ifndef QT_NO_TRANSLATION
+ [servicesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(0))];
+ [hideItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(1).arg(qt_mac_applicationName()))];
+ [hideAllOthersItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(2))];
+ [showAllItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(3))];
+ [preferencesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(4))];
+ [quitItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName()))];
+ [aboutItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()))];
+#endif
+}
+
+- (IBAction)qtDispatcherToQAction:(id)sender
+{
+ //
+ //QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData);
+ NSMenuItem *item = static_cast<NSMenuItem *>(sender);
+ if (QAction *action = reinterpret_cast<QAction *>([item tag])) {
+ action->trigger();
+ } else if (item == quitItem) {
+ // We got here because someone was once the quitItem, but it has been
+ // abandoned (e.g., the menubar was deleted). In the meantime, just do
+ // normal QApplication::quit().
+ qApp->quit();
+ }
+}
+
+ - (void)orderFrontCharacterPalette:(id)sender
+ {
+ [NSApp orderFrontCharacterPalette:sender];
+ }
+@end
diff --git a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 10fa61c972..f8216d8e61 100644
--- a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -39,17 +39,17 @@
**
****************************************************************************/
-#ifndef MRASTERPIXMAPDATA_H
-#define MRASTERPIXMAPDATA_H
+#ifndef QCOCOANATIVEINTERFACE_H
+#define QCOCOANATIVEINTERFACE_H
-#include <private/qpixmap_raster_p.h>
+#include <QtGui/QPlatformNativeInterface>
-class QMeeGoRasterPixmapData : public QRasterPixmapData
+class QWidget;
+
+class QCocoaNativeInterface : public QPlatformNativeInterface
{
public:
- QMeeGoRasterPixmapData();
- QMeeGoRasterPixmapData(QPixmapData::PixelType t);
- void copy(const QPixmapData *data, const QRect &rect);
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
};
-#endif
+#endif // QCOCOANATIVEINTERFACE_H
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 493d14e962..c6aa0d39e6 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -39,20 +39,21 @@
**
****************************************************************************/
-#include <QDebug>
-#include "qmeegographicssystemplugin.h"
-#include "qmeegographicssystem.h"
+#include "qcocoanativeinterface.h"
+#include "qcocoaglcontext.h"
+#include "qcocoawindow.h"
+#include <qbytearray.h>
+#include <qwindow.h>
+#include "qplatformwindow_qpa.h"
+#include "qsurfaceformat.h"
+#include "qplatformopenglcontext_qpa.h"
+#include "qopenglcontext.h"
+#include <qdebug.h>
-QStringList QMeeGoGraphicsSystemPlugin::keys() const
+void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
- QStringList list;
- list << "meego";
- return list;
+ if (resourceString == "nsopenglcontext") {
+ return static_cast<QCocoaWindow *>(window->handle())->currentContext()->nsOpenGLContext();
+ }
+ return 0;
}
-
-QGraphicsSystem *QMeeGoGraphicsSystemPlugin::create(const QString&)
-{
- return new QMeeGoGraphicsSystem;
-}
-
-Q_EXPORT_PLUGIN2(meego, QMeeGoGraphicsSystemPlugin)
diff --git a/src/plugins/platforms/cocoa/qcocoaresources.qrc b/src/plugins/platforms/cocoa/qcocoaresources.qrc
new file mode 100644
index 0000000000..de50d397c6
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaresources.qrc
@@ -0,0 +1,17 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/mac/cursors">
+<file>images/copyarrowcursor.png</file>
+<file>images/forbiddencursor.png</file>
+<file>images/spincursor.png</file>
+<file>images/waitcursor.png</file>
+<file>images/pluscursor.png</file>
+</qresource>
+<qresource prefix="/trolltech/mac/style">
+<file>images/leopard-unified-toolbar-on.png</file>
+</qresource>
+<qresource prefix="/trolltech/mac/">
+<file>qt_menu.nib/classes.nib</file>
+<file>qt_menu.nib/info.nib</file>
+<file>qt_menu.nib/keyedobjects.nib</file>
+</qresource>
+</RCC>
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 9e7e68b7d2..ce79d3967f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -45,28 +45,55 @@
#include <Cocoa/Cocoa.h>
#include <QPlatformWindow>
+#include <QRect>
+
+#include "qcocoaglcontext.h"
+#include "qnsview.h"
QT_BEGIN_NAMESPACE
+@interface QNSWindow : NSWindow {
+
+}
+
+@end
+
class QCocoaWindow : public QPlatformWindow
{
public:
- QCocoaWindow(QWidget *tlw);
+ QCocoaWindow(QWindow *tlw);
~QCocoaWindow();
void setGeometry(const QRect &rect);
-
void setVisible(bool visible);
+ void setWindowTitle(const QString &title);
+ void raise();
+ void lower();
WId winId() const;
-
NSView *contentView() const;
- void setContentView(NSView *contentView);
+ void windowDidMove();
void windowDidResize();
+ void windowWillClose();
+
+ void setCurrentContext(QCocoaGLContext *context);
+ QCocoaGLContext *currentContext() const;
+
+protected:
+ void determineWindowClass();
+ QNSWindow *createWindow();
+ NSRect globalGeometry(const QRect localWindowGeometry) const;
+ QRect windowGeometry() const;
+ QCocoaWindow *parentCocoaWindow() const;
private:
- NSWindow *m_nsWindow;
+ friend class QCocoaBackingStore;
+ QNSWindow *m_nsWindow;
+ QNSView *m_contentView;
+ quint32 m_windowAttributes;
+ quint32 m_windowClass;
+ QCocoaGLContext *m_glContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index a2fdce3520..7e4d4217ef 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -41,54 +41,116 @@
#include "qcocoawindow.h"
#include "qnswindowdelegate.h"
#include "qcocoaautoreleasepool.h"
+#include "qcocoaglcontext.h"
+#include "qnsview.h"
+#include <QtCore/private/qcore_mac_p.h>
+#include <qwindow.h>
+#include <QWindowSystemInterface>
+#include <QPlatformScreen>
-#include <QWidget>
+#include <Cocoa/Cocoa.h>
+#include <Carbon/Carbon.h>
-#include <QtGui/QApplication>
+#include <QDebug>
-#include <QWindowSystemInterface>
+@implementation QNSWindow
-#include <QDebug>
+- (BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
+- (BOOL)canBecomeMainWindow
+{
+ return YES;
+}
+
+@end
-QCocoaWindow::QCocoaWindow(QWidget *tlw)
+QCocoaWindow::QCocoaWindow(QWindow *tlw)
: QPlatformWindow(tlw)
+ , m_windowAttributes(0)
+ , m_windowClass(0)
+ , m_glContext(0)
{
QCocoaAutoReleasePool pool;
- const QRect geo = tlw->geometry();
- NSRect frame = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height());
- m_nsWindow = [[NSWindow alloc] initWithContentRect:frame
- styleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask
- backing:NSBackingStoreBuffered
- defer:YES];
+ determineWindowClass();
+ m_nsWindow = createWindow();
QNSWindowDelegate *delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
[m_nsWindow setDelegate:delegate];
-
- [m_nsWindow makeKeyAndOrderFront:nil];
[m_nsWindow setAcceptsMouseMovedEvents:YES];
+
+ // Prevent Cocoa from releasing the window on close. Qt
+ // handles the close event asynchronously and we want to
+ // make sure that m_nsWindow stays valid until the
+ // QCocoaWindow is deleted by Qt.
+ [m_nsWindow setReleasedWhenClosed : NO];
+
+ m_contentView = [[QNSView alloc] initWithQWindow:tlw];
+
+ setGeometry(tlw->geometry());
+
+ [m_nsWindow setContentView:m_contentView];
}
QCocoaWindow::~QCocoaWindow()
{
+ [m_nsWindow release];
}
void QCocoaWindow::setGeometry(const QRect &rect)
{
QPlatformWindow::setGeometry(rect);
- NSRect bounds = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
+ NSRect bounds = globalGeometry(rect);
[[m_nsWindow contentView]setFrameSize:bounds.size];
+ [m_nsWindow setContentSize : bounds.size];
+ [m_nsWindow setFrameOrigin : bounds.origin];
+
+ if (m_glContext)
+ m_glContext->update();
}
void QCocoaWindow::setVisible(bool visible)
{
- Q_UNUSED(visible);
+ if (visible) {
+ // The parent window might have moved while this window was hidden,
+ // update the window geometry if there is a parent.
+ if (window()->transientParent())
+ setGeometry(window()->geometry());
+
+ // Make sure the QWindow has a frame ready before we show the NSWindow.
+ QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size()));
+
+ [m_nsWindow makeKeyAndOrderFront:nil];
+ } else {
+ [m_nsWindow orderOut:nil];
+ }
+}
+
+void QCocoaWindow::setWindowTitle(const QString &title)
+{
+ CFStringRef windowTitle = QCFString::toCFStringRef(title);
+ [m_nsWindow setTitle: const_cast<NSString *>(reinterpret_cast<const NSString *>(windowTitle))];
+ CFRelease(windowTitle);
+}
+
+void QCocoaWindow::raise()
+{
+ // ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
+ [m_nsWindow orderFront: m_nsWindow];
+}
+
+void QCocoaWindow::lower()
+{
+ [m_nsWindow orderFront: m_nsWindow];
}
WId QCocoaWindow::winId() const
{
- return WId([m_nsWindow windowNumber]);
+ return WId(m_nsWindow);
}
NSView *QCocoaWindow::contentView() const
@@ -96,15 +158,231 @@ NSView *QCocoaWindow::contentView() const
return [m_nsWindow contentView];
}
-void QCocoaWindow::setContentView(NSView *contentView)
+void QCocoaWindow::windowDidMove()
{
- [m_nsWindow setContentView:contentView];
+ if (m_glContext)
+ m_glContext->update();
}
void QCocoaWindow::windowDidResize()
{
- //jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing...
+ if (m_glContext)
+ m_glContext->update();
+
NSRect rect = [[m_nsWindow contentView]frame];
QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
- QWindowSystemInterface::handleGeometryChange(widget(),geo);
+ QWindowSystemInterface::handleSynchronousGeometryChange(window(), geo);
+}
+
+
+void QCocoaWindow::windowWillClose()
+{
+ QWindowSystemInterface::handleCloseEvent(window());
+}
+
+void QCocoaWindow::setCurrentContext(QCocoaGLContext *context)
+{
+ m_glContext = context;
+}
+
+QCocoaGLContext *QCocoaWindow::currentContext() const
+{
+ return m_glContext;
}
+
+/*
+ Determine the window class based on the window type and
+ window flags, and widget attr Sets m_windowAttributes
+ and m_windowClass.
+*/
+void QCocoaWindow::determineWindowClass()
+{
+ Qt::WindowType type = window()->windowType();
+ Qt::WindowFlags flags = window()->windowFlags();
+
+ const bool popup = (type == Qt::Popup);
+
+ if (type == Qt::ToolTip || type == Qt::SplashScreen || popup)
+ flags |= Qt::FramelessWindowHint;
+
+ m_windowClass = kSheetWindowClass;
+
+ if (popup || type == Qt::SplashScreen)
+ m_windowClass = kModalWindowClass;
+ else if (type == Qt::ToolTip)
+ m_windowClass = kHelpWindowClass;
+ else if (type == Qt::Tool)
+ m_windowClass = kFloatingWindowClass;
+ else
+ m_windowClass = kDocumentWindowClass;
+
+ m_windowAttributes = (kWindowCompositingAttribute | kWindowStandardHandlerAttribute);
+
+// if(qt_mac_is_macsheet(window())) {
+// m_windowClass = kSheetWindowClass;
+// } else
+
+ {
+ // Shift things around a bit to get the correct window class based on the presence
+ // (or lack) of the border.
+
+ bool customize = flags & Qt::CustomizeWindowHint;
+ bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint)));
+ if (framelessWindow) {
+ if (m_windowClass == kDocumentWindowClass) {
+ m_windowAttributes |= kWindowNoTitleBarAttribute;
+ } else if (m_windowClass == kFloatingWindowClass) {
+ m_windowAttributes |= kWindowNoTitleBarAttribute;
+ } else if (m_windowClass == kMovableModalWindowClass) {
+ m_windowClass = kModalWindowClass;
+ }
+ } else {
+ m_windowAttributes |= NSTitledWindowMask;
+ if (m_windowClass != kModalWindowClass)
+ m_windowAttributes |= NSResizableWindowMask;
+ }
+
+ // Only add extra decorations (well, buttons) for widgets that can have them
+ // and have an actual border we can put them on.
+
+ if(m_windowClass != kModalWindowClass && m_windowClass != kMovableModalWindowClass
+ && m_windowClass != kSheetWindowClass && m_windowClass != kPlainWindowClass
+ && !framelessWindow && m_windowClass != kDrawerWindowClass
+ && m_windowClass != kHelpWindowClass) {
+ if (flags & Qt::WindowMinimizeButtonHint)
+ m_windowAttributes |= NSMiniaturizableWindowMask;
+ if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint)
+ m_windowAttributes |= NSClosableWindowMask;
+ } else {
+ // Clear these hints so that we aren't call them on invalid windows
+ flags &= ~(Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint
+ | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint);
+ }
+
+ }
+
+ if((popup || type == Qt::Tool) && !window()->isModal())
+ m_windowAttributes |= kWindowHideOnSuspendAttribute;
+ m_windowAttributes |= kWindowLiveResizeAttribute;
+}
+
+/*
+
+*/
+QNSWindow * QCocoaWindow::createWindow()
+{
+ // Determine if we need to add in our "custom window" attribute. Cocoa is rather clever
+ // in deciding if we need the maximize button or not (i.e., it's resizeable, so you
+ // must need a maximize button). So, the only buttons we have control over are the
+ // close and minimize buttons. If someone wants to customize and NOT have the maximize
+ // button, then we have to do our hack. We only do it for these cases because otherwise
+ // the window looks different when activated. This "QtMacCustomizeWindow" attribute is
+ // intruding on a public space and WILL BREAK in the future.
+ // One can hope that there is a more public API available by that time.
+/*
+ Qt::WindowFlags flags = widget ? widget->windowFlags() : Qt::WindowFlags(0);
+ if ((flags & Qt::CustomizeWindowHint)) {
+ if ((flags & (Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint))
+ && !(flags & Qt::WindowMaximizeButtonHint))
+ wattr |= QtMacCustomizeWindow;
+ }
+*/
+ NSRect frame = globalGeometry(window()->geometry());
+ QCocoaAutoReleasePool pool;
+ QNSWindow *window;
+
+ switch (m_windowClass) {
+ case kMovableModalWindowClass:
+ case kModalWindowClass:
+ case kSheetWindowClass:
+ case kFloatingWindowClass:
+ case kOverlayWindowClass:
+ case kHelpWindowClass: {
+ NSPanel *panel;
+
+ BOOL needFloating = NO;
+ BOOL worksWhenModal = (this->window()->windowType() == Qt::Popup);
+
+ // Add in the extra flags if necessary.
+ switch (m_windowClass) {
+ case kSheetWindowClass:
+ m_windowAttributes |= NSDocModalWindowMask;
+ break;
+ case kFloatingWindowClass:
+ case kHelpWindowClass:
+ needFloating = YES;
+ m_windowAttributes |= NSUtilityWindowMask;
+ break;
+ default:
+ break;
+ }
+
+ panel = [[NSPanel alloc] initWithContentRect:frame
+ styleMask:m_windowAttributes
+ backing:NSBackingStoreBuffered
+ defer:NO]; // see window case below
+// ### crashes
+// [panel setFloatingPanel:needFloating];
+// [panel setWorksWhenModal:worksWhenModal];
+ window = static_cast<NSWindow *>(panel);
+ break;
+ }
+ default:
+ window = [[QNSWindow alloc] initWithContentRect:frame
+ styleMask:(NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask)
+ 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.).
+ break;
+ }
+
+ //qt_syncCocoaTitleBarButtons(window, widget);
+ return window;
+}
+
+// Calculate the global screen geometry for the given local geometry, which
+// might be in the parent window coordinate system.
+NSRect QCocoaWindow::globalGeometry(const QRect localGeometry) const
+{
+ QRect finalGeometry = localGeometry;
+
+ if (QCocoaWindow *parent = parentCocoaWindow()) {
+ QRect parentGeometry = parent->windowGeometry();
+ finalGeometry.adjust(parentGeometry.x(), parentGeometry.y(), parentGeometry.x(), parentGeometry.y());
+
+ // Qt child window geometry assumes that the origin is at the
+ // top-left of the content area of the parent window. The title
+ // bar is not a part of this contet area, but is still included
+ // in the NSWindow height. Move the child window down to acccount
+ // for this if the parent window has a title bar.
+ const int titlebarHeight = 22;
+ if (!(window()->windowFlags() & Qt::FramelessWindowHint))
+ finalGeometry.adjust(0, titlebarHeight, 0, titlebarHeight);
+ }
+
+ // The final "y invert" to get OS X global geometry:
+ QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window());
+ int flippedY = onScreen->geometry().height() - finalGeometry.y() - finalGeometry.height();
+ return NSMakeRect(finalGeometry.x(), flippedY, finalGeometry.width(), finalGeometry.height());
+}
+
+// Returns the current global screen geometry for the nswindow accociated with this window.
+QRect QCocoaWindow::windowGeometry() const
+{
+ NSRect rect = [m_nsWindow frame];
+ QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window());
+ int flippedY = onScreen->geometry().height() - rect.origin.y - rect.size.height; // account for nswindow inverted y.
+ QRect qRect = QRect(rect.origin.x, flippedY, rect.size.width, rect.size.height);
+ return qRect;
+}
+
+// Returns a pointer to the parent QCocoaWindow for this window, or 0 if there is none.
+QCocoaWindow *QCocoaWindow::parentCocoaWindow() const
+{
+ if (window() && window()->transientParent()) {
+ return static_cast<QCocoaWindow*>(window()->transientParent()->handle());
+ }
+ return 0;
+}
+
diff --git a/src/plugins/platforms/cocoa/qmenu_mac.h b/src/plugins/platforms/cocoa/qmenu_mac.h
new file mode 100644
index 0000000000..f20f82c761
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qmenu_mac.h
@@ -0,0 +1,85 @@
+
+#include <private/qt_mac_p.h>
+#include <QtCore/qpointer.h>
+#include <QtWidgets/qmenu.h>
+#include <QtWidgets/qmenubar.h>
+#include <QtWidgets/qplatformmenu_qpa.h>
+
+@class NSMenuItem;
+class QCocoaMenuAction : public QPlatformMenuAction
+{
+public:
+ QCocoaMenuAction();
+ ~QCocoaMenuAction();
+
+ NSMenuItem *menuItem;
+ uchar ignore_accel : 1;
+ uchar merged : 1;
+ OSMenuRef menu;
+ QPointer<QMenu> qtMenu;
+};
+
+struct QMenuMergeItem
+{
+ inline QMenuMergeItem(NSMenuItem *c, QCocoaMenuAction *a) : menuItem(c), action(a) { }
+ NSMenuItem *menuItem;
+ QCocoaMenuAction *action;
+};
+typedef QList<QMenuMergeItem> QMenuMergeList;
+
+class QCocoaMenu : public QPlatformMenu
+{
+public:
+ QCocoaMenu(QMenu *qtMenu);
+ ~QCocoaMenu();
+
+ OSMenuRef macMenu(OSMenuRef merge = 0);
+ void syncSeparatorsCollapsible(bool collapse);
+ void setMenuEnabled(bool enable);
+
+ void addAction(QAction *action, QAction *before);
+ void syncAction(QAction *action);
+ void removeAction(QAction *action);
+
+ void addAction(QCocoaMenuAction *action, QCocoaMenuAction *before);
+ void syncAction(QCocoaMenuAction *action);
+ void removeAction(QCocoaMenuAction *action);
+ bool merged(const QAction *action) const;
+ QCocoaMenuAction *findAction(QAction *action) const;
+
+ OSMenuRef menu;
+ static QHash<OSMenuRef, OSMenuRef> mergeMenuHash;
+ static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash;
+ QList<QCocoaMenuAction*> actionItems;
+ QMenu *qtMenu;
+};
+
+class QCocoaMenuBar : public QPlatformMenuBar
+{
+public:
+ QCocoaMenuBar(QMenuBar *qtMenuBar);
+ ~QCocoaMenuBar();
+
+ void handleReparent(QWidget *newParent);
+
+ void addAction(QAction *action, QAction *before);
+ void syncAction(QAction *action);
+ void removeAction(QAction *action);
+
+ void addAction(QCocoaMenuAction *action, QCocoaMenuAction *before);
+ void syncAction(QCocoaMenuAction *action);
+ void removeAction(QCocoaMenuAction *action);
+
+ bool macWidgetHasNativeMenubar(QWidget *widget);
+ void macCreateMenuBar(QWidget *parent);
+ void macDestroyMenuBar();
+ OSMenuRef macMenu();
+ static bool macUpdateMenuBarImmediatly();
+ static void macUpdateMenuBar();
+ QCocoaMenuAction *findAction(QAction *action) const;
+
+ OSMenuRef menu;
+ OSMenuRef apple_menu;
+ QList<QCocoaMenuAction*> actionItems;
+ QMenuBar *qtMenuBar;
+};
diff --git a/src/plugins/platforms/cocoa/qmenu_mac.mm b/src/plugins/platforms/cocoa/qmenu_mac.mm
new file mode 100644
index 0000000000..7ca546dd79
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qmenu_mac.mm
@@ -0,0 +1,1274 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmenu_mac.h"
+
+#include <Cocoa/Cocoa.h>
+
+#include "qmenu.h"
+#include "qhash.h"
+#include <qdebug.h>
+#include "qapplication.h"
+#include "qregexp.h"
+#include "qtoolbar.h"
+#include "qevent.h"
+#include "qstyle.h"
+#include "qwidgetaction.h"
+
+#include <private/qmenu_p.h>
+#include <private/qmenubar_p.h>
+#include <private/qguiapplication_p.h>
+
+#include "qcocoahelpers.h"
+#include "qcocoaapplication.h"
+#include "qcocoamenuloader.h"
+#include "qcocoamenu.h"
+#include "qcocoahelpers.h"
+#include "qcocoaautoreleasepool.h"
+
+QT_BEGIN_NAMESPACE
+
+/*****************************************************************************
+ QMenu debug facilities
+ *****************************************************************************/
+
+/*****************************************************************************
+ QMenu globals
+ *****************************************************************************/
+bool qt_mac_no_menubar_merge = false;
+bool qt_mac_quit_menu_item_enabled = true;
+int qt_mac_menus_open_count = 0;
+
+static OSMenuRef qt_mac_create_menu(QWidget *w);
+
+static struct {
+ QPointer<QMenuBar> qmenubar;
+ bool modal;
+} qt_mac_current_menubar = { 0, false };
+
+
+
+
+/*****************************************************************************
+ Externals
+ *****************************************************************************/
+extern OSViewRef qt_mac_hiview_for(const QWidget *w); //qwidget_mac.cpp
+extern IconRef qt_mac_create_iconref(const QPixmap &px); //qpixmap_mac.cpp
+extern QWidget * mac_keyboard_grabber; //qwidget_mac.cpp
+extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication_xxx.cpp
+RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
+void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
+
+/*****************************************************************************
+ QMenu utility functions
+ *****************************************************************************/
+bool qt_mac_watchingAboutToShow(QMenu *menu)
+{
+ return menu; /* && menu->receivers(SIGNAL(aboutToShow()));*/
+}
+
+static int qt_mac_CountMenuItems(OSMenuRef menu)
+{
+ if (menu) {
+ return [menu numberOfItems];
+ }
+ return 0;
+}
+
+void qt_mac_menu_collapseSeparators(NSMenu * theMenu, bool collapse)
+{
+ QCocoaAutoReleasePool pool;
+ OSMenuRef menu = static_cast<OSMenuRef>(theMenu);
+ if (collapse) {
+ bool previousIsSeparator = true; // setting to true kills all the separators placed at the top.
+ NSMenuItem *previousItem = nil;
+
+ NSArray *itemArray = [menu itemArray];
+ for (unsigned int i = 0; i < [itemArray count]; ++i) {
+ NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]);
+ if ([item isSeparatorItem]) {
+ [item setHidden:previousIsSeparator];
+ }
+
+ if (![item isHidden]) {
+ previousItem = item;
+ previousIsSeparator = ([previousItem isSeparatorItem]);
+ }
+ }
+
+ // We now need to check the final item since we don't want any separators at the end of the list.
+ if (previousItem && previousIsSeparator)
+ [previousItem setHidden:YES];
+ } else {
+ NSArray *itemArray = [menu itemArray];
+ for (unsigned int i = 0; i < [itemArray count]; ++i) {
+ NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]);
+ if (QAction *action = reinterpret_cast<QAction *>([item tag]))
+ [item setHidden:!action->isVisible()];
+ }
+ }
+}
+
+#ifndef QT_NO_TRANSLATION
+static const char *application_menu_strings[] = {
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
+ };
+
+QString qt_mac_applicationmenu_string(int type)
+{
+ QString menuString = QString::fromLatin1(application_menu_strings[type]);
+ QString translated = qApp->translate("QMenuBar", application_menu_strings[type]);
+ if (translated != menuString)
+ return translated;
+ else
+ return qApp->translate("MAC_APPLICATION_MENU",
+ application_menu_strings[type]);
+}
+#endif
+
+
+static quint32 constructModifierMask(quint32 accel_key)
+{
+ quint32 ret = 0;
+ const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
+ if ((accel_key & Qt::CTRL) == Qt::CTRL)
+ ret |= (dontSwap ? NSControlKeyMask : NSCommandKeyMask);
+ if ((accel_key & Qt::META) == Qt::META)
+ ret |= (dontSwap ? NSCommandKeyMask : NSControlKeyMask);
+ if ((accel_key & Qt::ALT) == Qt::ALT)
+ ret |= NSAlternateKeyMask;
+ if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
+ ret |= NSShiftKeyMask;
+ return ret;
+}
+
+static void cancelAllMenuTracking()
+{
+ QCocoaAutoReleasePool pool;
+ NSMenu *mainMenu = [NSApp mainMenu];
+ [mainMenu cancelTracking];
+ for (NSMenuItem *item in [mainMenu itemArray]) {
+ if ([item submenu]) {
+ [[item submenu] cancelTracking];
+ }
+ }
+}
+
+static bool actualMenuItemVisibility(const QCocoaMenuBar *mbp,
+ const QCocoaMenuAction *action)
+{
+ bool visible = action->action->isVisible();
+ if (visible && action->action->text() == QString(QChar(0x14)))
+ return false;
+
+ if (visible && action->action->menu() && !action->action->menu()->actions().isEmpty() &&
+/* ### !qt_mac_CountMenuItems(cocoaMenu->macMenu(mbp->apple_menu)) &&*/
+ !qt_mac_watchingAboutToShow(action->action->menu())) {
+ return false;
+ }
+ return visible;
+}
+
+static inline void syncNSMenuItemVisiblity(NSMenuItem *menuItem, bool actionVisibility)
+{
+ [menuItem setHidden:NO];
+ [menuItem setHidden:YES];
+ [menuItem setHidden:!actionVisibility];
+}
+
+static inline void syncNSMenuItemEnabled(NSMenuItem *menuItem, bool enabled)
+{
+ [menuItem setEnabled:NO];
+ [menuItem setEnabled:YES];
+ [menuItem setEnabled:enabled];
+}
+
+static inline void syncMenuBarItemsVisiblity(const QCocoaMenuBar *mac_menubar)
+{
+ const QList<QCocoaMenuAction *> &menubarActions = mac_menubar->actionItems;
+ for (int i = 0; i < menubarActions.size(); ++i) {
+ const QCocoaMenuAction *action = menubarActions.at(i);
+ syncNSMenuItemVisiblity(action->menuItem, actualMenuItemVisibility(mac_menubar, action));
+ }
+}
+
+static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+{
+ return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
+}
+
+static NSMenuItem *createNSMenuItem(const QString &title)
+{
+ NSMenuItem *item = [[NSMenuItem alloc]
+ initWithTitle:qt_mac_QStringToNSString(title)
+ action:@selector(qtDispatcherToQAction:) keyEquivalent:@""];
+ [item setTarget:nil];
+ return item;
+}
+
+// helper that recurses into a menu structure and en/dis-ables them
+void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bool on)
+{
+ bool modalWindowOnScreen = qApp->activeModalWidget() != 0;
+ for (NSMenuItem *item in [menu itemArray]) {
+ OSMenuRef submenu = [item submenu];
+ if (submenu != merge) {
+ if (submenu)
+ qt_mac_set_modal_state_helper_recursive(submenu, merge, on);
+ if (!on) {
+ // The item should follow what the QAction has.
+ if ([item tag]) {
+ QAction *action = reinterpret_cast<QAction *>([item tag]);
+ syncNSMenuItemEnabled(item, action->isEnabled());
+ } else {
+ syncNSMenuItemEnabled(item, YES);
+ }
+ // We sneak in some extra code here to handle a menu problem:
+ // If there is no window on screen, we cannot set 'nil' as
+ // menu item target, because then cocoa will disable the item
+ // (guess it assumes that there will be no first responder to
+ // catch the trigger anyway?) OTOH, If we have a modal window,
+ // then setting the menu loader as target will make cocoa not
+ // deliver the trigger because the loader is then seen as modally
+ // shaddowed). So either way there are shortcomings. Instead, we
+ // decide the target as late as possible:
+ [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()];
+ } else {
+ syncNSMenuItemEnabled(item, NO);
+ }
+ }
+ }
+}
+
+//toggling of modal state
+static void qt_mac_set_modal_state(OSMenuRef menu, bool on)
+{
+ OSMenuRef merge = QCocoaMenu::mergeMenuHash.value(menu);
+ qt_mac_set_modal_state_helper_recursive(menu, merge, on);
+ // I'm ignoring the special items now, since they should get handled via a syncAction()
+}
+
+bool qt_mac_menubar_is_open()
+{
+ return qt_mac_menus_open_count > 0;
+}
+
+QCocoaMenuAction::~QCocoaMenuAction()
+{
+ [menu release];
+ // Update the menu item if this action still owns it. For some items
+ // (like 'Quit') ownership will be transferred between all menu bars...
+ if (action && action.data() == reinterpret_cast<QAction *>([menuItem tag])) {
+ QAction::MenuRole role = action->menuRole();
+ // Check if the item is owned by Qt, and should be hidden to keep it from causing
+ // problems. Do it for everything but the quit menu item since that should always
+ // be visible.
+ if (role > QAction::ApplicationSpecificRole && role < QAction::QuitRole) {
+ [menuItem setHidden:YES];
+ } else if (role == QAction::TextHeuristicRole
+ && menuItem != [getMenuLoader() quitMenuItem]) {
+ [menuItem setHidden:YES];
+ }
+ [menuItem setTag:nil];
+ }
+ [menuItem release];
+}
+
+static NSMenuItem *qt_mac_menu_merge_action(OSMenuRef merge, QCocoaMenuAction *action)
+{
+ if (qt_mac_no_menubar_merge || action->action->menu() || action->action->isSeparator()
+ || action->action->menuRole() == QAction::NoRole)
+ return 0;
+
+ QString t = qt_mac_removeMnemonics(action->action->text().toLower());
+ int st = t.lastIndexOf(QLatin1Char('\t'));
+ if (st != -1)
+ t.remove(st, t.length()-st);
+ t.replace(QRegExp(QString::fromLatin1("\\.*$")), QLatin1String("")); //no ellipses
+ //now the fun part
+ NSMenuItem *ret = 0;
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+
+ switch (action->action->menuRole()) {
+ case QAction::NoRole:
+ ret = 0;
+ break;
+ case QAction::ApplicationSpecificRole:
+ ret = [loader appSpecificMenuItem];
+ break;
+ case QAction::AboutRole:
+ ret = [loader aboutMenuItem];
+ break;
+ case QAction::AboutQtRole:
+ ret = [loader aboutQtMenuItem];
+ break;
+ case QAction::QuitRole:
+ ret = [loader quitMenuItem];
+ break;
+ case QAction::PreferencesRole:
+ ret = [loader preferencesMenuItem];
+ break;
+ case QAction::TextHeuristicRole: {
+ QString aboutString = QMenuBar::tr("About").toLower();
+ if (t.startsWith(aboutString) || t.endsWith(aboutString)) {
+ if (t.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) {
+ ret = [loader aboutMenuItem];
+ } else {
+ ret = [loader aboutQtMenuItem];
+ }
+ } else if (t.startsWith(QMenuBar::tr("Config").toLower())
+ || t.startsWith(QMenuBar::tr("Preference").toLower())
+ || t.startsWith(QMenuBar::tr("Options").toLower())
+ || t.startsWith(QMenuBar::tr("Setting").toLower())
+ || t.startsWith(QMenuBar::tr("Setup").toLower())) {
+ ret = [loader preferencesMenuItem];
+ } else if (t.startsWith(QMenuBar::tr("Quit").toLower())
+ || t.startsWith(QMenuBar::tr("Exit").toLower())) {
+ ret = [loader quitMenuItem];
+ }
+ }
+ break;
+ }
+
+ if (QMenuMergeList *list = QCocoaMenu::mergeMenuItemsHash.value(merge)) {
+ for(int i = 0; i < list->size(); ++i) {
+ const QMenuMergeItem &item = list->at(i);
+ if (item.menuItem == ret && item.action)
+ return 0;
+ }
+ }
+
+ return ret;
+}
+
+static QString qt_mac_menu_merge_text(QCocoaMenuAction *action)
+{
+ QString ret;
+ extern QString qt_mac_applicationmenu_string(int type);
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ if (action->action->menuRole() == QAction::ApplicationSpecificRole)
+ ret = action->action->text();
+ else if (action->menuItem == [loader aboutMenuItem]) {
+ ret = qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName());
+ } else if (action->menuItem == [loader aboutQtMenuItem]) {
+ if (action->action->text() == QString("About Qt"))
+ ret = QMenuBar::tr("About Qt");
+ else
+ ret = action->action->text();
+ } else if (action->menuItem == [loader preferencesMenuItem]) {
+ ret = qt_mac_applicationmenu_string(4);
+ } else if (action->menuItem == [loader quitMenuItem]) {
+ ret = qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName());
+ }
+ return ret;
+}
+
+static QKeySequence qt_mac_menu_merge_accel(QCocoaMenuAction *action)
+{
+ QKeySequence ret;
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ if (action->action->menuRole() == QAction::ApplicationSpecificRole)
+ ret = action->action->shortcut();
+ else if (action->menuItem == [loader preferencesMenuItem])
+ ret = QKeySequence(QKeySequence::Preferences);
+ else if (action->menuItem == [loader quitMenuItem])
+ ret = QKeySequence(QKeySequence::Quit);
+ return ret;
+}
+
+void Q_WIDGETS_EXPORT qt_mac_set_menubar_icons(bool b)
+{ QApplication::instance()->setAttribute(Qt::AA_DontShowIconsInMenus, !b); }
+void Q_WIDGETS_EXPORT qt_mac_set_native_menubar(bool b)
+{ QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, !b); }
+void Q_WIDGETS_EXPORT qt_mac_set_menubar_merge(bool b) { qt_mac_no_menubar_merge = !b; }
+
+/*****************************************************************************
+ QMenu bindings
+ *****************************************************************************/
+
+QCocoaMenuAction::QCocoaMenuAction()
+ : menuItem(0)
+ , ignore_accel(0), merged(0), menu(0)
+{
+
+}
+
+QCocoaMenu::QCocoaMenu(QMenu *a_qtMenu) : menu(0), qtMenu(a_qtMenu)
+{
+}
+
+QCocoaMenu::~QCocoaMenu()
+{
+ QCocoaAutoReleasePool pool;
+ while (actionItems.size()) {
+ QCocoaMenuAction *action = static_cast<QCocoaMenuAction *>(actionItems.takeFirst());
+ if (QMenuMergeList *list = mergeMenuItemsHash.value(action->menu)) {
+ int i = 0;
+ while (i < list->size()) {
+ const QMenuMergeItem &item = list->at(i);
+ if (item.action == action)
+ list->removeAt(i);
+ else
+ ++i;
+ }
+ }
+ delete action;
+ }
+ mergeMenuHash.remove(menu);
+ mergeMenuItemsHash.remove(menu);
+ [menu release];
+}
+
+
+void QCocoaMenu::addAction(QAction *a, QAction *before)
+{
+ QCocoaMenuAction *action = new QCocoaMenuAction;
+ action->action = a;
+ action->ignore_accel = 0;
+ action->merged = 0;
+ action->menu = 0;
+
+ QCocoaMenuAction *cocoaBefore = findAction(before);
+ addAction(action, cocoaBefore);
+}
+
+
+void QCocoaMenu::addAction(QCocoaMenuAction *action, QCocoaMenuAction *before)
+{
+ QCocoaAutoReleasePool pool;
+ if (!action)
+ return;
+ int before_index = actionItems.indexOf(before);
+ if (before_index < 0) {
+ before = 0;
+ before_index = actionItems.size();
+ }
+ actionItems.insert(before_index, action);
+
+ [menu retain];
+ [action->menu release];
+ action->menu = menu;
+
+ /* When the action is considered a mergable action it
+ will stay that way, until removed.. */
+ if (!qt_mac_no_menubar_merge) {
+ OSMenuRef merge = QCocoaMenu::mergeMenuHash.value(menu);
+ if (merge) {
+ if (NSMenuItem *cmd = qt_mac_menu_merge_action(merge, action)) {
+ action->merged = 1;
+ [merge retain];
+ [action->menu release];
+ action->menu = merge;
+ [cmd retain];
+ [cmd setAction:@selector(qtDispatcherToQAction:)];
+ [cmd setTarget:nil];
+ [action->menuItem release];
+ action->menuItem = cmd;
+ QMenuMergeList *list = QCocoaMenu::mergeMenuItemsHash.value(merge);
+ if (!list) {
+ list = new QMenuMergeList;
+ QCocoaMenu::mergeMenuItemsHash.insert(merge, list);
+ }
+ list->append(QMenuMergeItem(cmd, action));
+ }
+ }
+ }
+
+ NSMenuItem *newItem = action->menuItem;
+ if (newItem == 0) {
+ newItem = createNSMenuItem(action->action->text());
+ action->menuItem = newItem;
+ if (before) {
+ [menu insertItem:newItem atIndex:qMax(before_index, 0)];
+ } else {
+ [menu addItem:newItem];
+ }
+ } else {
+ [newItem setEnabled:YES];
+ // ###
+ //[newItem setEnabled:!QApplicationPrivate::modalState()];
+
+ }
+ [newItem setTag:long(static_cast<QAction *>(action->action))];
+ syncAction(action);
+}
+
+void QCocoaMenu::syncAction(QAction *a)
+{
+ syncAction(findAction(a));
+}
+
+void QCocoaMenu::removeAction(QAction *a)
+{
+ removeAction(findAction(a));
+}
+
+QCocoaMenuAction *QCocoaMenu::findAction(QAction *action) const
+{
+ for (int i = 0; i < actionItems.size(); i++) {
+ QCocoaMenuAction *act = actionItems[i];
+ if (action == act->action)
+ return act;
+ }
+ return 0;
+}
+
+
+// return an autoreleased string given a QKeySequence (currently only looks at the first one).
+NSString *keySequenceToKeyEqivalent(const QKeySequence &accel)
+{
+ quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL));
+ QChar cocoa_key = qt_mac_qtKey2CocoaKey(Qt::Key(accel_key));
+ if (cocoa_key.isNull())
+ cocoa_key = QChar(accel_key).toLower().unicode();
+ return [NSString stringWithCharacters:&cocoa_key.unicode() length:1];
+}
+
+// return the cocoa modifier mask for the QKeySequence (currently only looks at the first one).
+NSUInteger keySequenceModifierMask(const QKeySequence &accel)
+{
+ return constructModifierMask(accel[0]);
+}
+
+void QCocoaMenu::syncAction(QCocoaMenuAction *action)
+{
+ if (!action)
+ return;
+
+ NSMenuItem *item = action->menuItem;
+ if (!item)
+ return;
+
+ QCocoaAutoReleasePool pool;
+ NSMenu *menu = [item menu];
+ bool actionVisible = action->action->isVisible();
+ [item setHidden:!actionVisible];
+ if (!actionVisible)
+ return;
+
+ int itemIndex = [menu indexOfItem:item];
+ Q_ASSERT(itemIndex != -1);
+ if (action->action->isSeparator()) {
+ action->menuItem = [NSMenuItem separatorItem];
+ [action->menuItem retain];
+ [menu insertItem: action->menuItem atIndex:itemIndex];
+ [menu removeItem:item];
+ [item release];
+ item = action->menuItem;
+ return;
+ } else if ([item isSeparatorItem]) {
+ // I'm no longer a separator...
+ action->menuItem = createNSMenuItem(action->action->text());
+ [menu insertItem:action->menuItem atIndex:itemIndex];
+ [menu removeItem:item];
+ [item release];
+ item = action->menuItem;
+ }
+
+ //find text (and accel)
+ action->ignore_accel = 0;
+ QString text = action->action->text();
+ QKeySequence accel = action->action->shortcut();
+ {
+ int st = text.lastIndexOf(QLatin1Char('\t'));
+ if (st != -1) {
+ action->ignore_accel = 1;
+ accel = QKeySequence(text.right(text.length()-(st+1)));
+ text.remove(st, text.length()-st);
+ }
+ }
+ {
+ QString cmd_text = qt_mac_menu_merge_text(action);
+ if (!cmd_text.isEmpty()) {
+ text = cmd_text;
+ accel = qt_mac_menu_merge_accel(action);
+ }
+ }
+ // Show multiple key sequences as part of the menu text.
+ if (accel.count() > 1)
+ text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")");
+
+#if 0
+ QString finalString = qt_mac_removeMnemonics(text);
+#else
+ QString finalString = qt_mac_removeMnemonics(text);
+#endif
+ // Cocoa Font and title
+ if (action->action->font().resolve()) {
+ const QFont &actionFont = action->action->font();
+ NSFont *customMenuFont = [NSFont fontWithName:qt_mac_QStringToNSString(actionFont.family())
+ size:actionFont.pointSize()];
+ NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil];
+ NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil];
+ NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
+ NSAttributedString *str = [[[NSAttributedString alloc] initWithString:qt_mac_QStringToNSString(finalString)
+ attributes:attributes] autorelease];
+ [item setAttributedTitle: str];
+ } else {
+ [item setTitle: qt_mac_QStringToNSString(finalString)];
+ }
+
+ if (action->action->menuRole() == QAction::AboutRole || action->action->menuRole() == QAction::QuitRole)
+ [item setTitle:qt_mac_QStringToNSString(text)];
+ else
+ [item setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(text))];
+
+ // Cocoa Enabled
+ [item setEnabled: action->action->isEnabled()];
+
+ // Cocoa icon
+ NSImage *nsimage = 0;
+ if (!action->action->icon().isNull() && action->action->isIconVisibleInMenu()) {
+ nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(action->action->icon().pixmap(16, QIcon::Normal)));
+ }
+ [item setImage:nsimage];
+ [nsimage release];
+
+ if (action->action->menu()) { //submenu
+ QCocoaMenu *cocoaMenu = static_cast<QCocoaMenu *>(action->action->menu()->platformMenu());
+ NSMenu *subMenu = cocoaMenu->macMenu();
+ if ([subMenu supermenu] && [subMenu supermenu] != [item menu]) {
+ // The menu is already a sub-menu of another one. Cocoa will throw an exception,
+ // in such cases. For the time being, a new QMenu with same set of actions is the
+ // only workaround.
+ action->action->setEnabled(false);
+ } else {
+ [item setSubmenu:subMenu];
+ }
+ } else { //respect some other items
+ [item setSubmenu:0];
+ // No key equivalent set for multiple key QKeySequence.
+ if (accel.count() == 1) {
+ [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
+ [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
+ } else {
+ [item setKeyEquivalent:@""];
+ [item setKeyEquivalentModifierMask:NSCommandKeyMask];
+ }
+ }
+ //mark glyph
+ [item setState:action->action->isChecked() ? NSOnState : NSOffState];
+}
+
+void QCocoaMenu::removeAction(QCocoaMenuAction *action)
+{
+ if (!action)
+ return;
+ QCocoaAutoReleasePool pool;
+ if (action->merged) {
+ if (reinterpret_cast<QAction *>([action->menuItem tag]) == action->action) {
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ [action->menuItem setEnabled:false];
+ if (action->menuItem != [loader quitMenuItem]
+ && action->menuItem != [loader preferencesMenuItem]) {
+ [[action->menuItem menu] removeItem:action->menuItem];
+ }
+ }
+ } else {
+ [[action->menuItem menu] removeItem:action->menuItem];
+ }
+ actionItems.removeAll(action);
+}
+
+OSMenuRef QCocoaMenu::macMenu(OSMenuRef merge)
+{
+ if (menu)
+ return menu;
+ menu = qt_mac_create_menu(qtMenu);
+ if (merge) {
+ mergeMenuHash.insert(menu, merge);
+ }
+ QList<QAction*> items = qtMenu->actions();
+ for(int i = 0; i < items.count(); i++)
+ addAction(items[i], 0);
+ syncSeparatorsCollapsible(qtMenu->separatorsCollapsible());
+ return menu;
+}
+
+/*!
+ \internal
+*/
+void
+QCocoaMenu::syncSeparatorsCollapsible(bool collapse)
+{
+ qt_mac_menu_collapseSeparators(menu, collapse);
+}
+
+/*!
+ \internal
+*/
+void QCocoaMenu::setMenuEnabled(bool enable)
+{
+ QCocoaAutoReleasePool pool;
+ if (enable) {
+ for (int i = 0; i < actionItems.count(); ++i) {
+ QCocoaMenuAction *menuItem = static_cast<QCocoaMenuAction *>(actionItems.at(i));
+ if (menuItem && menuItem->action && menuItem->action->isEnabled()) {
+ [menuItem->menuItem setEnabled:true];
+ }
+ }
+ } else {
+ NSMenu *menu = menu;
+ for (NSMenuItem *item in [menu itemArray]) {
+ [item setEnabled:false];
+ }
+ }
+}
+
+/*!
+ \internal
+
+ This function will return the OSMenuRef used to create the native menu bar
+ bindings.
+
+ If Qt is built against Carbon, the OSMenuRef is a MenuRef that can be used
+ with Carbon's Menu Manager API.
+
+ If Qt is built against Cocoa, the OSMenuRef is a NSMenu pointer.
+
+ \warning This function is not portable.
+
+ \sa QMenuBar::macMenu()
+*/
+/// OSMenuRef QMenu::macMenu(OSMenuRef merge) { return d_func()->macMenu(merge); }
+
+/*****************************************************************************
+ QMenuBar bindings
+ *****************************************************************************/
+typedef QHash<QWidget *, QMenuBar *> MenuBarHash;
+Q_GLOBAL_STATIC(MenuBarHash, menubars)
+static QMenuBar *fallback = 0;
+
+QCocoaMenuBar::QCocoaMenuBar(QMenuBar *a_qtMenuBar) : menu(0), apple_menu(0), qtMenuBar(a_qtMenuBar)
+{
+ macCreateMenuBar(qtMenuBar->parentWidget());
+}
+
+QCocoaMenuBar::~QCocoaMenuBar()
+{
+ for(QList<QCocoaMenuAction*>::Iterator it = actionItems.begin(); it != actionItems.end(); ++it)
+ delete (*it);
+ [apple_menu release];
+ [menu release];
+}
+void QCocoaMenuBar::handleReparent(QWidget *newParent)
+{
+ if (macWidgetHasNativeMenubar(newParent)) {
+ // If the new parent got a native menubar from before, keep that
+ // menubar rather than replace it with this one (because a parents
+ // menubar has precedence over children menubars).
+ macDestroyMenuBar();
+ macCreateMenuBar(newParent);
+ }
+
+}
+
+void QCocoaMenuBar::addAction(QAction *action, QAction *beforeAction)
+{
+ if (action->isSeparator() || !menu)
+ return;
+ QCocoaMenuAction *cocoaAction = new QCocoaMenuAction;
+ cocoaAction->action = action;
+ cocoaAction->ignore_accel = 1;
+ QCocoaMenuAction *cocoaBeforeAction = findAction(beforeAction);
+ addAction(cocoaAction, cocoaBeforeAction);
+}
+
+void QCocoaMenuBar::addAction(QCocoaMenuAction *action, QCocoaMenuAction *before)
+{
+ if (!action || !menu)
+ return;
+
+ int before_index = actionItems.indexOf(before);
+ if (before_index < 0) {
+ before = 0;
+ before_index = actionItems.size();
+ }
+ actionItems.insert(before_index, action);
+
+ MenuItemIndex index = actionItems.size()-1;
+
+ action->menu = menu;
+ QCocoaAutoReleasePool pool;
+ [action->menu retain];
+ NSMenuItem *newItem = createNSMenuItem(action->action->text());
+ action->menuItem = newItem;
+
+ if (before) {
+ [menu insertItem:newItem atIndex:qMax(1, before_index + 1)];
+ index = before_index;
+ } else {
+ [menu addItem:newItem];
+ }
+ [newItem setTag:long(static_cast<QAction *>(action->action))];
+ syncAction(action);
+}
+
+
+void QCocoaMenuBar::syncAction(QCocoaMenuAction *action)
+{
+ if (!action || !menu)
+ return;
+
+ QCocoaAutoReleasePool pool;
+ NSMenuItem *item = action->menuItem;
+
+ OSMenuRef submenu = 0;
+ bool release_submenu = false;
+ if (action->action->menu()) {
+ QCocoaMenu *cocoaMenu = static_cast<QCocoaMenu *>(action->action->menu()->platformMenu());
+ if (!cocoaMenu) {
+
+ }
+
+ if ((submenu = cocoaMenu->macMenu(apple_menu))) {
+ if ([submenu supermenu] && [submenu supermenu] != [item menu])
+ return;
+ else
+ [item setSubmenu:submenu];
+ }
+ }
+
+ if (submenu) {
+ bool visible = actualMenuItemVisibility(this, action);
+ [item setSubmenu: submenu];
+ [submenu setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(action->action->text()))];
+ syncNSMenuItemVisiblity(item, visible);
+ if (release_submenu) { //no pointers to it
+ [submenu release];
+ }
+ } else {
+ qWarning("QMenu: No OSMenuRef created for popup menu");
+ }
+}
+
+
+void QCocoaMenuBar::removeAction(QCocoaMenuAction *action)
+{
+ if (!action || !menu)
+ return;
+ QCocoaAutoReleasePool pool;
+ [action->menu removeItem:action->menuItem];
+ actionItems.removeAll(action);
+}
+
+void QCocoaMenuBar::syncAction(QAction *a)
+{
+ syncAction(findAction(a));
+}
+
+void QCocoaMenuBar::removeAction(QAction *a)
+{
+ removeAction(findAction(a));
+}
+
+QCocoaMenuAction *QCocoaMenuBar::findAction(QAction *action) const
+{
+ for (int i = 0; i < actionItems.size(); i++) {
+ QCocoaMenuAction *act = actionItems[i];
+ if (action == act->action)
+ return act;
+ }
+ return 0;
+}
+
+bool QCocoaMenuBar::macWidgetHasNativeMenubar(QWidget *widget)
+{
+ // This function is different from q->isNativeMenuBar(), as
+ // it returns true only if a native menu bar is actually
+ // _created_.
+ if (!widget)
+ return false;
+ return menubars()->contains(widget->window());
+}
+
+void QCocoaMenuBar::macCreateMenuBar(QWidget *parent)
+{
+ static int dontUseNativeMenuBar = -1;
+ // We call the isNativeMenuBar function here
+ // because that will make sure that local overrides
+ // are dealt with correctly. q->isNativeMenuBar() will, if not
+ // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar:
+ bool qt_mac_no_native_menubar = !qtMenuBar->isNativeMenuBar();
+ if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) {
+ // The menubar is set to be native. Let's check (one time only
+ // for all menubars) if this is OK with the rest of the environment.
+ // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application
+ // might still choose to not respect, or change, this flag.
+ bool isPlugin = QApplication::testAttribute(Qt::AA_MacPluginApplication);
+ bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty();
+ dontUseNativeMenuBar = isPlugin || environmentSaysNo;
+ QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, dontUseNativeMenuBar);
+ qt_mac_no_native_menubar = !qtMenuBar->isNativeMenuBar();
+ }
+ if (qt_mac_no_native_menubar == false) {
+ // INVARIANT: Use native menubar.
+ macUpdateMenuBar();
+ if (!parent && !fallback) {
+ fallback = qtMenuBar;
+ } else if (parent && parent->isWindow()) {
+ menubars()->insert(qtMenuBar->window(), qtMenuBar);
+ }
+ }
+}
+
+void QCocoaMenuBar::macDestroyMenuBar()
+{
+ QCocoaAutoReleasePool pool;
+ if (fallback == qtMenuBar)
+ fallback = 0;
+ QWidget *tlw = qtMenuBar->window();
+ menubars()->remove(tlw);
+
+ if (!qt_mac_current_menubar.qmenubar || qt_mac_current_menubar.qmenubar == qtMenuBar) {
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ [loader removeActionsFromAppMenu];
+ QCocoaMenuBar::macUpdateMenuBar();
+ }
+}
+
+OSMenuRef QCocoaMenuBar::macMenu()
+{
+ if (!qtMenuBar->isNativeMenuBar()) {
+ return 0;
+ } else if (!menu) {
+ menu = qt_mac_create_menu(qtMenuBar);
+ ProcessSerialNumber mine, front;
+ if (GetCurrentProcess(&mine) == noErr && GetFrontProcess(&front) == noErr) {
+ if (!qt_mac_no_menubar_merge && !apple_menu) {
+ apple_menu = qt_mac_create_menu(qtMenuBar);
+ [apple_menu setTitle:qt_mac_QStringToNSString(QString(QChar(0x14)))];
+ NSMenuItem *apple_menuItem = [[NSMenuItem alloc] init];
+ [apple_menuItem setSubmenu:menu];
+ [apple_menu addItem:apple_menuItem];
+ [apple_menuItem release];
+ }
+ if (apple_menu) {
+ QCocoaMenu::mergeMenuHash.insert(menu, apple_menu);
+ }
+ QList<QAction*> items = qtMenuBar->actions();
+ for(int i = 0; i < items.count(); i++)
+ addAction(items[i], 0);
+ }
+ }
+ return menu;
+}
+
+/*!
+ \internal
+
+ This function will return the OSMenuRef used to create the native menu bar
+ bindings. This OSMenuRef is then set as the root menu for the Menu
+ Manager.
+
+ \warning This function is not portable.
+
+ \sa QMenu::macMenu()
+*/
+//OSMenuRef QMenuBar::macMenu() { return d_func()->macMenu(); }
+
+/* !
+ \internal
+ Ancestor function that crosses windows (QWidget::isAncestorOf
+ only considers widgets within the same window).
+*/
+static bool qt_mac_is_ancestor(QWidget* possibleAncestor, QWidget *child)
+{
+ if (!possibleAncestor)
+ return false;
+
+ QWidget * current = child->parentWidget();
+ while (current != 0) {
+ if (current == possibleAncestor)
+ return true;
+ current = current->parentWidget();
+ }
+ return false;
+}
+
+/* !
+ \internal
+ Returns true if the entries of menuBar should be disabled,
+ based on the modality type of modalWidget.
+*/
+static bool qt_mac_should_disable_menu(QMenuBar *menuBar)
+{
+ QWidget *modalWidget = qApp->activeModalWidget();
+ if (!modalWidget)
+ return false;
+
+ if (menuBar && menuBar == menubars()->value(modalWidget))
+ // The menu bar is owned by the modal widget.
+ // In that case we should enable it:
+ return false;
+
+ // When there is an application modal window on screen, the entries of
+ // the menubar should be disabled. The exception in Qt is that if the
+ // modal window is the only window on screen, then we enable the menu bar.
+ QWidget *w = modalWidget;
+ QWidgetList topLevelWidgets = QApplication::topLevelWidgets();
+ while (w) {
+ if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) {
+ for (int i=0; i<topLevelWidgets.size(); ++i) {
+ QWidget *top = topLevelWidgets.at(i);
+ if (w != top && top->isVisible()) {
+ // INVARIANT: we found another visible window
+ // on screen other than our modalWidget. We therefore
+ // disable the menu bar to follow normal modality logic:
+ return true;
+ }
+ }
+ // INVARIANT: We have only one window on screen that happends
+ // to be application modal. We choose to enable the menu bar
+ // in that case to e.g. enable the quit menu item.
+ return false;
+ }
+ w = w->parentWidget();
+ }
+
+ // INVARIANT: modalWidget is window modal. Disable menu entries
+ // if the menu bar belongs to an ancestor of modalWidget. If menuBar
+ // is nil, we understand it as the default menu bar set by the nib:
+ return menuBar ? qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget) : false;
+}
+
+static QWidget *findWindowThatShouldDisplayMenubar()
+{
+ QWidget *w = qApp->activeWindow();
+
+ if (!w) {
+ // We have no active window on screen. Try to
+ // find a window from the list of top levels:
+ QWidgetList tlws = QApplication::topLevelWidgets();
+ for(int i = 0; i < tlws.size(); ++i) {
+ QWidget *tlw = tlws.at(i);
+ if ((tlw->isVisible() && tlw->windowType() != Qt::Tool &&
+ tlw->windowType() != Qt::Popup)) {
+ w = tlw;
+ break;
+ }
+ }
+ }
+
+ return w;
+}
+
+static QMenuBar *findMenubarForWindow(QWidget *w)
+{
+ QMenuBar *mb = 0;
+ if (w) {
+ mb = menubars()->value(w);
+
+#if 0
+// ###
+//#ifndef QT_NO_MAINWINDOW
+ QDockWidget *dw = qobject_cast<QDockWidget *>(w);
+ if (!mb && dw) {
+ QMainWindow *mw = qobject_cast<QMainWindow *>(dw->parentWidget());
+ if (mw && (mb = menubars()->value(mw)))
+ w = mw;
+ }
+#endif
+ while(w && !mb)
+ mb = menubars()->value((w = w->parentWidget()));
+ }
+
+ if (!mb) {
+ // We could not find a menu bar for the window. Lets
+ // check if we have a global (parentless) menu bar instead:
+ mb = fallback;
+ }
+
+ return mb;
+}
+
+void qt_mac_clear_menubar()
+{
+ if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
+ return;
+
+ QCocoaAutoReleasePool pool;
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ NSMenu *menu = [loader menu];
+ [loader ensureAppMenuInMenu:menu];
+ [NSApp setMainMenu:menu];
+ const bool modal = qt_mac_should_disable_menu(0);
+ if (qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal)
+ qt_mac_set_modal_state(menu, modal);
+ qt_mac_current_menubar.qmenubar = 0;
+ qt_mac_current_menubar.modal = modal;
+}
+
+/*!
+ \internal
+
+ This function will update the current menu bar and set it as the
+ active menu bar in the Menu Manager.
+
+ \warning This function is not portable.
+*/
+void QCocoaMenuBar::macUpdateMenuBar()
+{
+ [getMenuLoader() performSelectorOnMainThread: @selector(qtUpdateMenubar) withObject: nil waitUntilDone: NO];
+}
+
+bool QCocoaMenuBar::macUpdateMenuBarImmediatly()
+{
+ bool ret = false;
+ cancelAllMenuTracking();
+ QWidget *w = findWindowThatShouldDisplayMenubar();
+ QMenuBar *mb = findMenubarForWindow(w);
+
+ // ### extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
+ bool qt_mac_app_fullscreen = false;
+ // We need to see if we are in full screen mode, if so we need to
+ // switch the full screen mode to be able to show or hide the menubar.
+ if(w && mb) {
+ // This case means we are creating a menubar, check if full screen
+ if(w->isFullScreen()) {
+ // Ok, switch to showing the menubar when hovering over it.
+ SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+ qt_mac_app_fullscreen = true;
+ }
+ } else if(w) {
+ // Removing a menubar
+ if(w->isFullScreen()) {
+ // Ok, switch to not showing the menubar when hovering on it
+ SetSystemUIMode(kUIModeAllHidden, 0);
+ qt_mac_app_fullscreen = true;
+ }
+ }
+
+ if (mb && mb->isNativeMenuBar()) {
+
+ // ###
+ bool modal = false;
+ //bool modal = QGuiApplicationPrivate::modalState();
+ QCocoaAutoReleasePool pool;
+ if (OSMenuRef menu = reinterpret_cast<QCocoaMenuBar *>(mb->platformMenuBar())->macMenu()) {
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ [loader ensureAppMenuInMenu:menu];
+ [NSApp setMainMenu:menu];
+ syncMenuBarItemsVisiblity(reinterpret_cast<QCocoaMenuBar *>(mb->platformMenuBar()));
+
+ if (OSMenuRef tmpMerge = QCocoaMenu::mergeMenuHash.value(menu)) {
+ if (QMenuMergeList *mergeList
+ = QCocoaMenu::mergeMenuItemsHash.value(tmpMerge)) {
+ const int mergeListSize = mergeList->size();
+
+ for (int i = 0; i < mergeListSize; ++i) {
+ const QMenuMergeItem &mergeItem = mergeList->at(i);
+ // Ideally we would call QCocoaMenu::syncAction, but that requires finding
+ // the original QMen and likely doing more work than we need.
+ // For example, enabled is handled below.
+ [mergeItem.menuItem setTag:reinterpret_cast<long>(
+ static_cast<QAction *>(mergeItem.action->action))];
+ [mergeItem.menuItem setHidden:!(mergeItem.action->action->isVisible())];
+ }
+ }
+ }
+ // Check if menu is modally shaddowed and should be disabled:
+ modal = qt_mac_should_disable_menu(mb);
+ if (mb != qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal)
+ qt_mac_set_modal_state(menu, modal);
+ }
+ qt_mac_current_menubar.qmenubar = mb;
+ qt_mac_current_menubar.modal = modal;
+ ret = true;
+ } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
+ // INVARIANT: The currently active menu bar (if any) is not native. But we do have a
+ // native menu bar from before. So we need to decide whether or not is should be enabled:
+ const bool modal = qt_mac_should_disable_menu(qt_mac_current_menubar.qmenubar);
+ if (modal != qt_mac_current_menubar.modal) {
+ ret = true;
+ if (OSMenuRef menu = reinterpret_cast<QCocoaMenuBar *>(qt_mac_current_menubar.qmenubar->platformMenuBar())->macMenu()) {
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ [loader ensureAppMenuInMenu:menu];
+ [NSApp setMainMenu:menu];
+ syncMenuBarItemsVisiblity(reinterpret_cast<QCocoaMenuBar *>(qt_mac_current_menubar.qmenubar->platformMenuBar()));
+ qt_mac_set_modal_state(menu, modal);
+ }
+ qt_mac_current_menubar.modal = modal;
+ }
+ }
+
+ if (!ret) {
+ qt_mac_clear_menubar();
+ }
+ return ret;
+}
+
+QHash<OSMenuRef, OSMenuRef> QCocoaMenu::mergeMenuHash;
+QHash<OSMenuRef, QMenuMergeList*> QCocoaMenu::mergeMenuItemsHash;
+
+bool QCocoaMenu::merged(const QAction *action) const
+{
+ if (OSMenuRef merge = mergeMenuHash.value(menu)) {
+ if (QMenuMergeList *list = mergeMenuItemsHash.value(merge)) {
+ for(int i = 0; i < list->size(); ++i) {
+ const QMenuMergeItem &item = list->at(i);
+ if (item.action->action == action)
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+//creation of the OSMenuRef
+static OSMenuRef qt_mac_create_menu(QWidget *w)
+{
+ OSMenuRef ret;
+ if (QMenu *qmenu = qobject_cast<QMenu *>(w)){
+ ret = [[QT_MANGLE_NAMESPACE(QNativeCocoaMenu) alloc] initWithQMenu:qmenu];
+ } else {
+ ret = [[NSMenu alloc] init];
+ }
+ return ret;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 69a11134bd..0b96928d5b 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -48,17 +48,18 @@
@interface QNSView : NSView {
CGImageRef m_cgImage;
- QWidget *m_widget;
+ QWindow *m_window;
Qt::MouseButtons m_buttons;
}
- (id)init;
-- (id)initWithWidget:(QWidget *)widget;
+- (id)initWithQWindow:(QWindow *)window;
- (void)setImage:(QImage *)image;
- (void)drawRect:(NSRect)dirtyRect;
- (BOOL)isFlipped;
+- (BOOL)acceptsFirstResponder;
- (void)handleMouseEvent:(NSEvent *)theEvent;
- (void)mouseDown:(NSEvent *)theEvent;
@@ -74,6 +75,12 @@
- (void)otherMouseDragged:(NSEvent *)theEvent;
- (void)otherMouseUp:(NSEvent *)theEvent;
+- (int) convertKeyCode : (QChar)keyCode;
+- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags;
+- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType;
+- (void)keyDown:(NSEvent *)theEvent;
+- (void)keyUp:(NSEvent *)theEvent;
+
@end
#endif //QNSVIEW_H
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 037cbdb5d6..f3c71d9eed 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -39,12 +39,20 @@
**
****************************************************************************/
+#include <Carbon/Carbon.h>
+
#include "qnsview.h"
+#include "qcocoahelpers.h"
#include <QtGui/QWindowSystemInterface>
-
#include <QtCore/QDebug>
+@interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
+ - (CGFloat)deviceDeltaX;
+ - (CGFloat)deviceDeltaY;
+ - (CGFloat)deviceDeltaZ;
+@end
+
@implementation QNSView
- (id) init
@@ -52,16 +60,16 @@
self = [super init];
if (self) {
m_cgImage = 0;
- m_widget = 0;
+ m_window = 0;
m_buttons = Qt::NoButton;
}
return self;
}
-- (id)initWithWidget:(QWidget *)widget {
+- (id)initWithQWindow:(QWindow *)widget {
self = [self init];
if (self) {
- m_widget = widget;
+ m_window = widget;
}
return self;
}
@@ -91,7 +99,7 @@
bitDepth,
bytesPrLine,
cgColourSpaceRef,
- kCGImageAlphaNone,
+ kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
cgDataProviderRef,
NULL,
false,
@@ -130,82 +138,185 @@
return YES;
}
+- (BOOL)acceptsFirstResponder
+{
+ return YES;
+}
+
- (void)handleMouseEvent:(NSEvent *)theEvent;
{
- NSPoint point = [self convertPoint: [theEvent locationInWindow] fromView: nil];
- QPoint qt_localPoint(point.x,point.y);
+ NSPoint windowPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil];
+ QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
NSTimeInterval timestamp = [theEvent timestamp];
ulong qt_timestamp = timestamp * 1000;
- QWindowSystemInterface::handleMouseEvent(m_widget,qt_timestamp,qt_localPoint,QPoint(),m_buttons);
+ // ### Should the points be windowPoint and screenPoint?
+ QWindowSystemInterface::handleMouseEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, m_buttons);
+}
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ m_buttons |= Qt::LeftButton;
+ [self handleMouseEvent:theEvent];
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent
+{
+ if (!(m_buttons & Qt::LeftButton))
+ qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
+ [self handleMouseEvent:theEvent];
+}
+
+- (void)mouseUp:(NSEvent *)theEvent
+{
+ m_buttons &= QFlag(~int(Qt::LeftButton));
+ [self handleMouseEvent:theEvent];
}
- - (void)mouseDown:(NSEvent *)theEvent
- {
- m_buttons |= Qt::LeftButton;
- [self handleMouseEvent:theEvent];
- }
- - (void)mouseDragged:(NSEvent *)theEvent
- {
- if (!(m_buttons & Qt::LeftButton))
- qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
- [self handleMouseEvent:theEvent];
- }
- - (void)mouseUp:(NSEvent *)theEvent
- {
- m_buttons &= QFlag(~int(Qt::LeftButton));
- [self handleMouseEvent:theEvent];
- }
- (void)mouseMoved:(NSEvent *)theEvent
{
- qDebug() << "mouseMove";
[self handleMouseEvent:theEvent];
}
+
- (void)mouseEntered:(NSEvent *)theEvent
{
- Q_UNUSED(theEvent);
- QWindowSystemInterface::handleEnterEvent(m_widget);
+ Q_UNUSED(theEvent);
+ QWindowSystemInterface::handleEnterEvent(m_window);
}
+
- (void)mouseExited:(NSEvent *)theEvent
{
- Q_UNUSED(theEvent);
- QWindowSystemInterface::handleLeaveEvent(m_widget);
+ Q_UNUSED(theEvent);
+ QWindowSystemInterface::handleLeaveEvent(m_window);
}
+
- (void)rightMouseDown:(NSEvent *)theEvent
{
- m_buttons |= Qt::RightButton;
+ m_buttons |= Qt::RightButton;
[self handleMouseEvent:theEvent];
}
+
- (void)rightMouseDragged:(NSEvent *)theEvent
{
- if (!(m_buttons & Qt::LeftButton))
- qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
- [self handleMouseEvent:theEvent];
+ if (!(m_buttons & Qt::LeftButton))
+ qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
+ [self handleMouseEvent:theEvent];
}
+
- (void)rightMouseUp:(NSEvent *)theEvent
{
- m_buttons &= QFlag(~int(Qt::RightButton));
- [self handleMouseEvent:theEvent];
+ m_buttons &= QFlag(~int(Qt::RightButton));
+ [self handleMouseEvent:theEvent];
}
+
- (void)otherMouseDown:(NSEvent *)theEvent
{
- m_buttons |= Qt::RightButton;
+ m_buttons |= Qt::RightButton;
[self handleMouseEvent:theEvent];
}
+
- (void)otherMouseDragged:(NSEvent *)theEvent
{
- if (!(m_buttons & Qt::LeftButton))
- qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
- [self handleMouseEvent:theEvent];
+ if (!(m_buttons & Qt::LeftButton))
+ qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
+ [self handleMouseEvent:theEvent];
}
+
- (void)otherMouseUp:(NSEvent *)theEvent
{
- m_buttons &= QFlag(~int(Qt::MiddleButton));
- [self handleMouseEvent:theEvent];
+ m_buttons &= QFlag(~int(Qt::MiddleButton));
+ [self handleMouseEvent:theEvent];
}
+#ifndef QT_NO_WHEELEVENT
+- (void)scrollWheel:(NSEvent *)theEvent
+{
+ int deltaX = 0;
+ int deltaY = 0;
+ int deltaZ = 0;
+
+ const EventRef carbonEvent = (EventRef)[theEvent eventRef];
+ const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
+ const bool scrollEvent = carbonEventKind == kEventMouseScroll;
+
+ if (scrollEvent) {
+ // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
+ // Since deviceDelta is delivered as pixels rather than degrees, we need to
+ // convert from pixels to degrees in a sensible manner.
+ // It looks like 1/4 degrees per pixel behaves most native.
+ // (NB: Qt expects the unit for delta to be 8 per degree):
+ const int pixelsToDegrees = 2; // 8 * 1/4
+ deltaX = [theEvent deviceDeltaX] * pixelsToDegrees;
+ deltaY = [theEvent deviceDeltaY] * pixelsToDegrees;
+ deltaZ = [theEvent deviceDeltaZ] * pixelsToDegrees;
+ } else {
+ // carbonEventKind == kEventMouseWheelMoved
+ // Remove acceleration, and use either -120 or 120 as delta:
+ deltaX = qBound(-120, int([theEvent deltaX] * 10000), 120);
+ deltaY = qBound(-120, int([theEvent deltaY] * 10000), 120);
+ deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120);
+ }
+
+ NSPoint windowPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil];
+ QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
+ NSTimeInterval timestamp = [theEvent timestamp];
+ ulong qt_timestamp = timestamp * 1000;
+
+ if (deltaX != 0)
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaX, Qt::Horizontal);
+
+ if (deltaY != 0)
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaY, Qt::Vertical);
+ if (deltaZ != 0)
+ // Qt doesn't explicitly support wheels with a Z component. In a misguided attempt to
+ // try to be ahead of the pack, I'm adding this extra value.
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaY, (Qt::Orientation)3);
+}
+#endif //QT_NO_WHEELEVENT
+
+- (int) convertKeyCode : (QChar)keyChar
+{
+ return qt_mac_cocoaKey2QtKey(keyChar);
+}
+
+- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags
+{
+ Qt::KeyboardModifiers qtMods =Qt::NoModifier;
+ if (modifierFlags & NSShiftKeyMask)
+ qtMods |= Qt::ShiftModifier;
+ if (modifierFlags & NSControlKeyMask)
+ qtMods |= Qt::MetaModifier;
+ if (modifierFlags & NSAlternateKeyMask)
+ qtMods |= Qt::AltModifier;
+ if (modifierFlags & NSCommandKeyMask)
+ qtMods |= Qt::ControlModifier;
+ if (modifierFlags & NSNumericPadKeyMask)
+ qtMods |= Qt::KeypadModifier;
+ return qtMods;
+}
+
+- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType
+{
+ NSTimeInterval timestamp = [theEvent timestamp];
+ ulong qt_timestamp = timestamp * 1000;
+ QString characters = QString::fromUtf8([[theEvent characters] UTF8String]);
+ Qt::KeyboardModifiers modifiers = [self convertKeyModifiers : [theEvent modifierFlags]];
+ QChar ch([[theEvent charactersIgnoringModifiers] characterAtIndex:0]);
+ int keyCode = [self convertKeyCode : ch];
+
+ QWindowSystemInterface::handleKeyEvent(m_window, qt_timestamp, QEvent::Type(eventType), keyCode, modifiers, characters);
+}
+
+- (void)keyDown:(NSEvent *)theEvent
+{
+ [self handleKeyEvent : theEvent eventType :int(QEvent::KeyPress)];
+}
+
+- (void)keyUp:(NSEvent *)theEvent
+{
+ [self handleKeyEvent : theEvent eventType :int(QEvent::KeyRelease)];
+}
@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index cf296c4a8b..5cd226a71d 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -46,6 +46,26 @@
#include "qcocoawindow.h"
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+@protocol NSWindowDelegate <NSObject>
+//- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
+//- (void)windowDidMiniaturize:(NSNotification*)notification;
+- (void)windowDidResize:(NSNotification *)notification;
+- (void)windowWillClose:(NSNotification *)notification;
+//- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)defaultFrame;
+- (void)windowDidMove:(NSNotification *)notification;
+//- (BOOL)windowShouldClose:(id)window;
+//- (void)windowDidDeminiaturize:(NSNotification *)notification;
+//- (void)windowDidBecomeMain:(NSNotification*)notification;
+//- (void)windowDidResignMain:(NSNotification*)notification;
+//- (void)windowDidBecomeKey:(NSNotification*)notification;
+//- (void)windowDidResignKey:(NSNotification*)notification;
+//- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu;
+//- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard;
+//- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame;
+@end
+#endif
+
@interface QNSWindowDelegate : NSObject <NSWindowDelegate>
{
QCocoaWindow *m_cocoaWindow;
@@ -54,6 +74,7 @@
- (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow;
- (void)windowDidResize:(NSNotification *)notification;
+- (void)windowDidMove:(NSNotification *)notification;
- (void)windowWillClose:(NSNotification *)notification;
@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 887b08f6d2..869ef7840b 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -64,10 +64,20 @@
}
}
+- (void)windowDidMove:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ if (m_cocoaWindow) {
+ m_cocoaWindow->windowDidMove();
+ }
+}
+
- (void)windowWillClose:(NSNotification *)notification
{
Q_UNUSED(notification);
- QWindowSystemInterface::handleCloseEvent(m_cocoaWindow->widget());
+ if (m_cocoaWindow) {
+ m_cocoaWindow->windowWillClose();
+ }
}
@end
diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib b/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib
new file mode 100644
index 0000000000..0031e0e4e5
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBClasses</key>
+ <array>
+ <dict>
+ <key>ACTIONS</key>
+ <dict>
+ <key>hide</key>
+ <string>id</string>
+ <key>hideOtherApplications</key>
+ <string>id</string>
+ <key>orderFrontStandardAboutPanel</key>
+ <string>id</string>
+ <key>qtDispatcherToQAction</key>
+ <string>id</string>
+ <key>terminate</key>
+ <string>id</string>
+ <key>unhideAllApplications</key>
+ <string>id</string>
+ </dict>
+ <key>CLASS</key>
+ <string>QCocoaMenuLoader</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ <key>OUTLETS</key>
+ <dict>
+ <key>aboutItem</key>
+ <string>NSMenuItem</string>
+ <key>aboutQtItem</key>
+ <string>NSMenuItem</string>
+ <key>appMenu</key>
+ <string>NSMenu</string>
+ <key>hideItem</key>
+ <string>NSMenuItem</string>
+ <key>preferencesItem</key>
+ <string>NSMenuItem</string>
+ <key>quitItem</key>
+ <string>NSMenuItem</string>
+ <key>theMenu</key>
+ <string>NSMenu</string>
+ </dict>
+ <key>SUPERCLASS</key>
+ <string>NSResponder</string>
+ </dict>
+ <dict>
+ <key>CLASS</key>
+ <string>FirstResponder</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ <key>SUPERCLASS</key>
+ <string>NSObject</string>
+ </dict>
+ </array>
+ <key>IBVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/info.nib b/src/plugins/platforms/cocoa/qt_menu.nib/info.nib
new file mode 100644
index 0000000000..02e5cca562
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qt_menu.nib/info.nib
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBFramework Version</key>
+ <string>672</string>
+ <key>IBOldestOS</key>
+ <integer>5</integer>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>57</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>9L31a</string>
+ <key>targetFramework</key>
+ <string>IBCocoaFramework</string>
+</dict>
+</plist>
diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib b/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib
new file mode 100644
index 0000000000..3edb0ed2eb
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib
Binary files differ
diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro
index f830177dcb..e516fb11f3 100644
--- a/src/plugins/platforms/directfb/directfb.pro
+++ b/src/plugins/platforms/directfb/directfb.pro
@@ -2,6 +2,8 @@ TARGET = qdirectfb
load(qt_plugin)
DESTDIR = $$QT.gui.plugins/platforms
+QT += core-private gui-private platformsupport-private
+
isEmpty(DIRECTFB_LIBS) {
DIRECTFB_LIBS = -ldirectfb -lfusion -ldirect -lpthread
}
@@ -19,16 +21,16 @@ SOURCES = main.cpp \
qdirectfbconvenience.cpp \
qdirectfbinput.cpp \
qdirectfbcursor.cpp \
- qdirectfbwindow.cpp \
- qdirectfbglcontext.cpp
+ qdirectfbwindow.cpp
HEADERS = qdirectfbintegration.h \
qdirectfbwindowsurface.h \
qdirectfbblitter.h \
qdirectfbconvenience.h \
qdirectfbinput.h \
qdirectfbcursor.h \
- qdirectfbwindow.h \
- qdirectfbglcontext.h
+ qdirectfbwindow.h
+
+# ### port the GL context
include(../fontdatabases/genericunix/genericunix.pri)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.cpp b/src/plugins/platforms/directfb/qdirectfbblitter.cpp
index 86a8bf7cb7..a4da2d8142 100644
--- a/src/plugins/platforms/directfb/qdirectfbblitter.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbblitter.cpp
@@ -92,10 +92,10 @@ void QDirectFbBlitter::fillRect(const QRectF &rect, const QColor &color)
void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, const QRectF &srcRect)
{
- QPixmapData *data = pixmap.pixmapData();
+ QPlatformPixmap *data = pixmap.handle();
Q_ASSERT(data->width() && data->height());
- Q_ASSERT(data->classId() == QPixmapData::BlitterClass);
- QBlittablePixmapData *blitPm = static_cast<QBlittablePixmapData*>(data);
+ Q_ASSERT(data->classId() == QPlatformPixmap::BlitterClass);
+ QBlittablePlatformPixmap *blitPm = static_cast<QBlittablePlatformPixmap*>(data);
QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blitPm->blittable());
dfbBlitter->unlock();
diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.h b/src/plugins/platforms/directfb/qdirectfbblitter.h
index 16d7599c83..2dcb2be07a 100644
--- a/src/plugins/platforms/directfb/qdirectfbblitter.h
+++ b/src/plugins/platforms/directfb/qdirectfbblitter.h
@@ -67,7 +67,7 @@ protected:
friend class QDirectFbConvenience;
};
-class QDirectFbBlitterPixmapData : public QBlittablePixmapData
+class QDirectFbBlitterPlatformPixmap : public QBlittablePlatformPixmap
{
public:
QBlittable *createBlittable(const QSize &size) const { return new QDirectFbBlitter(size); }
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index 37810dc461..38130c8deb 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -106,9 +106,9 @@ int QDirectFbConvenience::colorDepthForSurface(const DFBSurfacePixelFormat forma
return ((0x1f << 7) & format) >> 7;
}
-IDirectFBSurface *QDirectFbConvenience::dfbSurfaceForPixmapData(QPixmapData *pixmapData)
+IDirectFBSurface *QDirectFbConvenience::dfbSurfaceForPlatformPixmap(QPlatformPixmap *handle)
{
- QBlittablePixmapData *blittablePmData = static_cast<QBlittablePixmapData *>(pixmapData);
+ QBlittablePlatformPixmap *blittablePmData = static_cast<QBlittablePlatformPixmap *>(handle);
if (blittablePmData) {
QBlittable *blittable = blittablePmData->blittable();
QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blittable);
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.h b/src/plugins/platforms/directfb/qdirectfbconvenience.h
index c82bea84c7..93d47f3644 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.h
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.h
@@ -67,7 +67,7 @@ public:
static IDirectFB *dfbInterface();
static IDirectFBDisplayLayer *dfbDisplayLayer(int display = DLID_PRIMARY);
- static IDirectFBSurface *dfbSurfaceForPixmapData(QPixmapData *);
+ static IDirectFBSurface *dfbSurfaceForPlatformPixmap(QPlatformPixmap *);
static Qt::MouseButton mouseButton(DFBInputDeviceButtonIdentifier identifier);
static Qt::MouseButtons mouseButtons(DFBInputDeviceButtonMask mask);
diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.cpp b/src/plugins/platforms/directfb/qdirectfbcursor.cpp
index 8a38bc4e83..b39a3f3c0a 100644
--- a/src/plugins/platforms/directfb/qdirectfbcursor.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbcursor.cpp
@@ -43,25 +43,26 @@
#include "qdirectfbconvenience.h"
-QDirectFBCursor::QDirectFBCursor(QPlatformScreen* screen) :
- QPlatformCursor(screen), surface(0)
+QDirectFBCursor::QDirectFBCursor(QPlatformScreen *screen)
+ : QPlatformCursor(screen)
{
QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(),DLID_PRIMARY, &m_layer);
- image = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
+ m_image = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
}
-void QDirectFBCursor::changeCursor(QCursor * cursor, QWidget * widget)
+#warning "Memory leak?"
+
+void QDirectFBCursor::changeCursor(QCursor *cursor, QWindow *)
{
- Q_UNUSED(widget);
int xSpot;
int ySpot;
QPixmap map;
if (cursor->shape() != Qt::BitmapCursor) {
- image->set(cursor->shape());
- xSpot = image->hotspot().x();
- ySpot = image->hotspot().y();
- QImage *i = image->image();
+ m_image->set(cursor->shape());
+ xSpot = m_image->hotspot().x();
+ ySpot = m_image->hotspot().y();
+ QImage *i = m_image->image();
map = QPixmap::fromImage(*i);
} else {
QPoint point = cursor->hotSpot();
@@ -70,7 +71,7 @@ void QDirectFBCursor::changeCursor(QCursor * cursor, QWidget * widget)
map = cursor->pixmap();
}
- IDirectFBSurface *surface = QDirectFbConvenience::dfbSurfaceForPixmapData(map.pixmapData());
+ IDirectFBSurface *surface = QDirectFbConvenience::dfbSurfaceForPlatformPixmap(map.handle());
if (m_layer->SetCooperativeLevel(m_layer, DLSCL_ADMINISTRATIVE) != DFB_OK) {
return;
diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.h b/src/plugins/platforms/directfb/qdirectfbcursor.h
index b148de5589..22328da402 100644
--- a/src/plugins/platforms/directfb/qdirectfbcursor.h
+++ b/src/plugins/platforms/directfb/qdirectfbcursor.h
@@ -51,13 +51,11 @@ class QDirectFBCursor : public QPlatformCursor
{
public:
QDirectFBCursor(QPlatformScreen *screem);
- void changeCursor(QCursor * cursor, QWidget * widget);
+ void changeCursor(QCursor *cursor, QWindow *window);
private:
- IDirectFBDisplayLayer * m_layer;
- IDirectFBSurface * surface;
- QPlatformCursorImage * image;
- QDirectFbBlitter *blitter;
+ IDirectFBDisplayLayer *m_layer;
+ QPlatformCursorImage *m_image;
};
#endif // QDIRECTFBCURSOR_H
diff --git a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
index aca28f1d62..1121a42944 100644
--- a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
@@ -70,13 +70,13 @@ QDirectFbGLContext::QDirectFbGLContext(IDirectFBGL *glContext)
void QDirectFbGLContext::makeCurrent()
{
- QPlatformGLContext::makeCurrent();
+ QPlatformOpenGLContext::makeCurrent();
m_dfbGlContext->Lock(m_dfbGlContext);
}
void QDirectFbGLContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ QPlatformOpenGLContext::doneCurrent();
m_dfbGlContext->Unlock(m_dfbGlContext);
}
diff --git a/src/plugins/platforms/directfb/qdirectfbglcontext.h b/src/plugins/platforms/directfb/qdirectfbglcontext.h
index bff8b28d08..97bab0dcb0 100644
--- a/src/plugins/platforms/directfb/qdirectfbglcontext.h
+++ b/src/plugins/platforms/directfb/qdirectfbglcontext.h
@@ -42,11 +42,11 @@
#ifndef QDIRECTFBGLCONTEXT_H
#define QDIRECTFBGLCONTEXT_H
-#include <QPlatformGLContext>
+#include <QPlatformOpenGLContext>
#include "qdirectfbconvenience.h"
-class QDirectFbGLContext : public QPlatformGLContext
+class QDirectFbGLContext : public QPlatformOpenGLContext
{
public:
explicit QDirectFbGLContext(IDirectFBGL *glContext);
diff --git a/src/plugins/platforms/directfb/qdirectfbinput.cpp b/src/plugins/platforms/directfb/qdirectfbinput.cpp
index d35cea5ee9..d05729b992 100644
--- a/src/plugins/platforms/directfb/qdirectfbinput.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbinput.cpp
@@ -47,7 +47,6 @@
#include <QWindowSystemInterface>
#include <QMouseEvent>
#include <QEvent>
-#include <QApplication>
#include <directfb.h>
@@ -82,9 +81,9 @@ void QDirectFbInput::stopInputEventLoop()
m_waitStop.acquire();
}
-void QDirectFbInput::addWindow(DFBWindowID id, QWidget *tlw)
+void QDirectFbInput::addWindow(DFBWindowID id, QWindow *qt_window)
{
- m_tlwMap.insert(id,tlw);
+ m_tlwMap.insert(id,qt_window);
IDirectFBWindow *window;
m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,id,&window);
@@ -152,7 +151,7 @@ void QDirectFbInput::handleMouseEvents(const DFBEvent &event)
} else if (event.window.type == DWET_BUTTONUP) {
window->UngrabPointer(window);
}
- QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindow *tlw = m_tlwMap.value(event.window.window_id);
QWindowSystemInterface::handleMouseEvent(tlw, timestamp, p, globalPos, buttons);
}
@@ -161,7 +160,7 @@ void QDirectFbInput::handleWheelEvent(const DFBEvent &event)
QPoint p(event.window.cx, event.window.cy);
QPoint globalPos = globalPoint(event);
long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000);
- QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindow *tlw = m_tlwMap.value(event.window.window_id);
QWindowSystemInterface::handleWheelEvent(tlw, timestamp, p, globalPos,
event.window.step*120,
Qt::Vertical);
@@ -178,13 +177,13 @@ void QDirectFbInput::handleKeyEvents(const DFBEvent &event)
QChar character;
if (DFB_KEY_TYPE(event.window.key_symbol) == DIKT_UNICODE)
character = QChar(event.window.key_symbol);
- QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindow *tlw = m_tlwMap.value(event.window.window_id);
QWindowSystemInterface::handleKeyEvent(tlw, timestamp, type, key, modifiers, character);
}
void QDirectFbInput::handleEnterLeaveEvents(const DFBEvent &event)
{
- QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindow *tlw = m_tlwMap.value(event.window.window_id);
switch (event.window.type) {
case DWET_ENTER:
QWindowSystemInterface::handleEnterEvent(tlw);
diff --git a/src/plugins/platforms/directfb/qdirectfbinput.h b/src/plugins/platforms/directfb/qdirectfbinput.h
index 3b8008f1fe..b0fe0c79eb 100644
--- a/src/plugins/platforms/directfb/qdirectfbinput.h
+++ b/src/plugins/platforms/directfb/qdirectfbinput.h
@@ -57,7 +57,7 @@ class QDirectFbInput : public QObject
Q_OBJECT
public:
QDirectFbInput(QObject *parent);
- void addWindow(DFBWindowID id, QWidget *tlw);
+ void addWindow(DFBWindowID id, QWindow *window);
void removeWindow(WId wId);
public slots:
@@ -80,7 +80,7 @@ private:
bool m_shouldStop;
QSemaphore m_waitStop;
- QHash<DFBWindowID,QWidget *>m_tlwMap;
+ QHash<DFBWindowID,QWindow *>m_tlwMap;
};
#endif // QDIRECTFBINPUT_H
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
index 61f1d2513b..7bf26b433a 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
@@ -46,20 +46,21 @@
#include "qdirectfbcursor.h"
#include "qdirectfbwindow.h"
-#include "qgenericunixfontdatabase.h"
-
-#include <private/qwindowsurface_raster_p.h>
-#include <private/qpixmap_raster_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtGui/private/qpixmap_blitter_p.h>
-#include <QtGui/private/qpixmapdata_p.h>
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qplatformpixmap_qpa.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
+#include <QtCore/QAbstractEventDispatcher>
QT_BEGIN_NAMESPACE
QDirectFbScreen::QDirectFbScreen(int display)
- :QPlatformScreen()
+ : QPlatformScreen()
{
m_layer = QDirectFbConvenience::dfbDisplayLayer(display);
m_layer->SetCooperativeLevel(m_layer,DLSCL_SHARED);
@@ -74,16 +75,20 @@ QDirectFbScreen::QDirectFbScreen(int display)
m_depth = QDirectFbConvenience::colorDepthForSurface(config.pixelformat);
m_physicalSize = QSize(qRound(config.width * inch / dpi), qRound(config.height *inch / dpi));
- cursor = new QDirectFBCursor(this);
+ m_cursor = new QDirectFBCursor(this);
}
QDirectFbScreen::~QDirectFbScreen()
{
+#warning "Delete the cursor?"
}
QDirectFbIntegration::QDirectFbIntegration()
- : mFontDb(new QGenericUnixFontDatabase())
+ : m_fontDb(new QGenericUnixFontDatabase())
+ , m_eventDispatcher(createUnixEventDispatcher())
{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
+
const QStringList args = QCoreApplication::arguments();
int argc = args.size();
char **argv = new char*[argc];
@@ -99,46 +104,51 @@ QDirectFbIntegration::QDirectFbIntegration()
delete[] argv;
+
QDirectFbScreen *primaryScreen = new QDirectFbScreen(0);
- mScreens.append(primaryScreen);
+ screenAdded(primaryScreen);
- mInputRunner = new QThread;
- mInput = new QDirectFbInput(0);
- mInput->moveToThread(mInputRunner);
- QObject::connect(mInputRunner,SIGNAL(started()),mInput,SLOT(runInputEventLoop()));
- mInputRunner->start();
+ m_inputRunner = new QThread;
+ m_input = new QDirectFbInput(0);
+ m_input->moveToThread(m_inputRunner);
+ QObject::connect(m_inputRunner,SIGNAL(started()),m_input,SLOT(runInputEventLoop()));
+ m_inputRunner->start();
}
QDirectFbIntegration::~QDirectFbIntegration()
{
- mInput->stopInputEventLoop();
- delete mInputRunner;
- delete mInput;
+ m_input->stopInputEventLoop();
+ delete m_inputRunner;
+ delete m_input;
}
-QPixmapData *QDirectFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QDirectFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- if (type == QPixmapData::BitmapType)
- return new QRasterPixmapData(type);
+ if (type == QPlatformPixmap::BitmapType)
+ return new QRasterPlatformPixmap(type);
else
- return new QDirectFbBlitterPixmapData;
+ return new QDirectFbBlitterPlatformPixmap;
+}
+
+QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWindow *window) const
+{
+ QDirectFbInput *input = const_cast<QDirectFbInput *>(m_input);//gah
+ return new QDirectFbWindow(window,input);
}
-QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+QAbstractEventDispatcher *QDirectFbIntegration::guiThreadEventDispatcher() const
{
- Q_UNUSED(winId);
- QDirectFbInput *input = const_cast<QDirectFbInput *>(mInput);//gah
- return new QDirectFbWindow(widget,input);
+ return m_eventDispatcher;
}
-QWindowSurface *QDirectFbIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QPlatformBackingStore *QDirectFbIntegration::createPlatformBackingStore(QWindow *window) const
{
- return new QDirectFbWindowSurface(widget,winId);
+ return new QDirectFbWindowSurface(window);
}
QPlatformFontDatabase *QDirectFbIntegration::fontDatabase() const
{
- return mFontDb;
+ return m_fontDb;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h
index 0e8337a5fb..64f3b6005a 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.h
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.h
@@ -51,11 +51,11 @@
QT_BEGIN_NAMESPACE
class QThread;
+class QAbstractEventDispatcher;
class QDirectFBCursor;
class QDirectFbScreen : public QPlatformScreen
{
-Q_OBJECT
public:
QDirectFbScreen(int display);
~QDirectFbScreen();
@@ -74,8 +74,7 @@ public:
IDirectFBDisplayLayer *m_layer;
private:
- QDirectFBCursor * cursor;
-
+ QDirectFBCursor *m_cursor;
};
class QDirectFbIntegration : public QPlatformIntegration
@@ -84,19 +83,18 @@ public:
QDirectFbIntegration();
~QDirectFbIntegration();
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
-
- QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
QPlatformFontDatabase *fontDatabase() const;
private:
- QList<QPlatformScreen *> mScreens;
- QDirectFbInput *mInput;
- QThread *mInputRunner;
- QPlatformFontDatabase *mFontDb;
+ QDirectFbInput *m_input;
+ QThread *m_inputRunner;
+ QPlatformFontDatabase *m_fontDb;
+ QAbstractEventDispatcher *m_eventDispatcher;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.cpp b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
index d2c411eaeb..e75291b5c1 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindow.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
@@ -41,16 +41,13 @@
#include "qdirectfbwindow.h"
#include "qdirectfbinput.h"
-#include "qdirectfbglcontext.h"
-
-#include <QWidget>
#include "qdirectfbwindowsurface.h"
#include <directfb.h>
-QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler)
- : QPlatformWindow(tlw), m_inputHandler(inputhandler), m_context(0)
+QDirectFbWindow::QDirectFbWindow(QWindow *tlw, QDirectFbInput *inputhandler)
+ : QPlatformWindow(tlw), m_inputHandler(inputhandler)
{
IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer();
DFBDisplayLayerConfig layerConfig;
@@ -63,10 +60,10 @@ QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler)
|DWDESC_OPTIONS
#endif
|DWDESC_CAPS);
- description.width = tlw->rect().width();
- description.height = tlw->rect().height();
- description.posx = tlw->rect().x();
- description.posy = tlw->rect().y();
+ description.width = tlw->width();
+ description.height = tlw->height();
+ description.posx = tlw->x();
+ description.posy = tlw->y();
if (layerConfig.surface_caps & DSCAPS_PREMULTIPLIED)
description.surface_caps = DSCAPS_PREMULTIPLIED;
@@ -85,7 +82,7 @@ QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler)
m_dfbWindow->SetOpacity(m_dfbWindow,0xff);
- setVisible(widget()->isVisible());
+ setVisible(window()->visible());
DFBWindowID id;
m_dfbWindow->GetID(m_dfbWindow, &id);
@@ -100,17 +97,20 @@ QDirectFbWindow::~QDirectFbWindow()
void QDirectFbWindow::setGeometry(const QRect &rect)
{
- bool isMoveOnly = (rect.topLeft() != geometry().topLeft()) && (rect.size() == geometry().size());
+// bool isMoveOnly = (rect.topLeft() != geometry().topLeft()) && (rect.size() == geometry().size());
+
QPlatformWindow::setGeometry(rect);
- if (widget()->isVisible() && !(widget()->testAttribute(Qt::WA_DontShowOnScreen))) {
+ if (window()->visible()) {
m_dfbWindow->SetBounds(m_dfbWindow, rect.x(),rect.y(),
rect.width(), rect.height());
-
+// ### TODO port, verify if this is needed
+#if 0
//Hack. When moving since the WindowSurface of a window becomes invalid when moved
if (isMoveOnly) { //if resize then windowsurface is updated.
widget()->windowSurface()->resize(rect.size());
- widget()->update();
+ window()->update();
}
+#endif
}
}
@@ -169,23 +169,3 @@ WId QDirectFbWindow::winId() const
m_dfbWindow->GetID(m_dfbWindow, &id);
return WId(id);
}
-
-QPlatformGLContext *QDirectFbWindow::glContext() const
-{
- if (!m_context) {
- IDirectFBSurface *surface;
- DFBResult result = m_dfbWindow->GetSurface(m_dfbWindow,&surface);
- if (result != DFB_OK) {
- qWarning("could not retrieve surface in QDirectFbWindow::glContext()");
- return 0;
- }
- IDirectFBGL *gl;
- result = surface->GetGL(surface,&gl);
- if (result != DFB_OK) {
- qWarning("could not retrieve IDirectFBGL in QDirectFbWindow::glContext()");
- return 0;
- }
- const_cast<QDirectFbWindow *>(this)->m_context = new QDirectFbGLContext(gl);
- }
- return m_context;
-}
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.h b/src/plugins/platforms/directfb/qdirectfbwindow.h
index 4f839a05fa..4c9bbaaab5 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindow.h
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.h
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
class QDirectFbWindow : public QPlatformWindow
{
public:
- QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler);
+ QDirectFbWindow(QWindow *tlw, QDirectFbInput *inputhandler);
~QDirectFbWindow();
void setGeometry(const QRect &rect);
@@ -65,13 +65,9 @@ public:
void lower();
WId winId() const;
- QPlatformGLContext *glContext() const;
-
private:
IDirectFBWindow *m_dfbWindow;
QDirectFbInput *m_inputHandler;
-
- QPlatformGLContext *m_context;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp b/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp
index 730f01fa1b..ab355c48f4 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp
@@ -49,21 +49,21 @@
QT_BEGIN_NAMESPACE
-QDirectFbWindowSurface::QDirectFbWindowSurface(QWidget *window, WId wId)
- : QWindowSurface(window), m_pixmap(0), m_pmdata(0), m_dfbSurface(0)
+QDirectFbWindowSurface::QDirectFbWindowSurface(QWindow *window)
+ : QPlatformBackingStore(window), m_pixmap(0), m_pmdata(0), m_dfbSurface(0)
{
IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer();
- DFBWindowID id(wId);
+ DFBWindowID id(window->winId());
IDirectFBWindow *dfbWindow;
layer->GetWindow(layer,id,&dfbWindow);
dfbWindow->GetSurface(dfbWindow,&m_dfbSurface);
//WRONGSIZE
- QDirectFbBlitter *blitter = new QDirectFbBlitter(window->rect().size(), m_dfbSurface);
- m_pmdata = new QDirectFbBlitterPixmapData;
+ QDirectFbBlitter *blitter = new QDirectFbBlitter(window->size(), m_dfbSurface);
+ m_pmdata = new QDirectFbBlitterPlatformPixmap;
m_pmdata->setBlittable(blitter);
m_pixmap = new QPixmap(m_pmdata);
}
@@ -78,9 +78,8 @@ QPaintDevice *QDirectFbWindowSurface::paintDevice()
return m_pixmap;
}
-void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QDirectFbWindowSurface::flush(QWindow *, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(widget);
m_pmdata->blittable()->unlock();
QVector<QRect> rects = region.rects();
@@ -91,9 +90,9 @@ void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion &region, const
}
}
-void QDirectFbWindowSurface::resize(const QSize &size)
+void QDirectFbWindowSurface::resize(const QSize &size, const QRegion& reg)
{
- QWindowSurface::resize(size);
+ QPlatformBackingStore::resize(size, reg);
//Have to add 1 ref ass it will be removed by deleting the old blitter in setBlittable
m_dfbSurface->AddRef(m_dfbSurface);
diff --git a/src/plugins/platforms/directfb/qdirectfbwindowsurface.h b/src/plugins/platforms/directfb/qdirectfbwindowsurface.h
index 7f1140d4eb..2b6cb58aef 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindowsurface.h
+++ b/src/plugins/platforms/directfb/qdirectfbwindowsurface.h
@@ -42,22 +42,22 @@
#ifndef QWINDOWSURFACE_DIRECTFB_H
#define QWINDOWSURFACE_DIRECTFB_H
-#include <QtGui/private/qwindowsurface_p.h>
+#include <qplatformbackingstore_qpa.h>
#include <private/qpixmap_blitter_p.h>
#include <directfb.h>
QT_BEGIN_NAMESPACE
-class QDirectFbWindowSurface : public QWindowSurface
+class QDirectFbWindowSurface : public QPlatformBackingStore
{
public:
- QDirectFbWindowSurface(QWidget *window, WId wid);
+ QDirectFbWindowSurface(QWindow *window);
~QDirectFbWindowSurface();
QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize (const QSize &size);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize (const QSize &size, const QRegion &staticContents);
bool scroll(const QRegion &area, int dx, int dy);
void beginPaint(const QRegion &region);
@@ -67,7 +67,7 @@ private:
void lockSurfaceToImage();
QPixmap *m_pixmap;
- QBlittablePixmapData *m_pmdata;
+ QBlittablePlatformPixmap *m_pmdata;
IDirectFBSurface *m_dfbSurface;
};
diff --git a/src/plugins/platforms/eglconvenience/eglconvenience.pri b/src/plugins/platforms/eglconvenience/eglconvenience.pri
deleted file mode 100644
index 322d4e4633..0000000000
--- a/src/plugins/platforms/eglconvenience/eglconvenience.pri
+++ /dev/null
@@ -1,7 +0,0 @@
-INCLUDEPATH += $$PWD
-
-SOURCES += \
- $$PWD/qeglconvenience.cpp
-
-HEADERS += \
- $$PWD/qeglconvenience.h
diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
deleted file mode 100644
index 69747a87e8..0000000000
--- a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglconvenience.h"
-
-QT_BEGIN_NAMESPACE
-
-QVector<EGLint> q_createConfigAttributesFromFormat(const QPlatformWindowFormat &format)
-{
- int redSize = format.redBufferSize();
- int greenSize = format.greenBufferSize();
- int blueSize = format.blueBufferSize();
- int alphaSize = format.alphaBufferSize();
- int depthSize = format.depthBufferSize();
- int stencilSize = format.stencilBufferSize();
- int sampleCount = format.samples();
-
- // QPlatformWindowFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that
- // type has been requested. So we must check QPlatformWindowFormat's booleans too if size is -1:
- if (format.alpha() && alphaSize <= 0)
- alphaSize = 1;
- if (format.depth() && depthSize <= 0)
- depthSize = 1;
- if (format.stencil() && stencilSize <= 0)
- stencilSize = 1;
- if (format.sampleBuffers() && sampleCount <= 0)
- sampleCount = 1;
-
- // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide
- // the best performance. The EGL config selection algorithm is a bit stange in this regard:
- // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard
- // 32-bit configs completely from the selection. So it then comes to the sorting algorithm.
- // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort
- // order is special and described as "by larger _total_ number of color bits.". So EGL will
- // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on
- // to say "If the requested number of bits in attrib_list for a particular component is 0,
- // then the number of bits for that component is not considered". This part of the spec also
- // seems to imply that setting the red/green/blue bits to zero means none of the components
- // are considered and EGL disregards the entire sorting rule. It then looks to the next
- // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being
- // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are
- // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
- // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
- // if the application sets the red/green/blue size to 5/6/5 on the QPlatformWindowFormat,
- // they will probably get a 32-bit config, even when there's an RGB565 config available.
-
- // Now normalize the values so -1 becomes 0
- redSize = redSize > 0 ? redSize : 0;
- greenSize = greenSize > 0 ? greenSize : 0;
- blueSize = blueSize > 0 ? blueSize : 0;
- alphaSize = alphaSize > 0 ? alphaSize : 0;
- depthSize = depthSize > 0 ? depthSize : 0;
- stencilSize = stencilSize > 0 ? stencilSize : 0;
- sampleCount = sampleCount > 0 ? sampleCount : 0;
-
- QVector<EGLint> configAttributes;
-
- configAttributes.append(EGL_RED_SIZE);
- configAttributes.append(redSize);
-
- configAttributes.append(EGL_GREEN_SIZE);
- configAttributes.append(greenSize);
-
- configAttributes.append(EGL_BLUE_SIZE);
- configAttributes.append(blueSize);
-
- configAttributes.append(EGL_ALPHA_SIZE);
- configAttributes.append(alphaSize);
-
- configAttributes.append(EGL_DEPTH_SIZE);
- configAttributes.append(depthSize);
-
- configAttributes.append(EGL_STENCIL_SIZE);
- configAttributes.append(stencilSize);
-
- configAttributes.append(EGL_SAMPLES);
- configAttributes.append(sampleCount);
-
- configAttributes.append(EGL_SAMPLE_BUFFERS);
- configAttributes.append(sampleCount? 1:0);
-
- return configAttributes;
-}
-
-bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes)
-{
- int i = -1;
- // Reduce the complexity of a configuration request to ask for less
- // because the previous request did not result in success. Returns
- // true if the complexity was reduced, or false if no further
- // reductions in complexity are possible.
-
- i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR);
- if (i >= 0) {
- configAttributes->remove(i,2);
- }
-
-#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
- // For OpenVG, we sometimes try to create a surface using a pre-multiplied format. If we can't
- // find a config which supports pre-multiplied formats, remove the flag on the surface type:
-
- i = configAttributes->indexOf(EGL_SURFACE_TYPE);
- if (i >= 0) {
- EGLint surfaceType = configAttributes->at(i +1);
- if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) {
- surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT;
- configAttributes->replace(i+1,surfaceType);
- return true;
- }
- }
-#endif
-
- // EGL chooses configs with the highest color depth over
- // those with smaller (but faster) lower color depths. One
- // way around this is to set EGL_BUFFER_SIZE to 16, which
- // trumps the others. Of course, there may not be a 16-bit
- // config available, so it's the first restraint we remove.
- i = configAttributes->indexOf(EGL_BUFFER_SIZE);
- if (i >= 0) {
- if (configAttributes->at(i+1) == 16) {
- configAttributes->remove(i,2);
- return true;
- }
- }
-
- i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS);
- if (i >= 0) {
- configAttributes->remove(i,2);
- i = configAttributes->indexOf(EGL_SAMPLES);
- if (i >= 0) {
- configAttributes->remove(i,2);
- }
- return true;
- }
-
- i = configAttributes->indexOf(EGL_ALPHA_SIZE);
- if (i >= 0) {
- configAttributes->remove(i,2);
-#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB)
- i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA);
- if (i >= 0) {
- configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB);
- configAttributes->replace(i+1,TRUE);
-
- }
-#endif
- return true;
- }
-
- i = configAttributes->indexOf(EGL_STENCIL_SIZE);
- if (i >= 0) {
- configAttributes->remove(i,2);
- return true;
- }
- i = configAttributes->indexOf(EGL_DEPTH_SIZE);
- if (i >= 0) {
- configAttributes->remove(i,2);
- return true;
- }
-#ifdef EGL_BIND_TO_TEXTURE_RGB
- i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB);
- if (i >= 0) {
- configAttributes->remove(i,2);
- return true;
- }
-#endif
-
- return false;
-}
-
-EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat, int surfaceType)
-{
- EGLConfig cfg = 0;
- QVector<EGLint> configureAttributes = q_createConfigAttributesFromFormat(format);
- configureAttributes.append(EGL_SURFACE_TYPE); //we only support eglconfigs for windows for now
- configureAttributes.append(surfaceType);
-
- configureAttributes.append(EGL_RENDERABLE_TYPE);
- if (format.windowApi() == QPlatformWindowFormat::OpenVG) {
- configureAttributes.append(EGL_OPENVG_BIT);
- } else {
- configureAttributes.append(EGL_OPENGL_ES2_BIT);
- }
- configureAttributes.append(EGL_NONE);
-
- do {
- // Get the number of matching configurations for this set of properties.
- EGLint matching = 0;
- if (!eglChooseConfig(display, configureAttributes.constData(), 0, 0, &matching) || !matching)
- continue;
-
- // If we want the best pixel format, then return the first
- // matching configuration.
- if (highestPixelFormat) {
- eglChooseConfig(display, configureAttributes.constData(), &cfg, 1, &matching);
- if (matching < 1)
- continue;
- return cfg;
- }
-
- // Fetch all of the matching configurations and find the
- // first that matches the pixel format we wanted.
- int i = configureAttributes.indexOf(EGL_RED_SIZE);
- int confAttrRed = configureAttributes.at(i+1);
- i = configureAttributes.indexOf(EGL_GREEN_SIZE);
- int confAttrGreen = configureAttributes.at(i+1);
- i = configureAttributes.indexOf(EGL_BLUE_SIZE);
- int confAttrBlue = configureAttributes.at(i+1);
- i = configureAttributes.indexOf(EGL_ALPHA_SIZE);
- int confAttrAlpha = configureAttributes.at(i+1);
-
- EGLint size = matching;
- EGLConfig *configs = new EGLConfig [size];
- eglChooseConfig(display, configureAttributes.constData(), configs, size, &matching);
- for (EGLint index = 0; index < size; ++index) {
- EGLint red, green, blue, alpha;
- eglGetConfigAttrib(display, configs[index], EGL_RED_SIZE, &red);
- eglGetConfigAttrib(display, configs[index], EGL_GREEN_SIZE, &green);
- eglGetConfigAttrib(display, configs[index], EGL_BLUE_SIZE, &blue);
- eglGetConfigAttrib(display, configs[index], EGL_ALPHA_SIZE, &alpha);
- if (red == confAttrRed &&
- green == confAttrGreen &&
- blue == confAttrBlue &&
- (confAttrAlpha == 0 ||
- alpha == confAttrAlpha)) {
- cfg = configs[index];
- delete [] configs;
- return cfg;
- }
- }
- delete [] configs;
- } while (q_reduceConfigAttributes(&configureAttributes));
- qWarning("Cant find EGLConfig, returning null config");
- return 0;
-}
-
-QPlatformWindowFormat qt_qPlatformWindowFormatFromConfig(EGLDisplay display, const EGLConfig config)
-{
- QPlatformWindowFormat format;
- EGLint redSize = 0;
- EGLint greenSize = 0;
- EGLint blueSize = 0;
- EGLint alphaSize = 0;
- EGLint depthSize = 0;
- EGLint stencilSize = 0;
- EGLint sampleCount = 0;
- EGLint level = 0;
-
- eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
- eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
- eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
- eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
- eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
- eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
- eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
- eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
-
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
- format.setAlphaBufferSize(alphaSize);
- format.setDepthBufferSize(depthSize);
- format.setStencilBufferSize(stencilSize);
- format.setSamples(sampleCount);
- format.setDirectRendering(true); // All EGL contexts are direct-rendered
- format.setRgba(true); // EGL doesn't support colour index rendering
- format.setStereo(false); // EGL doesn't support stereo buffers
- format.setAccumBufferSize(0); // EGL doesn't support accululation buffers
-
- // Clear the EGL error state because some of the above may
- // have errored out because the attribute is not applicable
- // to the surface type. Such errors don't matter.
- eglGetError();
-
- return format;
-}
-
-bool q_hasEglExtension(EGLDisplay display, const char* extensionName)
-{
- QList<QByteArray> extensions =
- QByteArray(reinterpret_cast<const char *>
- (eglQueryString(display, EGL_EXTENSIONS))).split(' ');
- return extensions.contains(extensionName);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.h b/src/plugins/platforms/eglconvenience/qeglconvenience.h
deleted file mode 100644
index da4a0cdded..0000000000
--- a/src/plugins/platforms/eglconvenience/qeglconvenience.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEGLCONVENIENCE_H
-#define QEGLCONVENIENCE_H
-
-
-#include <QtGui/QPlatformWindowFormat>
-#include <QtCore/QVector>
-
-#include <EGL/egl.h>
-QT_BEGIN_NAMESPACE
-
-QVector<EGLint> q_createConfigAttributesFromFormat(const QPlatformWindowFormat &format);
-bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes);
-EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat = false, int surfaceType = EGL_WINDOW_BIT);
-QPlatformWindowFormat qt_qPlatformWindowFormatFromConfig(EGLDisplay display, const EGLConfig config);
-bool q_hasEglExtension(EGLDisplay display,const char* extensionName);
-
-QT_END_NAMESPACE
-
-#endif //QEGLCONVENIENCE_H
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
deleted file mode 100644
index 4d1d63e37f..0000000000
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglplatformcontext.h"
-
-
-#include <QtGui/QPlatformWindow>
-
-#include "qeglconvenience.h"
-
-#include <EGL/egl.h>
-
-QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi)
- : QPlatformGLContext()
- , m_eglDisplay(display)
- , m_eglSurface(surface)
- , m_eglApi(eglApi)
-{
- if (m_eglSurface == EGL_NO_SURFACE) {
- qWarning("Createing QEGLPlatformContext with no surface");
- }
-
- eglBindAPI(m_eglApi);
- m_eglContext = eglCreateContext(m_eglDisplay,config, 0,contextAttrs);
- if (m_eglContext == EGL_NO_CONTEXT) {
- qWarning("Could not create the egl context\n");
- eglTerminate(m_eglDisplay);
- qFatal("EGL error");
- }
-
- m_windowFormat = qt_qPlatformWindowFormatFromConfig(display,config);
-}
-
-QEGLPlatformContext::~QEGLPlatformContext()
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::~QEglContext(): %p\n",this);
-#endif
- if (m_eglSurface != EGL_NO_SURFACE) {
- doneCurrent();
- eglDestroySurface(m_eglDisplay, m_eglSurface);
- m_eglSurface = EGL_NO_SURFACE;
- }
-
- if (m_eglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(m_eglDisplay, m_eglContext);
- m_eglContext = EGL_NO_CONTEXT;
- }
-}
-
-void QEGLPlatformContext::makeCurrent()
-{
- QPlatformGLContext::makeCurrent();
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::makeCurrent: %p\n",this);
-#endif
- eglBindAPI(m_eglApi);
- bool ok = eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
- if (!ok)
- qWarning("QEGLPlatformContext::makeCurrent: eglError: %d, this: %p \n", eglGetError(), this);
-#ifdef QEGL_EXTRA_DEBUG
- static bool showDebug = true;
- if (showDebug) {
- showDebug = false;
- const char *str = (const char*)glGetString(GL_VENDOR);
- qWarning("Vendor %s\n", str);
- str = (const char*)glGetString(GL_RENDERER);
- qWarning("Renderer %s\n", str);
- str = (const char*)glGetString(GL_VERSION);
- qWarning("Version %s\n", str);
-
- str = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
- qWarning("Extensions %s\n",str);
-
- str = (const char*)glGetString(GL_EXTENSIONS);
- qWarning("Extensions %s\n", str);
-
- }
-#endif
-}
-void QEGLPlatformContext::doneCurrent()
-{
- QPlatformGLContext::doneCurrent();
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::doneCurrent:%p\n",this);
-#endif
- eglBindAPI(m_eglApi);
- bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (!ok)
- qWarning("QEGLPlatformContext::doneCurrent(): eglError: %d, this: %p \n", eglGetError(), this);
-}
-void QEGLPlatformContext::swapBuffers()
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::swapBuffers:%p\n",this);
-#endif
- eglBindAPI(m_eglApi);
- bool ok = eglSwapBuffers(m_eglDisplay, m_eglSurface);
- if (!ok)
- qWarning("QEGLPlatformContext::swapBuffers(): eglError: %d, this: %p \n", eglGetError(), this);
-}
-void* QEGLPlatformContext::getProcAddress(const QString& procName)
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::getProcAddress%p\n",this);
-#endif
- eglBindAPI(m_eglApi);
- return (void *)eglGetProcAddress(qPrintable(procName));
-}
-
-QPlatformWindowFormat QEGLPlatformContext::platformWindowFormat() const
-{
- return m_windowFormat;
-}
-
-EGLContext QEGLPlatformContext::eglContext() const
-{
- return m_eglContext;
-}
diff --git a/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp b/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
deleted file mode 100644
index cbd8f7d7c6..0000000000
--- a/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qxlibeglintegration.h"
-
-static int countBits(unsigned long mask)
-{
- int count = 0;
- while (mask != 0) {
- if (mask & 1)
- ++count;
- mask >>= 1;
- }
- return count;
-}
-
-VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
-{
- VisualID visualId = 0;
- EGLint eglValue = 0;
-
- EGLint configRedSize = 0;
- eglGetConfigAttrib(eglDisplay, config, EGL_RED_SIZE, &configRedSize);
-
- EGLint configGreenSize = 0;
- eglGetConfigAttrib(eglDisplay, config, EGL_GREEN_SIZE, &configGreenSize);
-
- EGLint configBlueSize = 0;
- eglGetConfigAttrib(eglDisplay, config, EGL_BLUE_SIZE, &configBlueSize);
-
- EGLint configAlphaSize = 0;
- eglGetConfigAttrib(eglDisplay, config, EGL_ALPHA_SIZE, &configAlphaSize);
-
- eglGetConfigAttrib(eglDisplay, config, EGL_CONFIG_ID, &eglValue);
- int configId = eglValue;
-
- // See if EGL provided a valid VisualID:
- eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue);
- visualId = (VisualID)eglValue;
- if (visualId) {
- // EGL has suggested a visual id, so get the rest of the visual info for that id:
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- visualInfoTemplate.visualid = visualId;
-
- XVisualInfo *chosenVisualInfo;
- int matchingCount = 0;
- chosenVisualInfo = XGetVisualInfo(display, VisualIDMask, &visualInfoTemplate, &matchingCount);
- if (chosenVisualInfo) {
- // Skip size checks if implementation supports non-matching visual
- // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444).
- if (q_hasEglExtension(eglDisplay,"EGL_NV_post_convert_rounding")) {
- XFree(chosenVisualInfo);
- return visualId;
- }
-
- int visualRedSize = countBits(chosenVisualInfo->red_mask);
- int visualGreenSize = countBits(chosenVisualInfo->green_mask);
- int visualBlueSize = countBits(chosenVisualInfo->blue_mask);
- int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
-
- bool visualMatchesConfig = false;
- if ( visualRedSize == configRedSize &&
- visualGreenSize == configGreenSize &&
- visualBlueSize == configBlueSize )
- {
- // We need XRender to check the alpha channel size of the visual. If we don't have
- // the alpha size, we don't check it against the EGL config's alpha size.
- if (visualAlphaSize >= 0)
- visualMatchesConfig = visualAlphaSize == configAlphaSize;
- else
- visualMatchesConfig = true;
- }
-
- if (!visualMatchesConfig) {
- if (visualAlphaSize >= 0) {
- qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable",
- (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize,
- configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize);
- } else {
- qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable",
- (int)visualId, visualRedSize, visualGreenSize, visualBlueSize,
- configId, configRedSize, configGreenSize, configBlueSize);
- }
- visualId = 0;
- }
- } else {
- qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID",
- (int)visualId, configId);
- visualId = 0;
- }
- XFree(chosenVisualInfo);
- }
-#ifdef QT_DEBUG_X11_VISUAL_SELECTION
- else
- qDebug("EGL did not suggest a VisualID (EGL_NATIVE_VISUAL_ID was zero) for EGLConfig %d", configId);
-#endif
-
- if (visualId) {
-#ifdef QT_DEBUG_X11_VISUAL_SELECTION
- if (configAlphaSize > 0)
- qDebug("Using ARGB Visual ID %d provided by EGL for config %d", (int)visualId, configId);
- else
- qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, configId);
-#endif
- return visualId;
- }
-
- // Finally, try to
- // use XGetVisualInfo and only use the bit depths to match on:
- if (!visualId) {
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- XVisualInfo *matchingVisuals;
- int matchingCount = 0;
-
- visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize;
- matchingVisuals = XGetVisualInfo(display,
- VisualDepthMask,
- &visualInfoTemplate,
- &matchingCount);
- if (!matchingVisuals) {
- // Try again without taking the alpha channel into account:
- visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize;
- matchingVisuals = XGetVisualInfo(display,
- VisualDepthMask,
- &visualInfoTemplate,
- &matchingCount);
- }
-
- if (matchingVisuals) {
- visualId = matchingVisuals[0].visualid;
- XFree(matchingVisuals);
- }
- }
-
- if (visualId) {
-#ifdef QT_DEBUG_X11_VISUAL_SELECTION
- qDebug("Using Visual ID %d provided by XGetVisualInfo for EGL config %d", (int)visualId, configId);
-#endif
- return visualId;
- }
-
- qWarning("Unable to find an X11 visual which matches EGL config %d", configId);
- return (VisualID)0;
-}
diff --git a/src/plugins/platforms/eglconvenience/xlibeglintegration.pri b/src/plugins/platforms/eglconvenience/xlibeglintegration.pri
deleted file mode 100644
index 9404a70373..0000000000
--- a/src/plugins/platforms/eglconvenience/xlibeglintegration.pri
+++ /dev/null
@@ -1,7 +0,0 @@
-INCLUDEPATH += $$PWD
-
-HEADERS += \
- $$PWD/qxlibeglintegration.h
-
-SOURCES += \
- $$PWD/qxlibeglintegration.cpp
diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro
index 471cf63dd8..73698322dd 100644
--- a/src/plugins/platforms/eglfs/eglfs.pro
+++ b/src/plugins/platforms/eglfs/eglfs.pro
@@ -2,7 +2,7 @@ TARGET = qeglfs
TEMPLATE = lib
CONFIG += plugin
-QT += opengl core-private gui-private opengl-private
+QT += opengl core-private gui-private opengl-private platformsupport-private widgets-private
DESTDIR = $$QT.gui.plugins/platforms
@@ -12,20 +12,16 @@ DESTDIR = $$QT.gui.plugins/platforms
SOURCES = main.cpp \
qeglfsintegration.cpp \
- ../eglconvenience/qeglconvenience.cpp \
- ../eglconvenience/qeglplatformcontext.cpp \
qeglfswindow.cpp \
- qeglfswindowsurface.cpp \
+ qeglfsbackingstore.cpp \
qeglfsscreen.cpp
HEADERS = qeglfsintegration.h \
- ../eglconvenience/qeglconvenience.h \
- ../eglconvenience/qeglplatformcontext.h \
qeglfswindow.h \
- qeglfswindowsurface.h \
+ qeglfsbackingstore.h \
qeglfsscreen.h
-include(../fontdatabases/genericunix/genericunix.pri)
+include(../../../platformsupport/fontdatabases/genericunix/genericunix.pri)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
index 970402015f..1d27be7fb3 100644
--- a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
@@ -39,11 +39,13 @@
**
****************************************************************************/
-#include "qeglfswindowsurface.h"
+#include <QtOpenGL/private/qgl_p.h>
-#include <QtGui/QPlatformGLContext>
+#include "qeglfsbackingstore.h"
+
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QScreen>
-#include <QtOpenGL/private/qgl_p.h>
#include <QtOpenGL/private/qglpaintdevice_p.h>
QT_BEGIN_NAMESPACE
@@ -51,16 +53,16 @@ QT_BEGIN_NAMESPACE
class QEglFSPaintDevice : public QGLPaintDevice
{
public:
- QEglFSPaintDevice(QEglFSScreen *screen, QWidget *widget)
+ QEglFSPaintDevice(QEglFSScreen *screen)
:QGLPaintDevice(), m_screen(screen)
{
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglPaintDevice %p, %p, %p",this, screen, widget);
+ qWarning("QEglPaintDevice %p, %p",this, screen);
#endif
}
QSize size() const { return m_screen->geometry().size(); }
- QGLContext* context() const { return QGLContext::fromPlatformGLContext(m_screen->platformContext());}
+ QGLContext* context() const { return QGLContext::fromOpenGLContext(m_screen->platformContext()->context()); }
QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
@@ -73,29 +75,30 @@ private:
};
-QEglFSWindowSurface::QEglFSWindowSurface( QEglFSScreen *screen, QWidget *window )
- :QWindowSurface(window)
+QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
{
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindowSurface %p, %p", window, screen);
+ qWarning("QEglBackingStore %p, %p", window, screen);
#endif
- m_paintDevice = new QEglFSPaintDevice(screen,window);
+ m_paintDevice = new QEglFSPaintDevice(static_cast<QEglFSScreen *>(window->screen()->handle()));
}
-void QEglFSWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QEglFSBackingStore::flush(QWindow *widget, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(widget);
Q_UNUSED(region);
Q_UNUSED(offset);
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindowSurface::flush %p",widget);
+ qWarning("QEglBackingStore::flush %p",widget);
#endif
- widget->platformWindow()->glContext()->swapBuffers();
+ static_cast<QEglFSPaintDevice *>(m_paintDevice)->context()->swapBuffers();
}
-void QEglFSWindowSurface::resize(const QSize &size)
+void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
Q_UNUSED(size);
+ Q_UNUSED(staticContents);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.h b/src/plugins/platforms/eglfs/qeglfsbackingstore.h
index 9ce8fd4f53..d6a28a7665 100644
--- a/src/plugins/platforms/eglfs/qeglfswindowsurface.h
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.h
@@ -45,19 +45,20 @@
#include "qeglfsintegration.h"
#include "qeglfswindow.h"
-#include <QtGui/private/qwindowsurface_p.h>
+#include <QtGui/qplatformbackingstore_qpa.h>
QT_BEGIN_NAMESPACE
-class QEglFSWindowSurface : public QWindowSurface
+class QEglFSBackingStore : public QPlatformBackingStore
{
public:
- QEglFSWindowSurface(QEglFSScreen *screen, QWidget *window);
- ~QEglFSWindowSurface() {}
+ QEglFSBackingStore(QWindow *window);
+ ~QEglFSBackingStore() {}
QPaintDevice *paintDevice() { return m_paintDevice; }
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+
private:
QPaintDevice *m_paintDevice;
};
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 9e8596f19e..3d3e05d351 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -42,13 +42,15 @@
#include "qeglfsintegration.h"
#include "qeglfswindow.h"
-#include "qeglfswindowsurface.h"
+#include "qeglfsbackingstore.h"
-#include "qgenericunixfontdatabase.h"
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtGui/QPlatformWindow>
-#include <QtGui/QPlatformWindowFormat>
-#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/QSurfaceFormat>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
#include <EGL/egl.h>
@@ -57,9 +59,8 @@ QT_BEGIN_NAMESPACE
QEglFSIntegration::QEglFSIntegration()
: mFontDb(new QGenericUnixFontDatabase())
{
- m_primaryScreen = new QEglFSScreen(EGL_DEFAULT_DISPLAY);
+ screenAdded(new QEglFSScreen(EGL_DEFAULT_DISPLAY));
- mScreens.append(m_primaryScreen);
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglIntegration\n");
#endif
@@ -69,36 +70,32 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
-QPixmapData *QEglFSIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
{
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglIntegration::createPixmapData %d\n", type);
+ qWarning("QEglIntegration::createPlatformWindow %p\n",window);
#endif
- return new QRasterPixmapData(type);
+ return new QEglFSWindow(window);
}
-QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+
+QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglIntegration::createPlatformWindow %p\n",widget);
+ qWarning("QEglIntegration::createWindowSurface %p\n",widget);
#endif
- return new QEglFSWindow(widget, m_primaryScreen);
+ return new QEglFSBackingStore(window);
}
-
-QWindowSurface *QEglFSIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- Q_UNUSED(winId);
-
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglIntegration::createWindowSurface %p\n",widget);
-#endif
- return new QEglFSWindowSurface(m_primaryScreen,widget);
+ return static_cast<QEglFSScreen *>(context->screen()->handle())->platformContext();
}
QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
@@ -106,4 +103,9 @@ QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
return mFontDb;
}
+QAbstractEventDispatcher *QEglFSIntegration::guiThreadEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index 6252a9c0e4..9538850faf 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -57,18 +57,17 @@ public:
QEglFSIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
- QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QPlatformFontDatabase *fontDatabase() const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
private:
QPlatformFontDatabase *mFontDb;
- QList<QPlatformScreen *> mScreens;
- QEglFSScreen *m_primaryScreen;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 42195364ae..6f317a375f 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -40,9 +40,10 @@
****************************************************************************/
#include "qeglfsscreen.h"
+#include "qeglfswindow.h"
-#include "../eglconvenience/qeglconvenience.h"
-#include "../eglconvenience/qeglplatformcontext.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#ifdef Q_OPENKODE
#include <KD/kd.h>
@@ -86,6 +87,23 @@ static struct AttrInfo attrs[] = {
{-1, 0}};
#endif //QEGL_EXTRA_DEBUG
+class QEglFSContext : public QEGLPlatformContext
+{
+public:
+ QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
+ EGLint eglClientVersion = 2, EGLenum eglApi = EGL_OPENGL_ES_API)
+ : QEGLPlatformContext(format, share, display, eglClientVersion, eglApi)
+ {
+ }
+
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+ {
+ QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
+ QEglFSScreen *screen = static_cast<QEglFSScreen *>(window->screen());
+ return screen->surface();
+ }
+};
+
QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display)
: m_depth(32)
, m_format(QImage::Format_Invalid)
@@ -136,32 +154,29 @@ void QEglFSScreen::createAndSetPlatformContext() const {
void QEglFSScreen::createAndSetPlatformContext()
{
- QPlatformWindowFormat platformFormat = QPlatformWindowFormat::defaultFormat();
-
- platformFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
+ QSurfaceFormat platformFormat;
QByteArray depthString = qgetenv("QT_QPA_EGLFS_DEPTH");
if (depthString.toInt() == 16) {
- platformFormat.setDepth(16);
+ platformFormat.setDepthBufferSize(16);
platformFormat.setRedBufferSize(5);
platformFormat.setGreenBufferSize(6);
platformFormat.setBlueBufferSize(5);
m_depth = 16;
m_format = QImage::Format_RGB16;
} else {
- platformFormat.setDepth(32);
+ platformFormat.setDepthBufferSize(32);
platformFormat.setRedBufferSize(8);
platformFormat.setGreenBufferSize(8);
platformFormat.setBlueBufferSize(8);
m_depth = 32;
m_format = QImage::Format_RGB32;
}
- if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty()) {
- platformFormat.setSampleBuffers(true);
- }
+ if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty())
+ platformFormat.setSamples(4);
- EGLConfig config = q_configFromQPlatformWindowFormat(m_dpy, platformFormat);
+ EGLConfig config = q_configFromGLFormat(m_dpy, platformFormat);
EGLNativeWindowType eglWindow = 0;
#ifdef Q_OPENKODE
@@ -193,16 +208,7 @@ void QEglFSScreen::createAndSetPlatformContext()
qWarning("\n");
#endif
- EGLint temp;
- EGLint attribList[32];
-
- temp = 0;
-
- attribList[temp++] = EGL_CONTEXT_CLIENT_VERSION;
- attribList[temp++] = 2; // GLES version 2
- attribList[temp++] = EGL_NONE;
-
- QEGLPlatformContext *platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API);
+ QEGLPlatformContext *platformContext = new QEglFSContext(platformFormat, 0, m_dpy);
m_platformContext = platformContext;
EGLint w,h; // screen size detection
@@ -232,7 +238,7 @@ QImage::Format QEglFSScreen::format() const
createAndSetPlatformContext();
return m_format;
}
-QPlatformGLContext *QEglFSScreen::platformContext() const
+QPlatformOpenGLContext *QEglFSScreen::platformContext() const
{
if (!m_platformContext) {
QEglFSScreen *that = const_cast<QEglFSScreen *>(this);
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 5cf1daca6f..41465d871c 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
-class QPlatformGLContext;
+class QPlatformOpenGLContext;
class QEglFSScreen : public QPlatformScreen //huh: FullScreenScreen ;) just to follow namespace
{
@@ -62,7 +62,9 @@ public:
int depth() const;
QImage::Format format() const;
- QPlatformGLContext *platformContext() const;
+ QPlatformOpenGLContext *platformContext() const;
+
+ EGLSurface surface() const { return m_surface; }
private:
void createAndSetPlatformContext() const;
@@ -71,7 +73,7 @@ private:
QRect m_geometry;
int m_depth;
QImage::Format m_format;
- QPlatformGLContext *m_platformContext;
+ QPlatformOpenGLContext *m_platformContext;
EGLDisplay m_dpy;
EGLSurface m_surface;
};
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 24b17b75e7..a6115cc829 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -45,25 +45,26 @@
QT_BEGIN_NAMESPACE
-QEglFSWindow::QEglFSWindow(QWidget *w, QEglFSScreen *screen)
- : QPlatformWindow(w), m_screen(screen)
+QEglFSWindow::QEglFSWindow(QWindow *w)
+ : QPlatformWindow(w)
{
static int serialNo = 0;
m_winid = ++serialNo;
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindow %p: %p %p 0x%x\n", this, w, screen, uint(m_winid));
+ qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_winid));
#endif
-}
+ QRect screenGeometry(screen()->availableGeometry());
+ if (w->geometry() != screenGeometry) {
+ QWindowSystemInterface::handleGeometryChange(w, screenGeometry);
+ }
+}
void QEglFSWindow::setGeometry(const QRect &)
{
// We only support full-screen windows
- QRect rect(m_screen->availableGeometry());
- QWindowSystemInterface::handleGeometryChange(this->widget(), rect);
-
- // Since toplevels are fullscreen, propegate the screen size back to the widget
- widget()->setGeometry(rect);
+ QRect rect(screen()->availableGeometry());
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
QPlatformWindow::setGeometry(rect);
}
@@ -73,15 +74,4 @@ WId QEglFSWindow::winId() const
return m_winid;
}
-
-
-QPlatformGLContext *QEglFSWindow::glContext() const
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindow::glContext %p\n", m_screen->platformContext());
-#endif
- Q_ASSERT(m_screen);
- return m_screen->platformContext();
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index 95a9ff51b9..09f553d3b7 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -46,22 +46,19 @@
#include "qeglfsscreen.h"
#include <QPlatformWindow>
-#include <QtGui/QWidget>
+#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class QEglFSWindow : public QPlatformWindow
{
public:
- QEglFSWindow(QWidget *w, QEglFSScreen *screen);
+ QEglFSWindow(QWindow *w);
void setGeometry(const QRect &);
WId winId() const;
- QPlatformGLContext *glContext() const;
-
private:
- QEglFSScreen *m_screen;
WId m_winid;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/externalplugin.pri b/src/plugins/platforms/externalplugin.pri
deleted file mode 100644
index 9b00acb4e9..0000000000
--- a/src/plugins/platforms/externalplugin.pri
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Lighthouse now has preliminarily support for building and
-# loading platform plugins from outside the Qt source/build
-# tree.
-#
-# 1) Building external plugins:
-# Set QTDIR to the Qt build directory, copy this file to
-# the plugin source repository and include it at the top
-# of the plugin's pro file. Use QT_SOURCE_TREE if you
-# want to pull in source code from Qt:
-#
-# include($$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri)
-#
-# 2) Loading external plugins:
-# Specify the path to the directory containing the
-# plugin on the command line, in addition to the
-# platform name.
-#
-# ./wiggly -platformPluginPath /path/to/myPlugin -platform gullfaksA
-#
-
-!exists($$(QTDIR)/.qmake.cache) {
- error("Please set QTDIR to the Qt build directory")
-}
-
-QT_SOURCE_TREE = $$fromfile($$(QTDIR)/.qmake.cache,QT_SOURCE_TREE)
-QT_BUILD_TREE = $$fromfile($$(QTDIR)/.qmake.cache,QT_BUILD_TREE)
-
-load(qt_plugin)
diff --git a/src/plugins/platforms/fb_base/fb_base.cpp b/src/plugins/platforms/fb_base/fb_base.cpp
deleted file mode 100644
index a83d739083..0000000000
--- a/src/plugins/platforms/fb_base/fb_base.cpp
+++ /dev/null
@@ -1,507 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "fb_base.h"
-#include <qpainter.h>
-#include <qdebug.h>
-#include <qbitmap.h>
-#include <QPlatformCursor>
-#include <QWindowSystemInterface>
-
-QPlatformSoftwareCursor::QPlatformSoftwareCursor(QPlatformScreen *scr)
- : QPlatformCursor(scr), currentRect(QRect()), prevRect(QRect())
-{
- graphic = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
- setCursor(Qt::ArrowCursor);
-}
-
-QRect QPlatformSoftwareCursor::getCurrentRect()
-{
- QRect rect = graphic->image()->rect().translated(-graphic->hotspot().x(),
- -graphic->hotspot().y());
- rect.translate(QCursor::pos());
- QPoint screenOffset = screen->geometry().topLeft();
- rect.translate(-screenOffset); // global to local translation
- return rect;
-}
-
-
-void QPlatformSoftwareCursor::pointerEvent(const QMouseEvent & e)
-{
- Q_UNUSED(e);
- QPoint screenOffset = screen->geometry().topLeft();
- currentRect = getCurrentRect();
- // global to local translation
- if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset))) {
- setDirty();
- }
-}
-
-QRect QPlatformSoftwareCursor::drawCursor(QPainter & painter)
-{
- dirty = false;
- if (currentRect.isNull())
- return QRect();
-
- // We need this because the cursor might be dirty due to moving off screen
- QPoint screenOffset = screen->geometry().topLeft();
- // global to local translation
- if (!currentRect.translated(screenOffset).intersects(screen->geometry()))
- return QRect();
-
- prevRect = currentRect;
- painter.drawImage(prevRect, *graphic->image());
- onScreen = true;
- return prevRect;
-}
-
-QRect QPlatformSoftwareCursor::dirtyRect()
-{
- if (onScreen) {
- onScreen = false;
- return prevRect;
- }
- return QRect();
-}
-
-void QPlatformSoftwareCursor::setCursor(Qt::CursorShape shape)
-{
- graphic->set(shape);
-}
-
-void QPlatformSoftwareCursor::setCursor(const QImage &image, int hotx, int hoty)
-{
- graphic->set(image, hotx, hoty);
-}
-
-void QPlatformSoftwareCursor::setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY)
-{
- graphic->set(data, mask, width, height, hotX, hotY);
-}
-
-void QPlatformSoftwareCursor::changeCursor(QCursor * widgetCursor, QWidget * widget)
-{
- Q_UNUSED(widget);
- Qt::CursorShape shape = widgetCursor->shape();
-
- if (shape == Qt::BitmapCursor) {
- // application supplied cursor
- QPoint spot = widgetCursor->hotSpot();
- setCursor(widgetCursor->pixmap().toImage(), spot.x(), spot.y());
- } else {
- // system cursor
- setCursor(shape);
- }
- currentRect = getCurrentRect();
- QPoint screenOffset = screen->geometry().topLeft(); // global to local translation
- if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset)))
- setDirty();
-}
-
-QFbScreen::QFbScreen() : cursor(0), mGeometry(), mDepth(16), mFormat(QImage::Format_RGB16), mScreenImage(0), compositePainter(0), isUpToDate(false)
-{
- mScreenImage = new QImage(mGeometry.size(), mFormat);
- redrawTimer.setSingleShot(true);
- redrawTimer.setInterval(0);
- QObject::connect(&redrawTimer, SIGNAL(timeout()), this, SLOT(doRedraw()));
-}
-
-void QFbScreen::setGeometry(QRect rect)
-{
- delete mScreenImage;
- mGeometry = rect;
- mScreenImage = new QImage(mGeometry.size(), mFormat);
- delete compositePainter;
- compositePainter = 0;
- invalidateRectCache();
-}
-
-void QFbScreen::setDepth(int depth)
-{
- mDepth = depth;
-}
-
-void QFbScreen::setPhysicalSize(QSize size)
-{
- mPhysicalSize = size;
-}
-
-void QFbScreen::setFormat(QImage::Format format)
-{
- mFormat = format;
- delete mScreenImage;
- mScreenImage = new QImage(mGeometry.size(), mFormat);
- delete compositePainter;
- compositePainter = 0;
-}
-
-QFbScreen::~QFbScreen()
-{
- delete compositePainter;
- delete mScreenImage;
-}
-
-void QFbScreen::setDirty(const QRect &rect)
-{
- QRect intersection = rect.intersected(mGeometry);
- QPoint screenOffset = mGeometry.topLeft();
- repaintRegion += intersection.translated(-screenOffset); // global to local translation
- if (!redrawTimer.isActive()) {
- redrawTimer.start();
- }
-}
-
-void QFbScreen::generateRects()
-{
- cachedRects.clear();
- QPoint screenOffset = mGeometry.topLeft();
- QRegion remainingScreen(mGeometry.translated(-screenOffset)); // global to local translation
-
- for (int i = 0; i < windowStack.length(); i++) {
- if (remainingScreen.isEmpty())
- break;
- if (!windowStack[i]->visible())
- continue;
- if (windowStack[i]->widget()->isMinimized())
- continue;
-
- if (!windowStack[i]->widget()->testAttribute(Qt::WA_TranslucentBackground)) {
- QRect localGeometry = windowStack.at(i)->geometry().translated(-screenOffset); // global to local translation
- remainingScreen -= localGeometry;
- QRegion windowRegion(localGeometry);
- windowRegion -= remainingScreen;
- foreach(QRect rect, windowRegion.rects()) {
- cachedRects += QPair<QRect, int>(rect, i);
- }
- }
- }
- foreach (QRect rect, remainingScreen.rects())
- cachedRects += QPair<QRect, int>(rect, -1);
- isUpToDate = true;
- return;
-}
-
-
-
-QRegion QFbScreen::doRedraw()
-{
- QPoint screenOffset = mGeometry.topLeft();
-
- QRegion touchedRegion;
- if (cursor && cursor->isDirty() && cursor->isOnScreen()) {
- QRect lastCursor = cursor->dirtyRect();
- repaintRegion += lastCursor;
- }
- if (repaintRegion.isEmpty() && (!cursor || !cursor->isDirty())) {
- return touchedRegion;
- }
-
- QVector<QRect> rects = repaintRegion.rects();
-
- if (!isUpToDate)
- generateRects();
-
- if (!compositePainter)
- compositePainter = new QPainter(mScreenImage);
- for (int rectIndex = 0; rectIndex < repaintRegion.numRects(); rectIndex++) {
- QRegion rectRegion = rects[rectIndex];
-
- for(int i = 0; i < cachedRects.length(); i++) {
- QRect screenSubRect = cachedRects[i].first;
- int layer = cachedRects[i].second;
- QRegion intersect = rectRegion.intersected(screenSubRect);
-
- if (intersect.isEmpty())
- continue;
-
- rectRegion -= intersect;
-
- // we only expect one rectangle, but defensive coding...
- foreach (QRect rect, intersect.rects()) {
- bool firstLayer = true;
- if (layer == -1) {
- compositePainter->fillRect(rect, Qt::black);
- firstLayer = false;
- layer = windowStack.size() - 1;
- }
-
- for (int layerIndex = layer; layerIndex != -1; layerIndex--) {
- if (!windowStack[layerIndex]->visible())
- continue;
- if (windowStack[layerIndex]->widget()->isMinimized())
- continue;
- QRect windowRect = windowStack[layerIndex]->geometry().translated(-screenOffset);
- QRect windowIntersect = rect.translated(-windowRect.left(),
- -windowRect.top());
- compositePainter->drawImage(rect, windowStack[layerIndex]->surface->image(),
- windowIntersect);
- if (firstLayer) {
- firstLayer = false;
- }
- }
- }
- }
- }
-
- QRect cursorRect;
- if (cursor && (cursor->isDirty() || repaintRegion.intersects(cursor->lastPainted()))) {
- cursorRect = cursor->drawCursor(*compositePainter);
- touchedRegion += cursorRect;
- }
- touchedRegion += repaintRegion;
- repaintRegion = QRegion();
-
-
-
-// qDebug() << "QFbScreen::doRedraw" << windowStack.size() << mScreenImage->size() << touchedRegion;
-
-
- return touchedRegion;
-}
-
-void QFbScreen::addWindow(QFbWindow *surface)
-{
- windowStack.prepend(surface);
- surface->mScreens.append(this);
- invalidateRectCache();
- setDirty(surface->geometry());
-}
-
-void QFbScreen::removeWindow(QFbWindow * surface)
-{
- windowStack.removeOne(surface);
- surface->mScreens.removeOne(this);
- invalidateRectCache();
- setDirty(surface->geometry());
-}
-
-void QFbWindow::raise()
-{
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->raise(this);
- ++i;
- }
-}
-
-void QFbScreen::raise(QPlatformWindow * surface)
-{
- QFbWindow *s = static_cast<QFbWindow *>(surface);
- int index = windowStack.indexOf(s);
- if (index <= 0)
- return;
- windowStack.move(index, 0);
- invalidateRectCache();
- setDirty(s->geometry());
-}
-
-void QFbWindow::lower()
-{
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->lower(this);
- ++i;
- }
-}
-
-void QFbScreen::lower(QPlatformWindow * surface)
-{
- QFbWindow *s = static_cast<QFbWindow *>(surface);
- int index = windowStack.indexOf(s);
- if (index == -1 || index == (windowStack.size() - 1))
- return;
- windowStack.move(index, windowStack.size() - 1);
- invalidateRectCache();
- setDirty(s->geometry());
-}
-
-QWidget * QFbScreen::topLevelAt(const QPoint & p) const
-{
- for(int i = 0; i < windowStack.size(); i++) {
- if (windowStack[i]->geometry().contains(p, false) &&
- windowStack[i]->visible() &&
- !windowStack[i]->widget()->isMinimized()) {
- return windowStack[i]->widget();
- }
- }
- return 0;
-}
-
-QFbWindow::QFbWindow(QWidget *window)
- :QPlatformWindow(window),
- visibleFlag(false)
-{
- static QAtomicInt winIdGenerator(1);
- windowId = winIdGenerator.fetchAndAddRelaxed(1);
-}
-
-
-QFbWindow::~QFbWindow()
-{
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->removeWindow(this);
- ++i;
- }
-}
-
-
-QFbWindowSurface::QFbWindowSurface(QFbScreen *screen, QWidget *window)
- : QWindowSurface(window),
- mScreen(screen)
-{
- mImage = QImage(window->size(), mScreen->format());
-
- platformWindow = static_cast<QFbWindow*>(window->platformWindow());
- platformWindow->surface = this;
-}
-
-QFbWindowSurface::~QFbWindowSurface()
-{
-}
-
-void QFbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(offset);
-
-
-// qDebug() << "QFbWindowSurface::flush" << region;
-
-
- platformWindow->repaint(region);
-}
-
-
-void QFbWindow::repaint(const QRegion &region)
-{
- QRect currentGeometry = geometry();
-
- QRect dirtyClient = region.boundingRect();
- QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
- currentGeometry.top() + dirtyClient.top(),
- dirtyClient.width(),
- dirtyClient.height());
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- QRect oldGeometryLocal = oldGeometry;
- oldGeometry = currentGeometry;
- while (i != end) {
- // If this is a move, redraw the previous location
- if (oldGeometryLocal != currentGeometry) {
- (*i)->setDirty(oldGeometryLocal);
- }
- (*i)->setDirty(dirtyRegion);
- ++i;
- }
-}
-
-void QFbWindowSurface::resize(const QSize &size)
-{
- // change the widget's QImage if this is a resize
- if (mImage.size() != size)
- mImage = QImage(size, mScreen->format());
- QWindowSurface::resize(size);
-}
-
-void QFbWindow::setGeometry(const QRect &rect)
-{
-// store previous geometry for screen update
- oldGeometry = geometry();
-
-
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->invalidateRectCache();
- ++i;
- }
-//### QWindowSystemInterface::handleGeometryChange(window(), rect);
-
- QPlatformWindow::setGeometry(rect);
-}
-
-bool QFbWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- return QWindowSurface::scroll(area, dx, dy);
-}
-
-void QFbWindowSurface::beginPaint(const QRegion &region)
-{
- Q_UNUSED(region);
-}
-
-void QFbWindowSurface::endPaint(const QRegion &region)
-{
- Q_UNUSED(region);
-}
-
-void QFbWindow::setVisible(bool visible)
-{
- visibleFlag = visible;
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->invalidateRectCache();
- (*i)->setDirty(geometry());
- ++i;
- }
-}
-
-Qt::WindowFlags QFbWindow::setWindowFlags(Qt::WindowFlags type)
-{
- flags = type;
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->invalidateRectCache();
- ++i;
- }
- return flags;
-}
-
-Qt::WindowFlags QFbWindow::windowFlags() const
-{
- return flags;
-}
diff --git a/src/plugins/platforms/fb_base/fb_base.h b/src/plugins/platforms/fb_base/fb_base.h
deleted file mode 100644
index 6b0b152482..0000000000
--- a/src/plugins/platforms/fb_base/fb_base.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLIGHTHOUSEGRAPHICSSCREEN_H
-#define QLIGHTHOUSEGRAPHICSSCREEN_H
-
-#include <qrect.h>
-#include <qimage.h>
-#include <qtimer.h>
-#include <qpainter.h>
-#include <QPlatformCursor>
-#include <QPlatformScreen>
-#include <QPlatformWindow>
-#include <QtGui/private/qwindowsurface_p.h>
-
-class QMouseEvent;
-class QSize;
-class QPainter;
-
-class QFbScreen;
-
-class QPlatformSoftwareCursor : public QPlatformCursor
-{
-public:
- QPlatformSoftwareCursor(QPlatformScreen * scr);
-
- // output methods
- QRect dirtyRect();
- virtual QRect drawCursor(QPainter & painter);
-
- // input methods
- virtual void pointerEvent(const QMouseEvent & event);
- virtual void changeCursor(QCursor * widgetCursor, QWidget * widget);
-
- virtual void setDirty() { dirty = true; screen->setDirty(QRect()); }
- virtual bool isDirty() { return dirty; }
- virtual bool isOnScreen() { return onScreen; }
- virtual QRect lastPainted() { return prevRect; }
-
-protected:
- QPlatformCursorImage * graphic;
-
-private:
- void setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY);
- void setCursor(Qt::CursorShape shape);
- void setCursor(const QImage &image, int hotx, int hoty);
- QRect currentRect; // next place to draw the cursor
- QRect prevRect; // last place the cursor was drawn
- QRect getCurrentRect();
- bool dirty;
- bool onScreen;
-};
-
-class QFbWindow;
-
-class QFbWindowSurface : public QWindowSurface
-{
-public:
- QFbWindowSurface(QFbScreen *screen, QWidget *window);
- ~QFbWindowSurface();
-
- virtual QPaintDevice *paintDevice() { return &mImage; }
- virtual void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- virtual bool scroll(const QRegion &area, int dx, int dy);
-
- virtual void beginPaint(const QRegion &region);
- virtual void endPaint(const QRegion &region);
-
-
- const QImage image() { return mImage; }
- void resize(const QSize &size);
-
-protected:
- friend class QFbWindow;
- QFbWindow *platformWindow;
-
- QFbScreen *mScreen;
- QImage mImage;
-};
-
-
-class QFbWindow : public QPlatformWindow
-{
-public:
-
- QFbWindow(QWidget *window);
- ~QFbWindow();
-
-
- virtual void setVisible(bool visible);
- virtual bool visible() { return visibleFlag; }
-
- virtual void raise();
- virtual void lower();
-
- void setGeometry(const QRect &rect);
-
- virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags type);
- virtual Qt::WindowFlags windowFlags() const;
-
- WId winId() const { return windowId; }
-
- virtual void repaint(const QRegion&);
-
-protected:
- friend class QFbWindowSurface;
- friend class QFbScreen;
- QFbWindowSurface *surface;
- QList<QFbScreen *> mScreens;
- QRect oldGeometry;
- bool visibleFlag;
- Qt::WindowFlags flags;
-
- WId windowId;
-};
-
-class QFbScreen : public QPlatformScreen
-{
- Q_OBJECT
-public:
- QFbScreen();
- ~QFbScreen();
-
- virtual QRect geometry() const { return mGeometry; }
- virtual int depth() const { return mDepth; }
- virtual QImage::Format format() const { return mFormat; }
- virtual QSize physicalSize() const { return mPhysicalSize; }
-
- virtual void setGeometry(QRect rect);
- virtual void setDepth(int depth);
- virtual void setFormat(QImage::Format format);
- virtual void setPhysicalSize(QSize size);
-
- virtual void setDirty(const QRect &rect);
-
- virtual void removeWindow(QFbWindow * surface);
- virtual void addWindow(QFbWindow * surface);
- virtual void raise(QPlatformWindow * surface);
- virtual void lower(QPlatformWindow * surface);
- virtual QWidget * topLevelAt(const QPoint & p) const;
-
- QImage * image() const { return mScreenImage; }
- QPaintDevice * paintDevice() const { return mScreenImage; }
-
-protected:
- QList<QFbWindow *> windowStack;
- QRegion repaintRegion;
- QPlatformSoftwareCursor * cursor;
- QTimer redrawTimer;
-
-protected slots:
- virtual QRegion doRedraw();
-
-protected:
- QRect mGeometry;
- int mDepth;
- QImage::Format mFormat;
- QSize mPhysicalSize;
- QImage *mScreenImage;
-
-private:
- QPainter * compositePainter;
- void generateRects();
- QList<QPair<QRect, int> > cachedRects;
-
- void invalidateRectCache() { isUpToDate = false; }
- friend class QFbWindowSurface;
- friend class QFbWindow;
- bool isUpToDate;
-};
-
-#endif // QLIGHTHOUSEGRAPHICSSCREEN_H
diff --git a/src/plugins/platforms/fb_base/fb_base.pri b/src/plugins/platforms/fb_base/fb_base.pri
deleted file mode 100644
index 41bd87fbca..0000000000
--- a/src/plugins/platforms/fb_base/fb_base.pri
+++ /dev/null
@@ -1,2 +0,0 @@
-SOURCES += ../fb_base/fb_base.cpp
-HEADERS += ../fb_base/fb_base.h
diff --git a/src/plugins/platforms/fb_base/fb_base.pro b/src/plugins/platforms/fb_base/fb_base.pro
deleted file mode 100644
index 4ebd53b407..0000000000
--- a/src/plugins/platforms/fb_base/fb_base.pro
+++ /dev/null
@@ -1,23 +0,0 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2009-11-05T13:22:31
-#
-#-------------------------------------------------
-
-#QT -= core gui
-TARGET = fb_base
-#load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-TEMPLATE = lib
-
-#DEFINES += STATIC_LIBRARY
-CONFIG += staticlib
-
-SOURCES += fb_base.cpp
-
-HEADERS += fb_base.h
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
diff --git a/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri b/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri
deleted file mode 100644
index c1fbf3e411..0000000000
--- a/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri
+++ /dev/null
@@ -1,88 +0,0 @@
-DEFINES += QT_NO_FONTCONFIG
-HEADERS += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h \
- $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h
-
-SOURCES += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp \
- $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp
-
-DEFINES += QT_COMPILES_IN_HARFBUZZ
-
-INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src
-
-INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix
-
-CONFIG += opentype
-
-contains(QT_CONFIG, freetype) {
- SOURCES += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbase.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbbox.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftdebug.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftglyph.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftinit.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftmm.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/fttype1.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftsynth.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbitmap.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/bdf/bdf.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cache/ftcache.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cff/cff.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cid/type1cid.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/gzip/ftgzip.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pcf/pcf.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pfr/pfr.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/psaux/psaux.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pshinter/pshinter.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/psnames/psmodule.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/raster/raster.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/sfnt/sfnt.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/smooth/smooth.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/truetype/truetype.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/type1/type1.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/type42/type42.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/winfonts/winfnt.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/lzw/ftlzw.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvalid.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvbase.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgdef.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvjstf.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvcommn.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgpos.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgsub.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvmod.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afangles.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afglobal.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/aflatin.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afmodule.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afdummy.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afhints.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afloader.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/autofit.c
-
- symbian {
- SOURCES += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftsystem.c
- } else {
- SOURCES += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/builds/unix/ftsystem.c
- INCLUDEPATH += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/builds/unix
- }
-
- INCLUDEPATH += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/include
-
- DEFINES += FT2_BUILD_LIBRARY
- contains(QT_CONFIG, system-zlib) {
- DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
- }
-
- } else:contains(QT_CONFIG, system-freetype) {
- # pull in the proper freetype2 include directory
- include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
- LIBS_PRIVATE += -lfreetype
- }
-
diff --git a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
deleted file mode 100644
index d91cce59a9..0000000000
--- a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbasicunixfontdatabase.h"
-
-#include <QtGui/private/qapplication_p.h>
-#include <QtGui/QPlatformScreen>
-
-#include <QtCore/QFile>
-#include <QtCore/QLibraryInfo>
-#include <QtCore/QDir>
-
-#undef QT_NO_FREETYPE
-#include <QtGui/private/qfontengine_ft_p.h>
-#include <QtGui/private/qfontengine_p.h>
-
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-
-#define SimplifiedChineseCsbBit 18
-#define TraditionalChineseCsbBit 20
-#define JapaneseCsbBit 17
-#define KoreanCsbBit 21
-
-static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
- // Any,
- { 127, 127 },
- // Latin,
- { 0, 127 },
- // Greek,
- { 7, 127 },
- // Cyrillic,
- { 9, 127 },
- // Armenian,
- { 10, 127 },
- // Hebrew,
- { 11, 127 },
- // Arabic,
- { 13, 127 },
- // Syriac,
- { 71, 127 },
- //Thaana,
- { 72, 127 },
- //Devanagari,
- { 15, 127 },
- //Bengali,
- { 16, 127 },
- //Gurmukhi,
- { 17, 127 },
- //Gujarati,
- { 18, 127 },
- //Oriya,
- { 19, 127 },
- //Tamil,
- { 20, 127 },
- //Telugu,
- { 21, 127 },
- //Kannada,
- { 22, 127 },
- //Malayalam,
- { 23, 127 },
- //Sinhala,
- { 73, 127 },
- //Thai,
- { 24, 127 },
- //Lao,
- { 25, 127 },
- //Tibetan,
- { 70, 127 },
- //Myanmar,
- { 74, 127 },
- // Georgian,
- { 26, 127 },
- // Khmer,
- { 80, 127 },
- // SimplifiedChinese,
- { 126, 127 },
- // TraditionalChinese,
- { 126, 127 },
- // Japanese,
- { 126, 127 },
- // Korean,
- { 56, 127 },
- // Vietnamese,
- { 0, 127 }, // same as latin1
- // Other,
- { 126, 127 },
- // Ogham,
- { 78, 127 },
- // Runic,
- { 79, 127 },
- // Nko,
- { 14, 127 },
-};
-
-static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
-{
- QSupportedWritingSystems writingSystems;
- bool hasScript = false;
-
- int i;
- for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
- int bit = requiredUnicodeBits[i][0];
- int index = bit/32;
- int flag = 1 << (bit&31);
- if (bit != 126 && unicodeRange[index] & flag) {
- bit = requiredUnicodeBits[i][1];
- index = bit/32;
-
- flag = 1 << (bit&31);
- if (bit == 127 || unicodeRange[index] & flag) {
- writingSystems.setSupported(QFontDatabase::WritingSystem(i));
- hasScript = true;
- // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
- }
- }
- }
- if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
- writingSystems.setSupported(QFontDatabase::SimplifiedChinese);
- hasScript = true;
- //qDebug("font %s supports Simplified Chinese", familyName.latin1());
- }
- if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
- writingSystems.setSupported(QFontDatabase::TraditionalChinese);
- hasScript = true;
- //qDebug("font %s supports Traditional Chinese", familyName.latin1());
- }
- if(codePageRange[0] & (1 << JapaneseCsbBit)) {
- writingSystems.setSupported(QFontDatabase::Japanese);
- hasScript = true;
- //qDebug("font %s supports Japanese", familyName.latin1());
- }
- if(codePageRange[0] & (1 << KoreanCsbBit)) {
- writingSystems.setSupported(QFontDatabase::Korean);
- hasScript = true;
- //qDebug("font %s supports Korean", familyName.latin1());
- }
- if (!hasScript)
- writingSystems.setSupported(QFontDatabase::Symbol);
-
- return writingSystems;
-}
-
-static inline bool scriptRequiresOpenType(int script)
-{
- return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
- || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
-}
-
-void QBasicUnixFontDatabase::populateFontDatabase()
-{
- QPlatformFontDatabase::populateFontDatabase();
- QString fontpath = fontDir();
-
- if(!QFile::exists(fontpath)) {
- qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
- qPrintable(fontpath));
- }
-
- QDir dir(fontpath);
- dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
- << QLatin1String("*.ttc") << QLatin1String("*.pfa")
- << QLatin1String("*.pfb"));
- dir.refresh();
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
-// qDebug() << "looking at" << file;
- addTTFile(QByteArray(), file);
- }
-}
-
-QFontEngine *QBasicUnixFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr)
-{
- QFontEngineFT *engine;
- FontFile *fontfile = static_cast<FontFile *> (usrPtr);
- QFontEngine::FaceId fid;
- fid.filename = fontfile->fileName.toLocal8Bit();
- fid.index = fontfile->indexValue;
- engine = new QFontEngineFT(fontDef);
-
- bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
- QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
- if (!engine->init(fid,antialias,format)) {
- delete engine;
- engine = 0;
- return engine;
- }
- if (engine->invalid()) {
- delete engine;
- engine = 0;
- } else if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = engine->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- delete engine;
- engine = 0;
- }
- }
-
- return engine;
-}
-
-QStringList QBasicUnixFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
-{
- Q_UNUSED(family);
- Q_UNUSED(style);
- Q_UNUSED(script);
- return QStringList();
-}
-
-QStringList QBasicUnixFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
-{
- return addTTFile(fontData,fileName.toLocal8Bit());
-}
-
-void QBasicUnixFontDatabase::releaseHandle(void *handle)
-{
- FontFile *file = static_cast<FontFile *>(handle);
- delete file;
-}
-
-QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
-{
- extern FT_Library qt_getFreetype();
- FT_Library library = qt_getFreetype();
-
- int index = 0;
- int numFaces = 0;
- QStringList families;
- do {
- FT_Face face;
- FT_Error error;
- if (!fontData.isEmpty()) {
- error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
- } else {
- error = FT_New_Face(library, file.constData(), index, &face);
- }
- if (error != FT_Err_Ok) {
- qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
- break;
- }
- numFaces = face->num_faces;
-
- QFont::Weight weight = QFont::Normal;
-
- QFont::Style style = QFont::StyleNormal;
- if (face->style_flags & FT_STYLE_FLAG_ITALIC)
- style = QFont::StyleItalic;
-
- if (face->style_flags & FT_STYLE_FLAG_BOLD)
- weight = QFont::Bold;
-
- QSupportedWritingSystems writingSystems;
- // detect symbol fonts
- for (int i = 0; i < face->num_charmaps; ++i) {
- FT_CharMap cm = face->charmaps[i];
- if (cm->encoding == ft_encoding_adobe_custom
- || cm->encoding == ft_encoding_symbol) {
- writingSystems.setSupported(QFontDatabase::Symbol);
- break;
- }
- }
-
- TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
- if (os2) {
- quint32 unicodeRange[4] = {
- os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4
- };
- quint32 codePageRange[2] = {
- os2->ulCodePageRange1, os2->ulCodePageRange2
- };
-
- writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
-
- if (os2->usWeightClass == 0)
- ;
- else if (os2->usWeightClass < 350)
- weight = QFont::Light;
- else if (os2->usWeightClass < 450)
- weight = QFont::Normal;
- else if (os2->usWeightClass < 650)
- weight = QFont::DemiBold;
- else if (os2->usWeightClass < 750)
- weight = QFont::Bold;
- else if (os2->usWeightClass < 1000)
- weight = QFont::Black;
-
- if (os2->panose[2] >= 2) {
- int w = os2->panose[2];
- if (w <= 3)
- weight = QFont::Light;
- else if (w <= 5)
- weight = QFont::Normal;
- else if (w <= 7)
- weight = QFont::DemiBold;
- else if (w <= 8)
- weight = QFont::Bold;
- else if (w <= 10)
- weight = QFont::Black;
- }
- }
-
- QString family = QString::fromAscii(face->family_name);
- FontFile *fontFile = new FontFile;
- fontFile->fileName = file;
- fontFile->indexValue = index;
-
- QFont::Stretch stretch = QFont::Unstretched;
-
- registerFont(family,"",weight,style,stretch,true,true,0,writingSystems,fontFile);
-
- families.append(family);
-
- FT_Done_Face(face);
- ++index;
- } while (index < numFaces);
- return families;
-}
diff --git a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h
deleted file mode 100644
index 0e17ed55b6..0000000000
--- a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBASICUNIXFONTDATABASE_H
-#define QBASICUNIXFONTDATABASE_H
-
-#include <QPlatformFontDatabase>
-#include <QtCore/QByteArray>
-#include <QtCore/QString>
-
-struct FontFile
-{
- QString fileName;
- int indexValue;
-};
-
-class QBasicUnixFontDatabase : public QPlatformFontDatabase
-{
-public:
- void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
- QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
- QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
- void releaseHandle(void *handle);
-
- static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file);
-};
-
-#endif // QBASICUNIXFONTDATABASE_H
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri b/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri
deleted file mode 100644
index 19c74ed089..0000000000
--- a/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri
+++ /dev/null
@@ -1,12 +0,0 @@
-include(../basicunix/basicunix.pri)
-
-HEADERS += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
-
-SOURCES += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
-
-INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig
-LIBS_PRIVATE += -lfontconfig
-
-
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
deleted file mode 100644
index 50cf4ed75a..0000000000
--- a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfontconfigdatabase.h"
-
-#include <QtCore/QList>
-#include <QtGui/private/qfont_p.h>
-
-#include <QtCore/QElapsedTimer>
-
-#include <QtGui/private/qapplication_p.h>
-#include <QtGui/QPlatformScreen>
-
-#include <QtGui/private/qfontengine_ft_p.h>
-#include <QtGui/private/qfontengine_p.h>
-
-
-
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-
-#include <fontconfig/fontconfig.h>
-
-#define SimplifiedChineseCsbBit 18
-#define TraditionalChineseCsbBit 20
-#define JapaneseCsbBit 17
-#define KoreanCsbBit 21
-
-static inline bool requiresOpenType(int writingSystem)
-{
- return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
- || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
-}
-static inline bool scriptRequiresOpenType(int script)
-{
- return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
- || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
-}
-
-static int getFCWeight(int fc_weight)
-{
- int qtweight = QFont::Black;
- if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2)
- qtweight = QFont::Light;
- else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2)
- qtweight = QFont::Normal;
- else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2)
- qtweight = QFont::DemiBold;
- else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
- qtweight = QFont::Bold;
-
- return qtweight;
-}
-
-static const char *specialLanguages[] = {
- "en", // Common
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "ko", // Hangul
- "", // Ogham
- "", // Runic
- "km", // Khmer
- "" // N'Ko
-};
-enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
-
-static const ushort specialChars[] = {
- 0, // English
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Hangul
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0, // Khmer
- 0x7ca // N'Ko
-};
-enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
-
-// this could become a list of all languages used for each writing
-// system, instead of using the single most common language.
-static const char *languageForWritingSystem[] = {
- 0, // Any
- "en", // Latin
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "km", // Khmer
- "zh-cn", // SimplifiedChinese
- "zh-tw", // TraditionalChinese
- "ja", // Japanese
- "ko", // Korean
- "vi", // Vietnamese
- 0, // Symbol
- 0, // Ogham
- 0, // Runic
- 0 // N'Ko
-};
-enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
-
-// Unfortunately FontConfig doesn't know about some languages. We have to test these through the
-// charset. The lists below contain the systems where we need to do this.
-static const ushort sampleCharForWritingSystem[] = {
- 0, // Any
- 0, // Latin
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Khmer
- 0, // SimplifiedChinese
- 0, // TraditionalChinese
- 0, // Japanese
- 0, // Korean
- 0, // Vietnamese
- 0, // Symbol
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0x7ca // N'Ko
-};
-enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
-
-// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
-// open type tables for is directly. Do this so we don't pick some strange
-// pseudo unicode font
-static const char *openType[] = {
- 0, // Any
- 0, // Latin
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- "syrc", // Syriac
- "thaa", // Thaana
- "deva", // Devanagari
- "beng", // Bengali
- "guru", // Gurmukhi
- "gurj", // Gujarati
- "orya", // Oriya
- "taml", // Tamil
- "telu", // Telugu
- "knda", // Kannada
- "mlym", // Malayalam
- "sinh", // Sinhala
- 0, // Thai
- 0, // Lao
- "tibt", // Tibetan
- "mymr", // Myanmar
- 0, // Georgian
- "khmr", // Khmer
- 0, // SimplifiedChinese
- 0, // TraditionalChinese
- 0, // Japanese
- 0, // Korean
- 0, // Vietnamese
- 0, // Symbol
- 0, // Ogham
- 0, // Runic
- "nko " // N'Ko
-};
-
-static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
-{
- const char *stylehint = 0;
- switch (style) {
- case QFont::SansSerif:
- stylehint = "sans-serif";
- break;
- case QFont::Serif:
- stylehint = "serif";
- break;
- case QFont::TypeWriter:
- stylehint = "monospace";
- break;
- default:
- break;
- }
- return stylehint;
-}
-
-void QFontconfigDatabase::populateFontDatabase()
-{
- FcFontSet *fonts;
-
- QString familyName;
- FcChar8 *value = 0;
- int weight_value;
- int slant_value;
- int spacing_value;
- FcChar8 *file_value;
- int indexValue;
- FcChar8 *foundry_value;
- FcBool scalable;
- FcBool antialias;
-
- {
- FcObjectSet *os = FcObjectSetCreate();
- FcPattern *pattern = FcPatternCreate();
- const char *properties [] = {
- FC_FAMILY, FC_WEIGHT, FC_SLANT,
- FC_SPACING, FC_FILE, FC_INDEX,
- FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
- FC_WIDTH,
-#if FC_VERSION >= 20297
- FC_CAPABILITY,
-#endif
- (const char *)0
- };
- const char **p = properties;
- while (*p) {
- FcObjectSetAdd(os, *p);
- ++p;
- }
- fonts = FcFontList(0, pattern, os);
- FcObjectSetDestroy(os);
- FcPatternDestroy(pattern);
- }
-
- for (int i = 0; i < fonts->nfont; i++) {
- if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- familyName = QString::fromUtf8((const char *)value);
- slant_value = FC_SLANT_ROMAN;
- weight_value = FC_WEIGHT_MEDIUM;
- spacing_value = FC_PROPORTIONAL;
- file_value = 0;
- indexValue = 0;
- scalable = FcTrue;
-
-
- if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
- slant_value = FC_SLANT_ROMAN;
- if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
- weight_value = FC_WEIGHT_MEDIUM;
- if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
- spacing_value = FC_PROPORTIONAL;
- if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = 0;
- if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
- indexValue = 0;
- if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = FcTrue;
- if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = 0;
- if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
- antialias = true;
-
- QSupportedWritingSystems writingSystems;
- FcLangSet *langset = 0;
- FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
- if (res == FcResultMatch) {
- for (int i = 1; i < LanguageCount; ++i) {
- const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[i];
- if (lang) {
- FcLangResult langRes = FcLangSetHasLang(langset, lang);
- if (langRes != FcLangDifferentLang)
- writingSystems.setSupported(QFontDatabase::WritingSystem(i));
- }
- }
- } else {
- // we set Other to supported for symbol fonts. It makes no
- // sense to merge these with other ones, as they are
- // special in a way.
- writingSystems.setSupported(QFontDatabase::Other);
- }
-
- FcCharSet *cs = 0;
- res = FcPatternGetCharSet(fonts->fonts[i], FC_CHARSET, 0, &cs);
- if (res == FcResultMatch) {
- // some languages are not supported by FontConfig, we rather check the
- // charset to detect these
- for (int i = 1; i < SampleCharCount; ++i) {
- if (!sampleCharForWritingSystem[i])
- continue;
- if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(i));
- }
- }
-
-#if FC_VERSION >= 20297
- for (int j = 1; j < LanguageCount; ++j) {
- if (writingSystems.supported(QFontDatabase::WritingSystem(j))
- && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
- }
- }
-#endif
-
- FontFile *fontFile = new FontFile;
- fontFile->fileName = QLatin1String((const char *)file_value);
- fontFile->indexValue = indexValue;
-
- QFont::Style style = (slant_value == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant_value == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
- QFont::Weight weight = QFont::Weight(getFCWeight(weight_value));
-
- double pixel_size = 0;
- if (!scalable) {
- int width = 100;
- FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
- FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
- }
-
- QFont::Stretch stretch = QFont::Unstretched;
- QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,writingSystems,fontFile);
-// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
- }
-
- FcFontSetDestroy (fonts);
-
- struct FcDefaultFont {
- const char *qtname;
- const char *rawname;
- bool fixed;
- };
- const FcDefaultFont defaults[] = {
- { "Serif", "serif", false },
- { "Sans Serif", "sans-serif", false },
- { "Monospace", "monospace", true },
- { 0, 0, false }
- };
- const FcDefaultFont *f = defaults;
- // aliases only make sense for 'common', not for any of the specials
- QSupportedWritingSystems ws;
- ws.setSupported(QFontDatabase::Latin);
-
-
- while (f->qtname) {
- registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,ws,0);
- registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,ws,0);
- registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,ws,0);
- ++f;
- }
-
- //Lighthouse has very lazy population of the font db. We want it to be initialized when
- //QApplication is constructed, so that the population procedure can do something like this to
- //set the default font
-// const FcDefaultFont *s = defaults;
-// QFont font("Sans Serif");
-// font.setPointSize(9);
-// QApplication::setFont(font);
-}
-
-QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
-{
- if (!usrPtr)
- return 0;
- QFontDef fontDef = f;
-
- QFontEngineFT *engine;
- FontFile *fontfile = static_cast<FontFile *> (usrPtr);
- QFontEngine::FaceId fid;
- fid.filename = fontfile->fileName.toLocal8Bit();
- fid.index = fontfile->indexValue;
-
- bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
- QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
-
- engine = new QFontEngineFT(fontDef);
-
- // try and get the pattern
- FcPattern *pattern = FcPatternCreate();
-
- FcValue value;
- value.type = FcTypeString;
- QByteArray cs = fontDef.family.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAdd(pattern,FC_FAMILY,value,true);
-
-
- value.u.s = (const FcChar8 *)fid.filename.data();
- FcPatternAdd(pattern,FC_FILE,value,true);
-
- value.type = FcTypeInteger;
- value.u.i = fid.index;
- FcPatternAdd(pattern,FC_INDEX,value,true);
-
- if (FcConfigSubstitute(0,pattern,FcMatchPattern)) {
- QFontEngineFT::HintStyle default_hint_style;
-
- //hinting
- int hint_style = 0;
- if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
- hint_style = QFontEngineFT::HintFull;
- switch (hint_style) {
- case FC_HINT_NONE:
- default_hint_style = QFontEngineFT::HintNone;
- break;
- case FC_HINT_SLIGHT:
- default_hint_style = QFontEngineFT::HintLight;
- break;
- case FC_HINT_MEDIUM:
- default_hint_style = QFontEngineFT::HintMedium;
- break;
- default:
- default_hint_style = QFontEngineFT::HintFull;
- break;
- }
- engine->setDefaultHintStyle(default_hint_style);
- }
- FcPatternDestroy(pattern);
-
- if (!engine->init(fid,antialias,format)) {
- delete engine;
- engine = 0;
- return engine;
- }
- if (engine->invalid()) {
- delete engine;
- engine = 0;
- } else if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = engine->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- delete engine;
- engine = 0;
- }
- }
-
- return engine;
-}
-
-QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
-{
- QStringList fallbackFamilies;
- FcPattern *pattern = FcPatternCreate();
- if (!pattern)
- return fallbackFamilies;
-
- FcValue value;
- value.type = FcTypeString;
- QByteArray cs = family.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAdd(pattern,FC_FAMILY,value,true);
-
- int slant_value = FC_SLANT_ROMAN;
- if (style == QFont::StyleItalic)
- slant_value = FC_SLANT_ITALIC;
- else if (style == QFont::StyleOblique)
- slant_value = FC_SLANT_OBLIQUE;
- FcPatternAddInteger(pattern, FC_SLANT, slant_value);
-
- if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
- Q_ASSERT(script < QUnicodeTables::ScriptCount);
- FcLangSet *ls = FcLangSetCreate();
- FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
- FcPatternAddLangSet(pattern, FC_LANG, ls);
- FcLangSetDestroy(ls);
- }
-
- const char *stylehint = getFcFamilyForStyleHint(styleHint);
- if (stylehint) {
- value.u.s = (const FcChar8 *)stylehint;
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
- }
-
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcResult result = FcResultMatch;
- FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
- FcPatternDestroy(pattern);
-
- if (fontSet) {
- if (result == FcResultMatch) {
- for (int i = 0; i < fontSet->nfont; i++) {
- FcChar8 *value = 0;
- if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- QString familyName = QString::fromUtf8((const char *)value);
- if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
- familyName.compare(family, Qt::CaseInsensitive)) {
- fallbackFamilies << familyName;
- }
- }
- }
- FcFontSetDestroy(fontSet);
- }
-// qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies;
-
- return fallbackFamilies;
-}
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
deleted file mode 100644
index 61700e391a..0000000000
--- a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTCONFIGDATABASE_H
-#define QFONTCONFIGDATABASE_H
-
-#include <QPlatformFontDatabase>
-#include "qbasicunixfontdatabase.h"
-
-class QFontconfigDatabase : public QBasicUnixFontDatabase
-{
-public:
- void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
- QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
-};
-
-#endif // QFONTCONFIGDATABASE_H
diff --git a/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri b/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
deleted file mode 100644
index 1153ab36b7..0000000000
--- a/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
+++ /dev/null
@@ -1,10 +0,0 @@
-contains(QT_CONFIG, fontconfig) {
- include(../fontconfig/fontconfig.pri)
- DEFINES += Q_FONTCONFIGDATABASE
-} else {
- include(../basicunix/basicunix.pri)
-}
-
-INCLUDEPATH += $$PWD
-HEADERS += \
- $$PWD/qgenericunixfontdatabase.h
diff --git a/src/plugins/platforms/glxconvenience/glxconvenience.pri b/src/plugins/platforms/glxconvenience/glxconvenience.pri
deleted file mode 100644
index b4d43a30b5..0000000000
--- a/src/plugins/platforms/glxconvenience/glxconvenience.pri
+++ /dev/null
@@ -1,15 +0,0 @@
-INCLUDEPATH += $$PWD
-
-HEADERS += \
- $$PWD/qglxconvenience.h
-
-SOURCES += \
- $$PWD/qglxconvenience.cpp
-
-CONFIG += xrender
-
-xrender {
- LIBS += -lXrender
-} else {
- DEFINES += QT_NO_XRENDER
-}
diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.cpp b/src/plugins/platforms/glxconvenience/qglxconvenience.cpp
deleted file mode 100644
index 34633d9692..0000000000
--- a/src/plugins/platforms/glxconvenience/qglxconvenience.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglxconvenience.h"
-
-#include <QtCore/QVector>
-
-#ifndef QT_NO_XRENDER
-#include <X11/extensions/Xrender.h>
-#endif
-
-enum {
- XFocusOut = FocusOut,
- XFocusIn = FocusIn,
- XKeyPress = KeyPress,
- XKeyRelease = KeyRelease,
- XNone = None,
- XRevertToParent = RevertToParent,
- XGrayScale = GrayScale,
- XCursorShape = CursorShape
-};
-#undef FocusOut
-#undef FocusIn
-#undef KeyPress
-#undef KeyRelease
-#undef None
-#undef RevertToParent
-#undef GrayScale
-#undef CursorShape
-
-#ifdef FontChange
-#undef FontChange
-#endif
-
-QVector<int> qglx_buildSpec(const QPlatformWindowFormat &format, int drawableBit)
-{
- QVector<int> spec(48);
- int i = 0;
-
- spec[i++] = GLX_LEVEL;
- spec[i++] = 0;
- spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = drawableBit;
-
- if (format.rgba()) {
- spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT;
- spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize();
- spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize();
- spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize();
- if (format.alpha()) {
- spec[i++] = GLX_ALPHA_SIZE; spec[i++] = (format.alphaBufferSize() == -1) ? 1 : format.alphaBufferSize();
- }
-
- if (format.accum()) {
- spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
- spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
- spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
-
- if (format.alpha()) {
- spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
- }
- }
- } else {
- spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_COLOR_INDEX_BIT; //I'm really not sure if this works....
- spec[i++] = GLX_BUFFER_SIZE; spec[i++] = 8;
- }
-
- spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.doubleBuffer() ? True : False;
- spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False;
-
- if (format.depth()) {
- spec[i++] = GLX_DEPTH_SIZE; spec[i++] = (format.depthBufferSize() == -1) ? 1 : format.depthBufferSize();
- }
-
- if (format.stencil()) {
- spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize();
- }
- if (format.sampleBuffers()) {
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = format.samples() == -1 ? 4 : format.samples();
- }
-
- spec[i++] = XNone;
- return spec;
-}
-
-GLXFBConfig qglx_findConfig(Display *display, int screen , const QPlatformWindowFormat &format, int drawableBit)
-{
- bool reduced = true;
- GLXFBConfig chosenConfig = 0;
- QPlatformWindowFormat reducedFormat = format;
- while (!chosenConfig && reduced) {
- QVector<int> spec = qglx_buildSpec(reducedFormat, drawableBit);
- int confcount = 0;
- GLXFBConfig *configs;
- configs = glXChooseFBConfig(display, screen,spec.constData(),&confcount);
- if (confcount)
- {
- for (int i = 0; i < confcount; i++) {
- chosenConfig = configs[i];
- // Make sure we try to get an ARGB visual if the format asked for an alpha:
- if (reducedFormat.alpha()) {
- int alphaSize;
- glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize);
- if (alphaSize > 0) {
- XVisualInfo *visual = glXGetVisualFromFBConfig(display, chosenConfig);
-#if !defined(QT_NO_XRENDER)
- XRenderPictFormat *pictFormat = XRenderFindVisualFormat(display, visual->visual);
- if (pictFormat->direct.alphaMask > 0)
- break;
-#else
- if (visual->depth == 32)
- break;
-#endif
- }
- } else {
- break; // Just choose the first in the list if there's no alpha requested
- }
- }
-
- XFree(configs);
- }
- reducedFormat = qglx_reducePlatformWindowFormat(reducedFormat,&reduced);
- }
-
- if (!chosenConfig)
- qWarning("Warning: no suitable glx confiuration found");
-
- return chosenConfig;
-}
-
-XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QPlatformWindowFormat &format)
-{
- GLXFBConfig config = qglx_findConfig(display,screen,format);
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display,config);
- return visualInfo;
-}
-
-QPlatformWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext ctx)
-{
- QPlatformWindowFormat format;
- int redSize = 0;
- int greenSize = 0;
- int blueSize = 0;
- int alphaSize = 0;
- int depthSize = 0;
- int stencilSize = 0;
- int sampleBuffers = 0;
- int sampleCount = 0;
- int level = 0;
- int rgba = 0;
- int stereo = 0;
- int accumSizeA = 0;
- int accumSizeR = 0;
- int accumSizeG = 0;
- int accumSizeB = 0;
-
- XVisualInfo *vi = glXGetVisualFromFBConfig(display,config);
- glXGetConfig(display,vi,GLX_RGBA,&rgba);
- XFree(vi);
- glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize);
- glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize);
- glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize);
- glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE, &alphaSize);
- glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize);
- glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize);
- glXGetFBConfigAttrib(display, config, GLX_SAMPLES, &sampleBuffers);
- glXGetFBConfigAttrib(display, config, GLX_LEVEL, &level);
- glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_ALPHA_SIZE, &accumSizeA);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_RED_SIZE, &accumSizeR);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_GREEN_SIZE, &accumSizeG);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_BLUE_SIZE, &accumSizeB);
-
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
- format.setAlphaBufferSize(alphaSize);
- format.setDepthBufferSize(depthSize);
- format.setStencilBufferSize(stencilSize);
- format.setSampleBuffers(sampleBuffers);
- if (format.sampleBuffers()) {
- glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount);
- format.setSamples(sampleCount);
- }
-
- format.setDirectRendering(glXIsDirect(display, ctx));
- format.setRgba(rgba);
- format.setStereo(stereo);
- format.setAccumBufferSize(accumSizeB);
-
- return format;
-}
-
-QPlatformWindowFormat qglx_reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced)
-{
- QPlatformWindowFormat retFormat = format;
- *reduced = true;
-
- if (retFormat.sampleBuffers()) {
- retFormat.setSampleBuffers(false);
- } else if (retFormat.stereo()) {
- retFormat.setStereo(false);
- } else if (retFormat.accum()) {
- retFormat.setAccum(false);
- }else if (retFormat.stencil()) {
- retFormat.setStencil(false);
- }else if (retFormat.alpha()) {
- retFormat.setAlpha(false);
- }else if (retFormat.depth()) {
- retFormat.setDepth(false);
- }else if (retFormat.doubleBuffer()) {
- retFormat.setDoubleBuffer(false);
- }else{
- *reduced = false;
- }
- return retFormat;
-}
diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.h b/src/plugins/platforms/glxconvenience/qglxconvenience.h
deleted file mode 100644
index 7478abfeba..0000000000
--- a/src/plugins/platforms/glxconvenience/qglxconvenience.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLXCONVENIENCE_H
-#define QGLXCONVENIENCE_H
-
-#include <QPlatformWindowFormat>
-
-#include <X11/Xlib.h>
-#include <GL/glx.h>
-
-XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QPlatformWindowFormat &format);
-GLXFBConfig qglx_findConfig(Display *display, int screen, const QPlatformWindowFormat &format, int drawableBit = GLX_WINDOW_BIT);
-QPlatformWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context);
-QVector<int> qglx_buildSpec(const QPlatformWindowFormat &format, int drawableBit = GLX_WINDOW_BIT);
-QPlatformWindowFormat qglx_reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced);
-
-#endif // QGLXCONVENIENCE_H
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
new file mode 100644
index 0000000000..73a3fa0418
--- /dev/null
+++ b/src/plugins/platforms/kms/kms.pro
@@ -0,0 +1,42 @@
+TARGET = qkms
+
+load(qt_plugin)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+QT = core-private gui-private platformsupport-private opengl-private
+
+CONFIG += link_pkgconfig qpa/genericunixfontdatabase
+
+PKGCONFIG += libdrm egl gbm glesv2
+
+SOURCES = main.cpp \
+ qkmsintegration.cpp \
+ qkmsscreen.cpp \
+ qkmscontext.cpp \
+ qkmswindow.cpp \
+ qkmscursor.cpp \
+ qkmsdevice.cpp \
+ qkmsbuffermanager.cpp \
+ qkmsbackingstore.cpp
+HEADERS = qkmsintegration.h \
+ qkmsscreen.h \
+ qkmscontext.h \
+ qkmswindow.h \
+ qkmscursor.h \
+ qkmsdevice.h \
+ qkmsbuffermanager.h \
+ qkmsbackingstore.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/graphicssystems/openvg/main.cpp b/src/plugins/platforms/kms/main.cpp
index 0aa265e50b..a07f1645dc 100644
--- a/src/plugins/graphicssystems/openvg/main.cpp
+++ b/src/plugins/platforms/kms/main.cpp
@@ -39,33 +39,34 @@
**
****************************************************************************/
-#include <private/qgraphicssystemplugin_p.h>
-#include "qgraphicssystem_vg_p.h"
+#include <QtGui/QPlatformIntegrationPlugin>
+#include "qkmsintegration.h"
QT_BEGIN_NAMESPACE
-class QVGGraphicsSystemPlugin : public QGraphicsSystemPlugin
+class QKmsIntegrationPlugin : public QPlatformIntegrationPlugin
{
public:
QStringList keys() const;
- QGraphicsSystem *create(const QString&);
+ QPlatformIntegration *create(const QString&, const QStringList&);
};
-QStringList QVGGraphicsSystemPlugin::keys() const
+QStringList QKmsIntegrationPlugin::keys() const
{
QStringList list;
- list << "OpenVG";
+ list << "kms";
return list;
}
-QGraphicsSystem* QVGGraphicsSystemPlugin::create(const QString& system)
+QPlatformIntegration *QKmsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
- if (system.toLower() == "openvg")
- return new QVGGraphicsSystem;
+ Q_UNUSED(paramList);
+ if (system.toLower() == "kms")
+ return new QKmsIntegration;
return 0;
}
-Q_EXPORT_PLUGIN2(openvg, QVGGraphicsSystemPlugin)
+Q_EXPORT_PLUGIN2(kms, QKmsIntegrationPlugin)
QT_END_NAMESPACE
diff --git a/src/plugins/decorations/windows/main.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp
index 8ee8a156e8..eb682e8ab3 100644
--- a/src/plugins/decorations/windows/main.cpp
+++ b/src/plugins/platforms/kms/qkmsbackingstore.cpp
@@ -39,38 +39,34 @@
**
****************************************************************************/
-#include <qdecorationplugin_qws.h>
-#include <qdecorationwindows_qws.h>
+#include "qkmsbackingstore.h"
QT_BEGIN_NAMESPACE
-class DecorationWindows : public QDecorationPlugin
-{
-public:
- DecorationWindows();
-
- QStringList keys() const;
- QDecoration *create(const QString&);
-};
-
-DecorationWindows::DecorationWindows()
- : QDecorationPlugin()
+QKmsBackingStore::QKmsBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
{
}
-QStringList DecorationWindows::keys() const
+QPaintDevice *QKmsBackingStore::paintDevice()
{
- return (QStringList() << QLatin1String("Windows"));
+ return &m_image;
}
-QDecoration* DecorationWindows::create(const QString& s)
+void QKmsBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
- if (s.toLower() == QLatin1String("windows"))
- return new QDecorationWindows();
+ //'window' can be a child window, in which case 'region' is in child window coordinates and
+ // offset is the (child) window's offset in relation to the window surface.
- return 0;
+ Q_UNUSED(region)
+ Q_UNUSED(offset)
+ Q_UNUSED(window)
}
-Q_EXPORT_PLUGIN2(qdecorationwindows, DecorationWindows)
+void QKmsBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents)
+ m_image = QImage(size, QImage::Format_RGB32);
+}
QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h b/src/plugins/platforms/kms/qkmsbackingstore.h
index a4c8cd67e4..e270d04db0 100644
--- a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h
+++ b/src/plugins/platforms/kms/qkmsbackingstore.h
@@ -39,20 +39,25 @@
**
****************************************************************************/
-#ifndef SHIVAVGGRAPHICSSYSTEM_H
-#define SHIVAVGGRAPHICSSYSTEM_H
+#ifndef QBACKINGSTORE_KMS_H
+#define QBACKINGSTORE_KMS_H
-#include <QtGui/private/qgraphicssystem_p.h>
+#include <QtGui/QPlatformBackingStore>
+#include <QImage>
QT_BEGIN_NAMESPACE
-class ShivaVGGraphicsSystem : public QGraphicsSystem
+class QKmsBackingStore : public QPlatformBackingStore
{
public:
- ShivaVGGraphicsSystem();
+ QKmsBackingStore(QWindow *window);
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
+ QPaintDevice *paintDevice();
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+
+private:
+ QImage m_image;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbuffermanager.cpp b/src/plugins/platforms/kms/qkmsbuffermanager.cpp
new file mode 100644
index 0000000000..0c2eec0f3b
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbuffermanager.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsbuffermanager.h"
+#include "qkmsscreen.h"
+#include "qkmscontext.h"
+#include "qkmsdevice.h"
+
+QT_BEGIN_NAMESPACE
+
+QKmsBufferManager::QKmsBufferManager(QKmsScreen *screen) :
+ m_screen(screen),
+ m_frameBufferObject(0),
+ m_renderTarget(0),
+ m_displayCanidate(0),
+ m_currentDisplay(0)
+{
+}
+
+QKmsBufferManager::~QKmsBufferManager()
+{
+ clearBuffers();
+ glDeleteFramebuffers(1, &m_frameBufferObject);
+}
+
+void QKmsBufferManager::setupBuffersForMode(const drmModeModeInfo &mode, int numBuffers)
+{
+ eglMakeCurrent(m_screen->device()->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_screen->device()->eglContext());
+ m_screen->bindFramebuffer();
+
+
+ if (m_frameBufferObject) {
+ clearBuffers();
+ } else {
+ //Setup Framebuffer Object
+ glGenFramebuffers(1, &m_frameBufferObject);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject);
+ }
+
+ //Setup shared Depth/Stencil buffer
+ glGenRenderbuffers(1, &m_depthAndStencilBufferObject);
+ glBindRenderbuffer(GL_RENDERBUFFER, m_depthAndStencilBufferObject);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES,
+ mode.hdisplay, mode.vdisplay);
+
+ //Setup "numBuffer" many rendering targets
+ for (int i = 0; i < numBuffers; i++) {
+ QKmsFramebuffer *buffer = new QKmsFramebuffer();
+
+ glGenRenderbuffers(1, &buffer->renderBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, buffer->renderBuffer);
+
+ buffer->graphicsBufferObject = gbm_bo_create(m_screen->device()->gbmDevice(),
+ mode.hdisplay, mode.vdisplay,
+ GBM_BO_FORMAT_XRGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ buffer->eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR,
+ buffer->graphicsBufferObject, 0);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, buffer->eglImage);
+
+ quint32 stride = gbm_bo_get_pitch(buffer->graphicsBufferObject);
+ quint32 handle = gbm_bo_get_handle(buffer->graphicsBufferObject).u32;
+
+ int status = drmModeAddFB(m_screen->device()->fd(), mode.hdisplay, mode.vdisplay,
+ 32, 32, stride, handle, &buffer->framebufferId);
+ //Todo: IF this returns true, then this is one less buffer that we use
+ //Not so fatal, but not handled at the moment.
+ if (status)
+ qFatal("failed to add framebuffer");
+ m_framebuffers.append(buffer);
+ }
+ //Attach the Depth and Stencil buffer
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
+ m_depthAndStencilBufferObject);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
+ m_depthAndStencilBufferObject);
+ //Attach renderbuffer as Color Attachment.
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ this->renderTargetBuffer());
+}
+
+void QKmsBufferManager::clearBuffers()
+{
+ //Make sure that the FBO is binded
+ glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject);
+ //Detach the Color/Depth/Stencil Attachments.
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
+ 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
+ 0);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ //Delete the shared Depth/Stencil buffer
+ glDeleteRenderbuffers(1, &m_depthAndStencilBufferObject);
+
+ //Delete each renderbuffer object
+ //Delete each EGLImage
+ //Remove each drm Framebuffer
+ foreach (QKmsFramebuffer *buffer, m_framebuffers) {
+ glDeleteRenderbuffers(1, &buffer->renderBuffer);
+ eglDestroyImageKHR(m_screen->device()->eglDisplay(), buffer->eglImage);
+ drmModeRmFB(m_screen->device()->fd(), buffer->framebufferId);
+ delete buffer;
+ }
+ m_framebuffers.clear();
+}
+
+GLuint QKmsBufferManager::renderTargetBuffer()
+{
+ //TODO: Handle more senarios than assuming at least 2 buffers
+ if (!m_renderTarget) {
+ m_renderTarget = m_framebuffers.at(1);
+ }
+ return m_renderTarget->renderBuffer;
+}
+
+quint32 QKmsBufferManager::displayFramebufferId()
+{
+ if (!m_currentDisplay) {
+ m_currentDisplay = m_framebuffers.at(0);
+ m_currentDisplay->available = false;
+ return m_currentDisplay->framebufferId;
+ }
+
+ if (!m_displayCanidate)
+ return m_currentDisplay->framebufferId;
+
+ m_currentDisplay->available = true;
+ m_displayCanidate->available = false;
+ m_currentDisplay = m_displayCanidate;
+ return m_currentDisplay->framebufferId;
+
+}
+
+bool QKmsBufferManager::nextBuffer()
+{
+ m_displayCanidate = m_renderTarget;
+ foreach (QKmsFramebuffer *buffer, m_framebuffers) {
+ if (buffer->available && buffer != m_displayCanidate) {
+ m_renderTarget = buffer;
+ return true;
+ }
+ }
+ return false;
+}
+
+QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbuffermanager.h b/src/plugins/platforms/kms/qkmsbuffermanager.h
new file mode 100644
index 0000000000..59db7ebeb1
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbuffermanager.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSBUFFERMANAGER_H
+#define QKMSBUFFERMANAGER_H
+
+#include <QObject>
+#include <QList>
+
+#define EGL_EGLEXT_PROTOTYPES 1
+#define GL_GLEXT_PROTOTYPES 1
+
+extern "C" {
+#include <gbm.h>
+#include <xf86drmMode.h>
+#include <xf86drm.h>
+}
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreen;
+
+class QKmsFramebuffer
+{
+public:
+ QKmsFramebuffer() : available(true) {}
+ gbm_bo *graphicsBufferObject;
+ GLuint renderBuffer;
+ EGLImageKHR eglImage;
+ quint32 framebufferId;
+ bool available;
+};
+
+
+class QKmsBufferManager
+{
+public:
+ explicit QKmsBufferManager(QKmsScreen *screen);
+ ~QKmsBufferManager();
+ void setupBuffersForMode(const drmModeModeInfo &mode, int numBuffers = 3);
+ GLuint framebufferObject() const { return m_frameBufferObject; }
+ quint32 displayFramebufferId();
+ GLuint renderTargetBuffer();
+ bool nextBuffer();
+
+private:
+ void clearBuffers();
+
+ QKmsScreen *m_screen;
+ QList<QKmsFramebuffer*> m_framebuffers;
+ GLuint m_frameBufferObject;
+ GLuint m_depthAndStencilBufferObject;
+
+ QKmsFramebuffer *m_renderTarget;
+ QKmsFramebuffer *m_displayCanidate;
+ QKmsFramebuffer *m_currentDisplay;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSBUFFERMANAGER_H
diff --git a/src/plugins/platforms/kms/qkmscontext.cpp b/src/plugins/platforms/kms/qkmscontext.cpp
new file mode 100644
index 0000000000..f27673a24d
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscontext.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+#include "qkmscontext.h"
+#include "qkmswindow.h"
+
+
+QT_BEGIN_NAMESPACE
+
+QKmsContext::QKmsContext(QKmsDevice *device)
+ : QPlatformOpenGLContext(),
+ m_device(device)
+{
+}
+
+bool QKmsContext::makeCurrent(QPlatformSurface *surface)
+{
+ EGLDisplay display = m_device->eglDisplay();
+ EGLContext context = m_device->eglContext();
+
+ bool ok = eglMakeCurrent(display, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, context);
+ if (!ok)
+ qWarning("QKmsContext::makeCurrent(): eglError: %d, this: %p",
+ eglGetError(), this);
+
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
+ screen->bindFramebuffer();
+ return true;
+}
+
+void QKmsContext::doneCurrent()
+{
+ QPlatformOpenGLContext::doneCurrent();
+ bool ok = eglMakeCurrent(m_device->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ if (!ok)
+ qWarning("QKmsContext::doneCurrent(): eglError: %d, this: %p",
+ eglGetError(), this);
+
+}
+
+void QKmsContext::swapBuffers(QPlatformSurface *surface)
+{
+ //After flush, the current render target should be moved to
+ //latest complete
+ glFlush();
+
+ //Cast context to a window surface and get the screen the context
+ //is on and call swapBuffers on that screen.
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
+ screen->swapBuffers();
+}
+
+void (*QKmsContext::getProcAddress(const QByteArray &procName)) ()
+{
+ return eglGetProcAddress(procName.data());
+}
+
+
+EGLContext QKmsContext::eglContext() const
+{
+ return m_device->eglContext();
+}
+
+QSurfaceFormat QKmsContext::format() const
+{
+ return QSurfaceFormat();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscontext.h b/src/plugins/platforms/kms/qkmscontext.h
new file mode 100644
index 0000000000..2f4f44c3d0
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscontext.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSCONTEXT_H
+#define QKMSCONTEXT_H
+
+#include <QtGui/QPlatformOpenGLContext>
+
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsDevice;
+
+class QKmsContext : public QPlatformOpenGLContext
+{
+public:
+ QKmsContext(QKmsDevice *device);
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ void swapBuffers(QPlatformSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ QSurfaceFormat format() const;
+
+ EGLContext eglContext() const;
+
+private:
+
+ QKmsDevice *m_device;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSCONTEXT_H
diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp
new file mode 100644
index 0000000000..91c23b0f1c
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscursor.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmscursor.h"
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+
+QT_BEGIN_NAMESPACE
+
+QKmsCursor::QKmsCursor(QKmsScreen *screen)
+ : QPlatformCursor(screen), m_screen(screen),
+ m_graphicsBufferManager(screen->device()->gbmDevice())
+{
+ gbm_bo *bo = gbm_bo_create(m_graphicsBufferManager, 64, 64,
+ GBM_BO_FORMAT_ARGB8888,
+ GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_RENDERING);
+
+ m_eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR,
+ bo, 0);
+ gbm_bo_destroy(bo);
+ m_cursorImage = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
+}
+
+void QKmsCursor::pointerEvent(const QMouseEvent &event)
+{
+ int status = drmModeMoveCursor(m_screen->device()->fd(),
+ m_screen->crtcId(),
+ event.globalX(),
+ event.globalY());
+ if (status) {
+ qWarning("failed to move cursor: %d", status);
+ }
+}
+
+void QKmsCursor::changeCursor(QCursor *widgetCursor, QWindow *window)
+{
+ Q_UNUSED(window)
+
+ if (widgetCursor->shape() != Qt::BitmapCursor) {
+ m_cursorImage->set(widgetCursor->shape());
+ } else {
+ m_cursorImage->set(widgetCursor->pixmap().toImage(),
+ widgetCursor->hotSpot().x(),
+ widgetCursor->hotSpot().y());
+ }
+
+ if ((m_cursorImage->image()->width() > 64) || (m_cursorImage->image()->width() > 64)) {
+ qWarning("failed to set hardware cursor: larger than 64x64.");
+ return;
+ }
+
+ QImage cursorImage = m_cursorImage->image()->convertToFormat(QImage::Format_RGB32);
+
+ //Load cursor image into EGLImage
+ GLuint cursorTexture;
+ glGenTextures(1, &cursorTexture);
+ glBindTexture(GL_TEXTURE_2D, cursorTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+
+ //TODO: Format may be wrong here, need a color icon to test.
+ if (m_eglImage != EGL_NO_IMAGE_KHR) {
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cursorImage.width(),
+ cursorImage.height(), GL_RGBA,
+ GL_UNSIGNED_BYTE, cursorImage.constBits());
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cursorImage.width(),
+ cursorImage.height(), 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, cursorImage.constBits());
+ }
+
+ //EGLImage needs to contain sprite before calling this:
+ gbm_bo *bufferObject = gbm_bo_create_from_egl_image(m_graphicsBufferManager,
+ m_screen->device()->eglDisplay(),
+ m_eglImage, 64, 64,
+ GBM_BO_USE_CURSOR_64X64);
+ quint32 handle = gbm_bo_get_handle(bufferObject).u32;
+
+ gbm_bo_destroy(bufferObject);
+
+ int status = drmModeSetCursor(m_screen->device()->fd(),
+ m_screen->crtcId(), handle, 64, 64);
+
+ if (status) {
+ qWarning("failed to set cursor: %d", status);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h b/src/plugins/platforms/kms/qkmscursor.h
index 6641379261..96be88e991 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h
+++ b/src/plugins/platforms/kms/qkmscursor.h
@@ -39,36 +39,36 @@
**
****************************************************************************/
-#ifndef QDIRECTFBKEYBOARD_H
-#define QDIRECTFBKEYBOARD_H
+#ifndef QKMSCURSOR_H
+#define QKMSCURSOR_H
-#include <qglobal.h>
-#include <QtGui/qkbd_qws.h>
+#include <QtGui/QPlatformCursor>
-#ifndef QT_NO_QWS_DIRECTFB
+#define EGL_EGLEXT_PROTOTYPES 1
-QT_BEGIN_HEADER
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
QT_BEGIN_NAMESPACE
-QT_MODULE(Gui)
+class QKmsScreen;
+class gbm_device;
-class QDirectFBKeyboardHandlerPrivate;
-
-class QDirectFBKeyboardHandler : public QWSKeyboardHandler
+class QKmsCursor : public QPlatformCursor
{
public:
- QDirectFBKeyboardHandler(const QString &device);
- ~QDirectFBKeyboardHandler();
+ QKmsCursor(QKmsScreen *screen);
+
+ void pointerEvent(const QMouseEvent &event);
+ void changeCursor(QCursor *widgetCursor, QWindow *window);
private:
- QDirectFBKeyboardHandlerPrivate *d;
+ QKmsScreen *m_screen;
+ gbm_device *m_graphicsBufferManager;
+ EGLImageKHR m_eglImage;
+ QPlatformCursorImage *m_cursorImage;
};
QT_END_NAMESPACE
-#endif // QT_NO_QWS_DIRECTFB
-
-QT_END_HEADER
-
-#endif // QDIRECTFBKEYBOARD_H
+#endif // QKMSCURSOR_H
diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp
new file mode 100644
index 0000000000..e0fac5611d
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsdevice.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+
+#include "qkmsintegration.h"
+
+#include <QtCore/QSocketNotifier>
+#include <QtCore/private/qcore_unix_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QKmsDevice::QKmsDevice(const QString &path, QKmsIntegration *parent) :
+ QObject(0), m_integration(parent)
+{
+ m_fd = QT_OPEN(path.toAscii().constData(), O_RDWR);
+ if (m_fd < 0) {
+ qWarning("Could not open %s.", path.toAscii().constData());
+ qFatal("No DRM display device");
+ }
+
+ m_graphicsBufferManager = gbm_create_device(m_fd);
+ m_eglDisplay = eglGetDisplay(m_graphicsBufferManager);
+
+ if (m_eglDisplay == EGL_NO_DISPLAY) {
+ qWarning("Could not open EGL display");
+ qFatal("EGL error");
+ }
+
+ EGLint major;
+ EGLint minor;
+ if (!eglInitialize(m_eglDisplay, &major, &minor)) {
+ qWarning("Could not initialize EGL display");
+ qFatal("EGL error");
+ }
+
+ QString extensions = eglQueryString(m_eglDisplay, EGL_EXTENSIONS);
+ if (!extensions.contains(QString::fromLatin1("EGL_KHR_surfaceless_opengl"))) {
+ qFatal("EGL_KHR_surfaceless_opengl extension not available");
+ }
+
+ //Initialize EGLContext
+ static EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ m_eglContext = eglCreateContext(m_eglDisplay, 0, 0, contextAttribs);
+ if (m_eglContext == EGL_NO_CONTEXT) {
+ qWarning("Could not create the EGL context.");
+ eglTerminate(m_eglDisplay);
+ qFatal("EGL error");
+ }
+
+ createScreens();
+
+ QSocketNotifier *notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(handlePageFlipCompleted()));
+}
+
+QKmsDevice::~QKmsDevice()
+{
+ if (m_eglContext != EGL_NO_CONTEXT) {
+ eglDestroyContext(m_eglDisplay, m_eglContext);
+ m_eglContext = EGL_NO_CONTEXT;
+ }
+}
+
+void QKmsDevice::createScreens()
+{
+ drmModeRes *resources = 0;
+ resources = drmModeGetResources(m_fd);
+ if (!resources)
+ qFatal("drmModeGetResources failed");
+
+ //Iterate connectors and create screens on each one active
+ for (int i = 0; i < resources->count_connectors; i++) {
+ drmModeConnector *connector = 0;
+ connector = drmModeGetConnector(m_fd, resources->connectors[i]);
+ if (connector && connector->connection == DRM_MODE_CONNECTED) {
+ m_integration->addScreen(new QKmsScreen(this, connector->connector_id));
+ }
+ drmModeFreeConnector(connector);
+ }
+ drmModeFreeResources(resources);
+}
+
+void QKmsDevice::handlePageFlipCompleted()
+{
+ //qDebug() << "Display signal recieved";
+ drmEventContext eventContext;
+
+ memset(&eventContext, 0, sizeof eventContext);
+ eventContext.version = DRM_EVENT_CONTEXT_VERSION;
+ eventContext.page_flip_handler = QKmsDevice::pageFlipHandler;
+ drmHandleEvent(m_fd, &eventContext);
+
+}
+
+void QKmsDevice::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
+{
+ Q_UNUSED(fd)
+ Q_UNUSED(frame)
+ Q_UNUSED(sec)
+ Q_UNUSED(usec)
+ static unsigned int previousTime = 0;
+
+ unsigned int currentTime = sec * 1000000 + usec;
+ unsigned int refreshTime = 0;
+// qDebug() << "fd: " << fd << " frame: " << frame << " sec: "
+// << sec << " usec: " << usec << " data: " << data
+// << "msecs" << sec * 1000 + usec / 1000;
+ QKmsScreen *screen = static_cast<QKmsScreen *>(data);
+
+ if (previousTime == 0)
+ refreshTime = 16000;
+ else
+ refreshTime = currentTime - previousTime;
+
+ screen->setFlipReady(refreshTime);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/kms/qkmsdevice.h
index 9be1480735..4868a72ede 100644
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
+++ b/src/plugins/platforms/kms/qkmsdevice.h
@@ -39,33 +39,49 @@
**
****************************************************************************/
-#ifndef QOPENKODEGLINTEGRATION_H
-#define QOPENKODEGLINTEGRATION_H
+#ifndef QKMSDEVICE_H
+#define QKMSDEVICE_H
-#include <QtGui/QPlatformGLContext>
+extern "C" {
+#include <gbm.h>
+}
#include <EGL/egl.h>
-class QEGLPlatformContext : public QPlatformGLContext
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class gbm_device;
+class QKmsIntegration;
+
+class QKmsDevice : public QObject
{
+ Q_OBJECT
public:
- QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi);
- ~QEGLPlatformContext();
+ explicit QKmsDevice(const QString &path, QKmsIntegration *parent);
+ ~QKmsDevice();
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ EGLDisplay eglDisplay() { return m_eglDisplay; }
+ gbm_device *gbmDevice() { return m_graphicsBufferManager; }
+ EGLContext eglContext() { return m_eglContext; }
+ int fd() const { return m_fd; }
- QPlatformWindowFormat platformWindowFormat() const;
+ static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec,
+ unsigned int usec, void *data);
- EGLContext eglContext() const;
+public slots:
+ void handlePageFlipCompleted();
private:
- EGLContext m_eglContext;
- EGLDisplay m_eglDisplay;
- EGLSurface m_eglSurface;
- EGLenum m_eglApi;
+ void createScreens();
- QPlatformWindowFormat m_windowFormat;
+ QKmsIntegration *m_integration;
+
+ EGLDisplay m_eglDisplay;
+ EGLContext m_eglContext;
+ gbm_device *m_graphicsBufferManager;
+ int m_fd;
};
-#endif //QOPENKODEGLINTEGRATION_H
+QT_END_NAMESPACE
+
+#endif // QKMSDEVICE_H
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
new file mode 100644
index 0000000000..d8e4876eee
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsintegration.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsintegration.h"
+#include "qkmsdevice.h"
+#include "qkmsscreen.h"
+#include "qkmswindow.h"
+#include "qkmsbackingstore.h"
+#include "qkmscontext.h"
+
+#include <QtPlatformSupport/private/qgenericunixprintersupport_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
+
+QT_BEGIN_NAMESPACE
+
+QKmsIntegration::QKmsIntegration()
+ : QPlatformIntegration(),
+ m_fontDatabase(new QGenericUnixFontDatabase()),
+ m_printerSupport(new QGenericUnixPrinterSupport()),
+ m_eventDispatcher(createUnixEventDispatcher())
+{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
+ setenv("EGL_PLATFORM", "drm",1);
+ QStringList drmDevices = findDrmDevices();
+ foreach (QString path, drmDevices) {
+ m_devices.append(new QKmsDevice(path, this));
+ }
+}
+
+QKmsIntegration::~QKmsIntegration()
+{
+ foreach (QKmsDevice *device, m_devices) {
+ delete device;
+ }
+ foreach (QPlatformScreen *screen, m_screens) {
+ delete screen;
+ }
+ delete m_printerSupport;
+ delete m_fontDatabase;
+}
+
+bool QKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformOpenGLContext *QKmsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ QKmsScreen *screen = static_cast<QKmsScreen *>(context->screen()->handle());
+ return new QKmsContext(screen->device());
+}
+
+QPlatformWindow *QKmsIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QKmsWindow(window);
+}
+
+QPlatformBackingStore *QKmsIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QKmsBackingStore(window);
+}
+
+QPlatformFontDatabase *QKmsIntegration::fontDatabase() const
+{
+ return m_fontDatabase;
+}
+
+QStringList QKmsIntegration::findDrmDevices()
+{
+ //Return a list addresses of DRM supported devices
+ //Hardcoded now, but could use udev to return a list
+ //of multiple devices.
+ return QStringList(QString::fromLatin1("/dev/dri/card0"));
+}
+
+void QKmsIntegration::addScreen(QKmsScreen *screen)
+{
+ m_screens.append(screen);
+ screenAdded(screen);
+}
+
+QAbstractEventDispatcher *QKmsIntegration::guiThreadEventDispatcher() const
+{
+ return m_eventDispatcher;
+}
+
+QPlatformPrinterSupport *QKmsIntegration::printerSupport() const
+{
+ return m_printerSupport;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
new file mode 100644
index 0000000000..a1f3623280
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsintegration.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMINTEGRATION_KMS_H
+#define QPLATFORMINTEGRATION_KMS_H
+
+#include <QtGui/QPlatformIntegration>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreen;
+class QKmsDevice;
+
+class QKmsIntegration : public QPlatformIntegration
+{
+public:
+ QKmsIntegration();
+ ~QKmsIntegration();
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+
+ QPlatformFontDatabase *fontDatabase() const;
+ QPlatformPrinterSupport *printerSupport() const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
+ void addScreen(QKmsScreen *screen);
+
+private:
+ QStringList findDrmDevices();
+
+ QList<QPlatformScreen *> m_screens;
+ QList<QKmsDevice *> m_devices;
+ QPlatformFontDatabase *m_fontDatabase;
+ QPlatformPrinterSupport *m_printerSupport;
+ QAbstractEventDispatcher *m_eventDispatcher;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp
new file mode 100644
index 0000000000..0cd1530930
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsscreen.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmscursor.h"
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+#include "qkmscontext.h"
+#include "qkmsbuffermanager.h"
+
+QT_BEGIN_NAMESPACE
+
+//Fallback mode (taken from Wayland DRM demo compositor)
+static drmModeModeInfo builtin_1024x768 = {
+ 63500, //clock
+ 1024, 1072, 1176, 1328, 0,
+ 768, 771, 775, 798, 0,
+ 59920,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
+ 0,
+ "1024x768"
+};
+
+QKmsScreen::QKmsScreen(QKmsDevice *device, int connectorId)
+ : m_device(device),
+ m_flipReady(true),
+ m_connectorId(connectorId),
+ m_depth(32),
+ m_format(QImage::Format_Invalid),
+ m_bufferManager(this),
+ m_refreshTime(16000)
+{
+ m_cursor = new QKmsCursor(this);
+ initializeScreenMode();
+}
+
+QKmsScreen::~QKmsScreen()
+{
+ delete m_cursor;
+}
+
+QRect QKmsScreen::geometry() const
+{
+ return m_geometry;
+}
+
+int QKmsScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QKmsScreen::format() const
+{
+ return m_format;
+}
+
+QSize QKmsScreen::physicalSize() const
+{
+ return m_physicalSize;
+}
+
+GLuint QKmsScreen::framebufferObject() const
+{
+ return m_bufferManager.framebufferObject();
+}
+
+void QKmsScreen::initializeScreenMode()
+{
+ //Determine optimal mode for screen
+ drmModeRes *resources = drmModeGetResources(m_device->fd());
+ if (!resources)
+ qFatal("drmModeGetResources failed");
+
+ drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId);
+ drmModeModeInfo *mode = 0;
+ if (connector->count_modes > 0)
+ mode = &connector->modes[0];
+ else
+ mode = &builtin_1024x768;
+
+ drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
+ if (encoder == 0)
+ qFatal("No encoder for connector.");
+
+ int i;
+ for (i = 0; i < resources->count_crtcs; i++) {
+ if (encoder->possible_crtcs & (1 << i))
+ break;
+ }
+ if (i == resources->count_crtcs)
+ qFatal("No usable crtc for encoder.");
+
+ m_crtcId = resources->crtcs[i];
+ m_mode = *mode;
+ m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay);
+ m_depth = 32;
+ m_format = QImage::Format_RGB32;
+ m_physicalSize = QSize(connector->mmWidth, connector->mmHeight);
+
+ //Setup three buffers for current mode
+ m_bufferManager.setupBuffersForMode(m_mode, 3);
+
+ //Set the Mode of the screen.
+ int ret = drmModeSetCrtc(m_device->fd(), m_crtcId, m_bufferManager.displayFramebufferId(),
+ 0, 0, &m_connectorId, 1, &m_mode);
+ if (ret)
+ qFatal("failed to set mode");
+
+ //Cleanup
+ drmModeFreeEncoder(encoder);
+ drmModeFreeConnector(connector);
+ drmModeFreeResources(resources);
+}
+
+void QKmsScreen::bindFramebuffer()
+{
+ if (m_bufferManager.framebufferObject()) {
+ glBindFramebuffer(GL_FRAMEBUFFER, m_bufferManager.framebufferObject());
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ m_bufferManager.renderTargetBuffer());
+ }
+}
+
+void QKmsScreen::swapBuffers()
+{
+ waitForPageFlipComplete();
+
+ if ( m_flipReady )
+ performPageFlip();
+ //TODO: Do something with return value here
+ m_bufferManager.nextBuffer();
+ //qDebug() << "swapBuffers now rendering to " << m_bufferManager.renderTargetBuffer();
+ bindFramebuffer();
+}
+
+void QKmsScreen::performPageFlip()
+{
+ quint32 displayFramebufferId = m_bufferManager.displayFramebufferId();
+ //qDebug() << "Flipping to framebuffer: " << displayFramebufferId;
+
+ int pageFlipStatus = drmModePageFlip(m_device->fd(), m_crtcId,
+ displayFramebufferId,
+ DRM_MODE_PAGE_FLIP_EVENT, this);
+ if (pageFlipStatus)
+ qWarning("Pageflip status: %d", pageFlipStatus);
+
+ m_flipReady = false;
+}
+
+void QKmsScreen::setFlipReady(unsigned int time)
+{
+ m_flipReady = true;
+ m_refreshTime = time;
+ performPageFlip();
+}
+
+QKmsDevice * QKmsScreen::device() const
+{
+ return m_device;
+}
+
+void QKmsScreen::waitForPageFlipComplete()
+{
+ //Check manually if there is something to be read on the device
+ //as there are senarios where the signal is not received (starvation)
+ fd_set fdSet;
+ timeval timeValue;
+ int returnValue;
+
+ FD_ZERO(&fdSet);
+ FD_SET(m_device->fd(), &fdSet);
+ timeValue.tv_sec = 0;
+ timeValue.tv_usec = m_refreshTime;
+
+ returnValue = select(1, &fdSet, 0, 0, &timeValue);
+
+ if (returnValue) {
+ m_device->handlePageFlipCompleted();
+ }
+
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h
new file mode 100644
index 0000000000..5c8b5ca4f5
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsscreen.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSSCREEN_H
+#define QKMSSCREEN_H
+
+#include <QtGui/QPlatformScreen>
+#include "qkmsbuffermanager.h"
+
+QT_BEGIN_NAMESPACE
+
+class QKmsCursor;
+class QKmsDevice;
+class QKmsContext;
+
+class QKmsScreen : public QPlatformScreen
+{
+public:
+ QKmsScreen(QKmsDevice *device, int connectorId);
+ ~QKmsScreen();
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSize physicalSize() const;
+
+ GLuint framebufferObject() const;
+ quint32 crtcId() const { return m_crtcId; }
+ QKmsDevice *device() const;
+
+ //Called by context for each screen
+ void bindFramebuffer();
+ void swapBuffers();
+ void setFlipReady(unsigned int time);
+
+private:
+ void performPageFlip();
+ void initializeScreenMode();
+ void waitForPageFlipComplete();
+
+ QKmsDevice *m_device;
+ bool m_flipReady;
+ quint32 m_connectorId;
+
+ quint32 m_crtcId;
+ drmModeModeInfo m_mode;
+ QRect m_geometry;
+ QSize m_physicalSize;
+ int m_depth;
+ QImage::Format m_format;
+
+ QKmsCursor *m_cursor;
+ QKmsBufferManager m_bufferManager;
+ unsigned int m_refreshTime;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSSCREEN_H
diff --git a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp b/src/plugins/platforms/kms/qkmswindow.cpp
index 48526538ab..63271c4ef5 100644
--- a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp
+++ b/src/plugins/platforms/kms/qkmswindow.cpp
@@ -39,24 +39,26 @@
**
****************************************************************************/
-#include "shivavggraphicssystem.h"
-#include "shivavgwindowsurface.h"
-#include <QtGui/private/qpixmap_raster_p.h>
+#include "qkmswindow.h"
+#include "qkmsscreen.h"
+#include <QtGui/QWindowSystemInterface>
QT_BEGIN_NAMESPACE
-ShivaVGGraphicsSystem::ShivaVGGraphicsSystem()
+QKmsWindow::QKmsWindow(QWindow *window)
+ : QPlatformWindow(window)
{
+ m_screen = QPlatformScreen::platformScreenForWindow(window);
}
-QPixmapData *ShivaVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
+void QKmsWindow::setGeometry(const QRect &rect)
{
- return new QRasterPixmapData(type);
-}
+ Q_UNUSED(rect)
+ //All Windows must be fullscreen
+ QRect fullscreenRect = m_screen->availableGeometry();
+ QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
-QWindowSurface *ShivaVGGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- return new ShivaVGWindowSurface(widget);
+ QPlatformWindow::setGeometry(fullscreenRect);
}
QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h b/src/plugins/platforms/kms/qkmswindow.h
index e38033a6cd..789d42e6f8 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h
+++ b/src/plugins/platforms/kms/qkmswindow.h
@@ -39,16 +39,24 @@
**
****************************************************************************/
-#ifndef MGRAPHICSSYSTEMPLUGIN_H
-#define MGRAPHICSSYSTEMPLUGIN_H
+#ifndef QKMSWINDOW_H
+#define QKMSWINDOW_H
-#include <private/qgraphicssystemplugin_p.h>
+#include <QtGui/QPlatformWindow>
-class QMeeGoGraphicsSystemPlugin : public QGraphicsSystemPlugin
+QT_BEGIN_NAMESPACE
+
+class QKmsWindow : public QPlatformWindow
{
public:
- virtual QStringList keys() const;
- virtual QGraphicsSystem *create(const QString&);
+ QKmsWindow(QWindow *window);
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QPlatformScreen *m_screen;
};
-#endif
+QT_END_NAMESPACE
+
+#endif // QKMSWINDOW_H
diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro
index ce6814ecc1..9375486d8b 100644
--- a/src/plugins/platforms/linuxfb/linuxfb.pro
+++ b/src/plugins/platforms/linuxfb/linuxfb.pro
@@ -3,6 +3,8 @@ load(qt_plugin)
DESTDIR = $$QT.gui.plugins/platforms
+QT += core-private gui-private platformsupport-private
+
SOURCES = main.cpp qlinuxfbintegration.cpp
HEADERS = qlinuxfbintegration.h
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index 4a24d6614a..1c098a0ffc 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -42,6 +42,7 @@
#include "qlinuxfbintegration.h"
#include "../fb_base/fb_base.h"
#include "qgenericunixfontdatabase.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
#include <qimage.h>
@@ -791,9 +792,9 @@ bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) co
}
-QPixmapData *QLinuxFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QLinuxFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
}
QWindowSurface *QLinuxFbIntegration::createWindowSurface(QWidget *widget, WId) const
@@ -810,6 +811,11 @@ QPlatformWindow *QLinuxFbIntegration::createPlatformWindow(QWidget *widget, WId
return w;
}
+QAbstractEventDispatcher *QMinimalIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
QPlatformFontDatabase *QLinuxFbIntegration::fontDatabase() const
{
return fontDb;
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index b96749ff03..f972a30452 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -70,6 +70,7 @@ class QLinuxFbIntegrationPrivate;
struct fb_cmap;
struct fb_var_screeninfo;
struct fb_fix_screeninfo;
+class QAbstractEventDispatcher;
class QLinuxFbIntegration : public QPlatformIntegration
{
@@ -79,9 +80,10 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId WinId) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId WinId) const;
+ QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const { return mScreens; }
diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro
index d51b6b2ed0..392d12d19a 100644
--- a/src/plugins/platforms/minimal/minimal.pro
+++ b/src/plugins/platforms/minimal/minimal.pro
@@ -1,14 +1,14 @@
TARGET = qminimal
load(qt_plugin)
-QT = core-private gui-private
+QT += core-private gui-private platformsupport-private
DESTDIR = $$QT.gui.plugins/platforms
SOURCES = main.cpp \
qminimalintegration.cpp \
- qminimalwindowsurface.cpp
+ qminimalbackingstore.cpp
HEADERS = qminimalintegration.h \
- qminimalwindowsurface.h
+ qminimalbackingstore.h
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/minimal/qminimalwindowsurface.cpp b/src/plugins/platforms/minimal/qminimalbackingstore.cpp
index 91c68d1d2d..08281405a4 100644
--- a/src/plugins/platforms/minimal/qminimalwindowsurface.cpp
+++ b/src/plugins/platforms/minimal/qminimalbackingstore.cpp
@@ -40,45 +40,45 @@
****************************************************************************/
-#include "qminimalwindowsurface.h"
+#include "qminimalbackingstore.h"
+#include "qscreen.h"
#include <QtCore/qdebug.h>
-#include <QtGui/private/qapplication_p.h>
+#include <private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
-QMinimalWindowSurface::QMinimalWindowSurface(QWidget *window)
- : QWindowSurface(window)
+QMinimalBackingStore::QMinimalBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
{
- //qDebug() << "QMinimalWindowSurface::QMinimalWindowSurface:" << (long)this;
+ //qDebug() << "QMinimalBackingStore::QMinimalBackingStore:" << (long)this;
}
-QMinimalWindowSurface::~QMinimalWindowSurface()
+QMinimalBackingStore::~QMinimalBackingStore()
{
}
-QPaintDevice *QMinimalWindowSurface::paintDevice()
+QPaintDevice *QMinimalBackingStore::paintDevice()
{
- //qDebug() << "QMinimalWindowSurface::paintDevice";
+ //qDebug() << "QMinimalBackingStore::paintDevice";
return &mImage;
}
-void QMinimalWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QMinimalBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
Q_UNUSED(region);
Q_UNUSED(offset);
static int c = 0;
QString filename = QString("output%1.png").arg(c++, 4, 10, QLatin1Char('0'));
- qDebug() << "QMinimalWindowSurface::flush() saving contents to" << filename.toLocal8Bit().constData();
+ qDebug() << "QMinimalBackingStore::flush() saving contents to" << filename.toLocal8Bit().constData();
mImage.save(filename);
}
-void QMinimalWindowSurface::resize(const QSize &size)
+void QMinimalBackingStore::resize(const QSize &size, const QRegion &)
{
- //qDebug() << "QMinimalWindowSurface::setGeometry:" << (long)this << rect;
- QWindowSurface::resize(size);
- QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
+ //qDebug() << "QMinimalBackingStore::setGeometry:" << (long)this << rect;
+ QImage::Format format = QGuiApplication::primaryScreen()->handle()->format();
if (mImage.size() != size)
mImage = QImage(size, format);
}
diff --git a/src/plugins/platforms/minimal/qminimalwindowsurface.h b/src/plugins/platforms/minimal/qminimalbackingstore.h
index 2c6196a19a..9b61275e9d 100644
--- a/src/plugins/platforms/minimal/qminimalwindowsurface.h
+++ b/src/plugins/platforms/minimal/qminimalbackingstore.h
@@ -39,24 +39,24 @@
**
****************************************************************************/
-#ifndef QWINDOWSURFACE_MINIMAL_H
-#define QWINDOWSURFACE_MINIMAL_H
-
-#include <QtGui/private/qwindowsurface_p.h>
+#ifndef QBACKINGSTORE_MINIMAL_H
+#define QBACKINGSTORE_MINIMAL_H
+#include <QtGui/QPlatformBackingStore>
#include <QtGui/QPlatformWindow>
+#include <QtGui/QImage>
QT_BEGIN_NAMESPACE
-class QMinimalWindowSurface : public QWindowSurface
+class QMinimalBackingStore : public QPlatformBackingStore
{
public:
- QMinimalWindowSurface(QWidget *window);
- ~QMinimalWindowSurface();
+ QMinimalBackingStore(QWindow *window);
+ ~QMinimalBackingStore();
QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
private:
QImage mImage;
diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp
index b9ab528b50..2f2da6967a 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.cpp
+++ b/src/plugins/platforms/minimal/qminimalintegration.cpp
@@ -40,20 +40,34 @@
****************************************************************************/
#include "qminimalintegration.h"
-#include "qminimalwindowsurface.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 <QtGui/QPlatformWindow>
-QMinimalIntegration::QMinimalIntegration()
+QT_BEGIN_NAMESPACE
+
+QMinimalIntegration::QMinimalIntegration() :
+#ifdef Q_OS_WIN
+ m_eventDispatcher(new QEventDispatcherWin32())
+#else
+ m_eventDispatcher(createUnixEventDispatcher())
+#endif
{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
QMinimalScreen *mPrimaryScreen = new QMinimalScreen();
mPrimaryScreen->mGeometry = QRect(0, 0, 240, 320);
mPrimaryScreen->mDepth = 32;
mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied;
- mScreens.append(mPrimaryScreen);
+ screenAdded(mPrimaryScreen);
}
bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -64,19 +78,20 @@ bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) co
}
}
-QPixmapData *QMinimalIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformWindow *QMinimalIntegration::createPlatformWindow(QWindow *window) const
{
- return new QRasterPixmapData(type);
+ Q_UNUSED(window);
+ return new QPlatformWindow(window);
}
-QPlatformWindow *QMinimalIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+QPlatformBackingStore *QMinimalIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
- return new QPlatformWindow(widget);
+ return new QMinimalBackingStore(window);
}
-QWindowSurface *QMinimalIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QAbstractEventDispatcher *QMinimalIntegration::guiThreadEventDispatcher() const
{
- Q_UNUSED(winId);
- return new QMinimalWindowSurface(widget);
+ return m_eventDispatcher;
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/minimal/qminimalintegration.h b/src/plugins/platforms/minimal/qminimalintegration.h
index d1fcc42c68..0835c39ab6 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.h
+++ b/src/plugins/platforms/minimal/qminimalintegration.h
@@ -71,14 +71,12 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
-
- QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
private:
- QList<QPlatformScreen *> mScreens;
+ QAbstractEventDispatcher *m_eventDispatcher;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.cpp b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
index 89475db54b..38c4325bb4 100644
--- a/src/plugins/platforms/openkode/qopenkodeintegration.cpp
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
@@ -43,7 +43,7 @@
#include "qopenkodewindow.h"
#include "qopenkodeeventloopintegration.h"
-#include <QtOpenGL/private/qpixmapdata_gl_p.h>
+#include <QtOpenGL/qplatformpixmap_gl_p.h>
#include <QtOpenGL/private/qwindowsurface_gl_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
@@ -197,9 +197,9 @@ bool QOpenKODEIntegration::hasCapability(QPlatformIntegration::Capability cap) c
}
}
-QPixmapData *QOpenKODEIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QOpenKODEIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QGLPixmapData(type);
+ return new QGLPlatformPixmap(type);
}
QPlatformWindow *QOpenKODEIntegration::createPlatformWindow(QWidget *tlw, WId ) const
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.h b/src/plugins/platforms/openkode/qopenkodeintegration.h
index 0f001c957b..43961add6d 100644
--- a/src/plugins/platforms/openkode/qopenkodeintegration.h
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.h
@@ -48,7 +48,7 @@
#include <QtGui/QPlatformIntegration>
#include <QtGui/QPlatformScreen>
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
#include <QtGui/QPlatformFontDatabase>
#include <GLES2/gl2.h>
@@ -92,7 +92,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp
index c6fe6d0176..e20904470f 100644
--- a/src/plugins/platforms/openkode/qopenkodewindow.cpp
+++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp
@@ -53,7 +53,7 @@
#include <EGL/egl.h>
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
#include <QtGui/private/qwidget_p.h>
#include <QtGui/private/qapplication_p.h>
@@ -235,7 +235,7 @@ WId QOpenKODEWindow::winId() const
return i++;
}
-QPlatformGLContext *QOpenKODEWindow::glContext() const
+QPlatformOpenGLContext *QOpenKODEWindow::glContext() const
{
return m_platformGlContext;
}
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.h b/src/plugins/platforms/openkode/qopenkodewindow.h
index 317a6b5cd6..f48c3a2bc0 100644
--- a/src/plugins/platforms/openkode/qopenkodewindow.h
+++ b/src/plugins/platforms/openkode/qopenkodewindow.h
@@ -63,7 +63,7 @@ public:
void setVisible(bool visible);
WId winId() const;
- QPlatformGLContext *glContext() const;
+ QPlatformOpenGLContext *glContext() const;
void raise();
void lower();
diff --git a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp
index 203896f489..d8e4cc984c 100644
--- a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp
+++ b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp
@@ -41,7 +41,7 @@
#include "qgraphicssystem_vglite.h"
#include "qwindowsurface_vglite.h"
-#include <QtOpenVG/private/qpixmapdata_vg_p.h>
+#include <QtOpenVG/qplatformpixmap_vg_p.h>
#include <QtGui/private/qegl_p.h>
#include <QtCore/qdebug.h>
#ifdef OPENVG_USBHP_INIT
@@ -163,16 +163,16 @@ QVGLiteGraphicsSystem::~QVGLiteGraphicsSystem()
{
}
-QPixmapData *QVGLiteGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QVGLiteGraphicsSystem::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
#if !defined(QVGLite_NO_SINGLE_CONTEXT) && !defined(QVGLite_NO_PIXMAP_DATA)
- // Pixmaps can use QVGLitePixmapData; bitmaps must use raster.
- if (type == QPixmapData::PixmapType)
- return new QVGPixmapData(type);
+ // Pixmaps can use QVGLitePlatformPixmap; bitmaps must use raster.
+ if (type == QPlatformPixmap::PixmapType)
+ return new QVGPlatformPixmap(type);
else
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
#else
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
#endif
}
diff --git a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h
index 41b1d286bc..6dc6a38439 100644
--- a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h
+++ b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h
@@ -57,7 +57,7 @@ public:
QVGLiteGraphicsSystem();
~QVGLiteGraphicsSystem();
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QWindowSurface *createWindowSurface(QWidget *widget) const;
QList<QGraphicsSystemScreen *> screens() const { return mScreens; }
diff --git a/src/plugins/graphicssystems/shivavg/main.cpp b/src/plugins/platforms/openwfd/main.cpp
index 53bc782378..c0159e7218 100644
--- a/src/plugins/graphicssystems/shivavg/main.cpp
+++ b/src/plugins/platforms/openwfd/main.cpp
@@ -39,33 +39,34 @@
**
****************************************************************************/
-#include <private/qgraphicssystemplugin_p.h>
-#include "shivavggraphicssystem.h"
+#include <QtGui/QPlatformIntegrationPlugin>
+#include "qopenwfdintegration.h"
QT_BEGIN_NAMESPACE
-class ShivaVGGraphicsSystemPlugin : public QGraphicsSystemPlugin
+class QOpenWFDIntegrationPlugin : public QPlatformIntegrationPlugin
{
public:
QStringList keys() const;
- QGraphicsSystem *create(const QString&);
+ QPlatformIntegration *create(const QString&, const QStringList&);
};
-QStringList ShivaVGGraphicsSystemPlugin::keys() const
+QStringList QOpenWFDIntegrationPlugin::keys() const
{
QStringList list;
- list << "ShivaVG";
+ list << "OpenWFD";
return list;
}
-QGraphicsSystem* ShivaVGGraphicsSystemPlugin::create(const QString& system)
+QPlatformIntegration* QOpenWFDIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
- if (system.toLower() == "shivavg")
- return new ShivaVGGraphicsSystem;
+ Q_UNUSED(paramList);
+ if (system.toLower() == "openwfd")
+ return new QOpenWFDIntegration;
return 0;
}
-Q_EXPORT_PLUGIN2(shivavg, ShivaVGGraphicsSystemPlugin)
+Q_EXPORT_PLUGIN2(openwfd, QOpenWFDIntegrationPlugin)
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openwfd/openwf.pro b/src/plugins/platforms/openwfd/openwf.pro
new file mode 100644
index 0000000000..d913a84411
--- /dev/null
+++ b/src/plugins/platforms/openwfd/openwf.pro
@@ -0,0 +1,41 @@
+TARGET = qopenwf
+
+load(qt_plugin)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+QT += core-private gui-private platformsupport-private
+
+CONFIG += qpa/genericunixfontdatabase
+
+HEADERS += \
+ qopenwfddevice.h \
+ qopenwfdintegration.h \
+ qopenwfdnativeinterface.h \
+ qopenwfdscreen.h \
+ qopenwfdbackingstore.h \
+ qopenwfdevent.h \
+ qopenwfdglcontext.h \
+ qopenwfdoutputbuffer.h \
+ qopenwfdport.h \
+ qopenwfdwindow.h \
+ qopenwfdportmode.h
+
+SOURCES += \
+ main.cpp \
+ qopenwfddevice.cpp \
+ qopenwfdintegration.cpp \
+ qopenwfdnativeinterface.cpp \
+ qopenwfdscreen.cpp \
+ qopenwfdbackingstore.cpp \
+ qopenwfdevent.cpp \
+ qopenwfdglcontext.cpp \
+ qopenwfdoutputbuffer.cpp \
+ qopenwfdport.cpp \
+ qopenwfdportmode.cpp \
+ qopenwfdwindow.cpp
+
+LIBS += -lWFD -lgbm -lGLESv2 -lEGL
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
+
diff --git a/src/plugins/platforms/openwfd/qopenwfdbackingstore.cpp b/src/plugins/platforms/openwfd/qopenwfdbackingstore.cpp
new file mode 100644
index 0000000000..2638d8cd5a
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdbackingstore.cpp
@@ -0,0 +1,25 @@
+#include "qopenwfdbackingstore.h"
+
+QOpenWFDBackingStore::QOpenWFDBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+}
+
+QPaintDevice * QOpenWFDBackingStore::paintDevice()
+{
+ return &mImage;
+}
+
+//we don't support flush yet :)
+void QOpenWFDBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+}
+
+void QOpenWFDBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents);
+ mImage = QImage(size,QImage::Format_RGB32);
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h b/src/plugins/platforms/openwfd/qopenwfdbackingstore.h
index 00da6976b8..c173de6c19 100644
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
+++ b/src/plugins/platforms/openwfd/qopenwfdbackingstore.h
@@ -39,31 +39,27 @@
**
****************************************************************************/
-#ifndef QWAYLANDDRMSURFACE_H
-#define QWAYLANDDRMSURFACE_H
+#ifndef QOPENWFDBACKINGSTORE_H
+#define QOPENWFDBACKINGSTORE_H
-#include "qwaylanddisplay.h"
+#include <QtGui/QPlatformBackingStore>
+#include <QtGui/QImage>
-#include <QtGui/private/qwindowsurface_p.h>
-
-class QGLFramebufferObject;
-
-class QWaylandGLWindowSurface : public QWindowSurface
+class QOpenWFDBackingStore : public QPlatformBackingStore
{
public:
- QWaylandGLWindowSurface(QWidget *window);
- ~QWaylandGLWindowSurface();
-
- void beginPaint(const QRegion &);
+ QOpenWFDBackingStore(QWindow *window);
QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
+ // 'window' can be a child window, in which case 'region' is in child window coordinates and
+ // offset is the (child) window's offset in relation to the window surface.
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+
+ void resize(const QSize &size, const QRegion &staticContents);
private:
- QWaylandDisplay *mDisplay;
- QGLFramebufferObject *mPaintDevice;
+ QImage mImage;
};
-#endif // QWAYLANDDRMSURFACE_H
+#endif // QOPENWFDBACKINGSTORE_H
diff --git a/src/plugins/platforms/openwfd/qopenwfddevice.cpp b/src/plugins/platforms/openwfd/qopenwfddevice.cpp
new file mode 100644
index 0000000000..d3ff6d45d8
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfddevice.cpp
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfddevice.h"
+
+#include "qopenwfdport.h"
+#include "qopenwfdscreen.h"
+
+#include <QtCore/QDebug>
+
+#include <WF/wfdext.h>
+#include <gbm.h>
+
+QOpenWFDDevice::QOpenWFDDevice(QOpenWFDIntegration *integration, WFDint device_enumeration)
+ : mIntegration(integration)
+ , mDeviceEnum(device_enumeration)
+ , mCommitedDevice(false)
+ , mWaitingForBindSourceEvent(false)
+{
+ mDevice = wfdCreateDevice(WFD_DEFAULT_DEVICE_ID,WFD_NONE);
+ if (mDevice == WFD_INVALID_HANDLE)
+ qDebug() << "failed to create device";
+
+ mEvent = wfdCreateEvent(mDevice,0);
+ if (mEvent == WFD_INVALID_HANDLE)
+ qDebug() << "failed to create event handle";
+
+ //initialize pipelines for device.
+ wfdEnumeratePipelines(mDevice,WFD_NONE,0,WFD_NONE);
+
+ initializeGbmAndEgl();
+
+ WFDint numberOfPorts = wfdEnumeratePorts(mDevice,0,0,0);
+ WFDint port_enumerations[numberOfPorts];
+ WFDint actualNumberOfPorts = wfdEnumeratePorts(mDevice,port_enumerations,numberOfPorts,WFD_NONE);
+ Q_ASSERT(actualNumberOfPorts == numberOfPorts);
+
+ for (int i = 0; i < actualNumberOfPorts; i++)
+ {
+ QOpenWFDPort *port = new QOpenWFDPort(this,port_enumerations[i]);
+ if (port->attached()) {
+ mPorts.append(port);
+ } else {
+ delete port;
+ }
+ }
+
+ int fd = wfdDeviceEventGetFD(mDevice,mEvent);
+ mEventSocketNotifier = new QSocketNotifier(fd,QSocketNotifier::Read,this);
+ connect(mEventSocketNotifier,SIGNAL(activated(int)),SLOT(readEvents()));
+
+ mCommitedDevice = true;
+ commit(WFD_COMMIT_ENTIRE_DEVICE, handle());
+}
+
+QOpenWFDDevice::~QOpenWFDDevice()
+{
+ delete mEventSocketNotifier;
+ wfdDestroyEvent(mDevice,mEvent);
+
+ for (int i = 0; i < mPorts.size(); i++) {
+ //probably don't need to remove them from the list
+ QList <WFDint> keys = mUsedPipelines.keys(mPorts.at(i));
+ for (int keyIndex = 0; keyIndex < keys.size(); keyIndex++) {
+ mUsedPipelines.remove(keys.at(keyIndex));
+ }
+ //but we have to delete them :)
+ delete mPorts[i];
+ }
+
+ eglDestroyContext(mEglDisplay,mEglContext);
+ eglTerminate(mEglDisplay);
+
+ gbm_device_destroy(mGbmDevice);
+
+ wfdDestroyDevice(mDevice);
+}
+
+WFDDevice QOpenWFDDevice::handle() const
+{
+ return mDevice;
+}
+
+QOpenWFDIntegration * QOpenWFDDevice::integration() const
+{
+ return mIntegration;
+}
+
+bool QOpenWFDDevice::isPipelineUsed(WFDint pipelineId)
+{
+ return mUsedPipelines.contains(pipelineId);
+}
+
+void QOpenWFDDevice::addToUsedPipelineSet(WFDint pipelineId,QOpenWFDPort *port)
+{
+ mUsedPipelines.insert(pipelineId,port);
+}
+
+void QOpenWFDDevice::removeFromUsedPipelineSet(WFDint pipelineId)
+{
+ mUsedPipelines.remove(pipelineId);
+}
+
+gbm_device * QOpenWFDDevice::gbmDevice() const
+
+{
+ return mGbmDevice;
+}
+
+EGLDisplay QOpenWFDDevice::eglDisplay() const
+{
+ return mEglDisplay;
+}
+
+EGLContext QOpenWFDDevice::eglContext() const
+{
+ return mEglContext;
+}
+
+void QOpenWFDDevice::commit(WFDCommitType type, WFDHandle handle)
+{
+ if (mCommitedDevice) {
+ wfdDeviceCommit(mDevice,type,handle);
+ }
+}
+
+void QOpenWFDDevice::waitForPipelineBindSourceCompleteEvent()
+{
+ mWaitingForBindSourceEvent = true;
+
+ while (mWaitingForBindSourceEvent) {
+ readEvents(WFD_FOREVER);
+ }
+}
+
+void QOpenWFDDevice::readEvents(WFDtime wait)
+{
+ WFDEventType type = wfdDeviceEventWait(mDevice,mEvent,wait);
+
+ if (type == WFD_EVENT_NONE || type == WFD_EVENT_DESTROYED) {
+ return;
+ }
+ switch (type) {
+ case WFD_EVENT_INVALID:
+ case WFD_EVENT_NONE:
+ return;
+ case WFD_EVENT_DESTROYED:
+ qDebug() << "Event or Device destoryed!";
+ return;
+ case WFD_EVENT_PORT_ATTACH_DETACH:
+ handlePortAttachDetach();
+ break;
+ case WFD_EVENT_PORT_PROTECTION_FAILURE:
+ qDebug() << "Port protection event handling not implemented";
+ break;
+ case WFD_EVENT_PIPELINE_BIND_SOURCE_COMPLETE:
+ handlePipelineBindSourceComplete();
+ break;
+ case WFD_EVENT_PIPELINE_BIND_MASK_COMPLETE:
+ qDebug() << "Pipeline bind mask event handling not implemented";
+ break;
+ default:
+ qDebug() << "Not recognised event type";
+ break;
+ }
+
+
+}
+
+void QOpenWFDDevice::initializeGbmAndEgl()
+{
+
+ qDebug() << "initializing GBM and EGL";
+ int fd = wfdGetDeviceAttribi(mDevice,WFD_DEVICE_ID);
+ if (fd < 0) {
+ qDebug() << "failed to get WFD_DEVICE_ID";
+ }
+
+ mGbmDevice = gbm_create_device(fd);
+
+ setenv("EGL_PLATFORM", "drm",1);
+
+ mEglDisplay = eglGetDisplay(mGbmDevice);
+
+ EGLint minor, major;
+
+ if (!eglInitialize(mEglDisplay,&major,&minor)) {
+ qDebug() << "failed to initialize egl";
+ }
+
+ QByteArray eglExtensions = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
+ if (!eglExtensions.contains("EGL_KHR_surfaceless_opengl")) {
+ qDebug() << "This egl implementation does not have the required EGL extension EGL_KHR_surfaceless_opengl";
+ }
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+
+ EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ mEglContext = eglCreateContext(mEglDisplay,NULL,EGL_NO_CONTEXT,contextAttribs);
+ if (mEglContext == EGL_NO_CONTEXT) {
+ qDebug() << "Failed to create EGL context";
+ }
+
+ eglCreateImage = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
+ if (!eglCreateImage) {
+ qWarning("failed to load extension eglCreateImageKHR");
+ }
+
+ eglDestroyImage = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
+ if (!eglDestroyImage) {
+ qWarning("failed to load extension eglDestoryImageKHR");
+ }
+
+ glEglImageTargetRenderBufferStorage = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES");
+ if (!glEglImageTargetRenderBufferStorage) {
+ qWarning("failed to load extension glEGLImageTargetRenderbufferStorageOES");
+ }
+}
+
+void QOpenWFDDevice::handlePortAttachDetach()
+{
+ WFDint id = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PORT_ATTACH_PORT_ID);
+ if (id == WFD_INVALID_PORT_ID)
+ return;
+
+ WFDint attachState = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PORT_ATTACH_STATE);
+ if (attachState == WFD_TRUE) {
+ int indexToAdd = -1;
+ for (int i = 0; i < mPorts.size(); i++) {
+ if (mPorts.at(i)->portId() == id) {
+ indexToAdd = i;
+ qDebug() << "found index to attach";
+ break;
+ }
+ }
+ if (indexToAdd >= 0) {
+ mPorts[indexToAdd]->attach();
+ } else {
+ mPorts.append(new QOpenWFDPort(this,id));
+ }
+
+ } else {
+ int indexToDelete = -1;
+ for (int i = 0; i < mPorts.size(); i++) {
+ if (mPorts.at(i)->portId() == id) {
+ indexToDelete = i;
+ break;
+ }
+ }
+ if (indexToDelete >= 0) {
+ QOpenWFDPort *portToDelete = mPorts.at(indexToDelete);
+ mPorts.removeAt(indexToDelete);
+ delete portToDelete;
+ }
+ }
+}
+
+void QOpenWFDDevice::handlePipelineBindSourceComplete()
+{
+ mWaitingForBindSourceEvent = false;
+
+ WFDint overflow = wfdGetEventAttribi(mDevice,mEvent, WFD_EVENT_PIPELINE_BIND_QUEUE_OVERFLOW);
+ if (overflow == WFD_TRUE) {
+ qDebug() << "PIPELINE_BIND_QUEUE_OVERFLOW event occured";
+ }
+
+ WFDint pipelineId = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PIPELINE_BIND_PIPELINE_ID);
+ for (int i = 0; i < mPorts.size(); i++) {
+ if (pipelineId != WFD_INVALID_PIPELINE_ID && mUsedPipelines.contains(pipelineId)) {
+ QOpenWFDPort *port = mUsedPipelines.value(pipelineId);
+ port->screen()->pipelineBindSourceComplete();
+ break;
+ }
+ }
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfddevice.h b/src/plugins/platforms/openwfd/qopenwfddevice.h
new file mode 100644
index 0000000000..83a5539124
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfddevice.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDDEVICE_H
+#define QOPENWFDDEVICE_H
+
+#include "qopenwfdintegration.h"
+
+#include <QtCore/QList>
+#include <QtCore/QSet>
+#include <QtCore/QSocketNotifier>
+
+#include <WF/wfd.h>
+
+#include <gbm.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+class QOpenWFDPort;
+
+class QOpenWFDDevice : public QObject
+{
+ Q_OBJECT
+public:
+ QOpenWFDDevice(QOpenWFDIntegration *integration, WFDint handle);
+ ~QOpenWFDDevice();
+ WFDDevice handle() const;
+ QOpenWFDIntegration *integration() const;
+
+
+ bool isPipelineUsed(WFDint pipelineId);
+ void addToUsedPipelineSet(WFDint pipelineId, QOpenWFDPort *port);
+ void removeFromUsedPipelineSet(WFDint pipelineId);
+
+ gbm_device *gbmDevice() const;
+ EGLDisplay eglDisplay() const;
+ EGLContext eglContext() const;
+
+ PFNEGLCREATEIMAGEKHRPROC eglCreateImage;
+ PFNEGLDESTROYIMAGEKHRPROC eglDestroyImage;
+ PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEglImageTargetRenderBufferStorage;
+
+ void commit(WFDCommitType type, WFDHandle handle);
+ bool isDeviceInitializedAndCommited() const { return mCommitedDevice; }
+
+ void waitForPipelineBindSourceCompleteEvent();
+
+public slots:
+ void readEvents(WFDtime wait = 0);
+private:
+ void initializeGbmAndEgl();
+ void handlePortAttachDetach();
+ void handlePipelineBindSourceComplete();
+ QOpenWFDIntegration *mIntegration;
+ WFDint mDeviceEnum;
+ WFDDevice mDevice;
+
+ WFDEvent mEvent;
+ QSocketNotifier *mEventSocketNotifier;
+
+ QList<QOpenWFDPort *> mPorts;
+
+ QMap<WFDint, QOpenWFDPort *> mUsedPipelines;
+
+ struct gbm_device *mGbmDevice;
+ EGLDisplay mEglDisplay;
+ EGLContext mEglContext;
+
+ bool mCommitedDevice;
+ bool mWaitingForBindSourceEvent;
+};
+
+#endif // QOPENWFDDEVICE_H
diff --git a/src/plugins/platforms/eglconvenience/qxlibeglintegration.h b/src/plugins/platforms/openwfd/qopenwfdevent.cpp
index 1d02ab8677..748dde65e7 100644
--- a/src/plugins/platforms/eglconvenience/qxlibeglintegration.h
+++ b/src/plugins/platforms/openwfd/qopenwfdevent.cpp
@@ -39,15 +39,8 @@
**
****************************************************************************/
-#ifndef QTESTLITEEGLINTEGRATION_H
-#define QTESTLITEEGLINTEGRATION_H
+#include "qopenwfdevent.h"
-#include "qeglconvenience.h"
-
-class QXlibEglIntegration
+QOpenWFDEvent::QOpenWFDEvent()
{
-public:
- static VisualID getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config);
-};
-
-#endif // QTESTLITEEGLINTEGRATION_H
+}
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h b/src/plugins/platforms/openwfd/qopenwfdevent.h
index c0e5c2a524..3010fdb55b 100644
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h
+++ b/src/plugins/platforms/openwfd/qopenwfdevent.h
@@ -39,9 +39,13 @@
**
****************************************************************************/
-#ifndef EGLNULLWSSCREENPLUGIN_H
-#define EGLNULLWSSCREENPLUGIN_H
+#ifndef QOPENWFDEVENT_H
+#define QOPENWFDEVENT_H
-const char *const PluginName = "eglnullws";
+class QOpenWFDEvent
+{
+public:
+ QOpenWFDEvent();
+};
-#endif // EGLNULLWSSCREENPLUGIN_H
+#endif // QOPENWFDEVENT_H
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/platforms/openwfd/qopenwfdglcontext.cpp
index 829996b0b0..0db717c4d6 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
+++ b/src/plugins/platforms/openwfd/qopenwfdglcontext.cpp
@@ -39,50 +39,59 @@
**
****************************************************************************/
-#include "qgraphicssystem_vg_p.h"
-#include <QtOpenVG/private/qpixmapdata_vg_p.h>
-#include <QtOpenVG/private/qwindowsurface_vg_p.h>
-#include <QtOpenVG/private/qvgimagepool_p.h>
-#if defined(Q_OS_SYMBIAN)
-#include <QtGui/private/qwidget_p.h>
-#endif
-#include <QtGui/private/qapplication_p.h>
+#include "qopenwfdglcontext.h"
-QT_BEGIN_NAMESPACE
+#include "qopenwfdwindow.h"
+#include "qopenwfdscreen.h"
-QVGGraphicsSystem::QVGGraphicsSystem()
+QOpenWFDGLContext::QOpenWFDGLContext(QOpenWFDDevice *device)
+ : QPlatformOpenGLContext()
+ , mWfdDevice(device)
{
- QApplicationPrivate::graphics_system_name = QLatin1String("openvg");
}
-QPixmapData *QVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
+QSurfaceFormat QOpenWFDGLContext::format() const
{
-#if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QVG_NO_PIXMAP_DATA)
- // Pixmaps can use QVGPixmapData; bitmaps must use raster.
- if (type == QPixmapData::PixmapType)
- return new QVGPixmapData(type);
- else
- return new QRasterPixmapData(type);
-#else
- return new QRasterPixmapData(type);
-#endif
+ return QSurfaceFormat();
}
-QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const
+bool QOpenWFDGLContext::makeCurrent(QPlatformSurface *surface)
{
-#if defined(Q_OS_SYMBIAN)
- if (!QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
- QWidgetPrivate *d = qt_widget_private(widget);
- if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground))
- return d->createDefaultWindowSurface_sys();
+ EGLDisplay display = mWfdDevice->eglDisplay();
+ EGLContext context = mWfdDevice->eglContext();
+ if (!eglMakeCurrent(display,EGL_NO_SURFACE,EGL_NO_SURFACE,context)) {
+ qDebug() << "GLContext: eglMakeCurrent FAILED!";
}
-#endif
- return new QVGWindowSurface(widget);
+
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QOpenWFDScreen *screen = static_cast<QOpenWFDScreen *>(QPlatformScreen::platformScreenForWindow(window->window()));
+ screen->bindFramebuffer();
+ return true;
}
-void QVGGraphicsSystem::releaseCachedResources()
+void QOpenWFDGLContext::doneCurrent()
{
- QVGImagePool::instance()->hibernate();
+ //do nothing :)
}
-QT_END_NAMESPACE
+void QOpenWFDGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ glFlush();
+
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QOpenWFDScreen *screen = static_cast<QOpenWFDScreen *>(QPlatformScreen::platformScreenForWindow(window->window()));
+
+ screen->swapBuffers();
+}
+
+void (*QOpenWFDGLContext::getProcAddress(const QByteArray &procName)) ()
+{
+ return eglGetProcAddress(procName.data());
+}
+
+EGLContext QOpenWFDGLContext::eglContext() const
+{
+ return mWfdDevice->eglContext();
+}
+
+
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h b/src/plugins/platforms/openwfd/qopenwfdglcontext.h
index bdb1d42d7e..3287a853c7 100644
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h
+++ b/src/plugins/platforms/openwfd/qopenwfdglcontext.h
@@ -39,25 +39,30 @@
**
****************************************************************************/
-#ifndef EGLNULLWSWINDOWSURFACE_H
-#define EGLNULLWSWINDOWSURFACE_H
+#ifndef QOPENWFDGLCONTEXT_H
+#define QOPENWFDGLCONTEXT_H
-#include <private/qglwindowsurface_qws_p.h>
+#include <QtGui/QPlatformOpenGLContext>
-class EGLNullWSWindowSurface : public QWSGLWindowSurface
+#include "qopenwfddevice.h"
+
+class QOpenWFDGLContext : public QPlatformOpenGLContext
{
public:
- EGLNullWSWindowSurface(QWidget *widget);
- EGLNullWSWindowSurface();
- virtual ~EGLNullWSWindowSurface();
+ QOpenWFDGLContext(QOpenWFDDevice *device);
+
+ QSurfaceFormat format() const;
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+
+ void swapBuffers(QPlatformSurface *surface);
- virtual QString key() const;
- virtual QPaintDevice *paintDevice();
- virtual bool isValid() const;
- virtual QImage image() const;
+ void (*getProcAddress(const QByteArray &procName)) ();
+ EGLContext eglContext() const;
private:
- QWidget *widget;
+ QOpenWFDDevice *mWfdDevice;
};
-#endif // EGLNULLWSWINDOWSURFACE_H
+#endif // QOPENWFDGLCONTEXT_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdintegration.cpp b/src/plugins/platforms/openwfd/qopenwfdintegration.cpp
new file mode 100644
index 0000000000..3d57759183
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdintegration.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdintegration.h"
+#include "qopenwfdscreen.h"
+#include "qopenwfdnativeinterface.h"
+#include "qopenwfddevice.h"
+#include "qopenwfdwindow.h"
+#include "qopenwfdglcontext.h"
+#include "qopenwfdbackingstore.h"
+
+#include <QtPlatformSupport/private/qgenericunixprintersupport_p.h>
+
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
+
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+
+#include <stdio.h>
+
+#include <WF/wfd.h>
+
+QOpenWFDIntegration::QOpenWFDIntegration()
+ : QPlatformIntegration()
+ , mPrinterSupport(new QGenericUnixPrinterSupport)
+ , mEventDispatcher(createUnixEventDispatcher())
+{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
+ int numberOfDevices = wfdEnumerateDevices(0,0,0);
+
+ WFDint devices[numberOfDevices];
+ int actualNumberOfDevices = wfdEnumerateDevices(devices,numberOfDevices,0);
+ Q_ASSERT(actualNumberOfDevices == numberOfDevices);
+
+ for (int i = 0; i < actualNumberOfDevices; i++) {
+ mDevices.append(new QOpenWFDDevice(this,devices[i]));
+ }
+
+ mFontDatabase = new QGenericUnixFontDatabase();
+ mNativeInterface = new QOpenWFDNativeInterface;
+}
+
+QOpenWFDIntegration::~QOpenWFDIntegration()
+{
+ //dont delete screens since they are deleted by the devices
+ qDebug() << "deleting platform integration";
+ for (int i = 0; i < mDevices.size(); i++) {
+ delete mDevices[i];
+ }
+
+ delete mFontDatabase;
+ delete mNativeInterface;
+ delete mPrinterSupport;
+}
+
+bool QOpenWFDIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformWindow *QOpenWFDIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QOpenWFDWindow(window);
+}
+
+QPlatformOpenGLContext *QOpenWFDIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ QOpenWFDScreen *screen = static_cast<QOpenWFDScreen *>(context->screen()->handle());
+
+ return new QOpenWFDGLContext(screen->port()->device());
+}
+
+QPlatformBackingStore *QOpenWFDIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QOpenWFDBackingStore(window);
+}
+
+QAbstractEventDispatcher *QOpenWFDIntegration::guiThreadEventDispatcher() const
+{
+ return mEventDispatcher;
+}
+
+QPlatformFontDatabase *QOpenWFDIntegration::fontDatabase() const
+{
+ return mFontDatabase;
+}
+
+QPlatformNativeInterface * QOpenWFDIntegration::nativeInterface() const
+{
+ return mNativeInterface;
+}
+
+QPlatformPrinterSupport * QOpenWFDIntegration::printerSupport() const
+{
+ return mPrinterSupport;
+}
+
+void QOpenWFDIntegration::addScreen(QOpenWFDScreen *screen)
+{
+ screenAdded(screen);
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdintegration.h b/src/plugins/platforms/openwfd/qopenwfdintegration.h
new file mode 100644
index 0000000000..b5315b31da
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdintegration.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDINTEGRATION_H
+#define QOPENWFDINTEGRATION_H
+
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenWFDDevice;
+class QOpenWFDScreen;
+
+class QOpenWFDIntegration : public QPlatformIntegration
+{
+public:
+ QOpenWFDIntegration();
+ ~QOpenWFDIntegration();
+
+ bool hasCapability(Capability cap) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+
+ //This should not be a factory interface, but rather a accessor
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+ QPlatformNativeInterface *nativeInterface()const;
+
+ QPlatformPrinterSupport *printerSupport() const;
+
+ void addScreen(QOpenWFDScreen *screen);
+private:
+ QList<QPlatformScreen *> mScreens;
+ QList<QOpenWFDDevice *>mDevices;
+
+ QPlatformFontDatabase *mFontDatabase;
+ QPlatformNativeInterface *mNativeInterface;
+ QPlatformPrinterSupport *mPrinterSupport;
+ QAbstractEventDispatcher *mEventDispatcher;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/openwfd/qopenwfdnativeinterface.cpp b/src/plugins/platforms/openwfd/qopenwfdnativeinterface.cpp
new file mode 100644
index 0000000000..758e0c4398
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdnativeinterface.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdnativeinterface.h"
+
+#include "qopenwfdscreen.h"
+#include "qopenwfdwindow.h"
+#include "qopenwfdglcontext.h"
+
+#include <private/qguiapplication_p.h>
+#include <QtCore/QMap>
+
+#include <QtCore/QDebug>
+
+#include <QtGui/qguiglcontext_qpa.h>
+
+class QOpenWFDResourceMap : public QMap<QByteArray, QOpenWFDNativeInterface::ResourceType>
+{
+public:
+ QOpenWFDResourceMap()
+ :QMap<QByteArray, QOpenWFDNativeInterface::ResourceType>()
+ {
+ insert("wfddevice",QOpenWFDNativeInterface::WFDDevice);
+ insert("egldisplay",QOpenWFDNativeInterface::EglDisplay);
+ insert("eglcontext",QOpenWFDNativeInterface::EglContext);
+ insert("wfdport",QOpenWFDNativeInterface::WFDPort);
+ insert("wfdpipeline",QOpenWFDNativeInterface::WFDPipeline);
+ }
+};
+
+Q_GLOBAL_STATIC(QOpenWFDResourceMap, qOpenWFDResourceMap)
+
+void *QOpenWFDNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qOpenWFDResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch (resource) {
+ case EglContext:
+ result = eglContextForContext(context);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+void *QOpenWFDNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qOpenWFDResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch (resource) {
+ //What should we do for int wfd handles? This is clearly not the solution
+ case WFDDevice:
+ result = (void *)wfdDeviceForWindow(window);
+ break;
+ case WFDPort:
+ result = (void *)wfdPortForWindow(window);
+ break;
+ case WFDPipeline:
+ result = (void *)wfdPipelineForWindow(window);
+ break;
+ case EglDisplay:
+ result = eglDisplayForWindow(window);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+WFDHandle QOpenWFDNativeInterface::wfdDeviceForWindow(QWindow *window)
+{
+ QOpenWFDWindow *openWFDwindow = static_cast<QOpenWFDWindow *>(window->handle());
+ return openWFDwindow->port()->device()->handle();
+}
+
+WFDHandle QOpenWFDNativeInterface::wfdPortForWindow(QWindow *window)
+{
+ QOpenWFDWindow *openWFDwindow = static_cast<QOpenWFDWindow *>(window->handle());
+ return openWFDwindow->port()->handle();
+}
+
+WFDHandle QOpenWFDNativeInterface::wfdPipelineForWindow(QWindow *window)
+
+{
+ QOpenWFDWindow *openWFDwindow = static_cast<QOpenWFDWindow *>(window->handle());
+ return openWFDwindow->port()->pipeline();
+
+}
+
+void *QOpenWFDNativeInterface::eglDisplayForWindow(QWindow *window)
+{
+ QOpenWFDWindow *openWFDwindow = static_cast<QOpenWFDWindow *>(window->handle());
+ return openWFDwindow->port()->device()->eglDisplay();
+}
+
+void * QOpenWFDNativeInterface::eglContextForContext(QOpenGLContext *context)
+{
+ QOpenWFDGLContext *openWFDContext = static_cast<QOpenWFDGLContext *>(context->handle());
+ return openWFDContext->eglContext();
+}
diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h b/src/plugins/platforms/openwfd/qopenwfdnativeinterface.h
index b6cfc60293..cff49dc8b0 100644
--- a/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h
+++ b/src/plugins/platforms/openwfd/qopenwfdnativeinterface.h
@@ -39,33 +39,38 @@
**
****************************************************************************/
-#ifndef QGRAPHICSSYSTEM_TRACE_P_H
-#define QGRAPHICSSYSTEM_TRACE_P_H
+#ifndef QOPENWFDNATIVEINTERFACE_H
+#define QOPENWFDNATIVEINTERFACE_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
+#include <QtGui/QPlatformNativeInterface>
-#include <QtGui/private/qgraphicssystem_p.h>
+#include <WF/wfdplatform.h>
-QT_BEGIN_NAMESPACE
+class QOpenWFDScreen;
-class QTraceGraphicsSystem : public QGraphicsSystem
+class QOpenWFDNativeInterface : public QPlatformNativeInterface
{
public:
- QTraceGraphicsSystem();
+ enum ResourceType {
+ WFDDevice,
+ EglDisplay,
+ EglContext,
+ WFDPort,
+ WFDPipeline
+ };
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-};
+ void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
+
+ WFDHandle wfdDeviceForWindow(QWindow *window);
+ void *eglDisplayForWindow(QWindow *window);
+ WFDHandle wfdPortForWindow(QWindow *window);
+ WFDHandle wfdPipelineForWindow(QWindow *window);
-QT_END_NAMESPACE
+ void *eglContextForContext(QOpenGLContext *context);
+
+private:
+ static QOpenWFDScreen *qPlatformScreenForWindow(QWindow *window);
+};
-#endif
+#endif // QOPENWFDNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h b/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.cpp
index 8bf542a215..fb3292c31a 100644
--- a/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
+++ b/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.cpp
@@ -39,15 +39,52 @@
**
****************************************************************************/
-#ifndef QGENERICUNIXFONTDATABASE_H
-#define QGENERICUNIXFONTDATABASE_H
-
-#ifdef Q_FONTCONFIGDATABASE
-#include "qfontconfigdatabase.h"
-typedef QFontconfigDatabase QGenericUnixFontDatabase;
-#else
-#include "qbasicunixfontdatabase.h"
-typedef QBasicUnixFontDatabase QGenericUnixFontDatabase;
-#endif //Q_FONTCONFIGDATABASE
-
-#endif // QGENERICUNIXFONTDATABASE_H
+#include "qopenwfdoutputbuffer.h"
+
+#include "qopenwfdport.h"
+
+QOpenWFDOutputBuffer::QOpenWFDOutputBuffer(const QSize &size, QOpenWFDPort *port)
+ : mPort(port)
+ , mAvailable(true)
+{
+ qDebug() << "creating output buffer for size" << size;
+ glGenRenderbuffers(1,&mRbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, mRbo);
+
+ mGbm_buffer = gbm_bo_create(port->device()->gbmDevice(),
+ size.width(),
+ size.height(),
+ GBM_BO_FORMAT_XRGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+
+ mEglImage = port->device()->eglCreateImage(port->device()->eglDisplay(),0, EGL_NATIVE_PIXMAP_KHR, mGbm_buffer, 0);
+
+ port->device()->glEglImageTargetRenderBufferStorage(GL_RENDERBUFFER,mEglImage);
+
+ mWfdSource = wfdCreateSourceFromImage(port->device()->handle(),port->pipeline(),mEglImage,WFD_NONE);
+ if (mWfdSource == WFD_INVALID_HANDLE) {
+ qWarning("failed to create wfdSource from image");
+ }
+}
+
+QOpenWFDOutputBuffer::~QOpenWFDOutputBuffer()
+{
+ wfdDestroySource(mPort->device()->handle(),mWfdSource);
+ if (!mPort->device()->eglDestroyImage(mPort->device()->eglDisplay(),mEglImage)) {
+ qDebug() << "could not delete eglImage";
+ }
+ gbm_bo_destroy(mGbm_buffer);
+
+ glDeleteRenderbuffers(1, &mRbo);
+}
+
+void QOpenWFDOutputBuffer::bindToCurrentFbo()
+{
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ mRbo);
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ qDebug() << "framebuffer not ready!";
+ }
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.h b/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.h
new file mode 100644
index 0000000000..1697f076a9
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDOUTPUTBUFFER_H
+#define QOPENWFDOUTPUTBUFFER_H
+
+#include "qopenwfdport.h"
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+
+class QOpenWFDOutputBuffer
+{
+public:
+ QOpenWFDOutputBuffer(const QSize &size, QOpenWFDPort *port);
+ ~QOpenWFDOutputBuffer();
+ void bindToCurrentFbo();
+ bool isAvailable() const { return mAvailable; }
+ void setAvailable(bool available) { mAvailable = available; }
+
+ WFDSource wfdSource() const { return mWfdSource; }
+private:
+ QOpenWFDPort *mPort;
+ WFDSource mWfdSource;
+ GLuint mRbo;
+ EGLImageKHR mEglImage;
+ struct gbm_bo *mGbm_buffer;
+ bool mAvailable;
+};
+
+#endif // QOPENWFDOUTPUTBUFFER_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdport.cpp b/src/plugins/platforms/openwfd/qopenwfdport.cpp
new file mode 100644
index 0000000000..5f38e48eed
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdport.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdport.h"
+
+#include "qopenwfdportmode.h"
+#include "qopenwfdscreen.h"
+
+#include <QtCore/QDebug>
+
+QOpenWFDPort::QOpenWFDPort(QOpenWFDDevice *device, WFDint portEnumeration)
+ : mDevice(device)
+ , mPortId(portEnumeration)
+ , mAttached(false)
+ , mPipelineId(WFD_INVALID_PIPELINE_ID)
+ , mPipeline(WFD_INVALID_HANDLE)
+{
+ mPort = wfdCreatePort(device->handle(),portEnumeration,0);
+ WFDint isPortAttached = wfdGetPortAttribi(device->handle(),mPort,WFD_PORT_ATTACHED);
+ if (isPortAttached) {
+ attach();
+ }
+}
+
+QOpenWFDPort::~QOpenWFDPort()
+{
+ detach();
+
+ wfdDestroyPort(mDevice->handle(),mPort);
+}
+
+void QOpenWFDPort::attach()
+{
+ if (mAttached) {
+ return;
+ }
+
+ //just forcing port to be on
+ wfdSetPortAttribi(mDevice->handle(), mPort, WFD_PORT_POWER_MODE, WFD_POWER_MODE_ON);
+
+ int numberOfPortModes = wfdGetPortModes(mDevice->handle(),mPort,0,0);
+ WFDPortMode portModes[numberOfPortModes];
+ int actualNumberOfPortModes = wfdGetPortModes(mDevice->handle(),mPort,portModes,numberOfPortModes);
+ Q_ASSERT(actualNumberOfPortModes == numberOfPortModes);
+
+ if (!actualNumberOfPortModes) {
+ qDebug() << "didn't find any available port modes";
+ return;
+ }
+
+ for (int i = 0; i < actualNumberOfPortModes; i++) {
+ if (portModes[i] != WFD_INVALID_HANDLE) {
+ mPortModes.append(QOpenWFDPortMode(this,portModes[i]));
+ qDebug() << "PortModeAdded:" << mPortModes.at(mPortModes.size()-1);
+ }
+ }
+
+
+ mPixelSize = setNativeResolutionMode();
+ if (mPixelSize.isEmpty()) {
+ qDebug() << "Could not set native resolution mode in QOpenWFPort";
+ }
+
+ WFDfloat physicalWFDSize[2];
+ wfdGetPortAttribfv(mDevice->handle(),mPort,WFD_PORT_PHYSICAL_SIZE,2,physicalWFDSize);
+ mPhysicalSize = QSizeF(physicalWFDSize[0],physicalWFDSize[1]);
+
+ WFDint numAvailablePipelines = wfdGetPortAttribi(mDevice->handle(),mPort,WFD_PORT_PIPELINE_ID_COUNT);
+ if (!numAvailablePipelines) {
+ qFatal("Not possible to make screen that is not possible to create WFPort with no pipline");
+ }
+
+ WFDint pipeIds[numAvailablePipelines];
+ wfdGetPortAttribiv(mDevice->handle(),mPort,WFD_PORT_BINDABLE_PIPELINE_IDS,numAvailablePipelines,pipeIds);
+
+ for (int i = 0; i < numAvailablePipelines; i++) {
+ if (pipeIds[i] != WFD_INVALID_PIPELINE_ID && !mDevice->isPipelineUsed(pipeIds[i])) {
+ mPipelineId = pipeIds[i];
+ mDevice-> addToUsedPipelineSet(mPipelineId,this);
+
+ mPipeline = wfdCreatePipeline(mDevice->handle(),mPipelineId,WFD_NONE);
+ if (mPipeline == WFD_INVALID_HANDLE) {
+ qFatal("Failed to create pipeline for port %p", this);
+ }
+ break;
+ }
+ }
+
+ if (mPipeline == WFD_INVALID_HANDLE) {
+ qWarning("Failed to create pipeline and cant bind it to port");
+ }
+
+ WFDint geomerty[] = { 0, 0, mPixelSize.width(), mPixelSize.height() };
+
+ wfdSetPipelineAttribiv(mDevice->handle(),mPipeline, WFD_PIPELINE_SOURCE_RECTANGLE, 4, geomerty);
+ wfdSetPipelineAttribiv(mDevice->handle(),mPipeline, WFD_PIPELINE_DESTINATION_RECTANGLE, 4, geomerty);
+
+ wfdBindPipelineToPort(mDevice->handle(),mPort,mPipeline);
+
+ mScreen = new QOpenWFDScreen(this);
+ mDevice->integration()->addScreen(mScreen);
+ mAttached = true;
+}
+
+void QOpenWFDPort::detach()
+{
+ if (!mAttached)
+ return;
+
+ mAttached = false;
+ mOn = false;
+
+ delete mScreen;
+
+ wfdDestroyPipeline(mDevice->handle(),mPipeline);
+ mPipelineId = WFD_INVALID_PIPELINE_ID;
+ mPipeline = WFD_INVALID_HANDLE;
+}
+
+bool QOpenWFDPort::attached() const
+{
+ return mAttached;
+}
+
+QSize QOpenWFDPort::setNativeResolutionMode()
+{
+ WFDint nativePixelSize[2];
+ wfdGetPortAttribiv(device()->handle(),mPort,WFD_PORT_NATIVE_RESOLUTION,2,nativePixelSize);
+ QSize nativeSize(nativePixelSize[0],nativePixelSize[1]);
+
+ for (int i = 0; i < mPortModes.size(); i++) {
+ const QOpenWFDPortMode &mode = mPortModes.at(i);
+ if (nativeSize == mode.size()) {
+ wfdSetPortMode(device()->handle(),mPort,mode.handle());
+ return nativeSize;
+ }
+ }
+ return QSize();
+}
+
+QSize QOpenWFDPort::pixelSize() const
+{
+ return mPixelSize;
+}
+
+QSizeF QOpenWFDPort::physicalSize() const
+{
+ return mPhysicalSize;
+}
+
+QOpenWFDDevice * QOpenWFDPort::device() const
+{
+ return mDevice;
+}
+
+WFDPort QOpenWFDPort::handle() const
+{
+ return mPort;
+}
+
+WFDint QOpenWFDPort::portId() const
+{
+ return mPortId;
+}
+
+WFDPipeline QOpenWFDPort::pipeline() const
+{
+ return mPipeline;
+}
+
+QOpenWFDScreen * QOpenWFDPort::screen() const
+{
+ return mScreen;
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdport.h b/src/plugins/platforms/openwfd/qopenwfdport.h
new file mode 100644
index 0000000000..497c43749e
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdport.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDPORT_H
+#define QOPENWFDPORT_H
+
+#include "qopenwfddevice.h"
+#include "qopenwfdportmode.h"
+
+#include <WF/wfd.h>
+
+class QOpenWFDPort
+{
+public:
+ QOpenWFDPort(QOpenWFDDevice *device, WFDint portEnumeration);
+ ~QOpenWFDPort();
+ void attach();
+ void detach();
+ bool attached() const;
+
+ QSize setNativeResolutionMode();
+
+ QSize pixelSize() const;
+ QSizeF physicalSize() const;
+
+ QOpenWFDDevice *device() const;
+ WFDPort handle() const;
+ WFDint portId() const;
+ WFDPipeline pipeline() const;
+ QOpenWFDScreen *screen() const;
+
+private:
+ QOpenWFDDevice *mDevice;
+ WFDPort mPort;
+ WFDint mPortId;
+
+ QList<QOpenWFDPortMode> mPortModes;
+
+ bool mAttached;
+ bool mOn;
+ QSize mPixelSize;
+ QSizeF mPhysicalSize;
+
+ QOpenWFDScreen *mScreen;
+
+ WFDint mPipelineId;
+ WFDPipeline mPipeline;
+
+};
+
+#endif // QOPENWFDPORT_H
diff --git a/src/plugins/gfxdrivers/ahi/qscreenahiplugin.cpp b/src/plugins/platforms/openwfd/qopenwfdportmode.cpp
index 8cbc0447e5..4e507a42a1 100644
--- a/src/plugins/gfxdrivers/ahi/qscreenahiplugin.cpp
+++ b/src/plugins/platforms/openwfd/qopenwfdportmode.cpp
@@ -39,36 +39,25 @@
**
****************************************************************************/
-#include "qscreenahi_qws.h"
+#include "qopenwfdportmode.h"
-#include <QScreenDriverPlugin>
-#include <QStringList>
+#include "qopenwfdport.h"
-class QAhiScreenPlugin : public QScreenDriverPlugin
+QOpenWFDPortMode::QOpenWFDPortMode(QOpenWFDPort *port, WFDPortMode portMode)
+ : mPortMode(portMode)
{
-public:
- QAhiScreenPlugin();
+ int width = wfdGetPortModeAttribi(port->device()->handle(),port->handle(),portMode,WFD_PORT_MODE_WIDTH);
+ int height = wfdGetPortModeAttribi(port->device()->handle(),port->handle(),portMode,WFD_PORT_MODE_HEIGHT);
+ mSize = QSize(width,height);
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-QAhiScreenPlugin::QAhiScreenPlugin()
- : QScreenDriverPlugin()
-{
+ mRefresh = wfdGetPortModeAttribf(port->device()->handle(),port->handle(),portMode,WFD_PORT_MODE_REFRESH_RATE);
+ mFlipMirror = wfdGetPortModeAttribi(port->device()->handle(),port->handle(),portMode,WFD_PORT_MODE_FLIP_MIRROR_SUPPORT);
+ mInterlaced = wfdGetPortModeAttribi(port->device()->handle(), port->handle(),portMode,WFD_PORT_MODE_INTERLACED);
}
-QStringList QAhiScreenPlugin::keys() const
+QDebug operator<<(QDebug s, const QOpenWFDPortMode &portMode)
{
- return (QStringList() << "ahi");
+ s.nospace() << "QOpenWFPortMode( " << portMode.size() << " Refreash: " << portMode.refreshRate()
+ << " FlipMirror: " << portMode.flipMirror() << " Interlaced: " << portMode.interlaced();
+ return s;
}
-
-QScreen* QAhiScreenPlugin::create(const QString& driver, int displayId)
-{
- if (driver.toLower() != "ahi")
- return 0;
-
- return new QAhiScreen(displayId);
-}
-
-Q_EXPORT_PLUGIN2(qahiscreen, QAhiScreenPlugin)
diff --git a/src/plugins/platforms/openwfd/qopenwfdportmode.h b/src/plugins/platforms/openwfd/qopenwfdportmode.h
new file mode 100644
index 0000000000..dd95339404
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdportmode.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDPORTMODE_H
+#define QOPENWFDPORTMODE_H
+
+#include <WF/wfd.h>
+
+#include <QtCore/QSize>
+
+#include <QtCore/QDebug>
+
+class QOpenWFDPort;
+
+class QOpenWFDPortMode
+{
+public:
+ QOpenWFDPortMode(QOpenWFDPort *port, WFDPortMode portMode);
+
+ QSize size() const {return mSize;}
+ qreal refreshRate() const { return mRefresh; }
+ bool flipMirror() const { return mFlipMirror; }
+ bool interlaced() const { return mInterlaced; }
+
+ WFDPortMode handle() const { return mPortMode; }
+private:
+ WFDPortMode mPortMode;
+
+ QSize mSize;
+ qreal mRefresh;
+ bool mFlipMirror;
+ bool mInterlaced;
+};
+
+QDebug operator<<(QDebug, const QOpenWFDPortMode &);
+#endif // QOPENWFPORTMODE_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdscreen.cpp b/src/plugins/platforms/openwfd/qopenwfdscreen.cpp
new file mode 100644
index 0000000000..785bee9c55
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdscreen.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdscreen.h"
+
+#include "qopenwfdport.h"
+#include "qopenwfdoutputbuffer.h"
+
+#include <QtGui/QGuiApplication>
+
+QOpenWFDScreen::QOpenWFDScreen(QOpenWFDPort *port)
+ : mPort(port)
+ , mFbo(0)
+ , mOutputBuffers(BUFFER_NUM)
+ , mCurrentRenderBufferIndex(0)
+ , mStagedBackBufferIndex(-1)
+ , mCommitedBackBufferIndex(-1)
+ , mBackBufferIndex(-1)
+{
+ printf ("\n");
+ printf ("Information of screen %p:\n", this);
+ printf (" width..........: %d\n", port->pixelSize().width());
+ printf (" height.........: %d\n", port->pixelSize().height());
+ printf (" physical width.: %f\n", port->physicalSize().width());
+ printf (" physical height: %f\n", port->physicalSize().height());
+ printf ("\n");
+
+ EGLDisplay display = mPort->device()->eglDisplay();
+ EGLContext context = mPort->device()->eglContext();
+
+ if (!eglMakeCurrent(display,EGL_NO_SURFACE,EGL_NO_SURFACE,context)) {
+ qDebug() << "screen: eglMakeCurrent FAILED";
+ }
+
+ glGenFramebuffers(1,&mFbo);
+ glBindFramebuffer(GL_FRAMEBUFFER,mFbo);
+
+ for (int i = 0; i < mOutputBuffers.size(); i++) {
+ mOutputBuffers[i] = new QOpenWFDOutputBuffer(mPort->pixelSize(),mPort);
+ }
+
+ mStagedBackBufferIndex = mOutputBuffers.size()-1;
+ mOutputBuffers[mStagedBackBufferIndex]->setAvailable(false);;
+ commitStagedOutputBuffer();
+
+ mOutputBuffers.at(mCurrentRenderBufferIndex)->bindToCurrentFbo();
+
+ if (mPort->device()->isDeviceInitializedAndCommited()) {
+ mPort->device()->commit(WFD_COMMIT_ENTIRE_PORT,mPort->handle());
+ }
+
+}
+
+QOpenWFDScreen::~QOpenWFDScreen()
+{
+ for (int i = 0; i < mOutputBuffers.size(); i++) {
+ delete mOutputBuffers[i];
+ }
+ glDeleteFramebuffers(1, &mFbo);
+}
+
+QRect QOpenWFDScreen::geometry() const
+{
+ return QRect(QPoint(),mPort->pixelSize());
+}
+
+int QOpenWFDScreen::depth() const
+{
+ return 32;
+}
+
+QImage::Format QOpenWFDScreen::format() const
+{
+ return QImage::Format_RGB32;
+}
+
+QSize QOpenWFDScreen::physicalSize() const
+{
+ return mPort->physicalSize().toSize();
+}
+
+QOpenWFDPort * QOpenWFDScreen::port() const
+{
+ return mPort;
+}
+
+void QOpenWFDScreen::swapBuffers()
+{
+ glFlush();
+
+ setStagedBackBuffer(mCurrentRenderBufferIndex);
+ mCurrentRenderBufferIndex = nextAvailableRenderBuffer();
+
+ bindFramebuffer();
+ mOutputBuffers.at(mCurrentRenderBufferIndex)->bindToCurrentFbo();
+}
+
+void QOpenWFDScreen::bindFramebuffer()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER,mFbo);
+}
+
+void QOpenWFDScreen::setStagedBackBuffer(int bufferIndex)
+{
+ if (mStagedBackBufferIndex >= 0) {
+ mOutputBuffers[mStagedBackBufferIndex]->setAvailable(true);
+ }
+
+ mOutputBuffers[bufferIndex]->setAvailable(false);;
+ mStagedBackBufferIndex = bufferIndex;
+
+ if (mCommitedBackBufferIndex < 0) {
+ commitStagedOutputBuffer();
+ }
+}
+
+void QOpenWFDScreen::commitStagedOutputBuffer()
+{
+ Q_ASSERT(mStagedBackBufferIndex >= 0);
+ wfdBindSourceToPipeline(mPort->device()->handle(),
+ mPort->pipeline(),
+ mOutputBuffers.at(mStagedBackBufferIndex)->wfdSource(),
+ WFD_TRANSITION_AT_VSYNC,
+ 0);
+ mPort->device()->commit(WFD_COMMIT_PIPELINE,mPort->pipeline());
+ mCommitedBackBufferIndex = mStagedBackBufferIndex;
+ mStagedBackBufferIndex = -1;
+}
+
+int QOpenWFDScreen::nextAvailableRenderBuffer() const
+{
+ while (true) {
+ for (int i = 0; i < mOutputBuffers.size(); i++) {
+ if (mOutputBuffers.at(i)->isAvailable()) {
+ return i;
+ }
+ }
+ mPort->device()->waitForPipelineBindSourceCompleteEvent();
+ }
+}
+
+void QOpenWFDScreen::pipelineBindSourceComplete()
+{
+ if (mBackBufferIndex >= 0) {
+ mOutputBuffers[mBackBufferIndex]->setAvailable(true);
+ }
+
+ mBackBufferIndex = mCommitedBackBufferIndex;
+ mCommitedBackBufferIndex = -1;
+
+ if (mStagedBackBufferIndex >= 0) {
+ commitStagedOutputBuffer();
+ }
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdscreen.h b/src/plugins/platforms/openwfd/qopenwfdscreen.h
new file mode 100644
index 0000000000..bb23744ac4
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdscreen.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDSCREEN_H
+#define QOPENWFDSCREEN_H
+
+#include <QtGui/QPlatformScreen>
+
+
+#include "qopenwfdoutputbuffer.h"
+
+#include <WF/wfd.h>
+
+#include <QtCore/QVarLengthArray>
+#include <QtCore/QLinkedList>
+
+#define BUFFER_NUM 4
+
+class QOpenWFDPort;
+class QOpenWFDScreen : public QPlatformScreen
+{
+public:
+ QOpenWFDScreen(QOpenWFDPort *port);
+ ~QOpenWFDScreen();
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSize physicalSize() const;
+
+ QOpenWFDPort *port() const;
+
+ void swapBuffers();
+ void bindFramebuffer();
+ void pipelineBindSourceComplete();
+
+private:
+ void setStagedBackBuffer(int bufferIndex);
+ void commitStagedOutputBuffer();
+ int nextAvailableRenderBuffer() const;
+
+ QOpenWFDPort *mPort;
+
+ GLuint mFbo;
+
+ QVarLengthArray<QOpenWFDOutputBuffer *, BUFFER_NUM> mOutputBuffers;
+ int mCurrentRenderBufferIndex;
+ int mStagedBackBufferIndex;
+ int mCommitedBackBufferIndex;
+ int mBackBufferIndex;
+};
+
+#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp b/src/plugins/platforms/openwfd/qopenwfdwindow.cpp
index 3d6545e017..15dc4b11c4 100644
--- a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp
+++ b/src/plugins/platforms/openwfd/qopenwfdwindow.cpp
@@ -39,22 +39,23 @@
**
****************************************************************************/
-#include "qmeegorasterpixmapdata.h"
+#include "qopenwfdwindow.h"
-/* Public */
+#include "qopenwfdscreen.h"
+#include "QtGui/QWindowSystemInterface"
-QMeeGoRasterPixmapData::QMeeGoRasterPixmapData() : QRasterPixmapData(QPixmapData::PixmapType)
+QOpenWFDWindow::QOpenWFDWindow(QWindow *window)
+ : QPlatformWindow(window)
{
-}
-QMeeGoRasterPixmapData::QMeeGoRasterPixmapData(QPixmapData::PixelType t) : QRasterPixmapData(t)
-{
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window);
+ mPort = static_cast<QOpenWFDScreen *>(platformScreen)->port();
+
+ QWindowSystemInterface::handleGeometryChange(window,QRect(QPoint(0,0),mPort->screen()->geometry().size()));
}
-void QMeeGoRasterPixmapData::copy(const QPixmapData *data, const QRect &rect)
+QOpenWFDPort *QOpenWFDWindow::port() const
{
- if (data->classId() == QPixmapData::OpenGLClass)
- fromImage(data->toImage(rect).copy(), Qt::NoOpaqueDetection);
- else
- QRasterPixmapData::copy(data, rect);
+ return mPort;
}
+
diff --git a/src/plugins/platforms/openwfd/qopenwfdwindow.h b/src/plugins/platforms/openwfd/qopenwfdwindow.h
new file mode 100644
index 0000000000..3c97b014b1
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdwindow.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDWINDOW_H
+#define QOPENWFDWINDOW_H
+
+#include <QtGui/QPlatformWindow>
+#include <QtCore/QVarLengthArray>
+
+#include "qopenwfdport.h"
+
+class QOpenWFDWindow : public QPlatformWindow
+{
+public:
+ QOpenWFDWindow(QWindow *window);
+
+ QOpenWFDPort *port() const;
+
+private:
+ QOpenWFDPort *mPort;
+};
+
+#endif // QOPENWFWINDOW_H
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 492569796f..ac001b665b 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -9,3 +9,9 @@ contains(QT_CONFIG, wayland) {
contains(QT_CONFIG, xcb) {
SUBDIRS += xcb
}
+
+mac {
+ SUBDIRS += cocoa
+}
+
+win32: SUBDIRS += windows
diff --git a/src/plugins/platforms/qvfb/qvfb.pro b/src/plugins/platforms/qvfb/qvfb.pro
index 5db8533264..a95b13efc7 100644
--- a/src/plugins/platforms/qvfb/qvfb.pro
+++ b/src/plugins/platforms/qvfb/qvfb.pro
@@ -3,6 +3,7 @@ load(qt_plugin)
DESTDIR = $$QT.gui.plugins/platforms
+QT += core-private gui-private platformsupport-private
SOURCES = main.cpp qvfbintegration.cpp qvfbwindowsurface.cpp
HEADERS = qvfbintegration.h qvfbwindowsurface.h
diff --git a/src/plugins/platforms/qvfb/qvfbintegration.cpp b/src/plugins/platforms/qvfb/qvfbintegration.cpp
index 6b54420402..d4d8183936 100644
--- a/src/plugins/platforms/qvfb/qvfbintegration.cpp
+++ b/src/plugins/platforms/qvfb/qvfbintegration.cpp
@@ -63,6 +63,7 @@
#include <QWindowSystemInterface>
#include "qgenericunixfontdatabase.h"
+#include "qgenericunixeventdispatcher.h"
QT_BEGIN_NAMESPACE
@@ -422,9 +423,9 @@ QVFbIntegration::QVFbIntegration(const QStringList &paramList)
mScreens.append(mPrimaryScreen);
}
-QPixmapData *QVFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QVFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
}
QWindowSurface *QVFbIntegration::createWindowSurface(QWidget *widget, WId) const
@@ -438,6 +439,11 @@ QPlatformWindow *QVFbIntegration::createPlatformWindow(QWidget *widget, WId) con
return new QVFbWindow(mPrimaryScreen, widget);
}
+QAbstractEventDispatcher *QVFbIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
QPlatformFontDatabase *QVFbIntegration::fontDatabase() const
{
return mFontDb;
diff --git a/src/plugins/platforms/qvfb/qvfbintegration.h b/src/plugins/platforms/qvfb/qvfbintegration.h
index ae3ba7bcc3..1c736c24e0 100644
--- a/src/plugins/platforms/qvfb/qvfbintegration.h
+++ b/src/plugins/platforms/qvfb/qvfbintegration.h
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
class QVFbScreenPrivate;
+class QAbstractEventDispatcher;
class QVFbScreen : public QPlatformScreen
{
@@ -78,9 +79,10 @@ class QVFbIntegration : public QPlatformIntegration
public:
QVFbIntegration(const QStringList &paramList);
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+ QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const { return mScreens; }
diff --git a/src/plugins/platforms/uikit/quikitintegration.h b/src/plugins/platforms/uikit/quikitintegration.h
index 92247fdff3..b8a15b3807 100644
--- a/src/plugins/platforms/uikit/quikitintegration.h
+++ b/src/plugins/platforms/uikit/quikitintegration.h
@@ -52,7 +52,7 @@ public:
QUIKitIntegration();
~QUIKitIntegration();
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm
index 737fa40d05..37ba2b9a02 100644
--- a/src/plugins/platforms/uikit/quikitintegration.mm
+++ b/src/plugins/platforms/uikit/quikitintegration.mm
@@ -64,9 +64,9 @@ QUIKitIntegration::~QUIKitIntegration()
{
}
-QPixmapData *QUIKitIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QUIKitIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
}
QPlatformWindow *QUIKitIntegration::createPlatformWindow(QWidget *widget, WId winId) const
diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h
index c482dae3d5..67f0242a48 100644
--- a/src/plugins/platforms/uikit/quikitwindow.h
+++ b/src/plugins/platforms/uikit/quikitwindow.h
@@ -117,7 +117,7 @@ public:
UIWindow *ensureNativeWindow();
- QPlatformGLContext *glContext() const;
+ QPlatformOpenGLContext *glContext() const;
private:
QUIKitScreen *mScreen;
diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm
index 29ca88b75a..cc17dbcbfb 100644
--- a/src/plugins/platforms/uikit/quikitwindow.mm
+++ b/src/plugins/platforms/uikit/quikitwindow.mm
@@ -48,12 +48,12 @@
#include <QtDebug>
#include <QtGui/QApplication>
#include <QtGui/QKeyEvent>
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
#include <QtGui/QWindowSystemInterface>
#include <QtDebug>
-class EAGLPlatformContext : public QPlatformGLContext
+class EAGLPlatformContext : public QPlatformOpenGLContext
{
public:
EAGLPlatformContext(EAGLView *view)
@@ -91,13 +91,13 @@ public:
void makeCurrent()
{
- QPlatformGLContext::makeCurrent();
+ QPlatformOpenGLContext::makeCurrent();
[mView makeCurrent];
}
void doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ QPlatformOpenGLContext::doneCurrent();
}
void swapBuffers()
@@ -381,7 +381,7 @@ UIWindow *QUIKitWindow::ensureNativeWindow()
return mWindow;
}
-QPlatformGLContext *QUIKitWindow::glContext() const
+QPlatformOpenGLContext *QUIKitWindow::glContext() const
{
if (!mContext) {
mContext = new EAGLPlatformContext(mView);
diff --git a/src/plugins/platforms/uikit/uikit.pro b/src/plugins/platforms/uikit/uikit.pro
index 45a48dc92a..5e3a0e6b7c 100644
--- a/src/plugins/platforms/uikit/uikit.pro
+++ b/src/plugins/platforms/uikit/uikit.pro
@@ -1,5 +1,5 @@
TARGET = quikit
-load(qt_plugin)
+load(qpa/plugin)
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
QT += opengl
@@ -22,6 +22,6 @@ HEADERS = quikitsoftwareinputhandler.h
#add libz for freetype.
LIBS += -lz
-#include(../fontdatabases/basicunix/basicunix.pri)
+#load(qpa/fontdatabases/basicunix)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp
index 1e8c6c1bc5..7506bff307 100644
--- a/src/plugins/platforms/vnc/qvncintegration.cpp
+++ b/src/plugins/platforms/vnc/qvncintegration.cpp
@@ -161,9 +161,9 @@ bool QVNCIntegration::hasCapability(QPlatformIntegration::Capability cap) const
}
-QPixmapData *QVNCIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QVNCIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
}
QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget, WId) const
@@ -173,6 +173,10 @@ QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget, WId) const
return surface;
}
+QAbstractEventDispatcher *QVFbIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
QPlatformWindow *QVNCIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
{
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
index 3e13bc3b8d..9787a59f0f 100644
--- a/src/plugins/platforms/vnc/qvncintegration.h
+++ b/src/plugins/platforms/vnc/qvncintegration.h
@@ -74,7 +74,7 @@ private:
};
class QVNCIntegrationPrivate;
-
+class QAbstractEventDispatcher;
class QVNCIntegration : public QPlatformIntegration
{
@@ -82,9 +82,10 @@ public:
QVNCIntegration(const QStringList& paramList);
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+ QAbstractEventDispatcher createEventDispatcher() const;
QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
diff --git a/src/plugins/platforms/vnc/qvncserver.cpp b/src/plugins/platforms/vnc/qvncserver.cpp
index 8b25e054d1..37412b6bd1 100644
--- a/src/plugins/platforms/vnc/qvncserver.cpp
+++ b/src/plugins/platforms/vnc/qvncserver.cpp
@@ -43,7 +43,7 @@
#include <QtCore/qtimer.h>
#include <QtCore/qregexp.h>
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
#include <QtGui/qpolygon.h>
#include <QtGui/qpainter.h>
diff --git a/src/plugins/platforms/vnc/vnc.pro b/src/plugins/platforms/vnc/vnc.pro
index 85bffb0637..321cee4790 100644
--- a/src/plugins/platforms/vnc/vnc.pro
+++ b/src/plugins/platforms/vnc/vnc.pro
@@ -1,7 +1,7 @@
TARGET = qvncgraphicssystem
load(qt_plugin)
-QT += network
+QT += network core-private gui-private platformsupport-private
DESTDIR = $$QT.gui.plugins/platforms
diff --git a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
index d9b5fa9bff..20c3aa0bd9 100644
--- a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
+++ b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
@@ -3,12 +3,10 @@ contains(QT_CONFIG, opengl) {
QT += opengl
HEADERS += \
- $$PWD/qwaylandglintegration.h \
- $$PWD/qwaylandglwindowsurface.h
+ $$PWD/qwaylandglintegration.h
SOURCES += \
- $$PWD/qwaylandglintegration.cpp \
- $$PWD/qwaylandglwindowsurface.cpp
+ $$PWD/qwaylandglintegration.cpp
QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG)
contains(QT_CONFIG, opengles2) {
@@ -22,6 +20,9 @@ SOURCES += \
QT_WAYLAND_GL_INTEGRATION = xcomposite_egl
CONFIG += xcomposite_egl
}
+ } else:mac {
+ QT_WAYLAND_GL_INTEGRATION = readback_cgl
+ CONFIG += readback_cgl
} else {
isEqual(QT_WAYLAND_GL_CONFIG, readback) {
QT_WAYLAND_GL_INTEGRATION = readback_glx
@@ -48,6 +49,10 @@ readback_glx {
include ($$PWD/readback_glx/readback_glx.pri)
}
+readback_cgl {
+ include ($$PWD/readback_cgl/readback_cgl.pri)
+}
+
xcomposite_glx {
include ($$PWD/xcomposite_glx/xcomposite_glx.pri)
}
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
index 4b50b4bd68..4f688e41d8 100644
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
@@ -44,7 +44,10 @@
class QWaylandWindow;
class QWaylandDisplay;
-class QWidget;
+class QWindow;
+
+class QPlatformOpenGLContext;
+class QSurfaceFormat;
class QWaylandGLIntegration
{
@@ -54,7 +57,8 @@ public:
virtual void initialize() = 0;
- virtual QWaylandWindow *createEglWindow(QWidget *widget) = 0;
+ virtual QWaylandWindow *createEglWindow(QWindow *window) = 0;
+ virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0;
static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay);
};
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
deleted file mode 100644
index fef07e6bf7..0000000000
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwaylandglwindowsurface.h"
-
-#include "qwaylanddisplay.h"
-#include "qwaylandwindow.h"
-#include "qwaylandscreen.h"
-
-#include <QtOpenGL/QGLFramebufferObject>
-#include <QtOpenGL/QGLContext>
-
-#include <QtOpenGL/private/qglengineshadermanager_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br)
-{
-#if !defined(QT_OPENGL_ES_2)
- QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
-#endif
- const GLenum target = GL_TEXTURE_2D;
- QRectF src = br.isEmpty()
- ? QRectF(QPointF(), texSize)
- : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size());
-
- if (target == GL_TEXTURE_2D) {
- qreal width = texSize.width();
- qreal height = texSize.height();
-
- src.setLeft(src.left() / width);
- src.setRight(src.right() / width);
- src.setTop(src.top() / height);
- src.setBottom(src.bottom() / height);
- }
-
- const GLfloat tx1 = src.left();
- const GLfloat tx2 = src.right();
- const GLfloat ty1 = src.top();
- const GLfloat ty2 = src.bottom();
-
- GLfloat texCoordArray[4*2] = {
- tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1
- };
-
- GLfloat vertexArray[4*2];
- vertexArray[0] = rect.left(); vertexArray[1] = rect.top();
- vertexArray[2] = rect.right(); vertexArray[3] = rect.top();
- vertexArray[4] = rect.right(); vertexArray[5] = rect.bottom();
- vertexArray[6] = rect.left(); vertexArray[7] = rect.bottom();
-
- glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray);
- glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray);
-
- glBindTexture(target, tex_id);
-
- glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
-
- glBindTexture(target, 0);
-}
-
-static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect)
-{
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
- glViewport(0, 0, viewport.width(), viewport.height());
-
- QGLShaderProgram *blitProgram =
- QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram();
- blitProgram->bind();
- blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/);
-
- // The shader manager's blit program does not multiply the
- // vertices by the pmv matrix, so we need to do the effect
- // of the orthographic projection here ourselves.
- QRectF r;
- qreal w = viewport.width();
- qreal h = viewport.height();
- r.setLeft((targetRect.left() / w) * 2.0f - 1.0f);
- if (targetRect.right() == (viewport.width() - 1))
- r.setRight(1.0f);
- else
- r.setRight((targetRect.right() / w) * 2.0f - 1.0f);
- r.setBottom((targetRect.top() / h) * 2.0f - 1.0f);
- if (targetRect.bottom() == (viewport.height() - 1))
- r.setTop(1.0f);
- else
- r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f);
-
- drawTexture(r, texture, texSize, sourceRect);
-}
-
-QWaylandGLWindowSurface::QWaylandGLWindowSurface(QWidget *window)
- : QWindowSurface(window)
- , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
- , mPaintDevice(0)
-{
-
-}
-
-QWaylandGLWindowSurface::~QWaylandGLWindowSurface()
-{
- delete mPaintDevice;
-}
-
-QPaintDevice *QWaylandGLWindowSurface::paintDevice()
-{
- return mPaintDevice;
-}
-
-void QWaylandGLWindowSurface::beginPaint(const QRegion &)
-{
- window()->platformWindow()->glContext()->makeCurrent();
- glClearColor(0,0,0,0xff);
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
-void QWaylandGLWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(offset);
- Q_UNUSED(region);
- QWaylandWindow *ww = (QWaylandWindow *) widget->platformWindow();
-
- if (mPaintDevice->isBound())
- mPaintDevice->release();
-
- QRect rect(0,0,size().width(),size().height());
- QGLContext *ctx = QGLContext::fromPlatformGLContext(ww->glContext());
- blitTexture(ctx,mPaintDevice->texture(),size(),mPaintDevice->size(),rect,rect);
- ww->glContext()->swapBuffers();
-}
-
-void QWaylandGLWindowSurface::resize(const QSize &size)
-{
- QWindowSurface::resize(size);
- window()->platformWindow()->glContext()->makeCurrent();
- delete mPaintDevice;
- mPaintDevice = new QGLFramebufferObject(size,QGLFramebufferObject::CombinedDepthStencil);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp
new file mode 100644
index 0000000000..5f7663ef55
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackcglcontext.h"
+
+#include "qwaylandshmbackingstore.h"
+#include "qwaylandreadbackcglwindow.h"
+
+#include <QtGui/QOpenGLContext>
+#include <QtCore/QDebug>
+
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/glu.h>
+
+#include <QtPlatformSupport/private/cglconvenience_p.h>
+
+QWaylandReadbackCGLContext::QWaylandReadbackCGLContext(QPlatformOpenGLContext *share)
+ : QPlatformOpenGLContext()
+{
+ Q_UNUSED(share);
+ m_glContext = qcgl_createGlContext();
+}
+
+QSurfaceFormat QWaylandReadbackCGLContext::format() const
+{
+ return qcgl_surfaceFormat();
+}
+
+bool QWaylandReadbackCGLContext::makeCurrent(QPlatformSurface *surface)
+{
+ QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface);
+ CGLSetPBuffer(m_glContext, window->pixelBuffer(), 0, 0, 0);
+ CGLSetCurrentContext(m_glContext);
+ return true;
+}
+
+void QWaylandReadbackCGLContext::doneCurrent()
+{
+ CGLSetCurrentContext(0);
+}
+
+void QWaylandReadbackCGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ Q_UNUSED(surface);
+
+ if (QOpenGLContext::currentContext()->handle() != this) {
+ makeCurrent(surface);
+ }
+ CGLFlushDrawable(m_glContext);
+
+ QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface);
+ QSize size = window->geometry().size();
+
+ uchar *dstBits = const_cast<uchar *>(window->buffer());
+ glReadPixels(0,0, size.width(), size.height(), GL_BGRA,GL_UNSIGNED_BYTE, dstBits);
+
+ window->damage(QRect(QPoint(0,0),size));
+
+ // ### Should sync here but this call deadlocks with the server.
+ //window->waitForFrameSync();
+}
+
+void (*QWaylandReadbackCGLContext::getProcAddress(const QByteArray &procName)) ()
+{
+ return qcgl_getProcAddress(procName);
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h
new file mode 100644
index 0000000000..eb065c3f69
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKCGLCONTEXT_H
+#define QWAYLANDREADBACKCGLCONTEXT_H
+
+#include <QPlatformOpenGLContext>
+
+#include "qwaylandreadbackcglintegration.h"
+
+#include <OpenGL/OpenGL.h>
+
+class QWaylandReadbackCGLWindow;
+class QWaylandShmBuffer;
+
+class QWaylandReadbackCGLContext : public QPlatformOpenGLContext
+{
+public:
+ QWaylandReadbackCGLContext(QPlatformOpenGLContext *share);
+
+ QSurfaceFormat format() const;
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ void swapBuffers(QPlatformSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ void geometryChanged();
+
+private:
+ CGLContextObj m_glContext;
+};
+
+#endif // QWAYLANDREADBACKCGLCONTEXT_H
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp
index e5ac994a05..2878f9e292 100644
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp
@@ -39,46 +39,44 @@
**
****************************************************************************/
-#include "eglnullwswindowsurface.h"
-#include "eglnullwsscreenplugin.h"
+#include "qwaylandreadbackcglintegration.h"
+#include "qwaylandreadbackcglcontext.h"
+#include "qwaylandreadbackcglwindow.h"
-#include <QGLWidget>
+#include <QtCore/QDebug>
-static const QWSWindowSurface::SurfaceFlags Flags
- = QWSWindowSurface::RegionReserved | QWSWindowSurface::RegionReserved;
-
-EGLNullWSWindowSurface::EGLNullWSWindowSurface(QWidget *w)
- :
- QWSGLWindowSurface(w),
- widget(w)
+QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
{
- setSurfaceFlags(Flags);
+ return new QWaylandReadbackCGLIntegration(waylandDisplay);
}
-EGLNullWSWindowSurface::EGLNullWSWindowSurface()
- : widget(0)
+QWaylandReadbackCGLIntegration::QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(waylandDispaly)
{
- setSurfaceFlags(Flags);
+ qDebug() << "Using Readback-CGL";
}
-EGLNullWSWindowSurface::~EGLNullWSWindowSurface() {}
+QWaylandReadbackCGLIntegration::~QWaylandReadbackCGLIntegration()
+{
+
+}
-QString EGLNullWSWindowSurface::key() const
+void QWaylandReadbackCGLIntegration::initialize()
{
- return QLatin1String(PluginName);
}
-QPaintDevice *EGLNullWSWindowSurface::paintDevice()
+QWaylandWindow * QWaylandReadbackCGLIntegration::createEglWindow(QWindow *window)
{
- return widget;
+ return new QWaylandReadbackCGLWindow(window,this);
}
-bool EGLNullWSWindowSurface::isValid() const
+QPlatformOpenGLContext *QWaylandReadbackCGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
{
- return qobject_cast<QGLWidget *>(window());
+ return new QWaylandReadbackCGLContext(share);
}
-QImage EGLNullWSWindowSurface::image() const
+QWaylandDisplay * QWaylandReadbackCGLIntegration::waylandDisplay() const
{
- return QImage();
+ return mWaylandDisplay;
}
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h
index 6f8f8dce66..34c8d00a7c 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h
@@ -39,35 +39,33 @@
**
****************************************************************************/
-#ifndef QGRAPHICSSYSTEM_VG_P_H
-#define QGRAPHICSSYSTEM_VG_P_H
+#ifndef QWAYLANDREADBACKGLXINTEGRATION_H
+#define QWAYLANDREADBACKGLXINTEGRATION_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
+#include "gl_integration/qwaylandglintegration.h"
-#include <QtGui/private/qgraphicssystem_p.h>
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWindow>
-QT_BEGIN_NAMESPACE
+#include <X11/Xlib.h>
-class QVGGraphicsSystem : public QGraphicsSystem
+class QWaylandReadbackCGLIntegration : public QWaylandGLIntegration
{
public:
- QVGGraphicsSystem();
+ QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly);
+ ~QWaylandReadbackCGLIntegration();
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
+ void initialize();
- void releaseCachedResources();
-};
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
+ QWaylandDisplay *waylandDisplay() const;
-QT_END_NAMESPACE
+private:
+ QWaylandDisplay *mWaylandDisplay;
+};
-#endif
+#endif // QWAYLANDREADBACKGLXINTEGRATION_H
diff --git a/src/plugins/graphicssystems/opengl/main.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp
index ee0fa802dd..9e7f8520c9 100644
--- a/src/plugins/graphicssystems/opengl/main.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp
@@ -39,57 +39,68 @@
**
****************************************************************************/
-#include <private/qgraphicssystemplugin_p.h>
-#include <private/qgraphicssystem_gl_p.h>
-#include <qgl.h>
+#include "qwaylandreadbackcglwindow.h"
+#include "qwaylandshmbackingstore.h"
-QT_BEGIN_NAMESPACE
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/glext.h>
-class QGLGraphicsSystemPlugin : public QGraphicsSystemPlugin
+QWaylandReadbackCGLWindow::QWaylandReadbackCGLWindow(QWindow *window, QWaylandReadbackCGLIntegration *cglIntegration)
+ : QWaylandShmWindow(window)
+ , m_CglIntegration(cglIntegration)
+ , mContext(0)
+ , m_buffer(0)
+ , m_pixelBuffer(0)
{
-public:
- QStringList keys() const;
- QGraphicsSystem *create(const QString&);
-};
+}
-QStringList QGLGraphicsSystemPlugin::keys() const
+QWaylandWindow::WindowType QWaylandReadbackCGLWindow::windowType() const
{
- QStringList list;
- list << QLatin1String("OpenGL") << QLatin1String("OpenGL1");
-#if !defined(QT_OPENGL_ES_1)
- list << QLatin1String("OpenGL2");
-#endif
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- list << QLatin1String("X11GL");
-#endif
- return list;
+ //yeah. this type needs a new name
+ return QWaylandWindow::Egl;
}
-QGraphicsSystem* QGLGraphicsSystemPlugin::create(const QString& system)
+
+void QWaylandReadbackCGLWindow::setGeometry(const QRect &rect)
{
- if (system.toLower() == QLatin1String("opengl1")) {
- QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
- return new QGLGraphicsSystem(false);
- }
+ QWaylandShmWindow::setGeometry(rect);
+
+ if (m_buffer) {
+ delete m_buffer;
+ m_buffer = 0;
-#if !defined(QT_OPENGL_ES_1)
- if (system.toLower() == QLatin1String("opengl2")) {
- QGL::setPreferredPaintEngine(QPaintEngine::OpenGL2);
- return new QGLGraphicsSystem(false);
+ CGLDestroyPBuffer(m_pixelBuffer);
+ m_pixelBuffer = 0;
}
-#endif
+}
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- if (system.toLower() == QLatin1String("x11gl"))
- return new QGLGraphicsSystem(true);
-#endif
+CGLPBufferObj QWaylandReadbackCGLWindow::pixelBuffer()
+{
+ if (!m_pixelBuffer)
+ createSurface();
- if (system.toLower() == QLatin1String("opengl"))
- return new QGLGraphicsSystem(false);
+ return m_pixelBuffer;
+}
- return 0;
+uchar *QWaylandReadbackCGLWindow::buffer()
+{
+ return m_buffer->image()->bits();
}
-Q_EXPORT_PLUGIN2(opengl, QGLGraphicsSystemPlugin)
+void QWaylandReadbackCGLWindow::createSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
+
+ waitForFrameSync();
+
+ CGLCreatePBuffer(size.width(), size.height(), GL_TEXTURE_RECTANGLE_ARB, GL_BGRA, 0, &m_pixelBuffer);
+
+ delete m_buffer;
+ m_buffer = new QWaylandShmBuffer(m_CglIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
+ attach(m_buffer);
+}
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h
index a9de7f5239..0598cf9037 100644
--- a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h
@@ -39,38 +39,32 @@
**
****************************************************************************/
-#ifndef SHIVAVGWINDOWSURFACE_H
-#define SHIVAVGWINDOWSURFACE_H
+#ifndef QWAYLANDREADBACKGLXWINDOW_H
+#define QWAYLANDREADBACKGLXWINDOW_H
-#include <QtGui/private/qwindowsurface_p.h>
+#include "qwaylandshmwindow.h"
+#include "qwaylandreadbackcglintegration.h"
+#include "qwaylandreadbackcglcontext.h"
-QT_BEGIN_NAMESPACE
+#include <OpenGL/OpenGL.h>
-class ShivaVGWindowSurfacePrivate;
-
-class ShivaVGWindowSurface : public QWindowSurface, public QPaintDevice
+class QWaylandReadbackCGLWindow : public QWaylandShmWindow
{
public:
- ShivaVGWindowSurface(QWidget *window);
- virtual ~ShivaVGWindowSurface();
+ QWaylandReadbackCGLWindow(QWindow *window, QWaylandReadbackCGLIntegration *cglIntegration);
+ WindowType windowType() const;
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
-
- void beginPaint(const QRegion &region);
- void endPaint(const QRegion &region);
-
- QPaintEngine *paintEngine() const;
+ CGLPBufferObj pixelBuffer();
+ uchar *buffer();
+private:
+ void createSurface();
-protected:
- int metric(PaintDeviceMetric metric) const;
+ QWaylandReadbackCGLIntegration *m_CglIntegration;
+ QWaylandReadbackCGLContext *mContext;
-private:
- ShivaVGWindowSurfacePrivate *d_ptr;
+ QWaylandShmBuffer *m_buffer;
+ CGLPBufferObj m_pixelBuffer;
};
-QT_END_NAMESPACE
-
-#endif
+#endif // QWAYLANDREADBACKGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri b/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri
new file mode 100644
index 0000000000..91cb90a30c
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri
@@ -0,0 +1,10 @@
+HEADERS += \
+ $$PWD/qwaylandreadbackcglintegration.h \
+ $$PWD/qwaylandreadbackcglwindow.h \
+ $$PWD/qwaylandreadbackcglcontext.h
+
+SOURCES += \
+ $$PWD/qwaylandreadbackcglintegration.cpp \
+ $$PWD/qwaylandreadbackcglwindow.cpp \
+ $$PWD/qwaylandreadbackcglcontext.cpp
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
index f02a10a05b..c03e8a9444 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
@@ -41,14 +41,16 @@
#include "qwaylandreadbackeglcontext.h"
-#include "../../../eglconvenience/qeglconvenience.h"
+#include <QPlatformSupport/eglconvenience/qeglconvenience_p.h>
+
+#include <QtCore/QDebug>
+#include <QtGui/QWindowContext>
#include <QtOpenGL/QGLContext>
#include <QtOpenGL/private/qglextensions_p.h>
#include "qwaylandshmsurface.h"
-#include <QtCore/QDebug>
static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
{
@@ -77,7 +79,7 @@ QWaylandReadbackEglContext::QWaylandReadbackEglContext(QWaylandReadbackEglIntegr
, mWindow(window)
, mBuffer(0)
, mPixmap(0)
- , mConfig(q_configFromQPlatformWindowFormat(eglIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_PIXMAP_BIT))
+ , mConfig(q_configFromQWindowFormat(eglIntegration->eglDisplay(),window->window()->requestedWindowFormat(),true,EGL_PIXMAP_BIT))
, mPixmapSurface(EGL_NO_SURFACE)
{
QVector<EGLint> eglContextAttrs;
@@ -97,8 +99,6 @@ QWaylandReadbackEglContext::~QWaylandReadbackEglContext()
void QWaylandReadbackEglContext::makeCurrent()
{
- QPlatformGLContext::makeCurrent();
-
mWindow->waitForFrameSync();
eglMakeCurrent(mEglIntegration->eglDisplay(),mPixmapSurface,mPixmapSurface,mContext);
@@ -106,7 +106,7 @@ void QWaylandReadbackEglContext::makeCurrent()
void QWaylandReadbackEglContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ QPlatformOpenGLContext::doneCurrent();
eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
}
@@ -114,7 +114,7 @@ void QWaylandReadbackEglContext::swapBuffers()
{
eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface);
- if (QPlatformGLContext::currentContext() != this) {
+ if (QWindowContext::currentContext()->handle() != this) {
makeCurrent();
}
@@ -143,9 +143,9 @@ void * QWaylandReadbackEglContext::getProcAddress(const QString &procName)
return (void *) eglGetProcAddress(procName.toLatin1().data());
}
-QPlatformWindowFormat QWaylandReadbackEglContext::platformWindowFormat() const
+QWindowFormat QWaylandReadbackEglContext::windowFormat() const
{
- return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+ return q_windowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
}
void QWaylandReadbackEglContext::geometryChanged()
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
index f9ab3783dd..75755fbd1a 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
@@ -42,15 +42,14 @@
#ifndef QWAYLANDREADBACKEGLGLCONTEXT_H
#define QWAYLANDREADBACKEGLGLCONTEXT_H
-#include <QPlatformGLContext>
-#include <QtGui/QWidget>
+#include <QPlatformOpenGLContext>
#include "qwaylandreadbackeglintegration.h"
#include "qwaylandreadbackeglwindow.h"
class QWaylandShmBuffer;
-class QWaylandReadbackEglContext : public QPlatformGLContext
+class QWaylandReadbackEglContext : public QPlatformOpenGLContext
{
public:
QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window);
@@ -61,7 +60,7 @@ public:
void swapBuffers();
void* getProcAddress(const QString& procName);
- virtual QPlatformWindowFormat platformWindowFormat() const;
+ virtual QWindowFormat windowFormat() const;
void geometryChanged();
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
index 6bbac603cf..39fa3d589c 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
@@ -81,9 +81,14 @@ void QWaylandReadbackEglIntegration::initialize()
}
}
-QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWidget *widget)
+QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandReadbackEglWindow(widget,this);
+ return new QWaylandReadbackEglWindow(window, this);
+}
+
+QPlatformOpenGLContext *QWaylandReadbackEglWindow::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandReadbackEglContext(glFormat, share, this);
}
EGLDisplay QWaylandReadbackEglIntegration::eglDisplay()
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
index ae1e8e5095..0d6aa55e4e 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
@@ -48,7 +48,8 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtCore/QEvent>
+#include <QtGui/QCursor>
#include <X11/Xlib.h>
@@ -61,7 +62,8 @@ public:
~QWaylandReadbackEglIntegration();
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
Display *xDisplay() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
index 868e32e030..f4bc6379d6 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
@@ -43,7 +43,7 @@
#include "qwaylandreadbackeglcontext.h"
-QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration)
+QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration)
: QWaylandShmWindow(window)
, mEglIntegration(eglIntegration)
, mContext(0)
@@ -57,7 +57,7 @@ QWaylandWindow::WindowType QWaylandReadbackEglWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext *QWaylandReadbackEglWindow::glContext() const
+QPlatformOpenGLContext *QWaylandReadbackEglWindow::glContext() const
{
if (!mContext) {
QWaylandReadbackEglWindow *that = const_cast<QWaylandReadbackEglWindow *>(this);
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
index 1433483923..0852a8ee66 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
@@ -50,11 +50,11 @@ class QWaylandReadbackEglContext;
class QWaylandReadbackEglWindow : public QWaylandShmWindow
{
public:
- QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration);
+ QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QPlatformOpenGLContext *glContext() const;
void setGeometry(const QRect &rect);
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
index 0d8e01b6bb..3325fe8ec9 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
@@ -1,14 +1,12 @@
-
LIBS += -lX11 -lXext -lEGL
+load(qpa/egl/convenience)
HEADERS += \
$$PWD/qwaylandreadbackeglintegration.h \
$$PWD/qwaylandreadbackeglcontext.h \
$$PWD/qwaylandreadbackeglwindow.h \
- $$PWD/../../../eglconvenience/qeglconvenience.h
SOURCES += \
$$PWD/qwaylandreadbackeglintegration.cpp \
$$PWD/qwaylandreadbackeglwindow.cpp \
$$PWD/qwaylandreadbackeglcontext.cpp \
- $$PWD/../../../eglconvenience/qeglconvenience.cpp
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
index 857c1db6e3..850e7bb0ac 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
@@ -41,9 +41,10 @@
#include "qwaylandreadbackglxcontext.h"
-#include "qwaylandshmsurface.h"
+#include "qwaylandshmbackingstore.h"
#include "qwaylandreadbackglxwindow.h"
+#include <QtGui/QOpenGLContext>
#include <QtCore/QDebug>
static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
@@ -68,96 +69,66 @@ static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
}
}
-QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window)
- : QPlatformGLContext()
- , mGlxIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mPixmap(0)
- , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat(),GLX_PIXMAP_BIT))
- , mGlxPixmap(0)
+QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(const QSurfaceFormat &format,
+ QPlatformOpenGLContext *share, Display *display, int screen)
+ : m_display(display)
{
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
- mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
+ GLXFBConfig config = qglx_findConfig(display, screen, format, GLX_PIXMAP_BIT);
- geometryChanged();
+ GLXContext shareContext = share ? static_cast<QWaylandReadbackGlxContext *>(share)->m_context : 0;
+
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config);
+ m_context = glXCreateContext(display, visualInfo, shareContext, TRUE);
+ m_format = qglx_surfaceFormatFromGLXFBConfig(display, config, m_context);
+}
+
+QSurfaceFormat QWaylandReadbackGlxContext::format() const
+{
+ return m_format;
}
-void QWaylandReadbackGlxContext::makeCurrent()
+bool QWaylandReadbackGlxContext::makeCurrent(QPlatformSurface *surface)
{
- QPlatformGLContext::makeCurrent();
+ GLXPixmap glxPixmap = static_cast<QWaylandReadbackGlxWindow *>(surface)->glxPixmap();
- glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext);
+ return glXMakeCurrent(m_display, glxPixmap, m_context);
}
void QWaylandReadbackGlxContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ glXMakeCurrent(m_display, 0, 0);
}
-void QWaylandReadbackGlxContext::swapBuffers()
+void QWaylandReadbackGlxContext::swapBuffers(QPlatformSurface *surface)
{
- if (QPlatformGLContext::currentContext() != this) {
- makeCurrent();
- }
+ // #### makeCurrent() directly on the platform context doesn't update QOpenGLContext::currentContext()
+ if (QOpenGLContext::currentContext()->handle() != this)
+ makeCurrent(surface);
+
+ QWaylandReadbackGlxWindow *w = static_cast<QWaylandReadbackGlxWindow *>(surface);
- QSize size = mWindow->geometry().size();
+ QSize size = w->geometry().size();
- QImage img(size,QImage::Format_ARGB32);
+ QImage img(size, QImage::Format_ARGB32);
const uchar *constBits = img.bits();
void *pixels = const_cast<uchar *>(constBits);
- glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
+ glReadPixels(0, 0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
img = img.mirrored();
- qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV);
+ qgl_byteSwapImage(img, GL_UNSIGNED_INT_8_8_8_8_REV);
constBits = img.bits();
- const uchar *constDstBits = mBuffer->image()->bits();
+ const uchar *constDstBits = w->buffer();
uchar *dstBits = const_cast<uchar *>(constDstBits);
- memcpy(dstBits,constBits,(img.width()*4) * img.height());
+ memcpy(dstBits, constBits, (img.width() * 4) * img.height());
+ w->damage(QRect(QPoint(), size));
- mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
- mWindow->waitForFrameSync();
-
+ w->waitForFrameSync();
}
-void * QWaylandReadbackGlxContext::getProcAddress(const QString &procName)
+void (*QWaylandReadbackGlxContext::getProcAddress(const QByteArray &procName)) ()
{
- return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
-}
-
-QPlatformWindowFormat QWaylandReadbackGlxContext::platformWindowFormat() const
-{
- return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
-}
-
-void QWaylandReadbackGlxContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- mWindow->waitForFrameSync();
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mPixmap) {
- XFreePixmap(mGlxIntegration->xDisplay(),mPixmap);
- }
-
- mBuffer = new QWaylandShmBuffer(mGlxIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
- mWindow->attach(mBuffer);
- int depth = XDefaultDepth(mGlxIntegration->xDisplay(),mGlxIntegration->screen());
- mPixmap = XCreatePixmap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),size.width(),size.height(),depth);
- XSync(mGlxIntegration->xDisplay(),False);
-
- mGlxPixmap = glXCreatePixmap(mGlxIntegration->xDisplay(),mConfig,mPixmap,0);
-
- if (!mGlxPixmap) {
- qDebug() << "Could not make egl surface out of pixmap :(";
- }
+ return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData()));
}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
index 07e0f620de..7b5eeece93 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
@@ -42,38 +42,35 @@
#ifndef QWAYLANDREADBACKGLXCONTEXT_H
#define QWAYLANDREADBACKGLXCONTEXT_H
-#include <QPlatformGLContext>
+#include <QPlatformOpenGLContext>
+#include <QSurfaceFormat>
#include "qwaylandreadbackglxintegration.h"
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
class QWaylandReadbackGlxWindow;
class QWaylandShmBuffer;
-class QWaylandReadbackGlxContext : public QPlatformGLContext
+class QWaylandReadbackGlxContext : public QPlatformOpenGLContext
{
public:
- QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window);
+ QWaylandReadbackGlxContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen);
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ QSurfaceFormat format() const;
+
+ void swapBuffers(QPlatformSurface *surface);
- QPlatformWindowFormat platformWindowFormat() const;
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
- void geometryChanged();
+ void (*getProcAddress(const QByteArray &procName)) ();
private:
- QWaylandReadbackGlxIntegration *mGlxIntegration;
- QWaylandReadbackGlxWindow *mWindow;
- QWaylandShmBuffer *mBuffer;
+ GLXContext m_context;
- Pixmap mPixmap;
- GLXFBConfig mConfig;
- GLXContext mContext;
- GLXPixmap mGlxPixmap;
+ Display *m_display;
+ QSurfaceFormat m_format;
};
#endif // QWAYLANDREADBACKGLXCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
index 37a14a9f4c..752bb06a43 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
@@ -66,9 +66,14 @@ void QWaylandReadbackGlxIntegration::initialize()
{
}
-QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWidget *widget)
+QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandReadbackGlxWindow(widget,this);
+ return new QWaylandReadbackGlxWindow(window,this);
+}
+
+QPlatformOpenGLContext *QWaylandReadbackGlxIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandReadbackGlxContext(glFormat, share, mDisplay, mScreen);
}
QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
index d267d8dffe..ee50d74ebd 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
@@ -48,7 +48,7 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtGui/QWindow>
#include <X11/Xlib.h>
@@ -60,7 +60,8 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
index 98198dfa06..35c3ca3154 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
@@ -39,12 +39,19 @@
**
****************************************************************************/
+#include <QtDebug>
+
#include "qwaylandreadbackglxwindow.h"
+#include "qwaylandshmbackingstore.h"
-QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration)
+QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration)
: QWaylandShmWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_buffer(0)
+ , m_pixmap(0)
+ , m_config(0)
+ , m_glxPixmap(0)
+ , m_window(window)
{
}
@@ -54,20 +61,54 @@ QWaylandWindow::WindowType QWaylandReadbackGlxWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandReadbackGlxWindow::glContext() const
+void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect)
{
- if (!mContext) {
- QWaylandReadbackGlxWindow *that = const_cast<QWaylandReadbackGlxWindow *>(this);
- that->mContext = new QWaylandReadbackGlxContext(mGlxIntegration,that);
+ QWaylandShmWindow::setGeometry(rect);
+
+ if (m_pixmap) {
+ delete mBuffer;
+ //XFreePixmap deletes the glxPixmap as well
+ XFreePixmap(m_glxIntegration->xDisplay(), m_pixmap);
+ m_pixmap = 0;
}
- return mContext;
}
-void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect)
+GLXPixmap QWaylandReadbackGlxWindow::glxPixmap() const
{
- QWaylandShmWindow::setGeometry(rect);
+ if (!m_pixmap)
+ const_cast<QWaylandReadbackGlxWindow *>(this)->createSurface();
+
+ return m_glxPixmap;
+}
- if (mContext) {
- mContext->geometryChanged();
+uchar *QWaylandReadbackGlxWindow::buffer()
+{
+ return m_buffer->image()->bits();
+}
+
+void QWaylandReadbackGlxWindow::createSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
}
+
+ waitForFrameSync();
+
+ m_buffer = new QWaylandShmBuffer(m_glxIntegration->waylandDisplay(), size, QImage::Format_ARGB32);
+ attach(m_buffer);
+
+ int depth = XDefaultDepth(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ m_pixmap = XCreatePixmap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(), size.width(), size.height(), depth);
+ XSync(m_glxIntegration->xDisplay(), False);
+
+ if (!m_config)
+ m_config = qglx_findConfig(m_glxIntegration->xDisplay(), m_glxIntegration->screen(), m_window->format());
+
+ m_glxPixmap = glXCreatePixmap(m_glxIntegration->xDisplay(), m_config, m_pixmap,0);
+
+ if (!m_glxPixmap)
+ qDebug() << "Could not make glx surface out of pixmap :(";
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
index d478961d53..c92646c80d 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
@@ -49,17 +49,25 @@
class QWaylandReadbackGlxWindow : public QWaylandShmWindow
{
public:
- QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration);
+ QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
-
void setGeometry(const QRect &rect);
+ Pixmap glxPixmap() const;
+
+ uchar *buffer();
+
private:
- QWaylandReadbackGlxIntegration *mGlxIntegration;
- QWaylandReadbackGlxContext *mContext;
+ void createSurface();
+
+ QWaylandReadbackGlxIntegration *m_glxIntegration;
+ QWaylandShmBuffer *m_buffer;
+ Pixmap m_pixmap;
+ GLXFBConfig m_config;
+ GLXPixmap m_glxPixmap;
+ QWindow *m_window;
};
#endif // QWAYLANDREADBACKGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
index f8ea005937..746d594fa2 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
@@ -1,4 +1,3 @@
-include (../../../glxconvenience/glxconvenience.pri)
HEADERS += \
$$PWD/qwaylandreadbackglxintegration.h \
$$PWD/qwaylandreadbackglxwindow.h \
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
index d4deb01022..27f17a6153 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
@@ -44,11 +44,12 @@
#include "gl_integration/qwaylandglintegration.h"
#include "qwaylandeglwindow.h"
+#include "qwaylandglcontext.h"
#include <QtCore/QDebug>
QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay)
- : mWaylandDisplay(waylandDisplay)
+ : m_waylandDisplay(waylandDisplay)
{
qDebug() << "Using Wayland-EGL";
}
@@ -56,31 +57,41 @@ QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay
QWaylandEglIntegration::~QWaylandEglIntegration()
{
- eglTerminate(mEglDisplay);
+ eglTerminate(m_eglDisplay);
}
void QWaylandEglIntegration::initialize()
{
+ QByteArray eglPlatform = qgetenv("EGL_PLATFORM");
+ if (eglPlatform.isEmpty()) {
+ setenv("EGL_PLATFORM","wayland",true);
+ }
+
EGLint major,minor;
- mEglDisplay = eglGetDisplay(mWaylandDisplay);
- if (mEglDisplay == NULL) {
+ m_eglDisplay = eglGetDisplay(m_waylandDisplay);
+ if (m_eglDisplay == NULL) {
qWarning("EGL not available");
} else {
- if (!eglInitialize(mEglDisplay, &major, &minor)) {
+ if (!eglInitialize(m_eglDisplay, &major, &minor)) {
qWarning("failed to initialize EGL display");
return;
}
}
}
-QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWidget *window)
+QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWindow *window)
{
return new QWaylandEglWindow(window);
}
+QPlatformOpenGLContext *QWaylandEglIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandGLContext(m_eglDisplay, glFormat, share);
+}
+
EGLDisplay QWaylandEglIntegration::eglDisplay() const
{
- return mEglDisplay;
+ return m_eglDisplay;
}
QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
index ea8b0f725c..7a26c57658 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
@@ -47,7 +47,7 @@
#include "qwaylandeglinclude.h"
class QWaylandWindow;
-class QWidget;
+class QWindow;
class QWaylandEglIntegration : public QWaylandGLIntegration
{
@@ -57,14 +57,15 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *window);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
EGLDisplay eglDisplay() const;
- struct wl_egl_display *nativeDisplay() const;
+
private:
- struct wl_display *mWaylandDisplay;
+ struct wl_display *m_waylandDisplay;
- EGLDisplay mEglDisplay;
+ EGLDisplay m_eglDisplay;
};
#endif // QWAYLANDEGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
index cd8b5b3524..e0e1f772b9 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
@@ -44,19 +44,30 @@
#include "qwaylandscreen.h"
#include "qwaylandglcontext.h"
-QWaylandEglWindow::QWaylandEglWindow(QWidget *window)
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+
+#include <QtGui/QWindow>
+#include <QtGui/QWindowSystemInterface>
+
+QWaylandEglWindow::QWaylandEglWindow(QWindow *window)
: QWaylandWindow(window)
- , mGLContext(0)
- , mWaylandEglWindow(0)
+ , m_waylandEglWindow(0)
+ , m_eglSurface(0)
+ , m_eglConfig(0)
+ , m_format(window->format())
{
- mEglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration());
+ m_eglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration());
+
//super creates a new surface
newSurfaceCreated();
}
QWaylandEglWindow::~QWaylandEglWindow()
{
- delete mGLContext;
+ if (m_eglSurface) {
+ eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface);
+ m_eglSurface = 0;
+ }
}
QWaylandWindow::WindowType QWaylandEglWindow::windowType() const
@@ -67,46 +78,48 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const
void QWaylandEglWindow::setGeometry(const QRect &rect)
{
QWaylandWindow::setGeometry(rect);
- if (mWaylandEglWindow) {
- wl_egl_window_resize(mWaylandEglWindow,rect.width(),rect.height(),0,0);
+ if (m_waylandEglWindow){
+ wl_egl_window_resize(m_waylandEglWindow, rect.width(), rect.height(), 0, 0);
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
}
}
-void QWaylandEglWindow::setParent(const QPlatformWindow *parent)
+void QWaylandEglWindow::newSurfaceCreated()
{
- const QWaylandWindow *wParent = static_cast<const QWaylandWindow *>(parent);
+ if (m_waylandEglWindow)
+ wl_egl_window_destroy(m_waylandEglWindow);
- mParentWindow = wParent;
-}
-
-QPlatformGLContext * QWaylandEglWindow::glContext() const
-{
- if (!mGLContext) {
- QWaylandEglWindow *that = const_cast<QWaylandEglWindow *>(this);
- that->mGLContext = new QWaylandGLContext(mEglIntegration->eglDisplay(),widget()->platformWindowFormat());
+ wl_visual *visual = QWaylandScreen::waylandScreenFromWindow(window())->visual();
+ QSize size = geometry().size();
+ if (!size.isValid())
+ size = QSize(0,0);
- EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
- EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
- that->mGLContext->setEglSurface(surface);
+ if (m_eglSurface) {
+ eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface);
+ m_eglSurface = 0;
}
- return mGLContext;
+ m_waylandEglWindow = wl_egl_window_create(mSurface, size.width(), size.height(), visual);
}
-void QWaylandEglWindow::newSurfaceCreated()
+QSurfaceFormat QWaylandEglWindow::format() const
{
- if (mWaylandEglWindow) {
- wl_egl_window_destroy(mWaylandEglWindow);
- }
- wl_visual *visual = QWaylandScreen::waylandScreenFromWidget(widget())->visual();
- QSize size = geometry().size();
- if (!size.isValid())
- size = QSize(0,0);
+ return m_format;
+}
- mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual);
- if (mGLContext) {
- EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
- EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
- mGLContext->setEglSurface(surface);
+EGLSurface QWaylandEglWindow::eglSurface() const
+{
+ if (!m_waylandEglWindow)
+ return 0;
+
+ if (!m_eglSurface) {
+ if (!m_eglConfig)
+ m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), window()->format(), true);
+
+ EGLNativeWindowType window = m_waylandEglWindow;
+ m_eglSurface = eglCreateWindowSurface(m_eglIntegration->eglDisplay(), m_eglConfig, window, 0);
}
+
+ return m_eglSurface;
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
index 6d2038824a..d435a511c4 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
@@ -51,20 +51,28 @@ class QWaylandGLContext;
class QWaylandEglWindow : public QWaylandWindow
{
public:
- QWaylandEglWindow(QWidget *window);
+ QWaylandEglWindow(QWindow *window);
~QWaylandEglWindow();
WindowType windowType() const;
void setGeometry(const QRect &rect);
- void setParent(const QPlatformWindow *parent);
- QPlatformGLContext *glContext() const;
+
+ EGLSurface eglSurface() const;
+
+ QSurfaceFormat format() const;
+
protected:
void newSurfaceCreated();
+
private:
- QWaylandEglIntegration *mEglIntegration;
- QWaylandGLContext *mGLContext;
- struct wl_egl_window *mWaylandEglWindow;
+ QWaylandEglIntegration *m_eglIntegration;
+ struct wl_egl_window *m_waylandEglWindow;
+
+ const QWaylandWindow *m_parentWindow;
+
+ mutable EGLSurface m_eglSurface;
+ mutable EGLConfig m_eglConfig;
- const QWaylandWindow *mParentWindow;
+ QSurfaceFormat m_format;
};
#endif // QWAYLANDEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
index 0f27501c71..aa61405eb6 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
@@ -43,26 +43,21 @@
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
+#include "qwaylandeglwindow.h"
-#include "../../../eglconvenience/qeglconvenience.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
-#include <QtGui/QPlatformGLContext>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QSurfaceFormat>
#include <QtCore/QMutex>
-QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format)
- : QPlatformGLContext()
- , mEglDisplay(eglDisplay)
- , mSurface(EGL_NO_SURFACE)
- , mConfig(q_configFromQPlatformWindowFormat(mEglDisplay,format,true))
- , mFormat(qt_qPlatformWindowFormatFromConfig(mEglDisplay,mConfig))
+QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : QPlatformOpenGLContext()
+ , m_eglDisplay(eglDisplay)
+ , m_config(q_configFromGLFormat(m_eglDisplay, format, true))
+ , m_format(q_glFormatFromConfig(m_eglDisplay, m_config))
{
- QPlatformGLContext *sharePlatformContext = 0;
- sharePlatformContext = format.sharedGLContext();
- mFormat.setSharedContext(sharePlatformContext);
- EGLContext shareEGLContext = EGL_NO_CONTEXT;
- if (sharePlatformContext)
- shareEGLContext = static_cast<const QWaylandGLContext*>(sharePlatformContext)->mContext;
+ EGLContext shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT;
eglBindAPI(EGL_OPENGL_ES_API);
@@ -71,63 +66,38 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindo
eglContextAttrs.append(2);
eglContextAttrs.append(EGL_NONE);
- mContext = eglCreateContext(mEglDisplay, mConfig,
- shareEGLContext, eglContextAttrs.constData());
+ m_context = eglCreateContext(m_eglDisplay, m_config, shareEGLContext, eglContextAttrs.constData());
}
-QWaylandGLContext::QWaylandGLContext()
- : QPlatformGLContext()
- , mEglDisplay(0)
- , mContext(EGL_NO_CONTEXT)
- , mSurface(EGL_NO_SURFACE)
- , mConfig(0)
-{ }
-
QWaylandGLContext::~QWaylandGLContext()
{
- eglDestroyContext(mEglDisplay,mContext);
+ eglDestroyContext(m_eglDisplay, m_context);
}
-void QWaylandGLContext::makeCurrent()
+bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
{
- QPlatformGLContext::makeCurrent();
- if (mSurface == EGL_NO_SURFACE) {
- qWarning("makeCurrent with EGL_NO_SURFACE");
- }
- eglMakeCurrent(mEglDisplay, mSurface, mSurface, mContext);
+ EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface();
+ return eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context);
}
void QWaylandGLContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-}
-
-void QWaylandGLContext::swapBuffers()
-{
- eglSwapBuffers(mEglDisplay,mSurface);
+ eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
-void *QWaylandGLContext::getProcAddress(const QString &string)
+void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
{
- return (void *) eglGetProcAddress(string.toLatin1().data());
+ EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface();
+ eglSwapBuffers(m_eglDisplay, eglSurface);
}
-void QWaylandGLContext::setEglSurface(EGLSurface surface)
+void (*QWaylandGLContext::getProcAddress(const QByteArray &procName)) ()
{
- bool wasCurrent = false;
- if (QPlatformGLContext::currentContext() == this) {
- wasCurrent = true;
- doneCurrent();
- }
- mSurface = surface;
- if (wasCurrent) {
- makeCurrent();
- }
+ return eglGetProcAddress(procName.constData());
}
EGLConfig QWaylandGLContext::eglConfig() const
{
- return mConfig;
+ return m_config;
}
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
index 2c6feb498c..16d9fa4ada 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
@@ -44,36 +44,36 @@
#include "qwaylanddisplay.h"
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
#include "qwaylandeglinclude.h"
class QWaylandWindow;
class QWaylandGLWindowSurface;
-class QWaylandGLContext : public QPlatformGLContext {
+class QWaylandGLContext : public QPlatformOpenGLContext {
public:
- QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format);
+ QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QWaylandGLContext();
- void makeCurrent();
+
+ void swapBuffers(QPlatformSurface *surface);
+
+ bool makeCurrent(QPlatformSurface *surface);
void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString&);
- QPlatformWindowFormat platformWindowFormat() const { return mFormat; }
+ void (*getProcAddress(const QByteArray &procName)) ();
- void setEglSurface(EGLSurface surface);
- EGLConfig eglConfig() const;
-private:
- EGLDisplay mEglDisplay;
+ QSurfaceFormat format() const { return m_format; }
- EGLContext mContext;
- EGLSurface mSurface;
- EGLConfig mConfig;
- QPlatformWindowFormat mFormat;
+ EGLConfig eglConfig() const;
+ EGLContext eglContext() const { return m_context; }
- QWaylandGLContext();
+private:
+ EGLDisplay m_eglDisplay;
+ EGLContext m_context;
+ EGLConfig m_config;
+ QSurfaceFormat m_format;
};
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
index cd0701150f..8b4b163b03 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
@@ -1,5 +1,3 @@
-include (../../../eglconvenience/eglconvenience.pri)
-
LIBS += -lwayland-egl -lEGL
INCLUDEPATH += $$PWD
SOURCES += $$PWD/qwaylandeglintegration.cpp \
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
index 999a411397..f2f9d1ceb6 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
@@ -42,128 +42,31 @@
#include "qwaylandxcompositeeglcontext.h"
#include "qwaylandxcompositeeglwindow.h"
-#include "qwaylandxcompositebuffer.h"
-#include "wayland-xcomposite-client-protocol.h"
#include <QtCore/QDebug>
+#include <QtGui/QRegion>
-#include "qeglconvenience.h"
-#include "qxlibeglintegration.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
-#include <X11/extensions/Xcomposite.h>
-
-QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window)
- : QPlatformGLContext()
- , mEglIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mXWindow(0)
- , mConfig(q_configFromQPlatformWindowFormat(glxIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_WINDOW_BIT))
- , mWaitingForSync(false)
-{
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- mContext = eglCreateContext(glxIntegration->eglDisplay(),mConfig,EGL_NO_CONTEXT,eglContextAttrs.constData());
- if (mContext == EGL_NO_CONTEXT) {
- qFatal("failed to find context");
- }
-
- geometryChanged();
-}
-
-void QWaylandXCompositeEGLContext::makeCurrent()
-{
- QPlatformGLContext::makeCurrent();
-
- eglMakeCurrent(mEglIntegration->eglDisplay(),mEglWindowSurface,mEglWindowSurface,mContext);
-}
-
-void QWaylandXCompositeEGLContext::doneCurrent()
+QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
+ : QEGLPlatformContext(format, share, display)
{
- QPlatformGLContext::doneCurrent();
- eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
}
-void QWaylandXCompositeEGLContext::swapBuffers()
+void QWaylandXCompositeEGLContext::swapBuffers(QPlatformSurface *surface)
{
- QSize size = mWindow->geometry().size();
+ QEGLPlatformContext::swapBuffers(surface);
- eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface);
- mWindow->damage(QRect(QPoint(0,0),size));
- mWindow->waitForFrameSync();
-}
+ QWaylandXCompositeEGLWindow *w =
+ static_cast<QWaylandXCompositeEGLWindow *>(surface);
-void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName)
-{
- return (void *)eglGetProcAddress(qPrintable(procName));
-}
+ QSize size = w->geometry().size();
-QPlatformWindowFormat QWaylandXCompositeEGLContext::platformWindowFormat() const
-{
- return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+ w->damage(QRect(QPoint(), size));
+ w->waitForFrameSync();
}
-void QWaylandXCompositeEGLContext::sync_function(void *data)
+EGLSurface QWaylandXCompositeEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
- QWaylandXCompositeEGLContext *that = static_cast<QWaylandXCompositeEGLContext *>(data);
- that->mWaitingForSync = false;
-}
-
-void QWaylandXCompositeEGLContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mXWindow) {
- XDestroyWindow(mEglIntegration->xDisplay(),mXWindow);
- }
-
- VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(mEglIntegration->xDisplay(),mEglIntegration->eglDisplay(),mConfig);
-
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- visualInfoTemplate.visualid = visualId;
-
- int matchingCount = 0;
- XVisualInfo *visualInfo = XGetVisualInfo(mEglIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
-
- Colormap cmap = XCreateColormap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),visualInfo->visual,AllocNone);
-
- XSetWindowAttributes a;
- a.colormap = cmap;
- mXWindow = XCreateWindow(mEglIntegration->xDisplay(), mEglIntegration->rootWindow(),0, 0, size.width(), size.height(),
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWColormap, &a);
-
- XCompositeRedirectWindow(mEglIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
- XMapWindow(mEglIntegration->xDisplay(), mXWindow);
-
- mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0);
- if (mEglWindowSurface == EGL_NO_SURFACE) {
- qFatal("Could not make eglsurface");
- }
-
- XSync(mEglIntegration->xDisplay(),False);
- mBuffer = new QWaylandXCompositeBuffer(mEglIntegration->waylandXComposite(),
- (uint32_t)mXWindow,
- size,
- mEglIntegration->waylandDisplay()->argbVisual());
- mWindow->attach(mBuffer);
- wl_display_sync_callback(mEglIntegration->waylandDisplay()->wl_display(),
- QWaylandXCompositeEGLContext::sync_function,
- this);
-
- mWaitingForSync = true;
- wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0);
- mEglIntegration->waylandDisplay()->flushRequests();
- while (mWaitingForSync) {
- mEglIntegration->waylandDisplay()->readEvents();
- }
+ return static_cast<QWaylandXCompositeEGLWindow *>(surface)->eglSurface();
}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
index 9d9dd53e0b..8420f2be13 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
@@ -42,41 +42,23 @@
#ifndef QWAYLANDXCOMPOSITEEGLCONTEXT_H
#define QWAYLANDXCOMPOSITEEGLCONTEXT_H
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
-#include <QtCore/QWaitCondition>
-
-#include "qwaylandbuffer.h"
#include "qwaylandxcompositeeglintegration.h"
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+
class QWaylandXCompositeEGLWindow;
-class QWaylandXCompositeEGLContext : public QPlatformGLContext
+class QWaylandXCompositeEGLContext : public QEGLPlatformContext
{
public:
- QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window);
-
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display);
- QPlatformWindowFormat platformWindowFormat() const;
-
- void geometryChanged();
+ void swapBuffers(QPlatformSurface *surface);
private:
- QWaylandXCompositeEGLIntegration *mEglIntegration;
- QWaylandXCompositeEGLWindow *mWindow;
- QWaylandBuffer *mBuffer;
-
- Window mXWindow;
- EGLConfig mConfig;
- EGLContext mContext;
- EGLSurface mEglWindowSurface;
-
- static void sync_function(void *data);
- bool mWaitingForSync;
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
};
#endif // QWAYLANDXCOMPOSITEEGLCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
index 53199e87b8..d7e37f8e70 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
@@ -70,9 +70,14 @@ void QWaylandXCompositeEGLIntegration::initialize()
{
}
-QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWidget *widget)
+QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandXCompositeEGLWindow(widget,this);
+ return new QWaylandXCompositeEGLWindow(window,this);
+}
+
+QPlatformOpenGLContext *QWaylandXCompositeEGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay());
}
Display * QWaylandXCompositeEGLIntegration::xDisplay() const
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
index 1e8055944f..74ea930e9a 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
@@ -49,7 +49,9 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtGui/QWindow>
+
+#include <QPlatformOpenGLContext>
#include <QWaitCondition>
@@ -66,7 +68,8 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
struct wl_xcomposite *waylandXComposite() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
index 1047cb8b0a..320113f58d 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
@@ -40,17 +40,29 @@
****************************************************************************/
#include "qwaylandxcompositeeglwindow.h"
+#include "qwaylandxcompositebuffer.h"
+
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtPlatformSupport/private/qxlibeglintegration_p.h>
+
+#include "wayland-xcomposite-client-protocol.h"
+
+#include <X11/extensions/Xcomposite.h>
#include "qwaylandxcompositeeglintegration.h"
#include "windowmanager_integration/qwaylandwindowmanagerintegration.h"
#include <QtCore/QDebug>
-QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration)
+QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration)
: QWaylandWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_context(0)
+ , m_buffer(0)
+ , m_xWindow(0)
+ , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->format(), true))
+ , m_surface(0)
+ , m_waitingForSync(false)
{
-
}
QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
@@ -59,23 +71,83 @@ QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const
+void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
{
- if (!mContext) {
- qDebug() << "creating glcontext;";
- QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this);
- that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that);
+ QWaylandWindow::setGeometry(rect);
+
+ if (m_surface) {
+ eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface);
+ m_surface = 0;
}
- return mContext;
}
-void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
+EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const
{
- QWaylandWindow::setGeometry(rect);
+ if (!m_surface)
+ const_cast<QWaylandXCompositeEGLWindow *>(this)->createEglSurface();
+ return m_surface;
+}
+
+void QWaylandXCompositeEGLWindow::createEglSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ // QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
- if (mContext) {
- mContext->geometryChanged();
+ delete m_buffer;
+ //XFreePixmap deletes the glxPixmap as well
+ if (m_xWindow) {
+ XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
}
+
+ VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), m_config);
+
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = visualId;
+
+ int matchingCount = 0;
+ XVisualInfo *visualInfo = XGetVisualInfo(m_glxIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
+
+ Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(),m_glxIntegration->rootWindow(),visualInfo->visual,AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+
+ XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
+ XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
+
+ m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, m_xWindow,0);
+ if (m_surface == EGL_NO_SURFACE) {
+ qFatal("Could not make eglsurface");
+ }
+
+ XSync(m_glxIntegration->xDisplay(),False);
+ mBuffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
+ (uint32_t)m_xWindow,
+ size,
+ m_glxIntegration->waylandDisplay()->argbVisual());
+ attach(m_buffer);
+ wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeEGLWindow::sync_function,
+ this);
+
+ m_waitingForSync = true;
+ wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(),0);
+ m_glxIntegration->waylandDisplay()->flushRequests();
+ while (m_waitingForSync)
+ m_glxIntegration->waylandDisplay()->readEvents();
+}
+
+void QWaylandXCompositeEGLWindow::sync_function(void *data)
+{
+ QWaylandXCompositeEGLWindow *that = static_cast<QWaylandXCompositeEGLWindow *>(data);
+ that->m_waitingForSync = false;
}
void QWaylandXCompositeEGLWindow::requestActivateWindow()
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
index ea4dd2d626..b2f8fbe6c4 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
@@ -43,24 +43,36 @@
#define QWAYLANDXCOMPOSITEEGLWINDOW_H
#include "qwaylandwindow.h"
+#include "qwaylandbuffer.h"
+
#include "qwaylandxcompositeeglintegration.h"
#include "qwaylandxcompositeeglcontext.h"
class QWaylandXCompositeEGLWindow : public QWaylandWindow
{
public:
- QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration);
+ QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
-
void setGeometry(const QRect &rect);
void requestActivateWindow();
+ EGLSurface eglSurface() const;
+
private:
- QWaylandXCompositeEGLIntegration *mGlxIntegration;
- QWaylandXCompositeEGLContext *mContext;
+ void createEglSurface();
+
+ QWaylandXCompositeEGLIntegration *m_glxIntegration;
+ QWaylandXCompositeEGLContext *m_context;
+ QWaylandBuffer *m_buffer;
+
+ Window m_xWindow;
+ EGLConfig m_config;
+ EGLSurface m_surface;
+
+ bool m_waitingForSync;
+ static void sync_function(void *data);
};
#endif // QWAYLANDXCOMPOSITEEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
index c3533f9ce3..5f86bd9588 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
@@ -1,6 +1,4 @@
include (../xcomposite_share/xcomposite_share.pri)
-include (../../../eglconvenience/eglconvenience.pri)
-include (../../../eglconvenience/xlibeglintegration.pri)
LIBS += -lXcomposite -lEGL
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
index 3d49790f3a..75881a7fdd 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
@@ -39,114 +39,56 @@
**
****************************************************************************/
+#include <QtCore/QDebug>
+
#include "qwaylandxcompositeglxcontext.h"
#include "qwaylandxcompositeglxwindow.h"
-#include "qwaylandxcompositebuffer.h"
-#include "wayland-xcomposite-client-protocol.h"
-#include <QtCore/QDebug>
+#include <QRegion>
-#include <X11/extensions/Xcomposite.h>
-
-QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window)
- : QPlatformGLContext()
- , mGlxIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mXWindow(0)
- , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat()))
- , mWaitingForSyncCallback(false)
+QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen)
+ : m_display(display)
{
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
- mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
-
- geometryChanged();
+ qDebug("creating XComposite-GLX context");
+ GLXContext shareContext = share ? static_cast<QWaylandXCompositeGLXContext *>(share)->m_context : 0;
+ GLXFBConfig config = qglx_findConfig(display, screen, format);
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config);
+ m_context = glXCreateContext(display, visualInfo, shareContext, true);
+ m_format = qglx_surfaceFormatFromGLXFBConfig(display, config, m_context);
}
-void QWaylandXCompositeGLXContext::makeCurrent()
+bool QWaylandXCompositeGLXContext::makeCurrent(QPlatformSurface *surface)
{
- QPlatformGLContext::makeCurrent();
- glXMakeCurrent(mGlxIntegration->xDisplay(),mXWindow,mContext);
+ Window xWindow = static_cast<QWaylandXCompositeGLXWindow *>(surface)->xWindow();
+
+ return glXMakeCurrent(m_display, xWindow, m_context);
}
void QWaylandXCompositeGLXContext::doneCurrent()
{
- glXMakeCurrent(mGlxIntegration->xDisplay(),0,0);
- QPlatformGLContext::doneCurrent();
+ glXMakeCurrent(m_display, 0, 0);
}
-void QWaylandXCompositeGLXContext::swapBuffers()
+void QWaylandXCompositeGLXContext::swapBuffers(QPlatformSurface *surface)
{
- QSize size = mWindow->geometry().size();
+ QWaylandXCompositeGLXWindow *w = static_cast<QWaylandXCompositeGLXWindow *>(surface);
- glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow);
- mWindow->damage(QRect(QPoint(0,0),size));
- mWindow->waitForFrameSync();
-}
+ QSize size = w->geometry().size();
-void * QWaylandXCompositeGLXContext::getProcAddress(const QString &procName)
-{
- return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
-}
+ glXSwapBuffers(m_display, w->xWindow());
-QPlatformWindowFormat QWaylandXCompositeGLXContext::platformWindowFormat() const
-{
- return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
+ w->damage(QRect(QPoint(), size));
+ w->waitForFrameSync();
}
-void QWaylandXCompositeGLXContext::sync_function(void *data)
+void (*QWaylandXCompositeGLXContext::getProcAddress(const QByteArray &procName)) ()
{
- QWaylandXCompositeGLXContext *that = static_cast<QWaylandXCompositeGLXContext *>(data);
- that->mWaitingForSyncCallback = false;
+ return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData()));
}
-void QWaylandXCompositeGLXContext::waitForSync()
+QSurfaceFormat QWaylandXCompositeGLXContext::format() const
{
- wl_display_sync_callback(mGlxIntegration->waylandDisplay()->wl_display(),
- QWaylandXCompositeGLXContext::sync_function,
- this);
- mWaitingForSyncCallback = true;
- wl_display_sync(mGlxIntegration->waylandDisplay()->wl_display(),0);
- mGlxIntegration->waylandDisplay()->flushRequests();
- while (mWaitingForSyncCallback) {
- mGlxIntegration->waylandDisplay()->readEvents();
- }
+ return m_format;
}
-void QWaylandXCompositeGLXContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mXWindow) {
- XDestroyWindow(mGlxIntegration->xDisplay(),mXWindow);
- }
-
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(mGlxIntegration->xDisplay(),mConfig);
- Colormap cmap = XCreateColormap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),visualInfo->visual,AllocNone);
-
- XSetWindowAttributes a;
- a.background_pixel = WhitePixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
- a.border_pixel = BlackPixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
- a.colormap = cmap;
- mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(),
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWBackPixel|CWBorderPixel|CWColormap, &a);
-
- XCompositeRedirectWindow(mGlxIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
- XMapWindow(mGlxIntegration->xDisplay(), mXWindow);
-
- XSync(mGlxIntegration->xDisplay(),False);
- mBuffer = new QWaylandXCompositeBuffer(mGlxIntegration->waylandXComposite(),
- (uint32_t)mXWindow,
- size,
- mGlxIntegration->waylandDisplay()->argbVisual());
- mWindow->attach(mBuffer);
- waitForSync();
-}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
index b6ee2bbc23..3364d88ec4 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
@@ -42,44 +42,33 @@
#ifndef QWAYLANDXCOMPOSITEGLXCONTEXT_H
#define QWAYLANDXCOMPOSITEGLXCONTEXT_H
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
-#include <QtCore/QWaitCondition>
-
-#include "qwaylandbuffer.h"
#include "qwaylandxcompositeglxintegration.h"
-
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
class QWaylandXCompositeGLXWindow;
class QWaylandShmBuffer;
-class QWaylandXCompositeGLXContext : public QPlatformGLContext
+class QWaylandXCompositeGLXContext : public QPlatformOpenGLContext
{
public:
- QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window);
+ QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen);
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ QSurfaceFormat format() const;
- QPlatformWindowFormat platformWindowFormat() const;
+ void swapBuffers(QPlatformSurface *surface);
- void geometryChanged();
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
-private:
- QWaylandXCompositeGLXIntegration *mGlxIntegration;
- QWaylandXCompositeGLXWindow *mWindow;
- QWaylandBuffer *mBuffer;
+ void (*getProcAddress(const QByteArray &procName)) ();
- Window mXWindow;
- GLXFBConfig mConfig;
- GLXContext mContext;
+private:
+ GLXContext m_context;
- static void sync_function(void *data);
- void waitForSync();
- bool mWaitingForSyncCallback;
+ Display *m_display;
+ QSurfaceFormat m_format;
};
#endif // QWAYLANDXCOMPOSITEGLXCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
index e8dbea48c6..e1eb2e635a 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
@@ -52,12 +52,15 @@ QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDispl
return new QWaylandXCompositeGLXIntegration(waylandDisplay);
}
-QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly)
- : QWaylandGLIntegration()
- , mWaylandDisplay(waylandDispaly)
+QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay *waylandDisplay)
+ : mWaylandDisplay(waylandDisplay)
+ , mWaylandComposite(0)
+ , mDisplay(0)
+ , mScreen(0)
+ , mRootWindow(0)
{
qDebug() << "Using XComposite-GLX";
- wl_display_add_global_listener(waylandDispaly->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal,
+ wl_display_add_global_listener(waylandDisplay->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal,
this);
}
@@ -70,9 +73,14 @@ void QWaylandXCompositeGLXIntegration::initialize()
{
}
-QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWidget *widget)
+QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandXCompositeGLXWindow(widget,this);
+ return new QWaylandXCompositeGLXWindow(window, this);
+}
+
+QPlatformOpenGLContext *QWaylandXCompositeGLXIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandXCompositeGLXContext(glFormat, share, mDisplay, mScreen);
}
Display * QWaylandXCompositeGLXIntegration::xDisplay() const
@@ -107,6 +115,7 @@ void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display
{
Q_UNUSED(version);
if (strcmp(interface, "wl_xcomposite") == 0) {
+ qDebug("XComposite-GLX: got wl_xcomposite global");
QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
integration->mWaylandComposite = wl_xcomposite_create(display,id,1);
wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
@@ -119,6 +128,8 @@ void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite
Q_UNUSED(xcomposite);
QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
+ qDebug("XComposite-GLX: xcomposite listener callback");
+
integration->mDisplay = XOpenDisplay(display_name);
integration->mRootWindow = (Window) root_window;
integration->mScreen = XDefaultScreen(integration->mDisplay);
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
index 17f2f6d4e4..b028067d8e 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
@@ -49,7 +49,7 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtGui/QWindow>
#include <X11/Xlib.h>
@@ -63,7 +63,8 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
struct wl_xcomposite *waylandXComposite() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
index cd7ae1964c..abaf3b16a9 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
@@ -40,15 +40,24 @@
****************************************************************************/
#include "qwaylandxcompositeglxwindow.h"
+#include "qwaylandxcompositebuffer.h"
#include <QtCore/QDebug>
-QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration)
+#include "wayland-xcomposite-client-protocol.h"
+#include <QtGui/QRegion>
+
+#include <X11/extensions/Xcomposite.h>
+
+
+QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration)
: QWaylandWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_xWindow(0)
+ , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->format()))
+ , m_buffer(0)
+ , m_waitingForSync(false)
{
-
}
QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
@@ -57,21 +66,79 @@ QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandXCompositeGLXWindow::glContext() const
+void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect)
{
- if (!mContext) {
- qDebug() << "creating glcontext;";
- QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this);
- that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that);
+ QWaylandWindow::setGeometry(rect);
+
+ if (m_xWindow) {
+ delete m_buffer;
+
+ XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
+ m_xWindow = 0;
}
- return mContext;
}
-void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect)
+Window QWaylandXCompositeGLXWindow::xWindow() const
{
- QWaylandWindow::setGeometry(rect);
+ if (!m_xWindow)
+ const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface();
- if (mContext) {
- mContext->geometryChanged();
+ return m_xWindow;
+}
+
+void QWaylandXCompositeGLXWindow::waitForSync()
+{
+ wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeGLXWindow::sync_function,
+ this);
+ m_waitingForSync= true;
+ wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(), 0);
+ m_glxIntegration->waylandDisplay()->flushRequests();
+ while (m_waitingForSync)
+ m_glxIntegration->waylandDisplay()->readEvents();
+}
+
+
+void QWaylandXCompositeGLXWindow::createSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
}
+
+ if (!m_glxIntegration->xDisplay()) {
+ qWarning("XCompositeGLXWindow: X display still null?!");
+ return;
+ }
+
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_glxIntegration->xDisplay(), m_config);
+ Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),
+ visualInfo->visual, AllocNone);
+
+ XSetWindowAttributes a;
+ a.background_pixel = WhitePixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ a.border_pixel = BlackPixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ a.colormap = cmap;
+ m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWBackPixel|CWBorderPixel|CWColormap, &a);
+
+ XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
+ XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
+
+ XSync(m_glxIntegration->xDisplay(), False);
+ m_buffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
+ (uint32_t)m_xWindow,
+ size,
+ m_glxIntegration->waylandDisplay()->argbVisual());
+ attach(m_buffer);
+ waitForSync();
+}
+
+void QWaylandXCompositeGLXWindow::sync_function(void *data)
+{
+ QWaylandXCompositeGLXWindow *that = static_cast<QWaylandXCompositeGLXWindow *>(data);
+ that->m_waitingForSync = false;
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
index 8808f2d482..acf6c8e63e 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
@@ -46,20 +46,34 @@
#include "qwaylandxcompositeglxintegration.h"
#include "qwaylandxcompositeglxcontext.h"
+#include <QtCore/QWaitCondition>
+
+#include "qwaylandbuffer.h"
+
class QWaylandXCompositeGLXWindow : public QWaylandWindow
{
public:
- QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration);
+ QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
-
void setGeometry(const QRect &rect);
+ Window xWindow() const;
+
private:
- QWaylandXCompositeGLXIntegration *mGlxIntegration;
- QWaylandXCompositeGLXContext *mContext;
+ void createSurface();
+
+ QWaylandXCompositeGLXIntegration *m_glxIntegration;
+
+ Window m_xWindow;
+ GLXFBConfig m_config;
+
+ QWaylandBuffer *m_buffer;
+
+ void waitForSync();
+ bool m_waitingForSync;
+ static void sync_function(void *data);
};
#endif // QWAYLANDXCOMPOSITEGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
index 43295e91e7..bbd6c12e42 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
@@ -1,5 +1,4 @@
include (../xcomposite_share/xcomposite_share.pri)
-include (../../../glxconvenience/glxconvenience.pri)
LIBS += -lXcomposite
SOURCES += \
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
index 7d309ef877..f4bacc3c1f 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
@@ -42,6 +42,7 @@
#include "qwaylandxcompositebuffer.h"
#include "wayland-client.h"
+#include "wayland-xcomposite-client-protocol.h"
QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(wl_xcomposite *xcomposite, uint32_t window, const QSize &size, wl_visual *visual)
:mSize(size)
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
index cbd40ad381..02176d7850 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
@@ -43,8 +43,10 @@
#define QWAYLANDXCOMPOSITEBUFFER_H
#include "qwaylandbuffer.h"
+#include <stdint.h>
-#include "wayland-xcomposite-client-protocol.h"
+struct wl_xcomposite;
+struct wl_visual;
class QWaylandXCompositeBuffer : public QWaylandBuffer
{
diff --git a/src/plugins/platforms/wayland/main.cpp b/src/plugins/platforms/wayland/main.cpp
index ba365ca3a1..e4d420d68a 100644
--- a/src/plugins/platforms/wayland/main.cpp
+++ b/src/plugins/platforms/wayland/main.cpp
@@ -54,8 +54,7 @@ public:
QStringList QWaylandIntegrationPlugin::keys() const
{
QStringList list;
- list << "Wayland";
- list << "WaylandGL";
+ list << "wayland";
return list;
}
@@ -63,9 +62,7 @@ QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, c
{
Q_UNUSED(paramList);
if (system.toLower() == "wayland")
- return new QWaylandIntegration;
- if (system.toLower() == "waylandgl")
- return new QWaylandIntegration(true);
+ return new QWaylandIntegration();
return 0;
}
diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp
index 45f0abc00a..f90d1a9802 100644
--- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp
+++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp
@@ -44,7 +44,7 @@
#include "qwaylandinputdevice.h"
#include "qwaylandmime.h"
#include <QtGui/QPlatformNativeInterface>
-#include <QtGui/QApplication>
+#include <QtGui/QGuiApplication>
#include <QtCore/QMimeData>
#include <QtCore/QStringList>
#include <QtCore/QFile>
diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp
index 87b846cefb..bbbab6dca7 100644
--- a/src/plugins/platforms/wayland/qwaylandcursor.cpp
+++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp
@@ -43,10 +43,11 @@
#include "qwaylanddisplay.h"
#include "qwaylandinputdevice.h"
-#include "qwaylandshmsurface.h"
#include "qwaylandscreen.h"
+#include "qwaylandshmbackingstore.h"
#include <QtGui/QImageReader>
+#include <QDebug>
#define DATADIR "/usr/share"
@@ -108,14 +109,15 @@ QWaylandCursor::QWaylandCursor(QWaylandScreen *screen)
{
}
-void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget)
+void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window)
{
const struct pointer_image *p;
- if (widget == NULL)
+ if (window == NULL)
return;
p = NULL;
+ bool isBitmap = false;
switch (cursor->shape()) {
case Qt::ArrowCursor:
@@ -152,32 +154,53 @@ void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget)
p = &pointer_images[cursor->shape()];
break;
- default:
case Qt::BitmapCursor:
+ isBitmap = true;
+ break;
+
+ default:
break;
}
- if (!p) {
+ if (!p && !isBitmap) {
p = &pointer_images[0];
qWarning("unhandled cursor %d", cursor->shape());
}
- QImageReader reader(p->filename);
-
- if (!reader.canRead())
- return;
-
- if (mBuffer == NULL || mBuffer->size() != reader.size()) {
- if (mBuffer)
+ if (isBitmap && !cursor->pixmap().isNull()) {
+ setupPixmapCursor(cursor);
+ } else if (isBitmap && cursor->bitmap()) {
+ qWarning("unsupported QBitmap cursor");
+ } else {
+ QImageReader reader(p->filename);
+ if (!reader.canRead())
+ return;
+ if (mBuffer == NULL || mBuffer->size() != reader.size()) {
delete mBuffer;
+ mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(),
+ QImage::Format_ARGB32);
+ }
+ reader.read(mBuffer->image());
+ mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y);
+ }
+}
- mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(),
+void QWaylandCursor::setupPixmapCursor(QCursor *cursor)
+{
+ if (!cursor) {
+ delete mBuffer;
+ mBuffer = 0;
+ return;
+ }
+ if (!mBuffer || mBuffer->size() != cursor->pixmap().size()) {
+ delete mBuffer;
+ mBuffer = new QWaylandShmBuffer(mDisplay, cursor->pixmap().size(),
QImage::Format_ARGB32);
}
-
- reader.read(mBuffer->image());
-
- mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y);
+ QImage src = cursor->pixmap().toImage().convertToFormat(QImage::Format_ARGB32);
+ for (int y = 0; y < src.height(); ++y)
+ qMemCopy(mBuffer->image()->scanLine(y), src.scanLine(y), src.bytesPerLine());
+ mDisplay->setCursor(mBuffer, cursor->hotSpot().x(), cursor->hotSpot().y());
}
void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y)
@@ -189,3 +212,19 @@ void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y)
inputDevice->attach(buffer, x, y);
}
}
+
+void QWaylandCursor::pointerEvent(const QMouseEvent &event)
+{
+ mLastPos = event.globalPos();
+}
+
+QPoint QWaylandCursor::pos() const
+{
+ return mLastPos;
+}
+
+void QWaylandCursor::setPos(const QPoint &pos)
+{
+ Q_UNUSED(pos);
+ qWarning() << "QWaylandCursor::setPos: not implemented";
+}
diff --git a/src/plugins/platforms/wayland/qwaylandcursor.h b/src/plugins/platforms/wayland/qwaylandcursor.h
index 236bfc56ee..8753aa5698 100644
--- a/src/plugins/platforms/wayland/qwaylandcursor.h
+++ b/src/plugins/platforms/wayland/qwaylandcursor.h
@@ -48,13 +48,23 @@ class QWaylandShmBuffer;
class QWaylandDisplay;
class QWaylandScreen;
-class QWaylandCursor : QPlatformCursor {
+class QWaylandCursor : public QPlatformCursor
+{
public:
QWaylandCursor(QWaylandScreen *screen);
- void changeCursor(QCursor *cursor, QWidget *widget);
+ void changeCursor(QCursor *cursor, QWindow *window);
+ void pointerEvent(const QMouseEvent &event);
+ QPoint pos() const;
+ void setPos(const QPoint &pos);
+
+ void setupPixmapCursor(QCursor *cursor);
+
QWaylandShmBuffer *mBuffer;
QWaylandDisplay *mDisplay;
+
+private:
+ QPoint mLastPos;
};
#endif // QWAYLANDCURSOR_H
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index 26e0e8ebeb..588096933c 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -46,6 +46,7 @@
#include "qwaylandcursor.h"
#include "qwaylandinputdevice.h"
#include "qwaylandclipboard.h"
+#include "qwaylanddnd.h"
#ifdef QT_WAYLAND_GL_SUPPORT
#include "gl_integration/qwaylandglintegration.h"
@@ -56,8 +57,7 @@
#endif
#include <QtCore/QAbstractEventDispatcher>
-#include <QtGui/QApplication>
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <unistd.h>
#include <fcntl.h>
@@ -142,6 +142,13 @@ QWaylandDisplay::QWaylandDisplay(void)
wl_display_add_global_listener(mDisplay, QWaylandDisplay::displayHandleGlobal, this);
+ mFd = wl_display_get_fd(mDisplay, sourceUpdate, this);
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
+ connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(flushRequests()));
+
+ mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this);
+ connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents()));
+
#ifdef QT_WAYLAND_GL_SUPPORT
mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
#endif
@@ -156,13 +163,6 @@ QWaylandDisplay::QWaylandDisplay(void)
mEglIntegration->initialize();
#endif
- connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(flushRequests()));
-
- mFd = wl_display_get_fd(mDisplay, sourceUpdate, this);
-
- mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this);
- connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents()));
-
waitForScreens();
}
@@ -313,6 +313,8 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id,
mInputDevices.append(inputDevice);
} else if (interface == "wl_selection_offer") {
QWaylandClipboard::instance(display)->createSelectionOffer(id);
+ } else if (interface == "wl_drag_offer") {
+ QWaylandDrag::instance(display)->createDragOffer(id);
}
}
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h
index 4dff24d086..2b7f33f4f6 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.h
@@ -49,6 +49,7 @@
#include <wayland-client.h>
+class QAbstractEventDispatcher;
class QWaylandInputDevice;
class QSocketNotifier;
class QWaylandBuffer;
@@ -142,6 +143,7 @@ private:
static void handleVisual(void *data,
struct wl_compositor *compositor,
uint32_t id, uint32_t token);
+
#ifdef QT_WAYLAND_GL_SUPPORT
QWaylandGLIntegration *mEglIntegration;
#endif
diff --git a/src/plugins/platforms/wayland/qwaylanddnd.cpp b/src/plugins/platforms/wayland/qwaylanddnd.cpp
new file mode 100644
index 0000000000..5368daaf63
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddnd.cpp
@@ -0,0 +1,423 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylanddnd.h"
+#include "qwaylandinputdevice.h"
+#include <QStringList>
+#include <QFile>
+#include <QtGui/private/qdnd_p.h>
+#include <QGuiApplication>
+#include <QSocketNotifier>
+#include <sys/time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <QDebug>
+
+#include <QPlatformCursor>
+#include "qwaylandcursor.h"
+
+class QWaylandDragWrapper
+{
+public:
+ QWaylandDragWrapper(QWaylandDisplay *display, QMimeData *data);
+ ~QWaylandDragWrapper();
+ QMimeData *mimeData() const { return mData; }
+
+private:
+ static void target(void *data, wl_drag *drag, const char *mimeType);
+ static void finish(void *data, wl_drag *drag, int fd);
+ static void reject(void *data, wl_drag *drag);
+ static const wl_drag_listener dragListener;
+
+ QWaylandDisplay *mDisplay;
+ wl_drag *mDrag;
+ QMimeData *mData;
+ QString mAcceptedType;
+};
+
+class QWaylandDragOfferWrapper
+{
+public:
+ QWaylandDragOfferWrapper(QWaylandDisplay *display, QMimeData *data, uint32_t id);
+ ~QWaylandDragOfferWrapper();
+
+private:
+ static void offer(void *data, struct wl_drag_offer *offer, const char *mimeType);
+ static void pointerFocus(void *data, struct wl_drag_offer *offer, uint32_t time,
+ wl_surface *surface,
+ int32_t x, int32_t y,
+ int32_t surfaceX, int32_t surfaceY);
+ static void motion(void *data, struct wl_drag_offer *offer, uint32_t time,
+ int32_t x, int32_t y,
+ int32_t surfaceX, int32_t surfaceY);
+ static void drop(void *data, struct wl_drag_offer *offer);
+ static const wl_drag_offer_listener dragOfferListener;
+
+ void sendEventToWindow(struct wl_drag_offer *offer, uint32_t time,
+ wl_surface *surface, const QPoint &pos);
+
+ QWaylandDisplay *mDisplay;
+ QMimeData *mData;
+ struct wl_drag_offer *mOffer;
+ QMimeData mOfferedTypes; // no data in this one, just the formats
+ wl_surface *mFocusSurface;
+ bool mAccepted;
+ QPoint mLastEventPos;
+ friend class QWaylandDrag;
+};
+
+static QWaylandDrag *dnd = 0;
+
+QWaylandDrag *QWaylandDrag::instance(QWaylandDisplay *display)
+{
+ if (!dnd)
+ dnd = new QWaylandDrag(display);
+ return dnd;
+}
+
+QWaylandDrag::QWaylandDrag(QWaylandDisplay *display)
+ : mDisplay(display), mDropData(0), mCurrentDrag(0), mCurrentOffer(0)
+{
+ mDropData = new QMimeData;
+}
+
+QWaylandDrag::~QWaylandDrag()
+{
+ delete mCurrentDrag;
+ delete mCurrentOffer;
+ delete mDropData;
+}
+
+QMimeData *QWaylandDrag::platformDropData()
+{
+ return mDropData;
+}
+
+static void showDragPixmap(bool show)
+{
+ QCursor c(QDragManager::self()->object->pixmap());
+ QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
+ foreach (QWeakPointer<QPlatformCursor> cursor, cursors)
+ if (cursor)
+ static_cast<QWaylandCursor *>(cursor.data())->setupPixmapCursor(show ? &c : 0);
+}
+
+
+QWaylandDragWrapper::QWaylandDragWrapper(QWaylandDisplay *display, QMimeData *data)
+ : mDisplay(display), mDrag(0), mData(data)
+{
+ QWaylandWindow *w = mDisplay->inputDevices().at(0)->pointerFocus();
+ if (!w) {
+ qWarning("QWaylandDragWrapper: No window with pointer focus?!");
+ return;
+ }
+ qDebug() << "QWaylandDragWrapper" << data->formats();
+ struct wl_shell *shell = display->wl_shell();
+ mDrag = wl_shell_create_drag(shell);
+ wl_drag_add_listener(mDrag, &dragListener, this);
+ foreach (const QString &format, data->formats())
+ wl_drag_offer(mDrag, format.toLatin1().constData());
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ wl_drag_activate(mDrag,
+ w->wl_surface(),
+ display->inputDevices().at(0)->wl_input_device(),
+ tv.tv_sec * 1000 + tv.tv_usec / 1000);
+ showDragPixmap(true);
+}
+
+QWaylandDragWrapper::~QWaylandDragWrapper()
+{
+ QWaylandDrag *dragHandler = QWaylandDrag::instance(mDisplay);
+ if (dragHandler->mCurrentDrag == this)
+ dragHandler->mCurrentDrag = 0;
+ wl_drag_destroy(mDrag);
+}
+
+const wl_drag_listener QWaylandDragWrapper::dragListener = {
+ QWaylandDragWrapper::target,
+ QWaylandDragWrapper::finish,
+ QWaylandDragWrapper::reject
+};
+
+void QWaylandDragWrapper::target(void *data, wl_drag *drag, const char *mimeType)
+{
+ Q_UNUSED(drag);
+ QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
+ self->mAcceptedType = mimeType ? QString::fromLatin1(mimeType) : QString();
+ qDebug() << "target" << self->mAcceptedType;
+ QDragManager *manager = QDragManager::self();
+ if (mimeType)
+ manager->global_accepted_action = manager->defaultAction(manager->possible_actions,
+ QGuiApplication::keyboardModifiers());
+ else
+ manager->global_accepted_action = Qt::IgnoreAction;
+}
+
+void QWaylandDragWrapper::finish(void *data, wl_drag *drag, int fd)
+{
+ Q_UNUSED(drag);
+ QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
+ qDebug() << "finish" << self->mAcceptedType;
+ if (self->mAcceptedType.isEmpty())
+ return; // no drag target was valid when the drag finished
+ QByteArray content = self->mData->data(self->mAcceptedType);
+ if (!content.isEmpty()) {
+ QFile f;
+ if (f.open(fd, QIODevice::WriteOnly))
+ f.write(content);
+ }
+ close(fd);
+ // Drag finished on source side with drop.
+
+ QDragManager::self()->stopDrag();
+ showDragPixmap(false);
+ delete self;
+ qDebug() << " *** DRAG OVER WITH DROP";
+}
+
+void QWaylandDragWrapper::reject(void *data, wl_drag *drag)
+{
+ Q_UNUSED(drag);
+ QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
+ self->mAcceptedType = QString();
+ qDebug() << "reject";
+ QDragManager::self()->global_accepted_action = Qt::IgnoreAction;
+}
+
+
+QWaylandDragOfferWrapper::QWaylandDragOfferWrapper(QWaylandDisplay *display,
+ QMimeData *data,
+ uint32_t id)
+ : mDisplay(display), mData(data), mOffer(0), mFocusSurface(0),
+ mAccepted(false)
+{
+ mOffer = wl_drag_offer_create(mDisplay->wl_display(), id, 1);
+ wl_drag_offer_add_listener(mOffer, &dragOfferListener, this);
+}
+
+QWaylandDragOfferWrapper::~QWaylandDragOfferWrapper()
+{
+ QWaylandDrag *dragHandler = QWaylandDrag::instance(mDisplay);
+ if (dragHandler->mCurrentOffer == this)
+ dragHandler->mCurrentOffer = 0;
+ wl_drag_offer_destroy(mOffer);
+}
+
+const wl_drag_offer_listener QWaylandDragOfferWrapper::dragOfferListener = {
+ QWaylandDragOfferWrapper::offer,
+ QWaylandDragOfferWrapper::pointerFocus,
+ QWaylandDragOfferWrapper::motion,
+ QWaylandDragOfferWrapper::drop
+};
+
+void QWaylandDragOfferWrapper::offer(void *data, struct wl_drag_offer *offer, const char *mimeType)
+{
+ // Called for each type before pointerFocus.
+ Q_UNUSED(offer);
+ QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
+ self->mOfferedTypes.setData(QString::fromLatin1(mimeType), QByteArray());
+}
+
+void QWaylandDragOfferWrapper::pointerFocus(void *data, struct wl_drag_offer *offer, uint32_t time,
+ wl_surface *surface,
+ int32_t x, int32_t y,
+ int32_t surfaceX, int32_t surfaceY)
+{
+ qDebug() << "pointerFocus" << surface << x << y << surfaceX << surfaceY;
+ QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
+ QWaylandDrag *mgr = QWaylandDrag::instance(self->mDisplay);
+
+ if (!surface) {
+ if (self->mFocusSurface) {
+ // This is a DragLeave.
+ QWindow *window = static_cast<QWaylandWindow *>(
+ wl_surface_get_user_data(self->mFocusSurface))->window();
+ QWindowSystemInterface::handleDrag(window, 0, QPoint());
+ if (self->mAccepted) {
+ wl_drag_offer_reject(offer);
+ self->mAccepted = false;
+ }
+ if (!mgr->mCurrentDrag) // no drag -> this is not the source side -> offer can be destroyed
+ delete mgr->mCurrentOffer;
+ } else {
+ // Drag finished on source side without drop.
+ QDragManager::self()->stopDrag();
+ showDragPixmap(false);
+ delete mgr->mCurrentDrag;
+ qDebug() << " *** DRAG OVER WITHOUT DROP";
+ }
+ }
+
+ self->mFocusSurface = surface;
+
+ // This is a DragMove or DragEnter+DragMove.
+ if (surface)
+ self->sendEventToWindow(offer, time, surface, QPoint(surfaceX, surfaceY));
+}
+
+void QWaylandDragOfferWrapper::motion(void *data, struct wl_drag_offer *offer, uint32_t time,
+ int32_t x, int32_t y,
+ int32_t surfaceX, int32_t surfaceY)
+{
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+ QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
+ if (!self->mFocusSurface)
+ return;
+// qDebug() << "motion" << self->mFocusSurface << x << y << surfaceX << surfaceY;
+ self->sendEventToWindow(offer, time, self->mFocusSurface, QPoint(surfaceX, surfaceY));
+}
+
+void QWaylandDragOfferWrapper::sendEventToWindow(struct wl_drag_offer *offer, uint32_t time,
+ wl_surface *surface, const QPoint &pos)
+{
+ QWindow *window = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface))->window();
+ Qt::DropAction action = QWindowSystemInterface::handleDrag(window, &mOfferedTypes, pos);
+ bool accepted = (action != Qt::IgnoreAction && !mOfferedTypes.formats().isEmpty());
+ if (accepted != mAccepted) {
+ mAccepted = accepted;
+ if (mAccepted) {
+ // What can we do, just accept the first type...
+ QByteArray ba = mOfferedTypes.formats().first().toLatin1();
+ qDebug() << "wl_drag_offer_accept" << ba;
+ wl_drag_offer_accept(offer, time, ba.constData());
+ } else {
+ qDebug() << "wl_drag_offer_reject";
+ wl_drag_offer_reject(offer);
+ }
+ }
+ mLastEventPos = pos;
+}
+
+void QWaylandDragOfferWrapper::drop(void *data, struct wl_drag_offer *offer)
+{
+ QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
+ if (!self->mAccepted) {
+ wl_drag_offer_reject(offer);
+ return;
+ }
+
+ QWaylandDrag *mgr = QWaylandDrag::instance(self->mDisplay);
+ QMimeData *mimeData = QWaylandDrag::instance(self->mDisplay)->platformDropData();
+ mimeData->clear();
+ if (mgr->mCurrentDrag) { // means this offer is the client's own
+ QMimeData *localData = mgr->mCurrentDrag->mimeData();
+ foreach (const QString &format, localData->formats())
+ mimeData->setData(format, localData->data(format));
+ QWindow *window = static_cast<QWaylandWindow *>(
+ wl_surface_get_user_data(self->mFocusSurface))->window();
+ QWindowSystemInterface::handleDrop(window, mimeData, self->mLastEventPos);
+ // Drag finished with drop (source == target).
+ QDragManager::self()->stopDrag();
+ showDragPixmap(false);
+ delete mgr->mCurrentOffer;
+ qDebug() << " *** DRAG OVER WITH DROP, SOURCE == TARGET";
+ } else {
+ // ### TODO
+ // This is a bit broken: The QMimeData will only contain the data for
+ // the first type. The Wayland protocol and QDropEvents/QMimeData do not
+ // match perfectly at the moment.
+ QString format = self->mOfferedTypes.formats().first();
+ QByteArray mimeTypeBa = format.toLatin1();
+ int pipefd[2];
+ if (pipe(pipefd) == -1) {
+ qWarning("QWaylandDragOfferWrapper: pipe() failed");
+ return;
+ }
+ fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL, 0) | O_NONBLOCK);
+ wl_drag_offer_receive(offer, pipefd[1]);
+ mgr->mPipeData.clear();
+ mgr->mMimeFormat = format;
+ mgr->mPipeWriteEnd = pipefd[1];
+ mgr->mPipeWatcher = new QSocketNotifier(pipefd[0], QSocketNotifier::Read);
+ QObject::connect(mgr->mPipeWatcher, SIGNAL(activated(int)), mgr, SLOT(pipeReadable(int)));
+ }
+}
+
+
+void QWaylandDrag::pipeReadable(int fd)
+{
+ if (mPipeWriteEnd) {
+ close(mPipeWriteEnd);
+ mPipeWriteEnd = 0;
+ }
+ char buf[256];
+ int n;
+ while ((n = read(fd, &buf, sizeof buf)) > 0 || errno == EINTR)
+ if (n > 0)
+ mPipeData.append(buf, n);
+ if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
+ return;
+ delete mPipeWatcher;
+ close(fd);
+
+ QMimeData *mimeData = platformDropData();
+ mimeData->setData(mMimeFormat, mPipeData);
+ foreach (const QString &format, mimeData->formats())
+ qDebug() << " got type" << format << "with data" << mimeData->data(format);
+
+ QWindow *window = static_cast<QWaylandWindow *>(
+ wl_surface_get_user_data(mCurrentOffer->mFocusSurface))->window();
+ QWindowSystemInterface::handleDrop(window, mimeData, mCurrentOffer->mLastEventPos);
+
+ // Drag finished on target side with drop.
+ delete mCurrentOffer;
+ qDebug() << " *** DRAG OVER ON TARGET WITH DROP";
+}
+
+void QWaylandDrag::createDragOffer(uint32_t id)
+{
+ delete mCurrentOffer;
+ mCurrentOffer = new QWaylandDragOfferWrapper(mDisplay, mDropData, id);
+}
+
+void QWaylandDrag::startDrag()
+{
+ QDragManager *manager = QDragManager::self();
+
+ // No need for the traditional desktop-oriented event handling in QDragManager.
+ manager->unmanageEvents();
+
+ delete mCurrentDrag;
+ mCurrentDrag = new QWaylandDragWrapper(mDisplay, manager->dropData());
+}
diff --git a/src/plugins/platforms/wayland/qwaylanddnd.h b/src/plugins/platforms/wayland/qwaylanddnd.h
new file mode 100644
index 0000000000..ebafd960ec
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddnd.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDDND_H
+#define QWAYLANDDND_H
+
+#include <QtGui/QPlatformDrag>
+#include <QtCore/QMimeData>
+#include "qwaylanddisplay.h"
+
+class QWaylandDragWrapper;
+class QWaylandDragOfferWrapper;
+class QSocketNotifier;
+
+class QWaylandDrag : public QObject, public QPlatformDrag
+{
+ Q_OBJECT
+
+public:
+ static QWaylandDrag *instance(QWaylandDisplay *display);
+ ~QWaylandDrag();
+ void createDragOffer(uint32_t id);
+
+ QMimeData *platformDropData();
+ void startDrag();
+ void move(const QMouseEvent *) { }
+ void drop(const QMouseEvent *) { }
+ void cancel() { }
+
+private slots:
+ void pipeReadable(int fd);
+
+private:
+ QWaylandDrag(QWaylandDisplay *display);
+
+ QWaylandDisplay *mDisplay;
+ QMimeData *mDropData;
+ QWaylandDragWrapper *mCurrentDrag;
+ QWaylandDragOfferWrapper *mCurrentOffer;
+ int mPipeWriteEnd;
+ QSocketNotifier *mPipeWatcher;
+ QByteArray mPipeData;
+ QString mMimeFormat;
+ friend class QWaylandDragWrapper;
+ friend class QWaylandDragOfferWrapper;
+};
+
+#endif // QWAYLANDDND_H
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
index 3c9afafada..c1e2325766 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
@@ -113,7 +113,7 @@ void QWaylandInputDevice::inputHandleMotion(void *data,
inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
inputDevice->mGlobalPos = QPoint(x, y);
inputDevice->mTime = time;
- QWindowSystemInterface::handleMouseEvent(window->widget(),
+ QWindowSystemInterface::handleMouseEvent(window->window(),
time,
inputDevice->mSurfacePos,
inputDevice->mGlobalPos,
@@ -155,7 +155,7 @@ void QWaylandInputDevice::inputHandleButton(void *data,
inputDevice->mButtons &= ~qt_button;
inputDevice->mTime = time;
- QWindowSystemInterface::handleMouseEvent(window->widget(),
+ QWindowSystemInterface::handleMouseEvent(window->window(),
time,
inputDevice->mSurfacePos,
inputDevice->mGlobalPos,
@@ -272,7 +272,7 @@ void QWaylandInputDevice::inputHandleKey(void *data,
sym = translateKey(sym, s, sizeof s);
if (window) {
- QWindowSystemInterface::handleKeyEvent(window->widget(),
+ QWindowSystemInterface::handleKeyEvent(window->window(),
time, type, sym,
inputDevice->mModifiers,
QString::fromLatin1(s));
@@ -295,13 +295,13 @@ void QWaylandInputDevice::inputHandlePointerFocus(void *data,
if (inputDevice->mPointerFocus) {
window = inputDevice->mPointerFocus;
- QWindowSystemInterface::handleLeaveEvent(window->widget());
+ QWindowSystemInterface::handleLeaveEvent(window->window());
inputDevice->mPointerFocus = NULL;
}
if (surface) {
window = (QWaylandWindow *) wl_surface_get_user_data(surface);
- QWindowSystemInterface::handleEnterEvent(window->widget());
+ QWindowSystemInterface::handleEnterEvent(window->window());
inputDevice->mPointerFocus = window;
}
@@ -333,7 +333,7 @@ void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
if (surface) {
window = (QWaylandWindow *) wl_surface_get_user_data(surface);
inputDevice->mKeyboardFocus = window;
- QWindowSystemInterface::handleWindowActivated(window->widget());
+ QWindowSystemInterface::handleWindowActivated(window->window());
} else {
inputDevice->mKeyboardFocus = NULL;
QWindowSystemInterface::handleWindowActivated(0);
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h
index 008ecf144d..05ebe05969 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.h
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h
@@ -63,6 +63,7 @@ public:
void attach(QWaylandBuffer *buffer, int x, int y);
void handleWindowDestroyed(QWaylandWindow *window);
struct wl_input_device *wl_input_device() const { return mInputDevice; }
+ QWaylandWindow *pointerFocus() const { return mPointerFocus; }
private:
QWaylandDisplay *mQDisplay;
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 5df71dc936..e17c2f8d95 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -42,30 +42,36 @@
#include "qwaylandintegration.h"
#include "qwaylanddisplay.h"
-#include "qwaylandshmsurface.h"
+#include "qwaylandshmbackingstore.h"
#include "qwaylandshmwindow.h"
#include "qwaylandnativeinterface.h"
#include "qwaylandclipboard.h"
+#include "qwaylanddnd.h"
-#include "qgenericunixfontdatabase.h"
+#include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QWindowSystemInterface>
#include <QtGui/QPlatformCursor>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QSurfaceFormat>
+#include <QtGui/QOpenGLContext>
-#include <QtGui/private/qpixmap_raster_p.h>
#ifdef QT_WAYLAND_GL_SUPPORT
#include "gl_integration/qwaylandglintegration.h"
-#include "gl_integration/qwaylandglwindowsurface.h"
-#include <QtOpenGL/private/qpixmapdata_gl_p.h>
#endif
-QWaylandIntegration::QWaylandIntegration(bool useOpenGL)
+QWaylandIntegration::QWaylandIntegration()
: mFontDb(new QGenericUnixFontDatabase())
- , mDisplay(new QWaylandDisplay())
- , mUseOpenGL(useOpenGL)
+ , mEventDispatcher(createUnixEventDispatcher())
, mNativeInterface(new QWaylandNativeInterface)
{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
+ mDisplay = new QWaylandDisplay();
+
+ foreach (QPlatformScreen *screen, mDisplay->screens())
+ screenAdded(screen);
}
QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
@@ -73,68 +79,63 @@ QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
return mNativeInterface;
}
-QList<QPlatformScreen *>
-QWaylandIntegration::screens() const
-{
- return mDisplay->screens();
-}
-
bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
- case OpenGL: return hasOpenGL();
+ case OpenGL:
+#ifdef QT_WAYLAND_GL_SUPPORT
+ return true;
+#else
+ return false;
+#endif
+ case ThreadedOpenGL:
+ return hasCapability(OpenGL);
default: return QPlatformIntegration::hasCapability(cap);
}
}
-QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const
{
#ifdef QT_WAYLAND_GL_SUPPORT
- if (mUseOpenGL)
- return new QGLPixmapData(type);
+ if (window->surfaceType() == QWindow::OpenGLSurface)
+ return mDisplay->eglIntegration()->createEglWindow(window);
#endif
- return new QRasterPixmapData(type);
+ return new QWaylandShmWindow(window);
}
-QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+QPlatformOpenGLContext *QWaylandIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- Q_UNUSED(winId);
#ifdef QT_WAYLAND_GL_SUPPORT
- bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
- if (useOpenGL)
- return mDisplay->eglIntegration()->createEglWindow(widget);
+ return mDisplay->eglIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle());
+#else
+ Q_UNUSED(glFormat);
+ Q_UNUSED(share);
+ return 0;
#endif
- return new QWaylandShmWindow(widget);
}
-QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
- Q_UNUSED(winId);
-#ifdef QT_WAYLAND_GL_SUPPORT
- bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
- if (useOpenGL)
- return new QWaylandGLWindowSurface(widget);
-#endif
- return new QWaylandShmWindowSurface(widget);
+ return new QWaylandShmBackingStore(window);
}
-QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
+QAbstractEventDispatcher *QWaylandIntegration::guiThreadEventDispatcher() const
{
- return mFontDb;
+ return mEventDispatcher;
}
-bool QWaylandIntegration::hasOpenGL() const
+QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
{
-#ifdef QT_WAYLAND_GL_SUPPORT
- return true;
-#else
- return false;
-#endif
+ return mFontDb;
}
QPlatformClipboard *QWaylandIntegration::clipboard() const
{
return QWaylandClipboard::instance(mDisplay);
}
+
+QPlatformDrag *QWaylandIntegration::drag() const
+{
+ return QWaylandDrag::instance(mDisplay);
+}
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
index f617d9697b..61e8559a7d 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -48,18 +48,19 @@ QT_BEGIN_NAMESPACE
class QWaylandBuffer;
class QWaylandDisplay;
+class QAbstractEventDispatcher;
class QWaylandIntegration : public QPlatformIntegration
{
public:
- QWaylandIntegration(bool useOpenGL = false);
+ QWaylandIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
- QList<QPlatformScreen *> screens() const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
QPlatformFontDatabase *fontDatabase() const;
@@ -67,12 +68,12 @@ public:
QPlatformClipboard *clipboard() const;
-private:
- bool hasOpenGL() const;
+ QPlatformDrag *drag() const;
+private:
QPlatformFontDatabase *mFontDb;
+ QAbstractEventDispatcher *mEventDispatcher;
QWaylandDisplay *mDisplay;
- bool mUseOpenGL;
QPlatformNativeInterface *mNativeInterface;
};
diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
index 17736968c6..d81fa350e9 100644
--- a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
@@ -42,34 +42,33 @@
#include "qwaylandnativeinterface.h"
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QScreen>
#include "windowmanager_integration/qwaylandwindowmanagerintegration.h"
-#include <QtGui/private/qapplication_p.h>
-#include <QDebug>
-
-void *QWaylandNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
QByteArray lowerCaseResource = resourceString.toLower();
if (lowerCaseResource == "display")
- return qPlatformScreenForWidget(widget)->display()->wl_display();
+ return qPlatformScreenForWindow(window)->display()->wl_display();
if (lowerCaseResource == "surface") {
- return ((QWaylandWindow *) widget->platformWindow())->wl_surface();
+ return ((QWaylandWindow *) window->handle())->wl_surface();
}
return NULL;
}
-QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWindow(QWindow *window)
{
QWaylandScreen *screen;
- if (widget) {
- screen = static_cast<QWaylandScreen *>(QPlatformScreen::platformScreenForWidget(widget));
+ if (window) {
+ screen = static_cast<QWaylandScreen *>(window->screen()->handle());
} else {
- screen = static_cast<QWaylandScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
+ screen = static_cast<QWaylandScreen *>(QGuiApplication::primaryScreen()->handle());
}
return screen;
}
diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.h b/src/plugins/platforms/wayland/qwaylandnativeinterface.h
index c92b44eb03..9db442a265 100644
--- a/src/plugins/platforms/wayland/qwaylandnativeinterface.h
+++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.h
@@ -49,8 +49,8 @@
class QWaylandNativeInterface : public QPlatformNativeInterface
{
public:
- void *nativeResourceForWidget(const QByteArray &resourceString,
- QWidget *widget);
+ void *nativeResourceForWindow(const QByteArray &resourceString,
+ QWindow *window);
QVariantMap windowProperties(QPlatformWindow *window) const;
QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
@@ -58,7 +58,7 @@ public:
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
private:
- static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget);
+ static QWaylandScreen *qPlatformScreenForWindow(QWindow *window);
private:
QHash<QPlatformWindow*, QVariantMap> m_windowProperties;
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp
index be6dcb2e88..7b064bac40 100644
--- a/src/plugins/platforms/wayland/qwaylandscreen.cpp
+++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp
@@ -53,7 +53,6 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output
, mFormat(QImage::Format_ARGB32_Premultiplied)
, mWaylandCursor(new QWaylandCursor(this))
{
- moveToThread(waylandDisplay->thread());
}
QWaylandScreen::~QWaylandScreen()
@@ -81,9 +80,9 @@ QImage::Format QWaylandScreen::format() const
return mFormat;
}
-QWaylandScreen * QWaylandScreen::waylandScreenFromWidget(QWidget *widget)
+QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window)
{
- QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWidget(widget);
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window);
return static_cast<QWaylandScreen *>(platformScreen);
}
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.h b/src/plugins/platforms/wayland/qwaylandscreen.h
index f2b3bcefbc..9bf4f6574a 100644
--- a/src/plugins/platforms/wayland/qwaylandscreen.h
+++ b/src/plugins/platforms/wayland/qwaylandscreen.h
@@ -62,7 +62,7 @@ public:
wl_visual *visual() const;
- static QWaylandScreen *waylandScreenFromWidget(QWidget *widget);
+ static QWaylandScreen *waylandScreenFromWindow(QWindow *window);
private:
QWaylandDisplay *mWaylandDisplay;
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
index b24c419424..25a1b466d4 100644
--- a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
@@ -38,10 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include "qwaylandshmsurface.h"
+#include "qwaylandshmbackingstore.h"
#include <QtCore/qdebug.h>
-#include <QtGui/private/qapplication_p.h>
#include "qwaylanddisplay.h"
#include "qwaylandshmwindow.h"
@@ -91,34 +90,34 @@ QWaylandShmBuffer::~QWaylandShmBuffer(void)
wl_buffer_destroy(mBuffer);
}
-QWaylandShmWindowSurface::QWaylandShmWindowSurface(QWidget *window)
- : QWindowSurface(window)
+QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
, mBuffer(0)
- , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
+ , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display())
{
}
-QWaylandShmWindowSurface::~QWaylandShmWindowSurface()
+QWaylandShmBackingStore::~QWaylandShmBackingStore()
{
}
-QPaintDevice *QWaylandShmWindowSurface::paintDevice()
+QPaintDevice *QWaylandShmBackingStore::paintDevice()
{
return mBuffer->image();
}
-void QWaylandShmWindowSurface::beginPaint(const QRegion &)
+void QWaylandShmBackingStore::beginPaint(const QRegion &)
{
- QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle());
Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
waylandWindow->waitForFrameSync();
}
-void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
Q_UNUSED(offset);
- QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window->handle());
Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
QVector<QRect> rects = region.rects();
for (int i = 0; i < rects.size(); i++) {
@@ -128,13 +127,12 @@ void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, con
}
}
-void QWaylandShmWindowSurface::resize(const QSize &size)
+void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &)
{
- QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle());
Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
- QWindowSurface::resize(size);
- QImage::Format format = QPlatformScreen::platformScreenForWidget(window())->format();
+ QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format();
if (mBuffer != NULL && mBuffer->size() == size)
return;
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.h b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h
index f3db8b86e5..5e6959dc2f 100644
--- a/src/plugins/platforms/wayland/qwaylandshmsurface.h
+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h
@@ -39,12 +39,12 @@
**
****************************************************************************/
-#ifndef QWINDOWSURFACE_WAYLAND_H
-#define QWINDOWSURFACE_WAYLAND_H
+#ifndef QWAYLANDSHMBACKINGSTORE_H
+#define QWAYLANDSHMBACKINGSTORE_H
#include "qwaylandbuffer.h"
-#include <QtGui/private/qwindowsurface_p.h>
-
+#include <QtGui/QPlatformBackingStore>
+#include <QtGui/QImage>
#include <QtGui/QPlatformWindow>
QT_BEGIN_NAMESPACE
@@ -62,15 +62,15 @@ private:
QImage mImage;
};
-class QWaylandShmWindowSurface : public QWindowSurface
+class QWaylandShmBackingStore : public QPlatformBackingStore
{
public:
- QWaylandShmWindowSurface(QWidget *window);
- ~QWaylandShmWindowSurface();
+ QWaylandShmBackingStore(QWindow *window);
+ ~QWaylandShmBackingStore();
QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
void beginPaint(const QRegion &);
private:
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
index a6b7050f7a..ba5e46cab1 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
@@ -47,8 +47,8 @@
#include <QtCore/QDebug>
-QWaylandShmWindow::QWaylandShmWindow(QWidget *widget)
- : QWaylandWindow(widget)
+QWaylandShmWindow::QWaylandShmWindow(QWindow *window)
+ : QWaylandWindow(window)
{
newSurfaceCreated();
}
@@ -63,9 +63,3 @@ QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
return QWaylandWindow::Shm;
}
-QPlatformGLContext * QWaylandShmWindow::glContext() const
-{
- qWarning("Trying to retrieve a glContext from a Raster window surface!");
- return 0;
-}
-
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h
index 8033703391..36f9f225b7 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h
@@ -48,11 +48,11 @@
class QWaylandShmWindow : public QWaylandWindow
{
public:
- QWaylandShmWindow(QWidget *widget);
+ QWaylandShmWindow(QWindow *window);
~QWaylandShmWindow();
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QSurfaceFormat format() const { return QSurfaceFormat(); }
};
#endif // QWAYLANDSHMWINDOW_H
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index 099ebabb06..6011621044 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -46,20 +46,21 @@
#include "qwaylandinputdevice.h"
#include "qwaylandscreen.h"
+#include <QtGui/QWindow>
+
#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
#include "windowmanager_integration/qwaylandwindowmanagerintegration.h"
#endif
#include <QCoreApplication>
-#include <QtGui/QWidget>
#include <QtGui/QWindowSystemInterface>
#include <QDebug>
-QWaylandWindow::QWaylandWindow(QWidget *window)
+QWaylandWindow::QWaylandWindow(QWindow *window)
: QPlatformWindow(window)
, mSurface(0)
- , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
+ , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display())
, mBuffer(0)
, mWaitingForFrameSync(false)
{
@@ -112,11 +113,11 @@ void QWaylandWindow::configure(uint32_t time, uint32_t edges,
{
Q_UNUSED(time);
Q_UNUSED(edges);
- QRect geometry = QRect(x, y, width, height);
+ QRect geometry = QRect(x, y, width, height);
setGeometry(geometry);
- QWindowSystemInterface::handleGeometryChange(widget(), geometry);
+ QWindowSystemInterface::handleGeometryChange(window(), geometry);
}
void QWaylandWindow::attach(QWaylandBuffer *buffer)
@@ -124,6 +125,7 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer)
mBuffer = buffer;
if (mSurface) {
wl_surface_attach(mSurface, buffer->buffer(),0,0);
+ QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h
index b91f6b6eb8..4f1e2c8183 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow.h
@@ -59,7 +59,7 @@ public:
Egl
};
- QWaylandWindow(QWidget *window);
+ QWaylandWindow(QWindow *window);
~QWaylandWindow();
virtual WindowType windowType() const = 0;
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index 1e0bbe6cdd..fd6ffc06de 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -1,19 +1,23 @@
TARGET = qwayland
load(qt_plugin)
-QT+=gui-private core-private opengl-private
+CONFIG += qpa/genericunixfontdatabase
DESTDIR = $$QT.gui.plugins/platforms
DEFINES += Q_PLATFORM_WAYLAND
DEFINES += $$QMAKE_DEFINES_WAYLAND
-QT += core-private gui-private opengl-private
+mac {
+ DEFINES += QT_NO_WAYLAND_XKB
+}
+
+QT += core-private gui-private opengl-private platformsupport-private
SOURCES = main.cpp \
qwaylandintegration.cpp \
qwaylandnativeinterface.cpp \
- qwaylandshmsurface.cpp \
+ qwaylandshmbackingstore.cpp \
qwaylandinputdevice.cpp \
qwaylandcursor.cpp \
qwaylanddisplay.cpp \
@@ -21,6 +25,7 @@ SOURCES = main.cpp \
qwaylandscreen.cpp \
qwaylandshmwindow.cpp \
qwaylandclipboard.cpp \
+ qwaylanddnd.cpp \
qwaylandmime.cpp
HEADERS = qwaylandintegration.h \
@@ -29,23 +34,23 @@ HEADERS = qwaylandintegration.h \
qwaylanddisplay.h \
qwaylandwindow.h \
qwaylandscreen.h \
- qwaylandshmsurface.h \
+ qwaylandshmbackingstore.h \
qwaylandbuffer.h \
qwaylandshmwindow.h \
qwaylandclipboard.h \
+ qwaylanddnd.h \
qwaylandmime.h
INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
LIBS += $$QMAKE_LIBS_WAYLAND
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND
-
-INCLUDEPATH += $$PWD
+mac {
+ LIBS += -lwayland-client
+}
-include ($$PWD/gl_integration/gl_integration.pri)
-include ($$PWD/windowmanager_integration/windowmanager_integration.pri)
-
-include (../fontdatabases/genericunix/genericunix.pri)
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
+include ($$PWD/gl_integration/gl_integration.pri)
+include ($$PWD/windowmanager_integration/windowmanager_integration.pri)
diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
index 798900bbce..7d68571c24 100644
--- a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
+++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
@@ -49,8 +49,7 @@
#include <QtGui/QPlatformNativeInterface>
#include <QtGui/QPlatformWindow>
#include <QtGui/QtEvents>
-#include <QtGui/QWidget>
-#include <QtGui/QApplication>
+#include <QtGui/QGuiApplication>
#include <QDebug>
@@ -237,15 +236,15 @@ void QWaylandWindowManagerIntegration::wlHandleWindowPropertyChange(void *data,
QPlatformNativeInterface *nativeInterface = qApp->platformNativeInterface();
QWaylandWindowManagerIntegration *inst = QWaylandWindowManagerIntegration::instance();
- QWidgetList widgets = qApp->topLevelWidgets();
- foreach (QWidget *widget, widgets) {
- QPlatformWindow *platformWindowForWidget = widget->platformWindow();
- if (!platformWindowForWidget)
+ QList<QWindow *> windows = qApp->topLevelWindows();
+ foreach (QWindow *window, windows) {
+ QPlatformWindow *platformWindowForWindow = window->handle();
+ if (!platformWindowForWindow)
continue;
- QWaylandWindow *window = static_cast<QWaylandWindow*>(platformWindowForWidget);
- wl_surface *windowSurface = (wl_surface*)nativeInterface->nativeResourceForWidget(QByteArray("surface"), widget);
+ QWaylandWindow *waylandWindow = static_cast<QWaylandWindow*>(platformWindowForWindow);
+ wl_surface *windowSurface = (wl_surface*)nativeInterface->nativeResourceForWindow(QByteArray("surface"), window);
if (windowSurface == surface) {
- inst->handleWindowPropertyChange(window, QString(propertyName), variantValue);
+ inst->handleWindowPropertyChange(waylandWindow, QString(propertyName), variantValue);
break;
}
}
diff --git a/src/plugins/platforms/windows/array.h b/src/plugins/platforms/windows/array.h
new file mode 100644
index 0000000000..216f1e8945
--- /dev/null
+++ b/src/plugins/platforms/windows/array.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include <QtCore/QtAlgorithms>
+
+QT_BEGIN_NAMESPACE
+
+/* A simple, non-shared array. */
+
+template <class T>
+class Array
+{
+ Q_DISABLE_COPY(Array)
+public:
+ enum { initialSize = 5 };
+
+ typedef T* const_iterator;
+
+ explicit Array(size_t size= 0) : data(0), m_capacity(0), m_size(0)
+ { if (size) resize(size); }
+ ~Array() { delete [] data; }
+
+ T *data;
+ inline size_t size() const { return m_size; }
+ inline const_iterator begin() const { return data; }
+ inline const_iterator end() const { return data + m_size; }
+
+ inline void append(const T &value)
+ {
+ const size_t oldSize = m_size;
+ resize(m_size + 1);
+ data[oldSize] = value;
+ }
+
+ inline void resize(size_t size)
+ {
+ if (size > m_size)
+ reserve(size > 1 ? size + size / 2 : size_t(initialSize));
+ m_size = size;
+ }
+
+ void reserve(size_t capacity)
+ {
+ if (capacity > m_capacity) {
+ const T *oldData = data;
+ data = new T[capacity];
+ if (oldData) {
+ qCopy(oldData, oldData + m_size, data);
+ delete [] oldData;
+ }
+ m_capacity = capacity;
+ }
+ }
+
+private:
+ size_t m_capacity;
+ size_t m_size;
+};
+
+QT_END_NAMESPACE
+
+#endif // ARRAY_H
diff --git a/src/plugins/decorations/default/main.cpp b/src/plugins/platforms/windows/main.cpp
index b93b6f8b0e..933aa76df8 100644
--- a/src/plugins/decorations/default/main.cpp
+++ b/src/plugins/platforms/windows/main.cpp
@@ -2,7 +2,7 @@
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: Nokia Corporation (info@qt.nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
@@ -39,38 +39,74 @@
**
****************************************************************************/
-#include <qdecorationplugin_qws.h>
-#include <qdecorationdefault_qws.h>
+
+#include <QtGui/QPlatformIntegrationPlugin>
+#include <QtCore/QStringList>
+
+#include "qwindowsintegration.h"
QT_BEGIN_NAMESPACE
-class DecorationDefault : public QDecorationPlugin
+/*!
+ \group qt-lighthouse-win
+ \title Qt Lighthouse plugin for Windows
+
+ \brief Class documentation of the Qt Lighthouse plugin for Windows.
+
+ \section1 Tips
+
+ \list
+ \o The environment variable \c QT_LIGHTHOUSE_WINDOWS_VERBOSE controls
+ the debug level. It takes the form
+ \c{<keyword1>:<level1>,<keyword2>:<level2>}, where
+ keyword is one of \c integration, \c windows, \c backingstore and
+ \c fonts. Level is an integer 0..9.
+ \endlist
+ */
+
+/*!
+ \class QWindowsIntegrationPlugin
+ \brief Plugin.
+ \ingroup qt-lighthouse-win
+ */
+
+/*!
+ \namespace QtWindows
+
+ \brief Namespace for enumerations, etc.
+ \ingroup qt-lighthouse-win
+*/
+
+/*!
+ \enum QtWindows::WindowsEventType
+
+ \brief Enumerations for WM_XX events.
+
+ With flags that should help to structure the code.
+
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsIntegrationPlugin : public QPlatformIntegrationPlugin
{
public:
- DecorationDefault();
-
QStringList keys() const;
- QDecoration *create(const QString&);
+ QPlatformIntegration *create(const QString&, const QStringList&);
};
-DecorationDefault::DecorationDefault()
- : QDecorationPlugin()
+QStringList QWindowsIntegrationPlugin::keys() const
{
+ return QStringList(QStringLiteral("windows"));
}
-QStringList DecorationDefault::keys() const
+QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
- return (QStringList() << QLatin1String("Default"));
-}
-
-QDecoration* DecorationDefault::create(const QString& s)
-{
- if (s.toLower() == QLatin1String("default"))
- return new QDecorationDefault();
-
+ Q_UNUSED(paramList);
+ if (system.compare(system, QStringLiteral("windows"), Qt::CaseInsensitive) == 0)
+ return new QWindowsIntegration;
return 0;
}
-Q_EXPORT_PLUGIN2(qdecorationdefault, DecorationDefault)
+Q_EXPORT_PLUGIN2(windows, QWindowsIntegrationPlugin)
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/pixmaputils.cpp b/src/plugins/platforms/windows/pixmaputils.cpp
new file mode 100644
index 0000000000..111df5a4b9
--- /dev/null
+++ b/src/plugins/platforms/windows/pixmaputils.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pixmaputils.h"
+
+#include <QtGui/QBitmap>
+#include <QtGui/QImage>
+#include <QtGui/QPlatformPixmap>
+#include <QtGui/private/qpixmap_raster_p.h>
+
+#include <QtCore/QScopedArrayPointer>
+#include <QtCore/QDebug>
+
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+HBITMAP createIconMask(const QBitmap &bitmap)
+{
+ QImage bm = bitmap.toImage().convertToFormat(QImage::Format_Mono);
+ const int w = bm.width();
+ const int h = bm.height();
+ const int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment
+ QScopedArrayPointer<uchar> bits(new uchar[bpl * h]);
+ bm.invertPixels();
+ for (int y = 0; y < h; ++y)
+ memcpy(bits.data() + y * bpl, bm.scanLine(y), bpl);
+ HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits.data());
+ return hbm;
+}
+
+HBITMAP qPixmapToWinHBITMAP(const QPixmap &p, HBitmapFormat format)
+{
+ if (p.isNull())
+ return 0;
+
+ HBITMAP bitmap = 0;
+ if (p.handle()->classId() != QPlatformPixmap::RasterClass) {
+ QRasterPlatformPixmap *data = new QRasterPlatformPixmap(p.depth() == 1 ?
+ QRasterPlatformPixmap::BitmapType : QRasterPlatformPixmap::PixmapType);
+ data->fromImage(p.toImage(), Qt::AutoColor);
+ return qPixmapToWinHBITMAP(QPixmap(data), format);
+ }
+
+ QRasterPlatformPixmap *d = static_cast<QRasterPlatformPixmap*>(p.handle());
+ const QImage *rasterImage = d->buffer();
+ const int w = rasterImage->width();
+ const int h = rasterImage->height();
+
+ HDC display_dc = GetDC(0);
+
+ // Define the header
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ // Create the pixmap
+ uchar *pixels = 0;
+ bitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (void **) &pixels, 0, 0);
+ ReleaseDC(0, display_dc);
+ if (!bitmap) {
+ qErrnoWarning("%s, failed to create dibsection", __FUNCTION__);
+ return 0;
+ }
+ if (!pixels) {
+ qErrnoWarning("%s, did not allocate pixel data", __FUNCTION__);
+ return 0;
+ }
+
+ // Copy over the data
+ QImage::Format imageFormat = QImage::Format_ARGB32;
+ if (format == HBitmapAlpha)
+ imageFormat = QImage::Format_RGB32;
+ else if (format == HBitmapPremultipliedAlpha)
+ imageFormat = QImage::Format_ARGB32_Premultiplied;
+ const QImage image = rasterImage->convertToFormat(imageFormat);
+ const int bytes_per_line = w * 4;
+ for (int y=0; y < h; ++y)
+ memcpy(pixels + y * bytes_per_line, image.scanLine(y), bytes_per_line);
+
+ return bitmap;
+}
+
+QPixmap qPixmapFromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format)
+{
+ // Verify size
+ BITMAP bitmap_info;
+ memset(&bitmap_info, 0, sizeof(BITMAP));
+
+ const int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info);
+ if (!res) {
+ qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info");
+ return QPixmap();
+ }
+ const int w = bitmap_info.bmWidth;
+ const int h = bitmap_info.bmHeight;
+
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ // Get bitmap bits
+ QScopedArrayPointer<uchar> data(new uchar[bmi.bmiHeader.biSizeImage]);
+ HDC display_dc = GetDC(0);
+ if (!GetDIBits(display_dc, bitmap, 0, h, data.data(), &bmi, DIB_RGB_COLORS)) {
+ ReleaseDC(0, display_dc);
+ qWarning("%s, failed to get bitmap bits", __FUNCTION__);
+ return QPixmap();
+ }
+
+ QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied;
+ uint mask = 0;
+ if (format == HBitmapNoAlpha) {
+ imageFormat = QImage::Format_RGB32;
+ mask = 0xff000000;
+ }
+
+ // Create image and copy data into image.
+ QImage image(w, h, imageFormat);
+ if (image.isNull()) { // failed to alloc?
+ ReleaseDC(0, display_dc);
+ qWarning("%s, failed create image of %dx%d", __FUNCTION__, w, h);
+ return QPixmap();
+ }
+ const int bytes_per_line = w * sizeof(QRgb);
+ for (int y = 0; y < h; ++y) {
+ QRgb *dest = (QRgb *) image.scanLine(y);
+ const QRgb *src = (const QRgb *) (data.data() + y * bytes_per_line);
+ for (int x = 0; x < w; ++x) {
+ const uint pixel = src[x];
+ if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0)
+ dest[x] = pixel | 0xff000000;
+ else
+ dest[x] = pixel | mask;
+ }
+ }
+ ReleaseDC(0, display_dc);
+ return QPixmap::fromImage(image);
+}
+
+HICON qPixmapToWinHICON(const QPixmap &p)
+{
+ QBitmap maskBitmap = p.mask();
+ if (maskBitmap.isNull()) {
+ maskBitmap = QBitmap(p.size());
+ maskBitmap.fill(Qt::color1);
+ }
+
+ ICONINFO ii;
+ ii.fIcon = true;
+ ii.hbmMask = createIconMask(maskBitmap);
+ ii.hbmColor = qPixmapToWinHBITMAP(p, HBitmapAlpha);
+ ii.xHotspot = 0;
+ ii.yHotspot = 0;
+
+ HICON hIcon = CreateIconIndirect(&ii);
+
+ DeleteObject(ii.hbmColor);
+ DeleteObject(ii.hbmMask);
+
+ return hIcon;
+}
+
+static QImage qImageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
+{
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
+ if (image.isNull())
+ return image;
+
+ // Get bitmap bits
+ QScopedPointer<uchar> data(new uchar [bmi.bmiHeader.biSizeImage]);
+ if (!GetDIBits(hdc, bitmap, 0, h, data.data(), &bmi, DIB_RGB_COLORS)) {
+ qErrnoWarning("%s: failed to get bitmap bits", __FUNCTION__);
+ return QImage();
+ }
+ // Create image and copy data into image.
+ for (int y = 0; y < h; ++y) {
+ void *dest = (void *) image.scanLine(y);
+ void *src = data.data() + y * image.bytesPerLine();
+ memcpy(dest, src, image.bytesPerLine());
+ }
+ return image;
+}
+
+QPixmap qPixmapFromWinHICON(HICON icon)
+{
+ bool foundAlpha = false;
+ HDC screenDevice = GetDC(0);
+ HDC hdc = CreateCompatibleDC(screenDevice);
+ ReleaseDC(0, screenDevice);
+
+ ICONINFO iconinfo;
+ const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
+ if (!result) {
+ qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
+ return QPixmap();
+ }
+
+ const int w = iconinfo.xHotspot * 2;
+ const int h = iconinfo.yHotspot * 2;
+
+ BITMAPINFOHEADER bitmapInfo;
+ bitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.biWidth = w;
+ bitmapInfo.biHeight = h;
+ bitmapInfo.biPlanes = 1;
+ bitmapInfo.biBitCount = 32;
+ bitmapInfo.biCompression = BI_RGB;
+ bitmapInfo.biSizeImage = 0;
+ bitmapInfo.biXPelsPerMeter = 0;
+ bitmapInfo.biYPelsPerMeter = 0;
+ bitmapInfo.biClrUsed = 0;
+ bitmapInfo.biClrImportant = 0;
+ DWORD* bits;
+
+ HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0);
+ HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);
+ DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
+ QImage image = qImageFromWinHBITMAP(hdc, winBitmap, w, h);
+
+ for (int y = 0 ; y < h && !foundAlpha ; y++) {
+ const QRgb *scanLine= reinterpret_cast<const QRgb *>(image.scanLine(y));
+ for (int x = 0; x < w ; x++) {
+ if (qAlpha(scanLine[x]) != 0) {
+ foundAlpha = true;
+ break;
+ }
+ }
+ }
+ if (!foundAlpha) {
+ //If no alpha was found, we use the mask to set alpha values
+ DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
+ const QImage mask = qImageFromWinHBITMAP(hdc, winBitmap, w, h);
+
+ for (int y = 0 ; y < h ; y++){
+ QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y));
+ const QRgb *scanlineMask = mask.isNull() ? 0 : reinterpret_cast<const QRgb *>(mask.scanLine(y));
+ for (int x = 0; x < w ; x++){
+ if (scanlineMask && qRed(scanlineMask[x]) != 0)
+ scanlineImage[x] = 0; //mask out this pixel
+ else
+ scanlineImage[x] |= 0xff000000; // set the alpha channel to 255
+ }
+ }
+ }
+ //dispose resources created by iconinfo call
+ DeleteObject(iconinfo.hbmMask);
+ DeleteObject(iconinfo.hbmColor);
+
+ SelectObject(hdc, oldhdc); //restore state
+ DeleteObject(winBitmap);
+ DeleteDC(hdc);
+ return QPixmap::fromImage(image);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/pixmaputils.h b/src/plugins/platforms/windows/pixmaputils.h
new file mode 100644
index 0000000000..bf94a2695c
--- /dev/null
+++ b/src/plugins/platforms/windows/pixmaputils.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PIXMAPUTILS_H
+#define PIXMAPUTILS_H
+
+#include "qtwindows_additional.h"
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+class QBitmap;
+class QPixmap;
+
+enum HBitmapFormat
+{
+ HBitmapNoAlpha,
+ HBitmapPremultipliedAlpha,
+ HBitmapAlpha
+};
+
+HBITMAP createIconMask(const QBitmap &bitmap);
+
+HBITMAP qPixmapToWinHBITMAP(const QPixmap &p, HBitmapFormat format);
+HICON qPixmapToWinHICON(const QPixmap &p);
+
+QPixmap qPixmapFromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format);
+QPixmap qPixmapFromWinHICON(HICON icon);
+
+QT_END_NAMESPACE
+
+#endif // PIXMAPUTILS_H
diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h
new file mode 100644
index 0000000000..e262159b7b
--- /dev/null
+++ b/src/plugins/platforms/windows/qtwindows_additional.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTWINDOWS_ADDITIONAL_H
+#define QTWINDOWS_ADDITIONAL_H
+
+#include <QtCore/QtGlobal> // get compiler define
+#include <QtCore/qt_windows.h>
+
+/* Complement the definitions and declarations missing
+ * when using MinGW or older Windows SDKs. */
+
+#if defined(Q_CC_MINGW)
+# if !defined(ULW_ALPHA)
+# define ULW_ALPHA 0x00000002
+# define LWA_ALPHA 0x00000002
+# endif // !defined(ULW_ALPHA)
+# define SPI_GETFONTSMOOTHINGTYPE 0x200A
+# define FE_FONTSMOOTHINGCLEARTYPE 0x0002
+# define CLEARTYPE_QUALITY 5
+
+# define CF_DIBV5 17
+
+#define CO_E_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80004021L)
+
+typedef struct tagUPDATELAYEREDWINDOWINFO {
+ DWORD cbSize;
+ HDC hdcDst;
+ const POINT *pptDst;
+ const SIZE *psize;
+ HDC hdcSrc;
+ const POINT *pptSrc;
+ COLORREF crKey;
+ const BLENDFUNCTION *pblend;
+ DWORD dwFlags;
+ const RECT *prcDirty;
+} UPDATELAYEREDWINDOWINFO, *PUPDATELAYEREDWINDOWINFO;
+
+// OpenGL Pixelformat flags.
+#define PFD_SUPPORT_DIRECTDRAW 0x00002000
+#define PFD_DIRECT3D_ACCELERATED 0x00004000
+#define PFD_SUPPORT_COMPOSITION 0x00008000
+
+// IME.
+#define IMR_CONFIRMRECONVERTSTRING 0x0005
+
+#endif // if defined(Q_CC_MINGW)
+
+/* Touch is supported from Windows 7 onwards and data structures
+ * are present in the Windows SDK's, but not in older MSVC Express
+ * versions. */
+
+#if defined(Q_CC_MINGW) || !defined(TOUCHEVENTF_MOVE)
+
+#define WM_TOUCH 0x0240
+
+typedef struct tagTOUCHINPUT {
+ LONG x;
+ LONG y;
+ HANDLE hSource;
+ DWORD dwID;
+ DWORD dwFlags;
+ DWORD dwMask;
+ DWORD dwTime;
+ ULONG_PTR dwExtraInfo;
+ DWORD cxContact;
+ DWORD cyContact;
+} TOUCHINPUT, *PTOUCHINPUT;
+typedef TOUCHINPUT const * PCTOUCHINPUT;
+
+# define TOUCHEVENTF_MOVE 0x0001
+# define TOUCHEVENTF_DOWN 0x0002
+# define TOUCHEVENTF_UP 0x0004
+# define TOUCHEVENTF_INRANGE 0x0008
+# define TOUCHEVENTF_PRIMARY 0x0010
+# define TOUCHEVENTF_NOCOALESCE 0x0020
+# define TOUCHEVENTF_PALM 0x0080
+# define TOUCHINPUTMASKF_CONTACTAREA 0x0004
+# define TOUCHINPUTMASKF_EXTRAINFO 0x0002
+
+#endif // if defined(Q_CC_MINGW) || !defined(TOUCHEVENTF_MOVE)
+
+#endif // QTWINDOWS_ADDITIONAL_H
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
new file mode 100644
index 0000000000..692489dfc6
--- /dev/null
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTWINDOWSGLOBAL_H
+#define QTWINDOWSGLOBAL_H
+
+#include "qtwindows_additional.h"
+#include <QtCore/qnamespace.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWindows
+{
+
+enum
+{
+ WindowEventFlag = 0x10000,
+ MouseEventFlag = 0x20000,
+ NonClientEventFlag = 0x40000,
+ InputMethodEventFlag = 0x80000,
+ KeyEventFlag = 0x100000,
+ KeyDownEventFlag = 0x200000,
+ TouchEventFlag = 0x400000,
+ ClipboardEventFlag = 0x800000,
+ ApplicationEventFlag = 0x1000000
+};
+
+enum WindowsEventType // Simplify event types
+{
+ ExposeEvent = WindowEventFlag + 1,
+ ActivateWindowEvent = WindowEventFlag + 2,
+ DeactivateWindowEvent = WindowEventFlag + 3,
+ LeaveEvent = WindowEventFlag + 5,
+ CloseEvent = WindowEventFlag + 6,
+ ShowEvent = WindowEventFlag + 7,
+ HideEvent = WindowEventFlag + 8,
+ DestroyEvent = WindowEventFlag + 9,
+ MoveEvent = WindowEventFlag + 10,
+ ResizeEvent = WindowEventFlag + 12,
+ QuerySizeHints = WindowEventFlag + 15,
+ CalculateSize = WindowEventFlag + 16,
+ MouseEvent = MouseEventFlag + 1,
+ MouseWheelEvent = MouseEventFlag + 2,
+ TouchEvent = TouchEventFlag + 1,
+ NonClientMouseEvent = NonClientEventFlag + MouseEventFlag + 1,
+ KeyEvent = KeyEventFlag + 1,
+ KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1,
+ InputMethodKeyEvent = InputMethodEventFlag + KeyEventFlag + 1,
+ InputMethodKeyDownEvent = InputMethodEventFlag + KeyEventFlag + KeyDownEventFlag + 1,
+ ClipboardEvent = ClipboardEventFlag + 1,
+ ActivateApplicationEvent = ApplicationEventFlag + 1,
+ DeactivateApplicationEvent = ApplicationEventFlag + 2,
+ InputMethodStartCompositionEvent = InputMethodEventFlag + 1,
+ InputMethodCompositionEvent = InputMethodEventFlag + 2,
+ InputMethodEndCompositionEvent = InputMethodEventFlag + 3,
+ InputMethodOpenCandidateWindowEvent = InputMethodEventFlag + 4,
+ InputMethodCloseCandidateWindowEvent = InputMethodEventFlag + 5,
+ InputMethodRequest = InputMethodEventFlag + 6,
+ UnknownEvent = 542
+};
+
+} // namespace QtWindows
+
+inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamIn)
+{
+ switch (message) {
+ case WM_PAINT:
+ case WM_ERASEBKGND:
+ return QtWindows::ExposeEvent;
+ case WM_CLOSE:
+ return QtWindows::CloseEvent;
+ case WM_DESTROY:
+ return QtWindows::DestroyEvent;
+ case WM_ACTIVATEAPP:
+ return (int)wParamIn ?
+ QtWindows::ActivateApplicationEvent : QtWindows::DeactivateApplicationEvent;
+ case WM_ACTIVATE:
+ return LOWORD(wParamIn) == WA_INACTIVE ?
+ QtWindows::DeactivateWindowEvent : QtWindows::ActivateWindowEvent;
+ case WM_MOUSELEAVE:
+ return QtWindows::MouseEvent;
+ case WM_MOUSEWHEEL:
+ case WM_MOUSEHWHEEL:
+ return QtWindows::MouseWheelEvent;
+ case WM_MOVE:
+ return QtWindows::MoveEvent;
+ case WM_SHOWWINDOW:
+ return wParamIn ? QtWindows::ShowEvent : QtWindows::HideEvent;
+ case WM_SIZE:
+ return QtWindows::ResizeEvent;
+ case WM_NCCALCSIZE:
+ return QtWindows::CalculateSize;
+ case WM_GETMINMAXINFO:
+ return QtWindows::QuerySizeHints;
+ case WM_KEYDOWN: // keyboard event
+ case WM_SYSKEYDOWN:
+ return QtWindows::KeyDownEvent;
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ case WM_CHAR:
+ return QtWindows::KeyEvent;
+ case WM_IME_CHAR:
+ return QtWindows::InputMethodKeyEvent;
+ case WM_IME_KEYDOWN:
+ return QtWindows::InputMethodKeyDownEvent;
+ case WM_TOUCH:
+ return QtWindows::TouchEvent;
+ case WM_CHANGECBCHAIN:
+ case WM_DRAWCLIPBOARD:
+ case WM_RENDERFORMAT:
+ case WM_RENDERALLFORMATS:
+ case WM_DESTROYCLIPBOARD:
+ return QtWindows::ClipboardEvent;
+ case WM_IME_STARTCOMPOSITION:
+ return QtWindows::InputMethodStartCompositionEvent;
+ case WM_IME_ENDCOMPOSITION:
+ return QtWindows::InputMethodEndCompositionEvent;
+ case WM_IME_COMPOSITION:
+ return QtWindows::InputMethodCompositionEvent;
+ case WM_IME_REQUEST:
+ return QtWindows::InputMethodRequest;
+ case WM_IME_NOTIFY:
+ switch (int(wParamIn)) {
+ case IMN_OPENCANDIDATE:
+ return QtWindows::InputMethodOpenCandidateWindowEvent;
+ case IMN_CLOSECANDIDATE:
+ return QtWindows::InputMethodCloseCandidateWindowEvent;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ if (message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK)
+ return QtWindows::NonClientMouseEvent; //
+ if ((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST)
+ || (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK))
+ return QtWindows::MouseEvent;
+ return QtWindows::UnknownEvent;
+}
+
+QT_END_NAMESPACE
+
+#endif // QTWINDOWSGLOBAL_H
diff --git a/src/plugins/platforms/windows/qwindows.qdocconf b/src/plugins/platforms/windows/qwindows.qdocconf
new file mode 100644
index 0000000000..c5a1ee904a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindows.qdocconf
@@ -0,0 +1,27 @@
+project = "Qt Windows Lighthouse Plugin"
+description = "Documentation of the Qt Windows Lighthouse Plugin"
+
+language = Cpp
+
+headerdirs = .
+
+sourcedirs = .
+
+showinternal = true
+
+headers.fileextensions = "*.h"
+sources.fileextensions = "*.cpp *.qdoc"
+
+outputdir = doc
+
+qhp.projects = QtLighthouseWindows
+qhp.QtLighthouseWindowsDev.file = qtlighthousewindows-dev.qhp
+qhp.QtLighthouseWindowsDev.namespace = com.nokia.qt.developer.lighthouse
+qhp.QtLighthouseWindowsDev.virtualFolder = doc
+qhp.QtLighthouseWindowsDev.indexTitle = Qt Windows Lighthouse Plugin
+qhp.QtLighthouseWindowsDev.indexRoot =
+
+# Doxygen compatibility commands
+
+macro.see = "\\sa"
+macro.function = "\\fn"
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
new file mode 100644
index 0000000000..a3698c4a7c
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsbackingstore.h"
+#include "qwindowswindow.h"
+#include "qwindowsnativeimage.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/QWindow>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsBackingStore
+ \brief Backing store for windows.
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsBackingStore::QWindowsBackingStore(QWindow *window) :
+ QPlatformBackingStore(window)
+{
+ if (QWindowsContext::verboseBackingStore)
+ qDebug() << __FUNCTION__ << this << window;
+}
+
+QWindowsBackingStore::~QWindowsBackingStore()
+{
+ if (QWindowsContext::verboseBackingStore)
+ qDebug() << __FUNCTION__ << this;
+}
+
+QPaintDevice *QWindowsBackingStore::paintDevice()
+{
+ Q_ASSERT(!m_image.isNull());
+ return &m_image->image();
+}
+
+void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
+ const QPoint &offset)
+{
+ // TODO: Prepare paint for translucent windows.
+ const QRect br = region.boundingRect();
+ if (QWindowsContext::verboseBackingStore > 1)
+ qDebug() << __FUNCTION__ << window << offset << br;
+ QWindowsWindow *rw = rasterWindow();
+ const HDC dc = rw->getDC();
+ if (!dc) {
+ qErrnoWarning("%s: GetDC failed", __FUNCTION__);
+ return;
+ }
+
+ 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__);
+ rw->releaseDC();
+ // Write image for debug purposes.
+ if (QWindowsContext::verboseBackingStore > 2) {
+ static int n = 0;
+ const QString fileName = QString::fromAscii("win%1_%2.png").
+ arg(rw->winId()).arg(n++);
+ m_image->image().save(fileName);
+ qDebug() << "Wrote " << m_image->image().size() << fileName;
+ }
+}
+
+void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
+{
+ if (m_image.isNull() || m_image->image().size() != size) {
+ if (QWindowsContext::verboseBackingStore) {
+ QDebug nsp = qDebug().nospace();
+ nsp << __FUNCTION__ << ' ' << rasterWindow()->window()
+ << ' ' << size << ' ' << region;
+ if (!m_image.isNull())
+ nsp << " from: " << m_image->image().size();
+ }
+ m_image.reset(new QWindowsNativeImage(size.width(), size.height(),
+ QWindowsNativeImage::systemFormat()));
+ }
+}
+
+void QWindowsBackingStore::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+ if (QWindowsContext::verboseBackingStore > 1)
+ qDebug() << __FUNCTION__;
+}
+
+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())
+ return m_image->hdc();
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
new file mode 100644
index 0000000000..53f033d14b
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSBACKINGSTORE_H
+#define QWINDOWSBACKINGSTORE_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPlatformBackingStore>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsWindow;
+class QWindowsNativeImage;
+
+class QWindowsBackingStore : public QPlatformBackingStore
+{
+ Q_DISABLE_COPY(QWindowsBackingStore)
+public:
+ QWindowsBackingStore(QWindow *window);
+ ~QWindowsBackingStore();
+
+ virtual QPaintDevice *paintDevice();
+ virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ virtual void resize(const QSize &size, const QRegion &r);
+ virtual void beginPaint(const QRegion &);
+
+ HDC getDC() const;
+
+private:
+ QWindowsWindow *rasterWindow() const;
+
+ QScopedPointer<QWindowsNativeImage> m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSBACKINGSTORE_H
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
new file mode 100644
index 0000000000..93063441ba
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsclipboard.h"
+#include "qwindowscontext.h"
+#include "qwindowsole.h"
+#include "qwindowsmime.h"
+#include "qwindowsguieventdispatcher.h"
+
+#include <QtGui/QGuiApplication>
+#include <QtGui/QClipboard>
+#include <QtGui/QColor>
+#include <QtGui/QImage>
+
+#include <QtCore/QDebug>
+#include <QtCore/QMimeData>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+static const char formatTextPlainC[] = "text/plain";
+static const char formatTextHtmlC[] = "text/html";
+
+/*!
+ \class QWindowsClipboard
+ \brief Clipboard implementation.
+
+ Registers a non-visible clipboard viewer window that
+ receives clipboard events in its own window procedure to be
+ able to receive clipboard-changed events, which
+ QPlatformClipboard needs to emit. That requires housekeeping
+ of the next in the viewer chain.
+
+ \note The OLE-functions used in this class require OleInitialize().
+
+ \ingroup qt-lighthouse-win
+*/
+
+QDebug operator<<(QDebug d, const QMimeData &m)
+{
+ QDebug nospace = d.nospace();
+ const QStringList formats = m.formats();
+ nospace << "QMimeData: " << formats.join(QStringLiteral(", ")) << '\n'
+ << " Text=" << m.hasText() << " HTML=" << m.hasHtml()
+ << " Color=" << m.hasColor() << " Image=" << m.hasImage()
+ << " URLs=" << m.hasUrls() << '\n';
+ if (m.hasText())
+ nospace << " Text: '" << m.text() << "'\n";
+ if (m.hasHtml())
+ nospace << " HTML: '" << m.html() << "'\n";
+ if (m.hasColor())
+ nospace << " Color: " << qvariant_cast<QColor>(m.colorData()) << '\n';
+ if (m.hasImage())
+ nospace << " Image: " << qvariant_cast<QImage>(m.imageData()).size() << '\n';
+ if (m.hasUrls())
+ nospace << " URLs: " << m.urls() << '\n';
+ return d;
+}
+
+/*!
+ \class QWindowsInternalMimeDataBase
+ \brief Base for implementations of QInternalMimeData using a IDataObject COM object.
+
+ In clipboard handling and Drag and drop, static instances
+ of QInternalMimeData implementations are kept and passed to the client.
+
+ QInternalMimeData provides virtuals that query the formats and retrieve
+ mime data on demand when the client invokes functions like QMimeData::hasHtml(),
+ QMimeData::html() on the instance returned. Otherwise, expensive
+ construction of a new QMimeData object containing all possible
+ formats would have to be done in each call to mimeData().
+
+ The base class introduces new virtuals to obtain and release
+ the instances IDataObject from the clipboard or Drag and Drop and
+ does conversion using QWindowsMime classes.
+
+ \sa QInternalMimeData, QWindowsMime, QWindowsMimeConverter
+ \ingroup qt-lighthouse-win
+*/
+
+bool QWindowsInternalMimeData::hasFormat_sys(const QString &mime) const
+{
+ IDataObject *pDataObj = retrieveDataObject();
+ if (!pDataObj)
+ return false;
+
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ const bool has = mc.converterToMime(mime, pDataObj) != 0;
+ releaseDataObject(pDataObj);
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << mime << has;
+ return has;
+}
+
+QStringList QWindowsInternalMimeData::formats_sys() const
+{
+ IDataObject *pDataObj = retrieveDataObject();
+ if (!pDataObj)
+ return QStringList();
+
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ const QStringList fmts = mc.allMimesForFormats(pDataObj);
+ releaseDataObject(pDataObj);
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << fmts;
+ return fmts;
+}
+
+QVariant QWindowsInternalMimeData::retrieveData_sys(const QString &mimeType,
+ QVariant::Type type) const
+{
+ IDataObject *pDataObj = retrieveDataObject();
+ if (!pDataObj)
+ return QVariant();
+
+ QVariant result;
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ 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;
+ }
+ return result;
+}
+
+/*!
+ \class QWindowsClipboardRetrievalMimeData
+ \brief Special mime data class managing delayed retrieval of clipboard data.
+
+ Implementation of QWindowsInternalMimeDataBase that obtains the
+ IDataObject from the clipboard.
+
+ \sa QWindowsInternalMimeDataBase, QWindowsClipboard
+ \ingroup qt-lighthouse-win
+*/
+
+IDataObject *QWindowsClipboardRetrievalMimeData::retrieveDataObject() const
+{
+ IDataObject * pDataObj = 0;
+ if (OleGetClipboard(&pDataObj) == S_OK)
+ return pDataObj;
+ return 0;
+}
+
+void QWindowsClipboardRetrievalMimeData::releaseDataObject(IDataObject *dataObject) const
+{
+ dataObject->Release();
+}
+
+extern "C" LRESULT QT_WIN_CALLBACK qClipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT result = 0;
+ if (QWindowsClipboard::instance()
+ && QWindowsClipboard::instance()->clipboardViewerWndProc(hwnd, message, wParam, lParam, &result))
+ return result;
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+QWindowsClipboard *QWindowsClipboard::m_instance = 0;
+
+QWindowsClipboard::QWindowsClipboard() :
+ m_data(0), m_clipboardViewer(0), m_nextClipboardViewer(0)
+{
+ QWindowsClipboard::m_instance = this;
+}
+
+QWindowsClipboard::~QWindowsClipboard()
+{
+ unregisterViewer(); // Should release data if owner.
+ releaseIData();
+ QWindowsClipboard::m_instance = 0;
+}
+
+void QWindowsClipboard::releaseIData()
+{
+ if (m_data) {
+ delete m_data->mimeData();
+ m_data->releaseQt();
+ m_data->Release();
+ m_data = 0;
+ }
+}
+
+void QWindowsClipboard::registerViewer()
+{
+ m_clipboardViewer = QWindowsContext::instance()->
+ createDummyWindow(QStringLiteral("Qt5ClipboardView"), L"Qt5ClipboardView",
+ qClipboardViewerWndProc, WS_OVERLAPPED);
+ m_nextClipboardViewer = SetClipboardViewer(m_clipboardViewer);
+
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s m_clipboardViewer: %p next=%p", __FUNCTION__,
+ m_clipboardViewer, m_nextClipboardViewer);
+}
+
+void QWindowsClipboard::unregisterViewer()
+{
+ if (m_clipboardViewer) {
+ ChangeClipboardChain(m_clipboardViewer, m_nextClipboardViewer);
+ DestroyWindow(m_clipboardViewer);
+ m_clipboardViewer = m_nextClipboardViewer = 0;
+ }
+}
+
+void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, LPARAM lParam) const
+{
+ if (!m_nextClipboardViewer)
+ return;
+ // In rare cases, a clipboard viewer can hang (application crashed,
+ // suspended by a shell prompt 'Select' or debugger).
+ if (QWindowsContext::user32dll.isHungAppWindow
+ && QWindowsContext::user32dll.isHungAppWindow(m_nextClipboardViewer)) {
+ qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO);
+ return;
+ }
+ SendMessage(m_nextClipboardViewer, message, wParam, lParam);
+}
+
+/*!
+ \brief Windows procedure of the clipboard viewer. Emits changed and does
+ housekeeping of the viewer chain.
+*/
+
+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));
+
+ switch (message) {
+ case WM_CHANGECBCHAIN: {
+ const HWND toBeRemoved = (HWND)wParam;
+ if (toBeRemoved == m_nextClipboardViewer) {
+ m_nextClipboardViewer = (HWND)lParam;
+ } else {
+ propagateClipboardMessage(message, wParam, lParam);
+ }
+ }
+ return true;
+ case WM_DRAWCLIPBOARD:
+ if (QWindowsContext::verboseOLE)
+ qDebug("Clipboard changed");
+ emitChanged(QClipboard::Clipboard);
+ // clean up the clipboard object if we no longer own the clipboard
+ if (!ownsClipboard() && m_data)
+ releaseIData();
+ propagateClipboardMessage(message, wParam, lParam);
+ return true;
+ case WM_DESTROY:
+ // Recommended shutdown
+ if (ownsClipboard()) {
+ if (QWindowsContext::verboseOLE)
+ qDebug("Clipboard owner on shutdown, releasing.");
+ OleFlushClipboard();
+ releaseIData();
+ }
+ return true;
+ } // switch (message)
+ return false;
+}
+
+QMimeData *QWindowsClipboard::mimeData(QClipboard::Mode mode)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << mode;
+ if (mode != QClipboard::Clipboard)
+ return 0;
+ return &m_retrievalData;
+}
+
+void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << mode << *mimeData;
+ if (mode != QClipboard::Clipboard)
+ return;
+
+ const bool newData = !m_data || m_data->mimeData() != mimeData;
+ if (newData) {
+ releaseIData();
+ m_data = new QWindowsOleDataObject(mimeData);
+ }
+
+ const HRESULT src = OleSetClipboard(m_data);
+ if (src != S_OK) {
+ qErrnoWarning("OleSetClipboard: Failed to set data on clipboard: %s",
+ QWindowsContext::comErrorString(src).constData());
+ releaseIData();
+ return;
+ }
+}
+
+void QWindowsClipboard::clear()
+{
+ const HRESULT src = OleSetClipboard(0);
+ if (src != S_OK)
+ qErrnoWarning("OleSetClipboard: Failed to clear the clipboard: 0x%lx", src);
+}
+
+bool QWindowsClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ return mode == QClipboard::Clipboard;
+}
+
+// Need a non-virtual in destructor.
+bool QWindowsClipboard::ownsClipboard() const
+{
+ return m_data && OleIsCurrentClipboard(m_data) == S_OK;
+}
+
+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);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.h b/src/plugins/platforms/windows/qwindowsclipboard.h
new file mode 100644
index 0000000000..fab6871012
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsclipboard.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCLIPBOARD_H
+#define QWINDOWSCLIPBOARD_H
+
+#include "qwindowsinternalmimedata.h"
+
+#include <QtGui/QPlatformClipboard>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsOleDataObject;
+
+class QWindowsClipboardRetrievalMimeData : public QWindowsInternalMimeData {
+public:
+
+protected:
+ virtual IDataObject *retrieveDataObject() const;
+ virtual void releaseDataObject(IDataObject *) const;
+};
+
+class QWindowsClipboard : public QPlatformClipboard
+{
+public:
+ QWindowsClipboard();
+ ~QWindowsClipboard();
+ void registerViewer(); // Call in initialization, when context is up.
+
+ virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
+ virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
+ virtual bool supportsMode(QClipboard::Mode mode) const;
+ virtual bool ownsMode(QClipboard::Mode mode) const;
+
+ inline bool clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
+
+ static QWindowsClipboard *instance() { return m_instance; }
+
+private:
+ void clear();
+ void releaseIData();
+ inline void propagateClipboardMessage(UINT message, WPARAM wParam, LPARAM lParam) const;
+ inline void unregisterViewer();
+ inline bool ownsClipboard() const;
+
+ static QWindowsClipboard *m_instance;
+
+ QWindowsClipboardRetrievalMimeData m_retrievalData;
+ QWindowsOleDataObject *m_data;
+ HWND m_clipboardViewer;
+ HWND m_nextClipboardViewer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSCLIPBOARD_H
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
new file mode 100644
index 0000000000..c77a111490
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -0,0 +1,750 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowskeymapper.h"
+#include "qwindowsguieventdispatcher.h"
+#include "qwindowsmousehandler.h"
+#include "qtwindowsglobal.h"
+#include "qwindowsmime.h"
+#include "qwindowsinputcontext.h"
+
+#include <QtGui/QWindow>
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtCore/QSet>
+#include <QtCore/QHash>
+#include <QtCore/QStringList>
+#include <QtCore/QDebug>
+#include <QtCore/QSysInfo>
+#include <QtCore/QScopedArrayPointer>
+#include <QtCore/private/qsystemlibrary_p.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <windowsx.h>
+
+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;
+
+// Get verbosity of components from "foo:2,bar:3"
+static inline int componentVerbose(const char *v, const char *keyWord)
+{
+ if (const char *k = strstr(v, keyWord)) {
+ k += qstrlen(keyWord);
+ if (*k == ':') {
+ ++k;
+ if (isdigit(*k))
+ return *k - '0';
+ }
+ }
+ return 0;
+}
+
+static inline bool hasTouchSupport(QSysInfo::WinVersion wv)
+{
+ enum { QT_SM_DIGITIZER = 94, QT_NID_INTEGRATED_TOUCH = 0x1,
+ QT_NID_EXTERNAL_TOUCH = 0x02, QT_NID_MULTI_INPUT = 0x40 };
+
+ return wv < QSysInfo::WV_WINDOWS7 ? false :
+ (GetSystemMetrics(QT_SM_DIGITIZER) & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH | QT_NID_MULTI_INPUT)) != 0;
+}
+
+#if !defined(LANG_SYRIAC)
+# define LANG_SYRIAC 0x5a
+#endif
+
+static inline bool useRTL_Extensions(QSysInfo::WinVersion ver)
+{
+ if ((ver & QSysInfo::WV_NT_based) && (ver >= QSysInfo::WV_VISTA)) {
+ // Since the IsValidLanguageGroup/IsValidLocale functions always return true on
+ // Vista, check the Keyboard Layouts for enabling RTL.
+ if (const UINT nLayouts = GetKeyboardLayoutList(0, 0)) {
+ QScopedArrayPointer<HKL> lpList(new HKL[nLayouts]);
+ GetKeyboardLayoutList(nLayouts, lpList.data());
+ for (UINT i = 0; i < nLayouts; ++i) {
+ switch (PRIMARYLANGID((quintptr)lpList[i])) {
+ case LANG_ARABIC:
+ case LANG_HEBREW:
+ case LANG_FARSI:
+ case LANG_SYRIAC:
+ return true;
+ default:
+ break;
+ }
+ }
+ }
+ return false;
+ } // NT/Vista
+ // Pre-NT: figure out whether a RTL language is installed
+ return IsValidLanguageGroup(LGRPID_ARABIC, LGRPID_INSTALLED)
+ || IsValidLanguageGroup(LGRPID_HEBREW, LGRPID_INSTALLED)
+ || IsValidLocale(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
+ || IsValidLocale(MAKELCID(MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
+ || IsValidLocale(MAKELCID(MAKELANGID(LANG_SYRIAC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
+ || IsValidLocale(MAKELCID(MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED);
+}
+
+/*!
+ \class QWindowsUser32DLL
+ \brief Struct that contains dynamically resolved symbols of User32.dll.
+
+ The stub libraries shipped with the MinGW compiler miss some of the
+ functions. They need to be retrieved dynamically.
+
+ In addition, touch-related functions are available only from Windows onwards.
+ These need to resolved dynamically for Q_CC_MSVC as well.
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsUser32DLL::QWindowsUser32DLL() :
+ setLayeredWindowAttributes(0), updateLayeredWindow(0),
+ updateLayeredWindowIndirect(0),
+ isHungAppWindow(0),
+ registerTouchWindow(0), getTouchInputInfo(0), closeTouchInputHandle(0)
+{
+}
+
+void QWindowsUser32DLL::init()
+{
+ QSystemLibrary library(QStringLiteral("user32"));
+ // MinGW (g++ 3.4.5) accepts only C casts.
+ setLayeredWindowAttributes = (SetLayeredWindowAttributes)(library.resolve("SetLayeredWindowAttributes"));
+ updateLayeredWindow = (UpdateLayeredWindow)(library.resolve("UpdateLayeredWindow"));
+ updateLayeredWindowIndirect = (UpdateLayeredWindowIndirect)(library.resolve("UpdateLayeredWindowIndirect"));
+
+ Q_ASSERT(setLayeredWindowAttributes && updateLayeredWindow
+ && updateLayeredWindowIndirect);
+
+ isHungAppWindow = (IsHungAppWindow)library.resolve("IsHungAppWindow");
+}
+
+bool QWindowsUser32DLL::initTouch()
+{
+ QSystemLibrary library(QStringLiteral("user32"));
+ registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow"));
+ getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo"));
+ closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle"));
+ return registerTouchWindow && getTouchInputInfo && getTouchInputInfo;
+}
+
+QWindowsUser32DLL QWindowsContext::user32dll;
+
+QWindowsContext *QWindowsContext::m_instance = 0;
+
+/*!
+ \class QWindowsContext
+ \brief Singleton container for all relevant information.
+
+ Holds state information formerly stored in \c qapplication_win.cpp.
+ \ingroup qt-lighthouse-win
+*/
+
+typedef QHash<HWND, QWindowsWindow *> HandleBaseWindowHash;
+
+struct QWindowsContextPrivate {
+ explicit QWindowsContextPrivate(bool isOpenGL);
+
+ const bool m_isOpenGL;
+ unsigned m_systemInfo;
+ QSet<QString> m_registeredWindowClassNames;
+ HandleBaseWindowHash m_windows;
+ HDC m_displayContext;
+ const int m_defaultDPI;
+ QWindowsKeyMapper m_keyMapper;
+ QWindowsMouseHandler m_mouseHandler;
+ QWindowsMimeConverter m_mimeConverter;
+ QSharedPointer<QWindowCreationContext> m_creationContext;
+ const HRESULT m_oleInitializeResult;
+};
+
+QWindowsContextPrivate::QWindowsContextPrivate(bool isOpenGL) :
+ m_isOpenGL(isOpenGL),
+ m_systemInfo(0),
+ m_displayContext(GetDC(0)),
+ m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)),
+ m_oleInitializeResult(OleInitialize(NULL))
+{
+ QWindowsContext::user32dll.init();
+
+ const QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
+
+ if (hasTouchSupport(ver) && QWindowsContext::user32dll.initTouch())
+ m_systemInfo |= QWindowsContext::SI_SupportsTouch;
+
+ if (useRTL_Extensions(ver)) {
+ m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
+ m_keyMapper.setUseRTLExtensions(true);
+ }
+}
+
+QWindowsContext::QWindowsContext(bool isOpenGL) :
+ d(new QWindowsContextPrivate(isOpenGL))
+{
+#ifdef Q_CC_MSVC
+# pragma warning( disable : 4996 )
+#endif
+ m_instance = this;
+ if (const char *v = getenv("QT_LIGHTHOUSE_WINDOWS_VERBOSE")) {
+ 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::~QWindowsContext()
+{
+ unregisterWindowClasses();
+ if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE)
+ OleUninitialize();
+
+ m_instance = 0;
+}
+
+QWindowsContext *QWindowsContext::instance()
+{
+ return m_instance;
+}
+
+unsigned QWindowsContext::systemInfo() const
+{
+ return d->m_systemInfo;
+}
+
+void QWindowsContext::setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx)
+{
+ d->m_creationContext = ctx;
+}
+
+bool QWindowsContext::isOpenGL() const
+{
+ return d->m_isOpenGL;
+}
+
+int QWindowsContext::defaultDPI() const
+{
+ return d->m_defaultDPI;
+}
+
+HDC QWindowsContext::displayContext() const
+{
+ return d->m_displayContext;
+}
+
+QWindow *QWindowsContext::keyGrabber() const
+{
+ return d->m_keyMapper.keyGrabber();
+}
+
+void QWindowsContext::setKeyGrabber(QWindow *w)
+{
+ d->m_keyMapper.setKeyGrabber(w);
+}
+
+// Window class registering code (from qapplication_win.cpp)
+// If 0 is passed as the widget pointer, register a window class
+// for QWidget as default. This is used in QGLTemporaryContext
+// during GL initialization, where we don't want to use temporary
+// QWidgets or QGLWidgets, neither do we want to have separate code
+// to register window classes.
+
+QString QWindowsContext::registerWindowClass(const QWindow *w, bool isGL)
+{
+ const Qt::WindowFlags flags = w ? w->windowFlags() : (Qt::WindowFlags)0;
+ const Qt::WindowFlags type = flags & Qt::WindowType_Mask;
+
+ uint style = 0;
+ bool icon = false;
+ QString cname = "Qt5";
+ if (w && isGL) {
+ cname += QStringLiteral("QGLWindow");
+ style = CS_DBLCLKS|CS_OWNDC;
+ icon = true;
+ } else if (w && (flags & Qt::MSWindowsOwnDC)) {
+ cname += QStringLiteral("QWindowOwnDC");
+ style = CS_DBLCLKS|CS_OWNDC;
+ icon = true;
+ } else if (w && (type == Qt::Tool || type == Qt::ToolTip)) {
+ style = CS_DBLCLKS;
+ if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) {
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ style |= CS_DROPSHADOW;
+ }
+ cname += QStringLiteral("QToolTip");
+ } else {
+ cname += QStringLiteral("QTool");
+ }
+ style |= CS_SAVEBITS;
+ icon = false;
+ } else if (w && (type == Qt::Popup)) {
+ cname += QStringLiteral("QPopup");
+ style = CS_DBLCLKS|CS_SAVEBITS;
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ style |= CS_DROPSHADOW;
+ icon = false;
+ } else {
+ cname += QStringLiteral("QWindow");
+ style = CS_DBLCLKS;
+ icon = true;
+ }
+
+ // force CS_OWNDC when the GL graphics system is
+ // used as the default renderer
+ if (d->m_isOpenGL)
+ style |= CS_OWNDC;
+
+ HBRUSH brush = 0;
+ if (w && !isGL)
+ brush = GetSysColorBrush(COLOR_WINDOW);
+ return registerWindowClass(cname, qWindowsWndProc, style, brush, icon);
+}
+
+QString QWindowsContext::registerWindowClass(QString cname,
+ WNDPROC proc,
+ unsigned style,
+ HBRUSH brush,
+ bool icon)
+{
+ // since multiple Qt versions can be used in one process
+ // each one has to have window class names with a unique name
+ // The first instance gets the unmodified name; if the class
+ // has already been registered by another instance of Qt then
+ // add an instance-specific ID, the address of the window proc.
+ static int classExists = -1;
+
+ const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0);
+ if (classExists == -1) {
+ WNDCLASS wcinfo;
+ classExists = GetClassInfo(appInstance, (wchar_t*)cname.utf16(), &wcinfo);
+ classExists = classExists && wcinfo.lpfnWndProc != proc;
+ }
+
+ if (classExists)
+ cname += QString::number((quintptr)proc);
+
+ if (d->m_registeredWindowClassNames.contains(cname)) // already registered in our list
+ return cname;
+
+ WNDCLASSEX wc;
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = style;
+ wc.lpfnWndProc = proc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = appInstance;
+ if (icon) {
+ wc.hIcon = (HICON)LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
+ if (wc.hIcon) {
+ int sw = GetSystemMetrics(SM_CXSMICON);
+ int sh = GetSystemMetrics(SM_CYSMICON);
+ wc.hIconSm = (HICON)LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0);
+ } else {
+ wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+ wc.hIconSm = 0;
+ }
+ } else {
+ wc.hIcon = 0;
+ wc.hIconSm = 0;
+ }
+ wc.hCursor = 0;
+ wc.hbrBackground = brush;
+ wc.lpszMenuName = 0;
+ wc.lpszClassName = (wchar_t*)cname.utf16();
+ ATOM atom = RegisterClassEx(&wc);
+
+ if (!atom)
+ qErrnoWarning("QApplication::regClass: Registering window class '%s' failed.",
+ qPrintable(cname));
+
+ d->m_registeredWindowClassNames.insert(cname);
+ if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
+ qDebug().nospace() << __FUNCTION__ << ' ' << cname
+ << " style=0x" << QString::number(style, 16)
+ << " brush=" << brush << " icon=" << icon << " atom=" << atom;
+ return cname;
+}
+
+void QWindowsContext::unregisterWindowClasses()
+{
+ const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0);
+
+ foreach (const QString &name, d->m_registeredWindowClassNames) {
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << name;
+ UnregisterClass((wchar_t*)name.utf16(), appInstance);
+ }
+ d->m_registeredWindowClassNames.clear();
+}
+
+int QWindowsContext::screenDepth() const
+{
+ return GetDeviceCaps(d->m_displayContext, BITSPIXEL);
+}
+
+QString QWindowsContext::windowsErrorMessage(unsigned long errorCode)
+{
+ QString rc = QString::fromLatin1("#%1: ").arg(errorCode);
+ ushort *lpMsgBuf;
+
+ const int len = FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, errorCode, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
+ if (len) {
+ rc = QString::fromUtf16(lpMsgBuf, len);
+ LocalFree(lpMsgBuf);
+ } else {
+ rc += QString::fromLatin1("<unknown error>");
+ }
+ return rc;
+}
+
+void QWindowsContext::addWindow(HWND hwnd, QWindowsWindow *w)
+{
+ d->m_windows.insert(hwnd, w);
+}
+
+void QWindowsContext::removeWindow(HWND hwnd)
+{
+ const HandleBaseWindowHash::iterator it = d->m_windows.find(hwnd);
+ if (it != d->m_windows.end()) {
+ if (d->m_keyMapper.keyGrabber() == it.value()->window())
+ d->m_keyMapper.setKeyGrabber(0);
+ d->m_windows.erase(it);
+ }
+}
+
+QWindowsWindow *QWindowsContext::findPlatformWindow(HWND hwnd) const
+{
+ return d->m_windows.value(hwnd);
+}
+
+QWindow *QWindowsContext::findWindow(HWND hwnd) const
+{
+ if (const QWindowsWindow *bw = findPlatformWindow(hwnd))
+ return bw->window();
+ return 0;
+}
+
+QWindow *QWindowsContext::windowUnderMouse() const
+{
+ return d->m_mouseHandler.windowUnderMouse();
+}
+
+/*!
+ \brief Find a child window at a screen point.
+
+ Deep search for a QWindow at global point, skipping non-owned
+ windows (accessibility?). Implemented using ChildWindowFromPointEx()
+ instead of (historically used) WindowFromPoint() to get a well-defined
+ behaviour for hidden/transparent windows.
+
+ \a cwex_flags are flags of ChildWindowFromPointEx().
+ \a parent is the parent window, pass GetDesktopWindow() for top levels.
+*/
+
+QWindowsWindow *QWindowsContext::findPlatformWindowAt(HWND parent,
+ const QPoint &screenPointIn,
+ unsigned cwex_flags) const
+{
+ QWindowsWindow *result = 0;
+ const POINT screenPoint = { screenPointIn.x(), screenPointIn.y() };
+ while (true) {
+ POINT point = screenPoint;
+ ScreenToClient(parent, &point);
+ // Returns parent if inside & none matched.
+ const HWND child = ChildWindowFromPointEx(parent, point, cwex_flags);
+ if (child && child != parent) {
+ if (QWindowsWindow *window = findPlatformWindow(child))
+ result = window;
+ parent = child;
+ } else {
+ break;
+ }
+ }
+ return result;
+}
+
+QWindowsMimeConverter &QWindowsContext::mimeConverter() const
+{
+ return d->m_mimeConverter;
+}
+
+/*!
+ \brief Convenience to create a non-visible dummy window
+ for example used as clipboard watcher or for GL.
+*/
+
+HWND QWindowsContext::createDummyWindow(const QString &classNameIn,
+ const wchar_t *windowName,
+ WNDPROC wndProc, DWORD style)
+{
+ if (!wndProc)
+ wndProc = DefWindowProc;
+ QString className = registerWindowClass(classNameIn, wndProc);
+ return CreateWindowEx(0, (wchar_t*)className.utf16(),
+ windowName, style,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 0, NULL, (HINSTANCE)GetModuleHandle(0), NULL);
+}
+
+/*!
+ \brief Common COM error strings.
+*/
+
+QByteArray QWindowsContext::comErrorString(HRESULT hr)
+{
+ switch (hr) {
+ case S_OK:
+ return QByteArray("S_OK");
+ case S_FALSE:
+ return QByteArray("S_FALSE");
+ case E_UNEXPECTED:
+ return QByteArray("E_UNEXPECTED");
+ case CO_E_ALREADYINITIALIZED:
+ return QByteArray("CO_E_ALREADYINITIALIZED");
+ case CO_E_NOTINITIALIZED:
+ return QByteArray("CO_E_NOTINITIALIZED");
+ case RPC_E_CHANGED_MODE:
+ return QByteArray("RPC_E_CHANGED_MODE");
+ case OLE_E_WRONGCOMPOBJ:
+ return QByteArray("OLE_E_WRONGCOMPOBJ");
+ case CO_E_NOT_SUPPORTED:
+ return QByteArray("CO_E_NOT_SUPPORTED");
+ case E_NOTIMPL:
+ return QByteArray("E_NOTIMPL");
+ case E_INVALIDARG:
+ return QByteArray("");
+ case E_NOINTERFACE:
+ return QByteArray("");
+ case E_POINTER:
+ return QByteArray("");
+ case E_HANDLE:
+ return QByteArray("");
+ case E_ABORT:
+ return QByteArray("");
+ case E_FAIL:
+ return QByteArray("");
+ case E_ACCESSDENIED:
+ return QByteArray("");
+ default:
+ break;
+ }
+ return "Unknown error 0x" + QByteArray::number(quint64(hr), 16);
+}
+
+/*!
+ \brief Main windows procedure registered for windows.
+
+ \sa QWindowsGuiEventDispatcher
+*/
+
+bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
+ QtWindows::WindowsEventType et,
+ WPARAM wParam, LPARAM lParam, LRESULT *result)
+{
+ *result = 0;
+ // Events without an associated QWindow or events we are not interested in.
+ switch (et) {
+ case QtWindows::DeactivateApplicationEvent:
+ case QtWindows::DeactivateWindowEvent:
+ QWindowSystemInterface::handleWindowActivated(0);
+ return true;
+ case QtWindows::InputMethodStartCompositionEvent:
+ return QWindowsInputContext::instance()->startComposition(hwnd);
+ case QtWindows::InputMethodCompositionEvent:
+ return QWindowsInputContext::instance()->composition(hwnd, lParam);
+ case QtWindows::InputMethodEndCompositionEvent:
+ return QWindowsInputContext::instance()->endComposition(hwnd);
+ case QtWindows::InputMethodRequest:
+ return QWindowsInputContext::instance()->handleIME_Request(wParam, lParam, result);
+ case QtWindows::InputMethodOpenCandidateWindowEvent:
+ case QtWindows::InputMethodCloseCandidateWindowEvent:
+ // TODO: Release/regrab mouse if a popup has mouse grab.
+ return false;
+ case QtWindows::ClipboardEvent:
+ case QtWindows::DestroyEvent:
+
+ case QtWindows::UnknownEvent:
+ return false;
+ default:
+ break;
+ }
+
+ QWindowsWindow *platformWindow = findPlatformWindow(hwnd);
+ // Before CreateWindowEx() returns, some events are sent,
+ // for example WM_GETMINMAXINFO asking for size constraints for top levels.
+ // Pass on to current creation context
+ if (!platformWindow && !d->m_creationContext.isNull()) {
+ switch (et) {
+ case QtWindows::QuerySizeHints:
+ d->m_creationContext->applyToMinMaxInfo(reinterpret_cast<MINMAXINFO *>(lParam));
+ return true;
+ case QtWindows::ResizeEvent:
+ d->m_creationContext->obtainedGeometry.setSize(QSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ return true;
+ case QtWindows::MoveEvent:
+ d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ return true;
+ case QtWindows::CalculateSize:
+ return false;
+ default:
+ break;
+ }
+ }
+ if (platformWindow) {
+ if (QWindowsContext::verboseEvents > 1)
+ qDebug().nospace() << "Event window: " << platformWindow->window();
+ } else {
+ qWarning("%s: No Qt Window found for event 0x%x (%s), hwnd=0x%p.",
+ __FUNCTION__, message,
+ QWindowsGuiEventDispatcher::windowsMessageName(message), hwnd);
+ return false;
+ }
+
+ MSG msg;
+ msg.hwnd = hwnd; // re-create MSG structure
+ 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);
+
+ switch (et) {
+ case QtWindows::KeyDownEvent:
+ case QtWindows::KeyEvent:
+ case QtWindows::InputMethodKeyEvent:
+ case QtWindows::InputMethodKeyDownEvent:
+ return d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
+ case QtWindows::MoveEvent:
+ platformWindow->handleMoved();
+ return true;
+ case QtWindows::ResizeEvent:
+ platformWindow->handleResized((int)wParam);
+ return true;
+ case QtWindows::QuerySizeHints:
+ platformWindow->getSizeHints(reinterpret_cast<MINMAXINFO *>(lParam));
+ return true;
+ case QtWindows::CalculateSize:
+ // NCCALCSIZE_PARAMS structure if wParam==TRUE
+ if (wParam && QWindowsContext::verboseWindows) {
+ const NCCALCSIZE_PARAMS *ncp = reinterpret_cast<NCCALCSIZE_PARAMS *>(lParam);
+ qDebug() << platformWindow->window() << *ncp;
+ }
+ break;
+ case QtWindows::ExposeEvent:
+ platformWindow->handleWmPaint(hwnd, message, wParam, lParam);
+ return true;
+ case QtWindows::MouseWheelEvent:
+ case QtWindows::MouseEvent:
+ case QtWindows::NonClientMouseEvent:
+ case QtWindows::LeaveEvent:
+ return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
+ case QtWindows::TouchEvent:
+ return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result);
+ case QtWindows::ActivateWindowEvent:
+ QWindowSystemInterface::handleWindowActivated(platformWindow->window());
+ return true;
+ case QtWindows::ShowEvent:
+ platformWindow->handleShown();
+ return true;
+ case QtWindows::HideEvent:
+ platformWindow->handleHidden();
+ return true;
+ case QtWindows::CloseEvent:
+ QWindowSystemInterface::handleCloseEvent(platformWindow->window());
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \brief Windows functions for actual windows.
+
+ There is another one for timers, sockets, etc in
+ QEventDispatcherWin32.
+
+ \ingroup qt-lighthouse-win
+*/
+
+extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT result;
+ const QtWindows::WindowsEventType et = windowsEventType(message, wParam);
+ const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result);
+ const bool guiEventsQueued = QWindowSystemInterface::windowSystemEventsQueued();
+ 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 gui=%d",
+ hwnd, eventName, message, et, int(wParam),
+ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), handled, guiEventsQueued);
+ if (guiEventsQueued) {
+ const QWindowsGuiEventDispatcher::DispatchContext dispatchContext =
+ QWindowsGuiEventDispatcher::currentDispatchContext();
+ if (dispatchContext.first)
+ QWindowSystemInterface::sendWindowSystemEvents(dispatchContext.first, dispatchContext.second);
+ }
+ if (!handled)
+ result = DefWindowProc(hwnd, message, wParam, lParam);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
new file mode 100644
index 0000000000..93662384c0
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCONTEXT_H
+#define QWINDOWSCONTEXT_H
+
+#include "qtwindowsglobal.h"
+#include "qtwindows_additional.h"
+
+#include <QtCore/QScopedPointer>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+class QPlatformScreen;
+class QWindowsWindow;
+class QWindowsMimeConverter;
+struct QWindowCreationContext;
+struct QWindowsContextPrivate;
+class QPoint;
+
+struct QWindowsUser32DLL
+{
+ QWindowsUser32DLL();
+ inline void init();
+ inline bool initTouch();
+
+ typedef BOOL (WINAPI *RegisterTouchWindow)(HWND, ULONG);
+ typedef BOOL (WINAPI *GetTouchInputInfo)(HANDLE, UINT, PVOID, int);
+ typedef BOOL (WINAPI *CloseTouchInputHandle)(HANDLE);
+ typedef BOOL (WINAPI *SetLayeredWindowAttributes)(HWND, COLORREF, BYTE, DWORD);
+ typedef BOOL (WINAPI *UpdateLayeredWindow)(HWND, HDC , const POINT *,
+ const SIZE *, HDC, const POINT *, COLORREF,
+ const BLENDFUNCTION *, DWORD);
+ typedef BOOL (WINAPI *UpdateLayeredWindowIndirect)(HWND, const UPDATELAYEREDWINDOWINFO *);
+ typedef BOOL (WINAPI *IsHungAppWindow)(HWND);
+
+ // Functions missing in Q_CC_GNU stub libraries.
+ SetLayeredWindowAttributes setLayeredWindowAttributes;
+ UpdateLayeredWindow updateLayeredWindow;
+ UpdateLayeredWindowIndirect updateLayeredWindowIndirect;
+
+ // Functions missing in older versions of Windows
+ IsHungAppWindow isHungAppWindow;
+
+ // Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC).
+ RegisterTouchWindow registerTouchWindow;
+ GetTouchInputInfo getTouchInputInfo;
+ CloseTouchInputHandle closeTouchInputHandle;
+};
+
+class QWindowsContext
+{
+ Q_DISABLE_COPY(QWindowsContext)
+public:
+ enum SystemInfoFlags
+ {
+ SI_RTL_Extensions = 0x1,
+ SI_SupportsTouch = 0x2
+ };
+
+ // Verbose flag set by environment variable QT_LIGHTHOUSE_WINDOWS_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;
+
+ explicit QWindowsContext(bool isOpenGL);
+ ~QWindowsContext();
+
+ bool isOpenGL() const;
+
+ int defaultDPI() const;
+
+ QString registerWindowClass(const QWindow *w, bool isGL);
+ QString registerWindowClass(QString cname, WNDPROC proc,
+ unsigned style = 0, HBRUSH brush = 0,
+ bool icon = false);
+ HWND createDummyWindow(const QString &classNameIn,
+ const wchar_t *windowName,
+ WNDPROC wndProc = 0, DWORD style = WS_OVERLAPPED);
+
+ HDC displayContext() const;
+ int screenDepth() const;
+
+ static QWindowsContext *instance();
+
+ static QString windowsErrorMessage(unsigned long errorCode);
+
+ void addWindow(HWND, QWindowsWindow *w);
+ void removeWindow(HWND);
+
+ QWindowsWindow *findPlatformWindow(HWND) const;
+ QWindow *findWindow(HWND) const;
+ QWindowsWindow *findPlatformWindowAt(HWND parent, const QPoint &screenPoint,
+ unsigned cwex_flags) const;
+
+ QWindow *windowUnderMouse() const;
+
+ inline bool windowsProc(HWND hwnd, UINT message,
+ QtWindows::WindowsEventType et,
+ WPARAM wParam, LPARAM lParam, LRESULT *result);
+
+ QWindow *keyGrabber() const;
+ void setKeyGrabber(QWindow *hwnd);
+
+ void setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx);
+
+ // Returns a combination of SystemInfoFlags
+ unsigned systemInfo() const;
+
+ QWindowsMimeConverter &mimeConverter() const;
+
+ static QWindowsUser32DLL user32dll;
+
+ static QByteArray comErrorString(HRESULT hr);
+
+private:
+ void unregisterWindowClasses();
+
+ QScopedPointer<QWindowsContextPrivate> d;
+ static QWindowsContext *m_instance;
+};
+
+extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND, UINT, WPARAM, LPARAM);
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSCONTEXT_H
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
new file mode 100644
index 0000000000..1ad2079962
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -0,0 +1,451 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowscursor.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsscreen.h"
+#include "pixmaputils.h"
+
+#include <QtGui/QPixmap>
+#include <QtGui/QImage>
+#include <QtGui/QBitmap>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+#include <QtGui/private/qguiapplication_p.h> // getPixmapCursor()
+
+#include <QtCore/QDebug>
+#include <QtCore/QScopedArrayPointer>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsCursor
+ \brief Platform cursor implementation
+
+ Note that whereas under X11, a cursor can be set as a property of
+ a window, there is only a global SetCursor() function on Windows.
+ Each Window sets on the global cursor on receiving a Enter-event
+ as do the Window manager frames (resize/move handles).
+
+ \ingroup qt-lighthouse-win
+ \sa QWindowsWindowCursor
+*/
+
+QWindowsCursor::QWindowsCursor(QPlatformScreen *s) :
+ QPlatformCursor(s)
+{
+}
+
+HCURSOR QWindowsCursor::createPixmapCursor(const QPixmap &pixmap, int hotX, int hotY)
+{
+ HCURSOR cur = 0;
+ QBitmap mask = pixmap.mask();
+ if (mask.isNull()) {
+ mask = QBitmap(pixmap.size());
+ mask.fill(Qt::color1);
+ }
+
+ HBITMAP ic = qPixmapToWinHBITMAP(pixmap, HBitmapAlpha);
+ const HBITMAP im = createIconMask(mask);
+
+ ICONINFO ii;
+ ii.fIcon = 0;
+ ii.xHotspot = hotX;
+ ii.yHotspot = hotY;
+ ii.hbmMask = im;
+ ii.hbmColor = ic;
+
+ cur = CreateIconIndirect(&ii);
+
+ DeleteObject(ic);
+ DeleteObject(im);
+ return cur;
+}
+
+HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
+{
+ int hx = c.hotSpot().x();
+ int hy = c.hotSpot().y();
+ const Qt::CursorShape cshape = c.shape();
+ if (cshape == Qt::BitmapCursor) {
+ const QPixmap pixmap = c.pixmap();
+ if (!pixmap.isNull())
+ if (const HCURSOR hc = createPixmapCursor(pixmap, hx, hy))
+ return hc;
+ }
+
+ // Non-standard Windows cursors are created from bitmaps
+
+ static const uchar vsplit_bits[] = {
+ 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, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 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 vsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 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 hsplit_bits[] = {
+ 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, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
+ 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 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 hsplitm_bits[] = {
+ 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, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
+ 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
+ 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
+ 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 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 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,
+ 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
+ static const uchar openhandm_bits[] = {
+ 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
+ 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
+ 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
+ static const uchar closedhand_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
+ 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
+ 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
+ static const uchar closedhandm_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
+ 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:
+ sh = IDC_ARROW;
+ break;
+ case Qt::UpArrowCursor:
+ sh = IDC_UPARROW;
+ break;
+ case Qt::CrossCursor:
+ sh = IDC_CROSS;
+ break;
+ case Qt::WaitCursor:
+ sh = IDC_WAIT;
+ break;
+ case Qt::IBeamCursor:
+ sh = IDC_IBEAM;
+ break;
+ case Qt::SizeVerCursor:
+ sh = IDC_SIZENS;
+ break;
+ case Qt::SizeHorCursor:
+ sh = IDC_SIZEWE;
+ break;
+ case Qt::SizeBDiagCursor:
+ sh = IDC_SIZENESW;
+ break;
+ case Qt::SizeFDiagCursor:
+ sh = IDC_SIZENWSE;
+ break;
+ case Qt::SizeAllCursor:
+ sh = IDC_SIZEALL;
+ break;
+ case Qt::ForbiddenCursor:
+ sh = IDC_NO;
+ break;
+ case Qt::WhatsThisCursor:
+ sh = IDC_HELP;
+ break;
+ case Qt::BusyCursor:
+ sh = IDC_APPSTARTING;
+ break;
+ case Qt::PointingHandCursor:
+ sh = IDC_HAND;
+ break;
+ case Qt::BlankCursor:
+ case Qt::SplitVCursor:
+ case Qt::SplitHCursor:
+ case Qt::OpenHandCursor:
+ case Qt::ClosedHandCursor:
+ case Qt::BitmapCursor: {
+ QImage bbits, mbits;
+ bool invb, invm;
+ if (cshape == Qt::BlankCursor) {
+ bbits = QImage(32, 32, QImage::Format_Mono);
+ bbits.fill(0); // ignore color table
+ mbits = bbits.copy();
+ hx = hy = 16;
+ invb = invm = false;
+ } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
+ bool open = cshape == Qt::OpenHandCursor;
+ QBitmap cb = QBitmap::fromData(QSize(16, 16), open ? openhand_bits : closedhand_bits);
+ QBitmap cm = QBitmap::fromData(QSize(16, 16), open ? openhandm_bits : closedhandm_bits);
+ bbits = cb.toImage().convertToFormat(QImage::Format_Mono);
+ 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 {
+ 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));
+ }
+ const int n = qMax(1, bbits.width() / 8);
+ const int h = bbits.height();
+ QScopedArrayPointer<uchar> xBits(new uchar[h * n]);
+ QScopedArrayPointer<uchar> xMask(new uchar[h * n]);
+ int x = 0;
+ for (int i = 0; i < h; ++i) {
+ uchar *bits = bbits.scanLine(i);
+ uchar *mask = mbits.scanLine(i);
+ for (int j = 0; j < n; ++j) {
+ uchar b = bits[j];
+ uchar m = mask[j];
+ if (invb)
+ b ^= 0xff;
+ if (invm)
+ m ^= 0xff;
+ xBits[x] = ~m;
+ xMask[x] = b ^ m;
+ ++x;
+ }
+ }
+ return CreateCursor(GetModuleHandle(0), hx, hy, bbits.width(), bbits.height(),
+ xBits.data(), xMask.data());
+ }
+ case Qt::DragCopyCursor:
+ case Qt::DragMoveCursor:
+ case Qt::DragLinkCursor: {
+ const QPixmap pixmap = QGuiApplicationPrivate::instance()->getPixmapCursor(cshape);
+ return createPixmapCursor(pixmap, hx, hy);
+ }
+ default:
+ qWarning("%s: Invalid cursor shape %d", __FUNCTION__, cshape);
+ return 0;
+ }
+ return (HCURSOR)LoadImage(0, sh, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+}
+
+/*!
+ \brief Return cached standard cursor resources or create new ones.
+*/
+
+QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
+{
+ StandardCursorCache::iterator it = m_standardCursorCache.find(shape);
+ if (it == m_standardCursorCache.end())
+ it = m_standardCursorCache.insert(shape, QWindowsWindowCursor(QCursor(shape)));
+ return it.value();
+}
+
+/*!
+ \brief Set a cursor on a window.
+
+ This is called frequently as the mouse moves over widgets in the window
+ (QLineEdits, etc).
+*/
+
+void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
+{
+
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << cursorIn << window;
+ if (!cursorIn || !window)
+ return;
+ const QWindowsWindowCursor wcursor =
+ cursorIn->shape() == Qt::BitmapCursor ?
+ QWindowsWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape());
+ if (wcursor.handle()) {
+ QWindowsWindow::baseWindowOf(window)->setCursor(wcursor);
+ } else {
+ qWarning("%s: Unable to obtain system cursor for %d",
+ __FUNCTION__, cursorIn->shape());
+ }
+}
+
+QPoint QWindowsCursor::mousePosition()
+{
+ POINT p;
+ GetCursorPos(&p);
+ if (QWindowsContext::verboseWindows)
+ qDebug("%s %ld,%ld", __FUNCTION__, p.x, p.y);
+ return QPoint(p.x, p.y);
+}
+
+void QWindowsCursor::setPos(const QPoint &pos)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug("%s %d,%d", __FUNCTION__, pos.x(), pos.y());
+ SetCursorPos(pos.x(), pos.y());
+}
+
+/*!
+ \class QWindowsWindowCursor
+ \brief Per-Window cursor. Contains a QCursor and manages its associated system
+ cursor handle resource.
+
+ Based on QSharedDataPointer, so that it can be passed around and
+ used as a property of QWindowsBaseWindow.
+
+ \ingroup qt-lighthouse-win
+ \sa QWindowsCursor
+*/
+
+class QWindowsWindowCursorData : public QSharedData
+{
+public:
+ explicit QWindowsWindowCursorData(const QCursor &c);
+ ~QWindowsWindowCursorData();
+
+ const QCursor m_cursor;
+ const HCURSOR m_handle;
+};
+
+QWindowsWindowCursorData::QWindowsWindowCursorData(const QCursor &c) :
+ m_cursor(c),
+ m_handle(QWindowsCursor::createSystemCursor(c))
+{
+}
+
+QWindowsWindowCursorData::~QWindowsWindowCursorData()
+{
+ DestroyCursor(m_handle);
+}
+
+QWindowsWindowCursor::QWindowsWindowCursor(const QCursor &c) :
+ m_data(new QWindowsWindowCursorData(c))
+{
+}
+
+QWindowsWindowCursor::~QWindowsWindowCursor()
+{
+}
+
+QWindowsWindowCursor::QWindowsWindowCursor(const QWindowsWindowCursor &rhs) :
+ m_data(rhs.m_data)
+{
+}
+
+QWindowsWindowCursor & QWindowsWindowCursor::operator =(const QWindowsWindowCursor &rhs)
+{
+ if (this != &rhs)
+ m_data.operator =(rhs.m_data);
+ return *this;
+}
+
+QCursor QWindowsWindowCursor::cursor() const
+{
+ return m_data->m_cursor;
+}
+
+HCURSOR QWindowsWindowCursor::handle() const
+{
+ return m_data->m_handle;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
new file mode 100644
index 0000000000..bf8cb837d9
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCURSOR_H
+#define QWINDOWSCURSOR_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPlatformCursor>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsWindowCursorData;
+
+class QWindowsWindowCursor
+{
+public:
+ explicit QWindowsWindowCursor(const QCursor &c);
+ ~QWindowsWindowCursor();
+ QWindowsWindowCursor(const QWindowsWindowCursor &c);
+ QWindowsWindowCursor &operator=(const QWindowsWindowCursor &c);
+
+ QCursor cursor() const;
+ HCURSOR handle() const;
+
+private:
+ QSharedDataPointer<QWindowsWindowCursorData> m_data;
+};
+
+class QWindowsCursor : public QPlatformCursor
+{
+public:
+ explicit QWindowsCursor(QPlatformScreen *);
+
+ virtual void changeCursor(QCursor * widgetCursor, QWindow * widget);
+ virtual QPoint pos() const { return mousePosition(); }
+ virtual void setPos(const QPoint &pos);
+
+ static HCURSOR createPixmapCursor(const QPixmap &pixmap, int hotX, int hotY);
+ static HCURSOR createSystemCursor(const QCursor &c);
+ static QPoint mousePosition();
+
+ QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
+
+private:
+ typedef QHash<Qt::CursorShape, QWindowsWindowCursor> StandardCursorCache;
+
+ StandardCursorCache m_standardCursorCache;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSCURSOR_H
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
new file mode 100644
index 0000000000..1535437a32
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -0,0 +1,721 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdrag.h"
+#include "qwindowscontext.h"
+#include "qwindowsclipboard.h"
+#include "qwindowsintegration.h"
+#include "qwindowsole.h"
+#include "qtwindows_additional.h"
+#include "qwindowswindow.h"
+#include "qwindowsmousehandler.h"
+#include "qwindowscursor.h"
+
+#include <QtGui/QMouseEvent>
+#include <QtGui/QPixmap>
+#include <QtGui/QPainter>
+#include <QtGui/QGuiApplication>
+
+#include <QtCore/QDebug>
+#include <QtCore/QPoint>
+
+#include <shlobj.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsDropMimeData
+ \brief Special mime data class for data retrieval from Drag operations.
+
+ Implementation of QWindowsInternalMimeDataBase which retrieves the
+ current drop data object from QWindowsDrag.
+
+ \sa QWindowsDrag
+ \ingroup qt-lighthouse-win
+*/
+
+IDataObject *QWindowsDropMimeData::retrieveDataObject() const
+{
+ return QWindowsDrag::instance()->dropDataObject();
+}
+
+static inline Qt::DropActions translateToQDragDropActions(DWORD pdwEffects)
+{
+ Qt::DropActions actions = Qt::IgnoreAction;
+ if (pdwEffects & DROPEFFECT_LINK)
+ actions |= Qt::LinkAction;
+ if (pdwEffects & DROPEFFECT_COPY)
+ actions |= Qt::CopyAction;
+ if (pdwEffects & DROPEFFECT_MOVE)
+ actions |= Qt::MoveAction;
+ return actions;
+}
+
+static inline Qt::DropAction translateToQDragDropAction(DWORD pdwEffect)
+{
+ if (pdwEffect & DROPEFFECT_LINK)
+ return Qt::LinkAction;
+ if (pdwEffect & DROPEFFECT_COPY)
+ return Qt::CopyAction;
+ if (pdwEffect & DROPEFFECT_MOVE)
+ return Qt::MoveAction;
+ return Qt::IgnoreAction;
+}
+
+static inline DWORD translateToWinDragEffects(Qt::DropActions action)
+{
+ DWORD effect = DROPEFFECT_NONE;
+ if (action & Qt::LinkAction)
+ effect |= DROPEFFECT_LINK;
+ if (action & Qt::CopyAction)
+ effect |= DROPEFFECT_COPY;
+ if (action & Qt::MoveAction)
+ effect |= DROPEFFECT_MOVE;
+ return effect;
+}
+
+static inline Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
+{
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+
+ if (keyState & MK_SHIFT)
+ modifiers |= Qt::ShiftModifier;
+ if (keyState & MK_CONTROL)
+ modifiers |= Qt::ControlModifier;
+ if (keyState & MK_ALT)
+ modifiers |= Qt::AltModifier;
+
+ return modifiers;
+}
+
+/*!
+ \class QWindowsOleDropSource
+ \brief Implementation of IDropSource
+
+ Used for drag operations.
+
+ \sa QWindowsDrag
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsOleDropSource : public IDropSource
+{
+public:
+ QWindowsOleDropSource();
+ virtual ~QWindowsOleDropSource();
+
+ void createCursors();
+
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj);
+ STDMETHOD_(ULONG,AddRef)(void);
+ STDMETHOD_(ULONG,Release)(void);
+
+ // IDropSource methods
+ STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState);
+ STDMETHOD(GiveFeedback)(DWORD dwEffect);
+
+private:
+ typedef QMap <Qt::DropAction, HCURSOR> ActionCursorMap;
+
+ inline void clearCursors();
+
+ Qt::MouseButtons m_currentButtons;
+ Qt::DropAction m_currentAction;
+ ActionCursorMap m_cursors;
+
+ ULONG m_refs;
+};
+
+QWindowsOleDropSource::QWindowsOleDropSource() :
+ m_currentButtons(Qt::NoButton), m_currentAction(Qt::IgnoreAction),
+ m_refs(1)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s", __FUNCTION__);
+}
+
+QWindowsOleDropSource::~QWindowsOleDropSource()
+{
+ clearCursors();
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s", __FUNCTION__);
+}
+
+void QWindowsOleDropSource::createCursors()
+{
+ QDragManager *manager = QDragManager::self();
+ if (!manager || !manager->object)
+ return;
+ const QPixmap pixmap = manager->object->pixmap();
+ const bool hasPixmap = !pixmap.isNull();
+ if (!hasPixmap && manager->dragPrivate()->customCursors.isEmpty())
+ return;
+
+ QList<Qt::DropAction> actions;
+ actions << Qt::MoveAction << Qt::CopyAction << Qt::LinkAction;
+ if (hasPixmap)
+ actions << Qt::IgnoreAction;
+ const QPoint hotSpot = manager->object->hotSpot();
+ for (int cnum = 0; cnum < actions.size(); ++cnum) {
+ const QPixmap cpm = manager->dragCursor(actions.at(cnum));
+ int w = cpm.width();
+ int h = cpm.height();
+
+ if (hasPixmap) {
+ const int x1 = qMin(-hotSpot.x(), 0);
+ const int x2 = qMax(pixmap.width() - hotSpot.x(), cpm.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 QRect srcRect = pixmap.rect();
+ const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
+ const QPoint newHotSpot = hotSpot;
+ QPixmap newCursor(w, h);
+ if (hasPixmap) {
+ newCursor.fill(QColor(0, 0, 0, 0));
+ QPainter p(&newCursor);
+ p.drawPixmap(pmDest, pixmap, srcRect);
+ p.drawPixmap(qMax(0,newHotSpot.x()),qMax(0,newHotSpot.y()),cpm);
+ } else {
+ newCursor = cpm;
+ }
+
+ 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(actions.at(cnum), sysCursor);
+ }
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %d cursors", __FUNCTION__, m_cursors.size());
+}
+
+void QWindowsOleDropSource::clearCursors()
+{
+ if (!m_cursors.isEmpty()) {
+ const ActionCursorMap::const_iterator cend = m_cursors.constEnd();
+ for (ActionCursorMap::const_iterator it = m_cursors.constBegin(); it != cend; ++it)
+ DestroyCursor(it.value());
+ m_cursors.clear();
+ }
+}
+
+//---------------------------------------------------------------------
+// IUnknown Methods
+//---------------------------------------------------------------------
+
+STDMETHODIMP
+QWindowsOleDropSource::QueryInterface(REFIID iid, void FAR* FAR* ppv)
+{
+ if (iid == IID_IUnknown || iid == IID_IDropSource) {
+ *ppv = this;
+ ++m_refs;
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDropSource::AddRef(void)
+{
+ return ++m_refs;
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDropSource::Release(void)
+{
+ if (--m_refs == 0) {
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+/*!
+ \brief Check for cancel.
+*/
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
+{
+ HRESULT hr = S_OK;
+ do {
+ if (fEscapePressed || QWindowsDrag::instance()->dragBeingCancelled()) {
+ hr = ResultFromScode(DRAGDROP_S_CANCEL);
+ break;
+ }
+
+ // grfKeyState is broken on CE & some Windows XP versions,
+ // therefore we need to check the state manually
+ if ((GetAsyncKeyState(VK_LBUTTON) == 0)
+ && (GetAsyncKeyState(VK_MBUTTON) == 0)
+ && (GetAsyncKeyState(VK_RBUTTON) == 0)) {
+ hr = ResultFromScode(DRAGDROP_S_DROP);
+ break;
+ }
+
+ const Qt::MouseButtons buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+ if (m_currentButtons == Qt::NoButton) {
+ m_currentButtons = buttons;
+ } else {
+ // Button changed: Complete Drop operation.
+ if (!(m_currentButtons & buttons)) {
+ hr = ResultFromScode(DRAGDROP_S_DROP);
+ break;
+ }
+ }
+
+ QGuiApplication::processEvents();
+
+ } while (false);
+
+ QDragManager::self()->willDrop = hr == DRAGDROP_S_DROP;
+
+ if (QWindowsContext::verboseOLE
+ && (QWindowsContext::verboseOLE > 1 || hr != S_OK))
+ qDebug("%s fEscapePressed=%d, grfKeyState=%lu buttons=%d willDrop = %d returns 0x%x",
+ __FUNCTION__, fEscapePressed,grfKeyState, int(m_currentButtons),
+ QDragManager::self()->willDrop, int(hr));
+ return hr;
+}
+
+/*!
+ \brief Give feedback: Change cursor accoding to action.
+*/
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
+{
+ const Qt::DropAction action = translateToQDragDropAction(dwEffect);
+
+ if (QWindowsContext::verboseOLE > 2)
+ qDebug("%s dwEffect=%lu, action=%d", __FUNCTION__, dwEffect, action);
+
+ if (m_currentAction != action) {
+ m_currentAction = action;
+ QDragManager::self()->emitActionChanged(m_currentAction);
+ }
+
+ const ActionCursorMap::const_iterator it = m_cursors.constFind(m_currentAction);
+ if (it != m_cursors.constEnd()) {
+ SetCursor(it.value());
+ return ResultFromScode(S_OK);
+ }
+
+ return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS);
+}
+
+/*!
+ \class QWindowsOleDropTarget
+ \brief Implementation of IDropTarget
+
+ To be registered for each window. Currently, drop sites
+ are enabled for top levels. The child window handling
+ (sending DragEnter/Leave, etc) is handled in here.
+
+ \sa QWindowsDrag
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) :
+ m_refs(1), m_window(w), m_currentWindow(0), m_chosenEffect(0), m_lastKeyState(0)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << this << w;
+}
+
+QWindowsOleDropTarget::~QWindowsOleDropTarget()
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %p", __FUNCTION__, this);
+}
+
+STDMETHODIMP
+QWindowsOleDropTarget::QueryInterface(REFIID iid, void FAR* FAR* ppv)
+{
+ if (iid == IID_IUnknown || iid == IID_IDropTarget) {
+ *ppv = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDropTarget::AddRef(void)
+{
+ return ++m_refs;
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDropTarget::Release(void)
+{
+ if (--m_refs == 0) {
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+QWindow *QWindowsOleDropTarget::findDragOverWindow(const POINTL &pt) const
+{
+ if (QWindowsWindow *child =
+ QWindowsWindow::baseWindowOf(m_window)->childAtScreenPoint(QPoint(pt.x, pt.y)))
+ return child->window();
+ return m_window;
+}
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
+ POINTL pt, LPDWORD pdwEffect)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, m_window, grfKeyState, pt.x, pt.y);
+
+ QWindowsDrag::instance()->setDropDataObject(pDataObj);
+ pDataObj->AddRef();
+ m_currentWindow = m_window;
+ sendDragEnterEvent(m_window, grfKeyState, pt, pdwEffect);
+ *pdwEffect = m_chosenEffect;
+ return NOERROR;
+}
+
+void QWindowsOleDropTarget::sendDragEnterEvent(QWindow *dragEnterWidget,
+ DWORD grfKeyState,
+ POINTL pt, LPDWORD pdwEffect)
+{
+ Q_ASSERT(dragEnterWidget);
+
+ m_lastPoint = QWindowsGeometryHint::mapFromGlobal(dragEnterWidget, QPoint(pt.x,pt.y));
+ m_lastKeyState = grfKeyState;
+
+ m_chosenEffect = DROPEFFECT_NONE;
+
+ QDragManager *manager = QDragManager::self();
+ QMimeData *md = manager->dropData();
+ const Qt::MouseButtons mouseButtons
+ = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+ const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
+ const Qt::KeyboardModifiers keyMods = toQtKeyboardModifiers(grfKeyState);
+ QDragEnterEvent enterEvent(m_lastPoint, actions, md, mouseButtons, keyMods);
+ QGuiApplication::sendEvent(m_currentWindow, &enterEvent);
+ m_answerRect = enterEvent.answerRect();
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << " sent drag enter to " << m_window
+ << *md << " actions=" << actions
+ << " mods=" << keyMods << " accepted: "
+ << enterEvent.isAccepted();
+
+ if (enterEvent.isAccepted())
+ m_chosenEffect = translateToWinDragEffects(enterEvent.dropAction());
+ // Documentation states that a drag move event is sent immediately after
+ // a drag enter event. This will honor widgets overriding dragMoveEvent only:
+ if (enterEvent.isAccepted()) {
+ QDragMoveEvent moveEvent(m_lastPoint, actions, md, mouseButtons, keyMods);
+ m_answerRect = enterEvent.answerRect();
+ moveEvent.setDropAction(enterEvent.dropAction());
+ moveEvent.accept(); // accept by default, since enter event was accepted.
+
+ QGuiApplication::sendEvent(dragEnterWidget, &moveEvent);
+ if (moveEvent.isAccepted()) {
+ m_answerRect = moveEvent.answerRect();
+ m_chosenEffect = translateToWinDragEffects(moveEvent.dropAction());
+ } else {
+ m_chosenEffect = DROPEFFECT_NONE;
+ }
+ }
+}
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
+{
+ QWindow *dragOverWindow = findDragOverWindow(pt);
+
+ 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;
+ return NOERROR;
+ }
+
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug().nospace() << '>' << __FUNCTION__ << ' ' << m_window << " current "
+ << dragOverWindow << " key=" << grfKeyState
+ << " pt=" <<pt.x << ',' << pt.y;
+
+ if (dragOverWindow != m_currentWindow) {
+ QPointer<QWindow> dragOverWindowGuard(dragOverWindow);
+ // Send drag leave event to the previous drag widget.
+ // Drag-Over widget might be deleted in DragLeave,
+ // (tasktracker 218353).
+ QDragLeaveEvent dragLeave;
+ if (m_currentWindow)
+ QGuiApplication::sendEvent(m_currentWindow, &dragLeave);
+ if (!dragOverWindowGuard) {
+ dragOverWindow = findDragOverWindow(pt);
+ }
+ // Send drag enter event to the current drag widget.
+ m_currentWindow = dragOverWindow;
+ sendDragEnterEvent(dragOverWindow, grfKeyState, pt, pdwEffect);
+ }
+
+ QDragManager *manager = QDragManager::self();
+ QMimeData *md = manager->dropData();
+
+ const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
+
+ QDragMoveEvent oldEvent(m_lastPoint, actions, md,
+ QWindowsMouseHandler::keyStateToMouseButtons(m_lastKeyState),
+ toQtKeyboardModifiers(m_lastKeyState));
+
+ m_lastPoint = tmpPoint;
+ m_lastKeyState = grfKeyState;
+
+ QDragMoveEvent e(tmpPoint, actions, md,
+ QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState),
+ toQtKeyboardModifiers(grfKeyState));
+ if (m_chosenEffect != DROPEFFECT_NONE) {
+ if (oldEvent.dropAction() == e.dropAction() &&
+ oldEvent.keyboardModifiers() == e.keyboardModifiers())
+ e.setDropAction(translateToQDragDropAction(m_chosenEffect));
+ e.accept();
+ }
+ QGuiApplication::sendEvent(dragOverWindow, &e);
+
+ m_answerRect = e.answerRect();
+ if (e.isAccepted())
+ m_chosenEffect = translateToWinDragEffects(e.dropAction());
+ else
+ m_chosenEffect = DROPEFFECT_NONE;
+ *pdwEffect = m_chosenEffect;
+
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("<%s effect=0x%lx", __FUNCTION__, m_chosenEffect);
+ return NOERROR;
+}
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropTarget::DragLeave()
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug().nospace() <<__FUNCTION__ << ' ' << m_window;
+
+ m_currentWindow = 0;
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(m_window, &e);
+ QWindowsDrag::instance()->releaseDropDataObject();
+
+ return NOERROR;
+}
+
+#define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState,
+ POINTL pt, LPDWORD pdwEffect)
+{
+ QWindow *dropWindow = findDragOverWindow(pt);
+
+ if (QWindowsContext::verboseOLE)
+ qDebug().nospace() << __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
+ // it doesn't then use the last known button state;
+ if ((grfKeyState & KEY_STATE_BUTTON_MASK) == 0)
+ grfKeyState |= m_lastKeyState & KEY_STATE_BUTTON_MASK;
+ m_lastKeyState = grfKeyState;
+
+ QWindowsDrag *windowsDrag = QWindowsDrag::instance();
+ QDragManager *manager = QDragManager::self();
+ QMimeData *md = manager->dropData();
+ QDropEvent e(m_lastPoint, translateToQDragDropActions(*pdwEffect), md,
+ QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState),
+ toQtKeyboardModifiers(grfKeyState));
+ if (m_chosenEffect != DROPEFFECT_NONE)
+ e.setDropAction(translateToQDragDropAction(m_chosenEffect));
+
+ QGuiApplication::sendEvent(dropWindow, &e);
+ if (m_chosenEffect != DROPEFFECT_NONE)
+ e.accept();
+
+ if (e.isAccepted()) {
+ if (e.dropAction() == Qt::MoveAction || e.dropAction() == Qt::TargetMoveAction) {
+ if (e.dropAction() == Qt::MoveAction)
+ m_chosenEffect = DROPEFFECT_MOVE;
+ else
+ m_chosenEffect = DROPEFFECT_COPY;
+ HGLOBAL hData = GlobalAlloc(0, sizeof(DWORD));
+ if (hData) {
+ DWORD *moveEffect = (DWORD *)GlobalLock(hData);;
+ *moveEffect = DROPEFFECT_MOVE;
+ GlobalUnlock(hData);
+ STGMEDIUM medium;
+ memset(&medium, 0, sizeof(STGMEDIUM));
+ medium.tymed = TYMED_HGLOBAL;
+ medium.hGlobal = hData;
+ FORMATETC format;
+ format.cfFormat = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT);
+ format.tymed = TYMED_HGLOBAL;
+ format.ptd = 0;
+ format.dwAspect = 1;
+ format.lindex = -1;
+ windowsDrag->dropDataObject()->SetData(&format, &medium, true);
+ }
+ } else {
+ m_chosenEffect = translateToWinDragEffects(e.dropAction());
+ }
+ } else {
+ m_chosenEffect = DROPEFFECT_NONE;
+ }
+ *pdwEffect = m_chosenEffect;
+
+ windowsDrag->releaseDropDataObject();
+ return NOERROR;
+}
+
+/*!
+ \class QWindowsDrag
+ \brief Windows drag implementation.
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsDrag::QWindowsDrag() : m_dropDataObject(0), m_dragBeingCancelled(false)
+{
+}
+
+QWindowsDrag::~QWindowsDrag()
+{
+}
+
+void QWindowsDrag::startDrag()
+{
+ // TODO: Accessibility handling?
+ QDragManager *dragManager = QDragManager::self();
+ QMimeData *dropData = dragManager->dropData();
+ m_dragBeingCancelled = false;
+
+ DWORD resultEffect;
+ QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource();
+ windowDropSource->createCursors();
+ QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
+ const Qt::DropActions possibleActions = dragManager->possible_actions;
+ const DWORD allowedEffects = translateToWinDragEffects(possibleActions);
+ if (QWindowsContext::verboseOLE)
+ qDebug(">%s possible Actions=%x, effects=0x%lx", __FUNCTION__,
+ int(possibleActions), allowedEffects);
+ const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect);
+ const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect();
+ Qt::DropAction ret = Qt::IgnoreAction;
+ if (r == DRAGDROP_S_DROP) {
+ if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) {
+ ret = Qt::TargetMoveAction;
+ resultEffect = DROPEFFECT_MOVE;
+ } else {
+ ret = translateToQDragDropAction(resultEffect);
+ }
+ // Force it to be a copy if an unsupported operation occurred.
+ // This indicates a bug in the drop target.
+ if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects))
+ ret = Qt::CopyAction;
+ } else {
+ dragManager->setCurrentTarget(0);
+ }
+
+ // clean up
+ 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), ret);
+}
+
+void QWindowsDrag::move(const QMouseEvent *me)
+{
+ const QPoint pos = me->pos();
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %d %d", __FUNCTION__, pos.x(), pos.y());
+}
+
+void QWindowsDrag::drop(const QMouseEvent *me)
+{
+ const QPoint pos = me->pos();
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %d %d", __FUNCTION__, pos.x(), pos.y());
+}
+
+void QWindowsDrag::cancel()
+{
+ // TODO: Accessibility handling?
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s", __FUNCTION__);
+ m_dragBeingCancelled = true;
+}
+
+QWindowsDrag *QWindowsDrag::instance()
+{
+ return static_cast<QWindowsDrag *>(QWindowsIntegration::instance()->drag());
+}
+
+void QWindowsDrag::releaseDropDataObject()
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %p", __FUNCTION__, m_dropDataObject);
+ if (m_dropDataObject) {
+ m_dropDataObject->Release();
+ m_dropDataObject = 0;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
new file mode 100644
index 0000000000..6e6ebe0424
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDRAG_H
+#define QWINDOWSDRAG_H
+
+#include "qwindowsinternalmimedata.h"
+
+#include <QtGui/QPlatformDrag>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDropMimeData : public QWindowsInternalMimeData {
+public:
+ QWindowsDropMimeData() {}
+ virtual IDataObject *retrieveDataObject() const;
+};
+
+class QWindowsOleDropTarget : public IDropTarget
+{
+public:
+ explicit QWindowsOleDropTarget(QWindow *w);
+ virtual ~QWindowsOleDropTarget();
+
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
+ STDMETHOD_(ULONG, AddRef)(void);
+ STDMETHOD_(ULONG, Release)(void);
+
+ // IDropTarget methods
+ STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+ STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+ STDMETHOD(DragLeave)();
+ STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+
+private:
+ inline QWindow *findDragOverWindow(const POINTL &pt) const;
+ void sendDragEnterEvent(QWindow *to, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+
+ ULONG m_refs;
+ QWindow *const m_window;
+ QWindow *m_currentWindow;
+ QRect m_answerRect;
+ QPoint m_lastPoint;
+ DWORD m_chosenEffect;
+ DWORD m_lastKeyState;
+};
+
+class QWindowsDrag : public QPlatformDrag
+{
+public:
+ QWindowsDrag();
+ virtual ~QWindowsDrag();
+
+ virtual QMimeData *platformDropData() { return &m_dropData; }
+
+ virtual void startDrag();
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+ virtual void cancel();
+
+ static QWindowsDrag *instance();
+
+ IDataObject *dropDataObject() const { return m_dropDataObject; }
+ void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; }
+ void releaseDropDataObject();
+
+ bool dragBeingCancelled() const { return m_dragBeingCancelled; }
+
+private:
+ QWindowsDropMimeData m_dropData;
+ IDataObject *m_dropDataObject;
+ bool m_dragBeingCancelled;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDRAG_H
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
new file mode 100644
index 0000000000..ea35ab5f9f
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -0,0 +1,950 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsfontdatabase.h"
+#include "qwindowscontext.h"
+#include "qwindowsfontengine.h"
+#include "qwindowsfontenginedirectwrite.h"
+#include "qtwindows_additional.h"
+
+#include <QtGui/QFont>
+#include <QtGui/QGuiApplication>
+
+#include <QtCore/qmath.h>
+#include <QtCore/QDebug>
+
+#if !defined(QT_NO_DIRECTWRITE)
+# include <dwrite.h>
+# include <d2d1.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \struct QWindowsFontEngineData
+ \brief Static constant data shared by the font engines.
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsFontEngineData::QWindowsFontEngineData()
+#if !defined(QT_NO_DIRECTWRITE)
+ : directWriteFactory(0)
+ , directWriteGdiInterop(0)
+#endif
+{
+ // from qapplication_win.cpp
+ UINT result = 0;
+ if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
+ clearTypeEnabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
+
+ int winSmooth;
+ if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) {
+ fontSmoothingGamma = winSmooth / qreal(1000.0);
+ } else {
+ fontSmoothingGamma = 1.0;
+ }
+
+ // Safeguard ourselves against corrupt registry values...
+ if (fontSmoothingGamma > 5 || fontSmoothingGamma < 1)
+ fontSmoothingGamma = qreal(1.4);
+
+ const qreal gray_gamma = 2.31;
+ for (int i=0; i<256; ++i)
+ pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
+
+ HDC displayDC = GetDC(0);
+ hdc = CreateCompatibleDC(displayDC);
+ ReleaseDC(0, displayDC);
+}
+
+QWindowsFontEngineData::~QWindowsFontEngineData()
+{
+ if (hdc)
+ ReleaseDC(0, hdc);
+#if !defined(QT_NO_DIRECTWRITE)
+ if (directWriteGdiInterop)
+ directWriteGdiInterop->Release();
+ if (directWriteFactory)
+ directWriteFactory->Release();
+#endif
+}
+
+#if !defined(QT_NO_DIRECTWRITE)
+static inline bool initDirectWrite(QWindowsFontEngineData *d)
+{
+ if (!d->directWriteFactory) {
+ const HRESULT hr = DWriteCreateFactory(
+ DWRITE_FACTORY_TYPE_SHARED,
+ __uuidof(IDWriteFactory),
+ reinterpret_cast<IUnknown **>(&d->directWriteFactory)
+ );
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: DWriteCreateFactory failed", __FUNCTION__);
+ return false;
+ }
+ }
+ if (!d->directWriteGdiInterop) {
+ const HRESULT hr = d->directWriteFactory->GetGdiInterop(&d->directWriteGdiInterop);
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGdiInterop failed", __FUNCTION__);
+ return false;
+ }
+ }
+ return true;
+}
+
+#endif // !defined(QT_NO_DIRECTWRITE)
+
+/*!
+ \class QWindowsFontDatabase
+ \brief Font database for Windows
+
+ \note The Qt 4.8 WIndows font database employed a mechanism of
+ delayed population of the database again passing a font name
+ to EnumFontFamiliesEx(), working around the fact that
+ EnumFontFamiliesEx() does not list all fonts by default.
+ This should be introduced to Lighthouse as well?
+
+ \ingroup qt-lighthouse-win
+*/
+
+QDebug operator<<(QDebug d, const QFontDef &def)
+{
+ d.nospace() << "Family=" << def.family << " Stylename=" << def.styleName
+ << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize
+ << " styleHint=" << def.styleHint << " weight=" << def.weight
+ << " stretch=" << def.stretch << " hintingPreference="
+ << def.hintingPreference << ' ';
+ return d;
+}
+
+/* From QFontDatabase.cpp, qt_determine_writing_systems_from_truetype_bits().
+ * Fixme: Make public? */
+
+// see the Unicode subset bitfields in the MSDN docs
+static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
+ // Any,
+ { 127, 127 },
+ // Latin,
+ { 0, 127 },
+ // Greek,
+ { 7, 127 },
+ // Cyrillic,
+ { 9, 127 },
+ // Armenian,
+ { 10, 127 },
+ // Hebrew,
+ { 11, 127 },
+ // Arabic,
+ { 13, 127 },
+ // Syriac,
+ { 71, 127 },
+ //Thaana,
+ { 72, 127 },
+ //Devanagari,
+ { 15, 127 },
+ //Bengali,
+ { 16, 127 },
+ //Gurmukhi,
+ { 17, 127 },
+ //Gujarati,
+ { 18, 127 },
+ //Oriya,
+ { 19, 127 },
+ //Tamil,
+ { 20, 127 },
+ //Telugu,
+ { 21, 127 },
+ //Kannada,
+ { 22, 127 },
+ //Malayalam,
+ { 23, 127 },
+ //Sinhala,
+ { 73, 127 },
+ //Thai,
+ { 24, 127 },
+ //Lao,
+ { 25, 127 },
+ //Tibetan,
+ { 70, 127 },
+ //Myanmar,
+ { 74, 127 },
+ // Georgian,
+ { 26, 127 },
+ // Khmer,
+ { 80, 127 },
+ // SimplifiedChinese,
+ { 126, 127 },
+ // TraditionalChinese,
+ { 126, 127 },
+ // Japanese,
+ { 126, 127 },
+ // Korean,
+ { 56, 127 },
+ // Vietnamese,
+ { 0, 127 }, // same as latin1
+ // Other,
+ { 126, 127 },
+ // Ogham,
+ { 78, 127 },
+ // Runic,
+ { 79, 127 },
+ // Nko,
+ { 14, 127 },
+};
+
+enum
+{
+ SimplifiedChineseCsbBit = 18,
+ TraditionalChineseCsbBit = 20,
+ JapaneseCsbBit = 17,
+ KoreanCsbBit = 21
+};
+
+static inline void writingSystemsFromTrueTypeBits(quint32 unicodeRange[4],
+ quint32 codePageRange[2],
+ QSupportedWritingSystems *ws)
+{
+ bool hasScript = false;
+ for(int i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
+ int bit = requiredUnicodeBits[i][0];
+ int index = bit/32;
+ int flag = 1 << (bit&31);
+ if (bit != 126 && unicodeRange[index] & flag) {
+ bit = requiredUnicodeBits[i][1];
+ index = bit/32;
+
+ flag = 1 << (bit&31);
+ if (bit == 127 || unicodeRange[index] & flag) {
+ ws->setSupported(QFontDatabase::WritingSystem(i), true);
+ hasScript = true;
+ }
+ }
+ }
+ if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
+ ws->setSupported(QFontDatabase::SimplifiedChinese, true);
+ hasScript = true;
+ }
+ if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
+ ws->setSupported(QFontDatabase::TraditionalChinese, true);
+ hasScript = true;
+ }
+ if(codePageRange[0] & (1 << JapaneseCsbBit)) {
+ ws->setSupported(QFontDatabase::Japanese, true);
+ hasScript = true;
+ //qDebug("font %s supports Japanese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << KoreanCsbBit)) {
+ ws->setSupported(QFontDatabase::Korean, true);
+ hasScript = true;
+ }
+ if (!hasScript)
+ ws->setSupported(QFontDatabase::Symbol, true);
+}
+
+// convert 0 ~ 1000 integer to QFont::Weight
+static inline QFont::Weight weightFromInteger(long weight)
+{
+ if (weight < 400)
+ return QFont::Light;
+ if (weight < 600)
+ return QFont::Normal;
+ if (weight < 700)
+ return QFont::DemiBold;
+ if (weight < 800)
+ return QFont::Bold;
+ return QFont::Black;
+}
+
+static inline QFontDatabase::WritingSystem writingSystemFromScript(const QString &scriptName)
+{
+ if (scriptName == QStringLiteral("Western")
+ || scriptName == QStringLiteral("Baltic")
+ || scriptName == QStringLiteral("Central European")
+ || scriptName == QStringLiteral("Turkish")
+ || scriptName == QStringLiteral("Vietnamese")
+ || scriptName == QStringLiteral("OEM/Dos"))
+ return QFontDatabase::Latin;
+ if (scriptName == QStringLiteral("Thai"))
+ return QFontDatabase::Thai;
+ if (scriptName == QStringLiteral("Symbol")
+ || scriptName == QStringLiteral("Other"))
+ return QFontDatabase::Symbol;
+ if (scriptName == QStringLiteral("CHINESE_GB2312"))
+ return QFontDatabase::SimplifiedChinese;
+ if (scriptName == QStringLiteral("CHINESE_BIG5"))
+ return QFontDatabase::TraditionalChinese;
+ if (scriptName == QStringLiteral("Cyrillic"))
+ return QFontDatabase::Cyrillic;
+ if (scriptName == QStringLiteral("Hangul"))
+ return QFontDatabase::Korean;
+ if (scriptName == QStringLiteral("Hebrew"))
+ return QFontDatabase::Hebrew;
+ if (scriptName == QStringLiteral("Greek"))
+ return QFontDatabase::Greek;
+ if (scriptName == QStringLiteral("Japanese"))
+ return QFontDatabase::Japanese;
+ if (scriptName == QStringLiteral("Arabic"))
+ return QFontDatabase::Arabic;
+ return QFontDatabase::Any;
+}
+
+static bool addFontToDatabase(QString familyName, const QString &scriptName,
+ const TEXTMETRIC *textmetric,
+ const FONTSIGNATURE *signature,
+ int type)
+{
+ // the "@family" fonts are just the same as "family". Ignore them.
+ if (familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_")))
+ return false;
+
+ static const int SMOOTH_SCALABLE = 0xffff;
+ const QString foundryName; // No such concept.
+ const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric;
+ const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH);
+ const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE);
+ const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
+ const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
+ const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
+ const bool antialias = false;
+ const QFont::Weight weight = weightFromInteger(tm->tmWeight);
+ const QFont::Stretch stretch = QFont::Unstretched;
+
+ Q_UNUSED(fixed)
+
+ if (QWindowsContext::verboseFonts > 2) {
+ QDebug nospace = qDebug().nospace();
+ nospace << __FUNCTION__ << familyName << scriptName
+ << "TTF=" << ttf;
+ if (type & DEVICE_FONTTYPE)
+ nospace << " DEVICE";
+ if (type & RASTER_FONTTYPE)
+ nospace << " RASTER";
+ if (type & TRUETYPE_FONTTYPE)
+ nospace << " TRUETYPE";
+ nospace << " scalable=" << scalable << " Size=" << size
+ << " Style=" << style << " Weight=" << weight
+ << " stretch=" << stretch;
+ }
+
+/* Fixme: omitted for the moment
+ if(ttf && localizedName(familyName) && family->english_name.isEmpty())
+ family->english_name = getEnglishName(familyName);
+*/
+ QSupportedWritingSystems writingSystems;
+ if (type & TRUETYPE_FONTTYPE) {
+ quint32 unicodeRange[4] = {
+ signature->fsUsb[0], signature->fsUsb[1],
+ signature->fsUsb[2], signature->fsUsb[3]
+ };
+ quint32 codePageRange[2] = {
+ signature->fsCsb[0], signature->fsCsb[1]
+ };
+ writingSystemsFromTrueTypeBits(unicodeRange, codePageRange, &writingSystems);
+ // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains
+ // the symbol for Baht, and Windows thus reports that it supports the Thai script.
+ // Since it's the default UI font on this platform, most widgets will be unable to
+ // display Thai text by default. As a temporary work around, we special case Segoe UI
+ // and remove the Thai script from its list of supported writing systems.
+ if (writingSystems.supported(QFontDatabase::Thai) &&
+ familyName == QStringLiteral("Segoe UI"))
+ writingSystems.setSupported(QFontDatabase::Thai, false);
+ } else {
+ const QFontDatabase::WritingSystem ws = writingSystemFromScript(scriptName);
+ if (ws != QFontDatabase::Any)
+ writingSystems.setSupported(ws);
+ }
+
+ QPlatformFontDatabase::registerFont(familyName, foundryName, weight,
+ style, stretch, antialias, scalable, size, writingSystems, 0);
+ // add fonts windows can generate for us:
+ if (weight <= QFont::DemiBold)
+ QPlatformFontDatabase::registerFont(familyName, foundryName, QFont::Bold,
+ style, stretch, antialias, scalable, size, writingSystems, 0);
+ if (style != QFont::StyleItalic)
+ QPlatformFontDatabase::registerFont(familyName, foundryName, weight,
+ QFont::StyleItalic, stretch, antialias, scalable, size, writingSystems, 0);
+ if (weight <= QFont::DemiBold && style != QFont::StyleItalic)
+ QPlatformFontDatabase::registerFont(familyName, foundryName, QFont::Bold,
+ QFont::StyleItalic, stretch, antialias, scalable, size, writingSystems, 0);
+ return true;
+}
+
+static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
+ int type, LPARAM namesSetIn)
+{
+ typedef QSet<QString> StringSet;
+ const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
+ const QString script = QString::fromWCharArray(f->elfScript);
+
+ const FONTSIGNATURE signature = textmetric->ntmFontSig;
+
+ // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
+ // identical to a TEXTMETRIC except for the last four members, which we don't use
+ // anyway
+ if (addFontToDatabase(familyName, script, (TEXTMETRIC *)textmetric, &signature, type))
+ reinterpret_cast<StringSet *>(namesSetIn)->insert(familyName);
+
+ // keep on enumerating
+ return 1;
+}
+
+void QWindowsFontDatabase::populateFontDatabase()
+{
+ if (m_families.isEmpty()) {
+ QPlatformFontDatabase::populateFontDatabase();
+ populate(); // Called multiple times.
+ // Work around EnumFontFamiliesEx() not listing the system font, see below.
+ const QString sysFontFamily = QGuiApplication::font().family();
+ if (!m_families.contains(sysFontFamily))
+ populate(sysFontFamily);
+ }
+}
+
+/*!
+ \brief Populate font database using EnumFontFamiliesEx().
+
+ Normally, leaving the name empty should enumerate
+ all fonts, however, system fonts like "MS Shell Dlg 2"
+ are only found when specifying the name explicitly.
+*/
+
+void QWindowsFontDatabase::populate(const QString &family)
+ {
+
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << m_families.size() << family;
+
+ HDC dummy = GetDC(0);
+ LOGFONT lf;
+ lf.lfCharSet = DEFAULT_CHARSET;
+ if (family.size() >= LF_FACESIZE) {
+ qWarning("%s: Unable to enumerate family '%s'.",
+ __FUNCTION__, qPrintable(family));
+ return;
+ }
+ wmemcpy(lf.lfFaceName, reinterpret_cast<const wchar_t*>(family.utf16()),
+ family.size() + 1);
+ lf.lfPitchAndFamily = 0;
+ EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont,
+ (LPARAM)&m_families, 0);
+ ReleaseDC(0, dummy);
+}
+
+QWindowsFontDatabase::QWindowsFontDatabase() :
+ m_fontEngineData(new QWindowsFontEngineData)
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << "Clear type: "
+ << m_fontEngineData->clearTypeEnabled << "gamma: "
+ << m_fontEngineData->fontSmoothingGamma;
+}
+
+QWindowsFontDatabase::~QWindowsFontDatabase()
+{
+}
+
+QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef,
+ QUnicodeTables::Script script,
+ void *handle)
+{
+ QFontEngine *fe = QWindowsFontDatabase::createEngine(script, fontDef,
+ 0, QWindowsContext::instance()->defaultDPI(), false,
+ QStringList(), m_fontEngineData);
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << "FONTDEF" << fontDef << script << fe << handle;
+ return fe;
+}
+
+QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
+{
+ QFontEngine *fe = QPlatformFontDatabase::fontEngine(fontData, pixelSize, hintingPreference);
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe;
+ return fe;
+}
+
+QStringList QWindowsFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+{
+ QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script);
+ if (!result.isEmpty())
+ return result;
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << family << style << styleHint
+ << script << result << m_families.size();
+ return result;
+}
+
+QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+{
+ const QStringList result = QPlatformFontDatabase::addApplicationFont(fontData, fileName);
+ Q_UNIMPLEMENTED();
+ return result;
+}
+
+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;
+ return result;
+}
+
+HFONT QWindowsFontDatabase::systemFont()
+{
+ static const HFONT stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT);
+ return stock_sysfont;
+}
+
+// Creation functions
+
+static inline bool scriptRequiresOpenType(int script)
+{
+ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+}
+
+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;
+
+QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &request,
+ HDC fontHdc, int dpi, bool rawMode,
+ const QStringList &family_list,
+ const QSharedPointer<QWindowsFontEngineData> &data)
+{
+ LOGFONT lf;
+ memset(&lf, 0, sizeof(LOGFONT));
+
+ const bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fontHdc;
+
+ const HDC hdc = useDevice ? fontHdc : data->hdc;
+
+ bool stockFont = false;
+ bool preferClearTypeAA = false;
+
+ HFONT hfont = 0;
+
+#if !defined(QT_NO_DIRECTWRITE)
+ bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting)
+ || (request.hintingPreference == QFont::PreferVerticalHinting);
+ IDWriteFont *directWriteFont = 0;
+#else
+ bool useDirectWrite = false;
+#endif
+
+ if (rawMode) { // will choose a stock font
+ int f = SYSTEM_FONT;
+ const QString fam = request.family.toLower();
+ if (fam == QStringLiteral("default") || fam == QStringLiteral("system"))
+ f = SYSTEM_FONT;
+ else if (fam == QStringLiteral("system_fixed"))
+ f = SYSTEM_FIXED_FONT;
+ else if (fam == QStringLiteral("ansi_fixed"))
+ f = ANSI_FIXED_FONT;
+ else if (fam == QStringLiteral("ansi_var"))
+ f = ANSI_VAR_FONT;
+ else if (fam == QStringLiteral("device_default"))
+ f = DEVICE_DEFAULT_FONT;
+ else if (fam == QStringLiteral("oem_fixed"))
+ f = OEM_FIXED_FONT;
+ else if (fam.at(0) == QLatin1Char('#'))
+ f = fam.right(fam.length()-1).toInt();
+ hfont = (HFONT)GetStockObject(f);
+ if (!hfont) {
+ qErrnoWarning("%s: GetStockObject failed", __FUNCTION__);
+ hfont = QWindowsFontDatabase::systemFont();
+ }
+ stockFont = true;
+ } else {
+ int hint = FF_DONTCARE;
+ switch (request.styleHint) {
+ case QFont::Helvetica:
+ hint = FF_SWISS;
+ break;
+ case QFont::Times:
+ hint = FF_ROMAN;
+ break;
+ case QFont::Courier:
+ hint = FF_MODERN;
+ break;
+ case QFont::OldEnglish:
+ hint = FF_DECORATIVE;
+ break;
+ case QFont::System:
+ hint = FF_MODERN;
+ break;
+ default:
+ break;
+ }
+
+ lf.lfHeight = -qRound(request.pixelSize);
+ lf.lfWidth = 0;
+ lf.lfEscapement = 0;
+ lf.lfOrientation = 0;
+ if (request.weight == 50)
+ lf.lfWeight = FW_DONTCARE;
+ else
+ lf.lfWeight = (request.weight*900)/99;
+ lf.lfItalic = request.style != QFont::StyleNormal;
+ lf.lfCharSet = DEFAULT_CHARSET;
+
+ int strat = OUT_DEFAULT_PRECIS;
+ if (request.styleStrategy & QFont::PreferBitmap) {
+ strat = OUT_RASTER_PRECIS;
+ } else if (request.styleStrategy & QFont::PreferDevice) {
+ strat = OUT_DEVICE_PRECIS;
+ } else if (request.styleStrategy & QFont::PreferOutline) {
+ strat = OUT_OUTLINE_PRECIS;
+ } else if (request.styleStrategy & QFont::ForceOutline) {
+ strat = OUT_TT_ONLY_PRECIS;
+ }
+
+ lf.lfOutPrecision = strat;
+
+ int qual = DEFAULT_QUALITY;
+
+ if (request.styleStrategy & QFont::PreferMatch)
+ qual = DRAFT_QUALITY;
+ else if (request.styleStrategy & QFont::PreferQuality)
+ qual = PROOF_QUALITY;
+
+ if (request.styleStrategy & QFont::PreferAntialias) {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) {
+ qual = CLEARTYPE_QUALITY;
+ preferClearTypeAA = true;
+ } else {
+ qual = ANTIALIASED_QUALITY;
+ }
+ } else if (request.styleStrategy & QFont::NoAntialias) {
+ qual = NONANTIALIASED_QUALITY;
+ }
+
+ lf.lfQuality = qual;
+
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfPitchAndFamily = DEFAULT_PITCH | hint;
+
+ QString fam = request.family;
+
+ if(fam.isEmpty())
+ fam = QStringLiteral("MS Sans Serif");
+
+ if ((fam == QStringLiteral("MS Sans Serif"))
+ && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) {
+ fam = QStringLiteral("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale
+ }
+ if (fam == QStringLiteral("Courier") && !(request.styleStrategy & QFont::PreferBitmap))
+ fam = QStringLiteral("Courier New");
+
+ memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
+
+ hfont = CreateFontIndirect(&lf);
+ if (!hfont)
+ qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__);
+
+ stockFont = (hfont == 0);
+ bool ttf = false;
+ int avWidth = 0;
+ BOOL res;
+ HGDIOBJ oldObj = SelectObject(hdc, hfont);
+
+ TEXTMETRIC tm;
+ res = GetTextMetrics(hdc, &tm);
+ avWidth = tm.tmAveCharWidth;
+ ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
+ SelectObject(hdc, oldObj);
+
+ if (!ttf || !useDirectWrite) {
+ useDirectWrite = false;
+
+ if (hfont && (!ttf || request.stretch != 100)) {
+ DeleteObject(hfont);
+ if (!res)
+ qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed");
+ lf.lfWidth = avWidth * request.stretch/100;
+ hfont = CreateFontIndirect(&lf);
+ if (!hfont)
+ qErrnoWarning("%s: CreateFontIndirect with stretch failed", __FUNCTION__);
+ }
+
+ if (hfont == 0) {
+ hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
+ stockFont = true;
+ }
+ }
+
+#if !defined(QT_NO_DIRECTWRITE)
+ else {
+ // Default to false for DirectWrite (and re-enable once/if everything
+ // turns out okay)
+ useDirectWrite = false;
+ if (initDirectWrite(data.data())) {
+ const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(QString::fromWCharArray(lf.lfFaceName));
+ memcpy(lf.lfFaceName, nameSubstitute.utf16(),
+ sizeof(wchar_t) * qMin(nameSubstitute.length() + 1, LF_FACESIZE));
+
+ HRESULT hr = data->directWriteGdiInterop->CreateFontFromLOGFONT(
+ &lf,
+ &directWriteFont);
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: CreateFontFromLOGFONT failed", __FUNCTION__);
+ } else {
+ DeleteObject(hfont);
+ useDirectWrite = true;
+ }
+ }
+ }
+#endif
+ }
+
+ QFontEngine *fe = 0;
+ if (!useDirectWrite) {
+ QWindowsFontEngine *few = new QWindowsFontEngine(request.family, hfont, stockFont, lf, data);
+ few->setObjectName(QStringLiteral("QWindowsFontEngine_") + request.family);
+ if (preferClearTypeAA)
+ few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
+
+ // Also check for OpenType tables when using complex scripts
+ // ### TODO: This only works for scripts that require OpenType. More generally
+ // for scripts that do not require OpenType we should just look at the list of
+ // supported writing systems in the font's OS/2 table.
+ if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = few->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ qWarning(" OpenType support missing for script\n");
+ delete few;
+ return 0;
+ }
+ }
+
+ few->initFontInfo(request, fontHdc, dpi);
+ fe = few;
+ }
+
+#if !defined(QT_NO_DIRECTWRITE)
+ else {
+ IDWriteFontFace *directWriteFontFace = NULL;
+ HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace);
+ if (SUCCEEDED(hr)) {
+ QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace,
+ request.pixelSize,
+ data);
+ fedw->initFontInfo(request, dpi, directWriteFont);
+ fedw->setObjectName(QStringLiteral("QWindowsFontEngineDirectWrite_") + request.family);
+ fe = fedw;
+ } else {
+ qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__);
+ }
+ }
+
+ if (directWriteFont != 0)
+ directWriteFont->Release();
+#endif
+
+ if(script == QUnicodeTables::Common
+ && !(request.styleStrategy & QFont::NoFontMerging)) {
+ QFontDatabase db;
+ if (!db.writingSystems(request.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 fm = QFontDatabase().families();
+ QStringList list = family_list;
+ const char **tf = tryFonts;
+ while(tf && *tf) {
+ if(fm.contains(QLatin1String(*tf)))
+ list << QLatin1String(*tf);
+ ++tf;
+ }
+ QFontEngine *mfe = new QWindowsMultiFontEngine(fe, list);
+ mfe->setObjectName(QStringLiteral("QWindowsMultiFontEngine_") + request.family);
+ mfe->fontDef = fe->fontDef;
+ fe = mfe;
+ }
+ }
+ return fe;
+}
+
+static inline int verticalDPI()
+{
+ return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY);
+}
+
+QFont QWindowsFontDatabase::defaultFont() const
+{
+ LOGFONT lf;
+ GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
+ QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(lf);
+ // "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;
+ return systemFont;
+}
+
+QHash<QByteArray, QFont> QWindowsFontDatabase::defaultFonts() const
+{
+ QHash<QByteArray, QFont> result;
+ NONCLIENTMETRICS ncm;
+ ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
+
+ const int verticalRes = verticalDPI();
+
+ const QFont menuFont = LOGFONT_to_QFont(ncm.lfMenuFont, verticalRes);
+ const QFont messageFont = LOGFONT_to_QFont(ncm.lfMessageFont, verticalRes);
+ const QFont statusFont = LOGFONT_to_QFont(ncm.lfStatusFont, verticalRes);
+ const QFont titleFont = LOGFONT_to_QFont(ncm.lfCaptionFont, verticalRes);
+
+ LOGFONT lfIconTitleFont;
+ SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
+ const QFont iconTitleFont = LOGFONT_to_QFont(lfIconTitleFont, verticalRes);
+
+ result.insert(QByteArray("QMenu"), menuFont);
+ result.insert(QByteArray("QMenuBar"), menuFont);
+ result.insert(QByteArray("QMessageBox"), messageFont);
+ result.insert(QByteArray("QTipLabel"), statusFont);
+ result.insert(QByteArray("QStatusBar"), statusFont);
+ result.insert(QByteArray("Q3TitleBar"), titleFont);
+ result.insert(QByteArray("QWorkspaceTitleBar"), titleFont);
+ result.insert(QByteArray("QAbstractItemView"), iconTitleFont);
+ result.insert(QByteArray("QDockWidgetTitle"), iconTitleFont);
+ if (QWindowsContext::verboseFonts) {
+ typedef QHash<QByteArray, QFont>::const_iterator CIT;
+ QDebug nsp = qDebug().nospace();
+ nsp << __FUNCTION__ << " DPI=" << verticalRes << "\n";
+ const CIT cend = result.constEnd();
+ for (CIT it = result.constBegin(); it != cend; ++it)
+ nsp << it.key() << ' ' << it.value() << '\n';
+ }
+ return result;
+}
+
+QFont QWindowsFontDatabase::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(false);
+ qFont.setOverline(false);
+ qFont.setStrikeOut(false);
+ return qFont;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h
new file mode 100644
index 0000000000..a80482f6e2
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSFONTDATABASE_H
+#define QWINDOWSFONTDATABASE_H
+
+#include <QtGui/QPlatformFontDatabase>
+#include <QtCore/QSharedPointer>
+#include "qtwindows_additional.h"
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_DIRECTWRITE)
+ struct IDWriteFactory;
+ struct IDWriteGdiInterop;
+#endif
+
+class QWindowsFontEngineData
+{
+ Q_DISABLE_COPY(QWindowsFontEngineData)
+public:
+ QWindowsFontEngineData();
+ ~QWindowsFontEngineData();
+
+ uint pow_gamma[256];
+
+ bool clearTypeEnabled;
+ qreal fontSmoothingGamma;
+ HDC hdc;
+#if !defined(QT_NO_DIRECTWRITE)
+ IDWriteFactory *directWriteFactory;
+ IDWriteGdiInterop *directWriteGdiInterop;
+#endif
+};
+
+class QWindowsFontDatabase : public QPlatformFontDatabase
+{
+public:
+ QWindowsFontDatabase();
+ ~QWindowsFontDatabase();
+
+ virtual void populateFontDatabase();
+ virtual QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
+ virtual QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+ virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
+ virtual void releaseHandle(void *handle);
+ virtual QString fontDir() const;
+
+ virtual QFont defaultFont() const;
+ virtual QHash<QByteArray, QFont> defaultFonts() const;
+
+ static QFontEngine *createEngine(int script, const QFontDef &request,
+ HDC fontHdc, int dpi, bool rawMode,
+ const QStringList &family_list,
+ const QSharedPointer<QWindowsFontEngineData> &data);
+
+ static HFONT systemFont();
+ static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
+
+private:
+ void populate(const QString &family = QString());
+ QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
+ QSet<QString> m_families;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSFONTDATABASE_H
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
new file mode 100644
index 0000000000..80d9ed4686
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -0,0 +1,1223 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if _WIN32_WINNT < 0x0500
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+
+#include "qwindowsfontengine.h"
+#include "qwindowsnativeimage.h"
+#include "qwindowscontext.h"
+#include "qwindowsfontdatabase.h"
+#include "qtwindows_additional.h"
+
+#include <QtGui/private/qtextengine_p.h> // glyph_metrics_t
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QPaintDevice>
+#include <QtGui/QBitmap>
+#include <QtGui/QPainter>
+#include <QtGui/private/qpainter_p.h>
+#include <QtGui/QPaintEngine>
+#include <QtGui/private/qpaintengine_raster_p.h>
+
+#include <QtCore/QtEndian>
+#include <QtCore/qmath.h>
+#include <QtCore/QThreadStorage>
+#include <QtCore/private/qsystemlibrary_p.h>
+
+#include <QtCore/private/qunicodetables_p.h>
+#include <QtCore/QDebug>
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+//### mingw needed define
+#ifndef TT_PRIM_CSPLINE
+#define TT_PRIM_CSPLINE 3
+#endif
+
+#ifdef MAKE_TAG
+#undef MAKE_TAG
+#endif
+// GetFontData expects the tags in little endian ;(
+#define MAKE_TAG(ch1, ch2, ch3, ch4) (\
+ (((quint32)(ch4)) << 24) | \
+ (((quint32)(ch3)) << 16) | \
+ (((quint32)(ch2)) << 8) | \
+ ((quint32)(ch1)) \
+ )
+
+// common DC for all fonts
+
+QT_BEGIN_NAMESPACE
+
+typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
+static PtrGetCharWidthI ptrGetCharWidthI = 0;
+static bool resolvedGetCharWidthI = false;
+
+static void resolveGetCharWidthI()
+{
+ if (resolvedGetCharWidthI)
+ return;
+ resolvedGetCharWidthI = true;
+ ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QStringLiteral("gdi32"), "GetCharWidthI");
+}
+
+// defined in qtextengine_win.cpp
+typedef void *SCRIPT_CACHE;
+typedef HRESULT (WINAPI *fScriptFreeCache)(SCRIPT_CACHE *);
+extern fScriptFreeCache ScriptFreeCache;
+
+static inline quint32 getUInt(unsigned char *p)
+{
+ quint32 val;
+ val = *p++ << 24;
+ val |= *p++ << 16;
+ val |= *p++ << 8;
+ val |= *p;
+
+ return val;
+}
+
+static inline quint16 getUShort(unsigned char *p)
+{
+ quint16 val;
+ val = *p++ << 8;
+ val |= *p;
+
+ return val;
+}
+
+// general font engine
+
+QFixed QWindowsFontEngine::lineThickness() const
+{
+ if(lineWidth > 0)
+ return lineWidth;
+
+ return QFontEngine::lineThickness();
+}
+
+static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
+{
+ int size;
+ size = GetOutlineTextMetrics(hdc, 0, 0);
+ OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size);
+ GetOutlineTextMetrics(hdc, size, otm);
+ return otm;
+}
+
+void QWindowsFontEngine::getCMap()
+{
+ ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE);
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ bool symb = false;
+ if (ttf) {
+ cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
+ int size = 0;
+ cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
+ cmapTable.size(), &symb, &size);
+ }
+ if (!cmap) {
+ ttf = false;
+ symb = false;
+ }
+ symbol = symb;
+ designToDevice = 1;
+ _faceId.index = 0;
+ if(cmap) {
+ OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
+ designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight);
+ unitsPerEm = otm->otmEMSquare;
+ x_height = (int)otm->otmsXHeight;
+ loadKerningPairs(designToDevice);
+ _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName)).toLatin1();
+ lineWidth = otm->otmsUnderscoreSize;
+ fsType = otm->otmfsType;
+ free(otm);
+ } else {
+ unitsPerEm = tm.tmHeight;
+ }
+}
+
+
+inline unsigned int getChar(const QChar *str, int &i, const int len)
+{
+ unsigned int uc = str[i].unicode();
+ if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
+ uint low = str[i+1].unicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ ++i;
+ }
+ }
+ return uc;
+}
+
+int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
+{
+ int i = 0;
+ int glyph_pos = 0;
+ if (mirrored) {
+ 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 {
+ 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 (ucs >= first && ucs <= last)
+ glyphs->glyphs[glyph_pos] = ucs;
+ else
+ glyphs->glyphs[glyph_pos] = 0;
+ }
+ }
+ } else {
+ if (symbol) {
+ for (; i < numChars; ++i, ++glyph_pos) {
+ unsigned int uc = getChar(str, i, numChars);
+ glyphs->glyphs[i] = 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, uc);
+ }
+ } else {
+ wchar_t first = tm.tmFirstChar;
+ wchar_t last = tm.tmLastChar;
+
+ for (; i < numChars; ++i, ++glyph_pos) {
+ uint uc = getChar(str, i, numChars);
+ if (uc >= first && uc <= last)
+ glyphs->glyphs[glyph_pos] = uc;
+ else
+ glyphs->glyphs[glyph_pos] = 0;
+ }
+ }
+ }
+ glyphs->numGlyphs = glyph_pos;
+ return glyph_pos;
+}
+
+/*!
+ \class QWindowsFontEngine
+ \brief Standard Windows font engine.
+ \ingroup qt-lighthouse-win
+
+ Will probably be superseded by a common Free Type font engine in Qt 5.X.
+*/
+
+QWindowsFontEngine::QWindowsFontEngine(const QString &name,
+ HFONT _hfont, bool stockFontIn, LOGFONT lf,
+ QSharedPointer<QWindowsFontEngineData> fontEngineData) :
+ m_fontEngineData(fontEngineData),
+ _name(name),
+ hfont(_hfont),
+ m_logfont(lf),
+ stockFont(stockFontIn),
+ ttf(0),
+ hasOutline(0),
+ lw(0),
+ cmap(0),
+ lbearing(SHRT_MIN),
+ rbearing(SHRT_MIN),
+ x_height(-1),
+ synthesized_flags(-1),
+ lineWidth(-1),
+ widthCache(0),
+ widthCacheSize(0),
+ designAdvances(0),
+ designAdvancesSize(0)
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s: font='%s', size=%ld", __FUNCTION__, qPrintable(name), lf.lfHeight);
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ fontDef.pixelSize = -lf.lfHeight;
+ const BOOL res = GetTextMetrics(hdc, &tm);
+ fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
+ if (!res) {
+ qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__);
+ ZeroMemory(&tm, sizeof(TEXTMETRIC));
+ }
+
+ cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000;
+ getCMap();
+
+ if (!resolvedGetCharWidthI)
+ resolveGetCharWidthI();
+}
+
+QWindowsFontEngine::~QWindowsFontEngine()
+{
+ if (designAdvances)
+ free(designAdvances);
+
+ if (widthCache)
+ free(widthCache);
+
+ // make sure we aren't by accident still selected
+ SelectObject(m_fontEngineData->hdc, (HFONT)GetStockObject(SYSTEM_FONT));
+
+ if (!stockFont) {
+ 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));
+}
+
+HGDIOBJ QWindowsFontEngine::selectDesignFont() const
+{
+ LOGFONT f = m_logfont;
+ f.lfHeight = unitsPerEm;
+ HFONT designFont = CreateFontIndirect(&f);
+ return SelectObject(m_fontEngineData->hdc, designFont);
+}
+
+bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
+{
+ if (*nglyphs < len) {
+ *nglyphs = len;
+ return false;
+ }
+
+ *nglyphs = getGlyphIndexes(str, len, glyphs, flags & QTextEngine::RightToLeft);
+
+ if (flags & QTextEngine::GlyphIndicesOnly)
+ return true;
+
+ recalcAdvances(glyphs, flags);
+ return true;
+}
+
+inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
+{
+ if (ptrGetCharWidthI)
+ ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
+}
+
+void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
+{
+ HGDIOBJ oldFont = 0;
+ HDC hdc = m_fontEngineData->hdc;
+ if (ttf && (flags & QTextEngine::DesignMetrics)) {
+ for(int i = 0; i < glyphs->numGlyphs; i++) {
+ unsigned int glyph = glyphs->glyphs[i];
+ if(int(glyph) >= designAdvancesSize) {
+ int newSize = (glyph + 256) >> 8 << 8;
+ designAdvances = q_check_ptr((QFixed *)realloc(designAdvances,
+ newSize*sizeof(QFixed)));
+ for(int i = designAdvancesSize; i < newSize; ++i)
+ designAdvances[i] = -1000000;
+ designAdvancesSize = newSize;
+ }
+ if (designAdvances[glyph] < -999999) {
+ if (!oldFont)
+ oldFont = selectDesignFont();
+
+ int width = 0;
+ calculateTTFGlyphWidth(hdc, glyph, width);
+ designAdvances[glyph] = QFixed(width) / designToDevice;
+ }
+ glyphs->advances_x[i] = designAdvances[glyph];
+ glyphs->advances_y[i] = 0;
+ }
+ if(oldFont)
+ DeleteObject(SelectObject(hdc, oldFont));
+ } else {
+ 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,
+ newSize*sizeof(QFixed)));
+ memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
+ widthCacheSize = newSize;
+ }
+ glyphs->advances_x[i] = widthCache[glyph];
+ // font-width cache failed
+ if (glyphs->advances_x[i] == 0) {
+ int width = 0;
+ if (!oldFont)
+ oldFont = SelectObject(hdc, hfont);
+
+ if (!ttf) {
+ QChar ch[2] = { ushort(glyph), 0 };
+ int chrLen = 1;
+ if (glyph > 0xffff) {
+ ch[0] = QChar::highSurrogate(glyph);
+ ch[1] = QChar::lowSurrogate(glyph);
+ ++chrLen;
+ }
+ SIZE size = {0, 0};
+ GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size);
+ width = size.cx;
+ } else {
+ calculateTTFGlyphWidth(hdc, glyph, width);
+ }
+ glyphs->advances_x[i] = width;
+ // if glyph's within cache range, store it for later
+ if (width > 0 && width < 0x100)
+ widthCache[glyph] = width;
+ }
+ }
+
+ if (oldFont)
+ SelectObject(hdc, oldFont);
+ }
+}
+
+glyph_metrics_t QWindowsFontEngine::boundingBox(const QGlyphLayout &glyphs)
+{
+ if (glyphs.numGlyphs == 0)
+ return glyph_metrics_t();
+
+ QFixed w = 0;
+ for (int i = 0; i < glyphs.numGlyphs; ++i)
+ w += glyphs.effectiveAdvance(i);
+
+ return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0);
+}
+
+bool QWindowsFontEngine::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const
+{
+ Q_ASSERT(metrics != 0);
+
+ HDC hdc = m_fontEngineData->hdc;
+
+ GLYPHMETRICS gm;
+ DWORD res = 0;
+ MAT2 mat;
+ mat.eM11.value = mat.eM22.value = 1;
+ mat.eM11.fract = mat.eM22.fract = 0;
+ mat.eM21.value = mat.eM12.value = 0;
+ mat.eM21.fract = mat.eM12.fract = 0;
+
+ if (t.type() > QTransform::TxTranslate) {
+ // We need to set the transform using the HDC's world
+ // matrix rather than using the MAT2 above, because the
+ // results provided when transforming via MAT2 does not
+ // match the glyphs that are drawn using a WorldTransform
+ XFORM xform;
+ xform.eM11 = t.m11();
+ xform.eM12 = t.m12();
+ xform.eM21 = t.m21();
+ xform.eM22 = t.m22();
+ xform.eDx = 0;
+ xform.eDy = 0;
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ SetWorldTransform(hdc, &xform);
+ }
+
+ uint format = GGO_METRICS;
+ if (ttf)
+ format |= GGO_GLYPH_INDEX;
+ res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat);
+
+ if (t.type() > QTransform::TxTranslate) {
+ XFORM xform;
+ xform.eM11 = xform.eM22 = 1;
+ xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0;
+ SetWorldTransform(hdc, &xform);
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ }
+
+ if (res != GDI_ERROR) {
+ *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y,
+ (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+glyph_metrics_t QWindowsFontEngine::boundingBox(glyph_t glyph, const QTransform &t)
+{
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+
+ glyph_metrics_t glyphMetrics;
+ bool success = getOutlineMetrics(glyph, t, &glyphMetrics);
+
+ if (!ttf && !success) {
+ // Bitmap fonts
+ wchar_t ch = glyph;
+ ABCFLOAT abc;
+ GetCharABCWidthsFloat(hdc, ch, ch, &abc);
+ int width = qRound(abc.abcfB);
+
+ return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t);
+ }
+
+ return glyphMetrics;
+}
+
+QFixed QWindowsFontEngine::ascent() const
+{
+ return tm.tmAscent;
+}
+
+QFixed QWindowsFontEngine::descent() const
+{
+ // ### we subtract 1 to even out the historical +1 in QFontMetrics'
+ // ### height=asc+desc+1 equation. Fix in Qt5.
+ return tm.tmDescent - 1;
+}
+
+QFixed QWindowsFontEngine::leading() const
+{
+ return tm.tmExternalLeading;
+}
+
+
+QFixed QWindowsFontEngine::xHeight() const
+{
+ if(x_height >= 0)
+ return x_height;
+ return QFontEngine::xHeight();
+}
+
+QFixed QWindowsFontEngine::averageCharWidth() const
+{
+ return tm.tmAveCharWidth;
+}
+
+qreal QWindowsFontEngine::maxCharWidth() const
+{
+ return tm.tmMaxCharWidth;
+}
+
+enum { max_font_count = 256 };
+static const ushort char_table[] = {
+ 40,
+ 67,
+ 70,
+ 75,
+ 86,
+ 88,
+ 89,
+ 91,
+ 102,
+ 114,
+ 124,
+ 127,
+ 205,
+ 645,
+ 884,
+ 922,
+ 1070,
+ 12386,
+ 0
+};
+
+static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
+
+#ifndef Q_CC_MINGW
+void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
+{
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+
+ if (ttf)
+ {
+ ABC abcWidths;
+ GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths);
+ if (leftBearing)
+ *leftBearing = abcWidths.abcA;
+ if (rightBearing)
+ *rightBearing = abcWidths.abcC;
+ } else {
+ QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing);
+ }
+}
+#endif // Q_CC_MINGW
+
+qreal QWindowsFontEngine::minLeftBearing() const
+{
+ if (lbearing == SHRT_MIN)
+ minRightBearing(); // calculates both
+
+ return lbearing;
+}
+
+qreal QWindowsFontEngine::minRightBearing() const
+{
+ if (rbearing == SHRT_MIN) {
+ int ml = 0;
+ int mr = 0;
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ if (ttf) {
+ ABC *abc = 0;
+ int n = tm.tmLastChar - tm.tmFirstChar;
+ if (n <= max_font_count) {
+ abc = new ABC[n+1];
+ GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
+ } else {
+ abc = new ABC[char_table_entries+1];
+ for(int i = 0; i < char_table_entries; i++)
+ GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i);
+ n = char_table_entries;
+ }
+ ml = abc[0].abcA;
+ mr = abc[0].abcC;
+ for (int i = 1; i < n; i++) {
+ if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) {
+ ml = qMin(ml,abc[i].abcA);
+ mr = qMin(mr,abc[i].abcC);
+ }
+ }
+ delete [] abc;
+ } else {
+ ABCFLOAT *abc = 0;
+ int n = tm.tmLastChar - tm.tmFirstChar+1;
+ if (n <= max_font_count) {
+ abc = new ABCFLOAT[n];
+ GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
+ } else {
+ abc = new ABCFLOAT[char_table_entries];
+ for(int i = 0; i < char_table_entries; i++)
+ GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i);
+ n = char_table_entries;
+ }
+ float fml = abc[0].abcfA;
+ float fmr = abc[0].abcfC;
+ for (int i=1; i<n; i++) {
+ if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) {
+ fml = qMin(fml,abc[i].abcfA);
+ fmr = qMin(fmr,abc[i].abcfC);
+ }
+ }
+ ml = int(fml - 0.9999);
+ mr = int(fmr - 0.9999);
+ delete [] abc;
+ }
+ lbearing = ml;
+ rbearing = mr;
+ }
+
+ return rbearing;
+}
+
+
+const char *QWindowsFontEngine::name() const
+{
+ return 0;
+}
+
+bool QWindowsFontEngine::canRender(const QChar *string, int len)
+{
+ if (symbol) {
+ for (int i = 0; i < len; ++i) {
+ unsigned int uc = getChar(string, i, len);
+ if (getTrueTypeGlyphIndex(cmap, uc) == 0) {
+ if (uc < 0x100) {
+ if (getTrueTypeGlyphIndex(cmap, uc + 0xf000) == 0)
+ return false;
+ } else {
+ return false;
+ }
+ }
+ }
+ } else if (ttf) {
+ for (int i = 0; i < len; ++i) {
+ unsigned int uc = getChar(string, i, len);
+ if (getTrueTypeGlyphIndex(cmap, uc) == 0)
+ return false;
+ }
+ } else {
+ while(len--) {
+ if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode())
+ return false;
+ }
+ }
+ return true;
+}
+
+QFontEngine::Type QWindowsFontEngine::type() const
+{
+ return QFontEngine::Win;
+}
+
+static inline double qt_fixed_to_double(const FIXED &p) {
+ return ((p.value << 16) + p.fract) / 65536.0;
+}
+
+static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) {
+ return QPointF(qt_fixed_to_double(pt.x) * scale, -qt_fixed_to_double(pt.y) * scale);
+}
+
+#ifndef GGO_UNHINTED
+#define GGO_UNHINTED 0x0100
+#endif
+
+static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
+ QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1)
+{
+ MAT2 mat;
+ mat.eM11.value = mat.eM22.value = 1;
+ mat.eM11.fract = mat.eM22.fract = 0;
+ mat.eM21.value = mat.eM12.value = 0;
+ mat.eM21.fract = mat.eM12.fract = 0;
+ uint glyphFormat = GGO_NATIVE;
+
+ if (ttf)
+ glyphFormat |= GGO_GLYPH_INDEX;
+
+ GLYPHMETRICS gMetric;
+ memset(&gMetric, 0, sizeof(GLYPHMETRICS));
+ int bufferSize = GDI_ERROR;
+ bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
+ if ((DWORD)bufferSize == GDI_ERROR) {
+ return false;
+ }
+
+ void *dataBuffer = new char[bufferSize];
+ DWORD ret = GDI_ERROR;
+ ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat);
+ if (ret == GDI_ERROR) {
+ delete [](char *)dataBuffer;
+ return false;
+ }
+
+ if(metric) {
+ // #### obey scale
+ *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
+ (int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY,
+ gMetric.gmCellIncX, gMetric.gmCellIncY);
+ }
+
+ int offset = 0;
+ int headerOffset = 0;
+ TTPOLYGONHEADER *ttph = 0;
+
+ QPointF oset = position.toPointF();
+ while (headerOffset < bufferSize) {
+ ttph = (TTPOLYGONHEADER*)((char *)dataBuffer + headerOffset);
+
+ QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale));
+ path->moveTo(lastPoint + oset);
+ offset += sizeof(TTPOLYGONHEADER);
+ TTPOLYCURVE *curve;
+ while (offset<int(headerOffset + ttph->cb)) {
+ curve = (TTPOLYCURVE*)((char*)(dataBuffer) + offset);
+ switch (curve->wType) {
+ case TT_PRIM_LINE: {
+ for (int i=0; i<curve->cpfx; ++i) {
+ QPointF p = qt_to_qpointf(curve->apfx[i], scale) + oset;
+ path->lineTo(p);
+ }
+ break;
+ }
+ case TT_PRIM_QSPLINE: {
+ const QPainterPath::Element &elm = path->elementAt(path->elementCount()-1);
+ QPointF prev(elm.x, elm.y);
+ QPointF endPoint;
+ for (int i=0; i<curve->cpfx - 1; ++i) {
+ QPointF p1 = qt_to_qpointf(curve->apfx[i], scale) + oset;
+ QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale) + oset;
+ if (i < curve->cpfx - 2) {
+ endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2);
+ } else {
+ endPoint = p2;
+ }
+
+ path->quadTo(p1, endPoint);
+ prev = endPoint;
+ }
+
+ break;
+ }
+ case TT_PRIM_CSPLINE: {
+ for (int i=0; i<curve->cpfx; ) {
+ QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
+ QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
+ QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
+ path->cubicTo(p2, p3, p4);
+ }
+ break;
+ }
+ default:
+ qWarning("QFontEngineWin::addOutlineToPath, unhandled switch case");
+ }
+ offset += sizeof(TTPOLYCURVE) + (curve->cpfx-1) * sizeof(POINTFX);
+ }
+ path->closeSubpath();
+ headerOffset += ttph->cb;
+ }
+ delete [] (char*)dataBuffer;
+
+ return true;
+}
+
+void QWindowsFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags)
+{
+ LOGFONT lf = m_logfont;
+ // The sign must be negative here to make sure we match against character height instead of
+ // hinted cell height. This ensures that we get linear matching, and we need this for
+ // paths since we later on apply a scaling transform to the glyph outline to get the
+ // font at the correct pixel size.
+ lf.lfHeight = -unitsPerEm;
+ lf.lfWidth = 0;
+ HFONT hf = CreateFontIndirect(&lf);
+ HDC hdc = m_fontEngineData->hdc;
+ HGDIOBJ oldfont = SelectObject(hdc, hf);
+
+ for(int i = 0; i < nglyphs; ++i) {
+ if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0,
+ qreal(fontDef.pixelSize) / unitsPerEm)) {
+ // Some windows fonts, like "Modern", are vector stroke
+ // fonts, which are reported as TMPF_VECTOR but do not
+ // support GetGlyphOutline, and thus we set this bit so
+ // that addOutLineToPath can check it and return safely...
+ hasOutline = false;
+ break;
+ }
+ }
+ DeleteObject(SelectObject(hdc, oldfont));
+}
+
+void QWindowsFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags)
+{
+ if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {
+ hasOutline = true;
+ QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
+ if (hasOutline) {
+ // has_outline is set to false if addGlyphToPath gets
+ // false from GetGlyphOutline, meaning its not an outline
+ // font.
+ return;
+ }
+ }
+ QFontEngine::addBitmapFontToPath(x, y, glyphs, path, flags);
+}
+
+QFontEngine::FaceId QWindowsFontEngine::faceId() const
+{
+ return _faceId;
+}
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <qdebug.h>
+QT_END_INCLUDE_NAMESPACE
+
+int QWindowsFontEngine::synthesized() const
+{
+ if(synthesized_flags == -1) {
+ synthesized_flags = 0;
+ if(ttf) {
+ const DWORD HEAD = MAKE_TAG('h', 'e', 'a', 'd');
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ uchar data[4];
+ GetFontData(hdc, HEAD, 44, &data, 4);
+ USHORT macStyle = getUShort(data);
+ if (tm.tmItalic && !(macStyle & 2))
+ synthesized_flags = SynthesizedItalic;
+ if (fontDef.stretch != 100 && ttf)
+ synthesized_flags |= SynthesizedStretch;
+ if (tm.tmWeight >= 500 && !(macStyle & 1))
+ synthesized_flags |= SynthesizedBold;
+ //qDebug() << "font is" << _name <<
+ // "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags;
+ }
+ }
+ return synthesized_flags;
+}
+
+QFixed QWindowsFontEngine::emSquareSize() const
+{
+ return unitsPerEm;
+}
+
+QFontEngine::Properties QWindowsFontEngine::properties() const
+{
+ LOGFONT lf = m_logfont;
+ lf.lfHeight = unitsPerEm;
+ HFONT hf = CreateFontIndirect(&lf);
+ HDC hdc = m_fontEngineData->hdc;
+ HGDIOBJ oldfont = SelectObject(hdc, hf);
+ OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
+ Properties p;
+ p.emSquare = unitsPerEm;
+ p.italicAngle = otm->otmItalicAngle;
+ p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFamilyName)).toLatin1();
+ p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpStyleName)).toLatin1();
+ p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(p.postscriptName);
+ p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top,
+ otm->otmrcFontBox.right - otm->otmrcFontBox.left,
+ otm->otmrcFontBox.top - otm->otmrcFontBox.bottom);
+ p.ascent = otm->otmAscent;
+ p.descent = -otm->otmDescent;
+ p.leading = (int)otm->otmLineGap;
+ p.capHeight = 0;
+ p.lineWidth = otm->otmsUnderscoreSize;
+ free(otm);
+ DeleteObject(SelectObject(hdc, oldfont));
+ return p;
+}
+
+void QWindowsFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
+{
+ LOGFONT lf = m_logfont;
+ lf.lfHeight = unitsPerEm;
+ int flags = synthesized();
+ if(flags & SynthesizedItalic)
+ lf.lfItalic = false;
+ lf.lfWidth = 0;
+ HFONT hf = CreateFontIndirect(&lf);
+ HDC hdc = m_fontEngineData->hdc;
+ HGDIOBJ oldfont = SelectObject(hdc, hf);
+ QFixedPoint p;
+ p.x = 0;
+ p.y = 0;
+ addGlyphToPath(glyph, p, hdc, path, ttf, metrics);
+ DeleteObject(SelectObject(hdc, oldfont));
+}
+
+bool QWindowsFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+ if (!ttf)
+ return false;
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ DWORD t = qbswap<quint32>(tag);
+ *length = GetFontData(hdc, t, 0, buffer, *length);
+ return *length != GDI_ERROR;
+}
+
+#if !defined(CLEARTYPE_QUALITY)
+# define CLEARTYPE_QUALITY 5
+#endif
+
+QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, int margin,
+ const QTransform &t,
+ QImage::Format mask_format)
+{
+ Q_UNUSED(mask_format)
+ glyph_metrics_t gm = boundingBox(glyph);
+
+// printf(" -> for glyph %4x\n", glyph);
+
+ int gx = gm.x.toInt();
+ int gy = gm.y.toInt();
+ int iw = gm.width.toInt();
+ int ih = gm.height.toInt();
+
+ if (iw <= 0 || iw <= 0)
+ return 0;
+
+ bool has_transformation = t.type() > QTransform::TxTranslate;
+
+ unsigned int options = ttf ? ETO_GLYPH_INDEX : 0;
+ XFORM xform;
+
+ if (has_transformation) {
+ xform.eM11 = t.m11();
+ xform.eM12 = t.m12();
+ xform.eM21 = t.m21();
+ xform.eM22 = t.m22();
+ xform.eDx = margin;
+ xform.eDy = margin;
+
+ HDC hdc = CreateCompatibleDC(QWindowsContext::instance()->displayContext());
+
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ SetWorldTransform(hdc, &xform);
+ HGDIOBJ old_font = SelectObject(hdc, font);
+
+ int ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0);
+ GLYPHMETRICS tgm;
+ MAT2 mat;
+ memset(&mat, 0, sizeof(mat));
+ mat.eM11.value = mat.eM22.value = 1;
+
+ if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) {
+ qWarning("QWinFontEngine: unable to query transformed glyph metrics...");
+ return 0;
+ }
+
+ iw = tgm.gmBlackBoxX;
+ ih = tgm.gmBlackBoxY;
+
+ xform.eDx -= tgm.gmptGlyphOrigin.x;
+ xform.eDy += tgm.gmptGlyphOrigin.y;
+
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ SelectObject(hdc, old_font);
+ ReleaseDC(0, hdc);
+ }
+ QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin + 4,
+ ih + 2 * margin + 4,
+ QWindowsNativeImage::systemFormat());
+
+ /*If cleartype is enabled we use the standard system format even on Windows CE
+ and not the special textbuffer format we have to use if cleartype is disabled*/
+
+ ni->image().fill(0xffffffff);
+
+ HDC hdc = ni->hdc();
+
+ SelectObject(hdc, GetStockObject(NULL_BRUSH));
+ SelectObject(hdc, GetStockObject(BLACK_PEN));
+ SetTextColor(hdc, RGB(0,0,0));
+ SetBkMode(hdc, TRANSPARENT);
+ SetTextAlign(hdc, TA_BASELINE);
+
+ HGDIOBJ old_font = SelectObject(hdc, font);
+
+ if (has_transformation) {
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ SetWorldTransform(hdc, &xform);
+ ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0);
+ } else
+ {
+ ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0);
+ }
+
+ SelectObject(hdc, old_font);
+ return ni;
+}
+
+QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
+{
+ HFONT font = hfont;
+ if (m_fontEngineData->clearTypeEnabled) {
+ LOGFONT lf = m_logfont;
+ lf.lfQuality = ANTIALIASED_QUALITY;
+ font = CreateFontIndirect(&lf);
+ }
+ QImage::Format mask_format = QWindowsNativeImage::systemFormat();
+ mask_format = QImage::Format_RGB32;
+
+ QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format);
+ if (mask == 0)
+ return QImage();
+
+ QImage indexed(mask->width(), mask->height(), QImage::Format_Indexed8);
+
+ // ### This part is kinda pointless, but we'll crash later if we don't because some
+ // code paths expects there to be colortables for index8-bit...
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+ indexed.setColorTable(colors);
+
+ // Copy data... Cannot use QPainter here as GDI has messed up the
+ // Alpha channel of the ni.image pixels...
+ for (int y=0; y<mask->height(); ++y) {
+ uchar *dest = indexed.scanLine(y);
+ if (mask->image().format() == QImage::Format_RGB16) {
+ const qint16 *src = (qint16 *) ((const QImage &) mask->image()).scanLine(y);
+ for (int x=0; x<mask->width(); ++x)
+ dest[x] = 255 - qGray(src[x]);
+ } else {
+ const uint *src = (uint *) ((const QImage &) mask->image()).scanLine(y);
+ for (int x=0; x<mask->width(); ++x) {
+ if (QWindowsNativeImage::systemFormat() == QImage::Format_RGB16)
+ dest[x] = 255 - qGray(src[x]);
+ else
+ dest[x] = 255 - (m_fontEngineData->pow_gamma[qGray(src[x])] * 255. / 2047.);
+ }
+ }
+ }
+
+ // Cleanup...
+ delete mask;
+ if (m_fontEngineData->clearTypeEnabled) {
+ DeleteObject(font);
+ }
+
+ return indexed;
+}
+
+#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
+#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
+
+QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t)
+{
+ HFONT font = hfont;
+
+ int contrast;
+ SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0);
+ SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0);
+
+ QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32);
+ SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) contrast, 0);
+
+ if (mask == 0)
+ return QImage();
+
+ // Gracefully handle the odd case when the display is 16-bit
+ const QImage source = mask->image().depth() == 32
+ ? mask->image()
+ : mask->image().convertToFormat(QImage::Format_RGB32);
+
+ QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32);
+ for (int y=0; y<mask->height(); ++y) {
+ uint *dest = (uint *) rgbMask.scanLine(y);
+ const uint *src = (uint *) source.scanLine(y);
+ for (int x=0; x<mask->width(); ++x) {
+ dest[x] = 0xffffffff - (0x00ffffff & src[x]);
+ }
+ }
+
+ delete mask;
+
+ return rgbMask;
+}
+
+QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const
+{
+ QFontDef request = fontDef;
+ QString actualFontName = request.family;
+ if (!uniqueFamilyName.isEmpty())
+ request.family = uniqueFamilyName;
+ request.pixelSize = pixelSize;
+
+ QFontEngine *fontEngine =
+ QWindowsFontDatabase::createEngine(QUnicodeTables::Common, request, 0,
+ QWindowsContext::instance()->defaultDPI(),
+ false,
+ QStringList(), m_fontEngineData);
+ if (fontEngine)
+ fontEngine->fontDef.family = actualFontName;
+ return fontEngine;
+}
+
+void QWindowsFontEngine::initFontInfo(const QFontDef &request,
+ HDC fontHdc,
+ int dpi)
+{
+ fontDef = request; // most settings are equal
+ HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fontHdc) ? fontHdc : m_fontEngineData->hdc;
+ SelectObject(dc, hfont);
+ wchar_t n[64];
+ GetTextFace(dc, 64, n);
+ fontDef.family = QString::fromWCharArray(n);
+ fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
+ if (fontDef.pointSize < 0) {
+ fontDef.pointSize = fontDef.pixelSize * 72. / dpi;
+ } else if (fontDef.pixelSize == -1) {
+ fontDef.pixelSize = qRound(fontDef.pointSize * dpi / 72.);
+ }
+}
+
+/*!
+ \class QWindowsMultiFontEngine
+ \brief Standard Windows Multi font engine.
+ \ingroup qt-lighthouse-win
+
+ "Merges" several font engines that have gaps in the
+ supported writing systems.
+
+ Will probably be superseded by a common Free Type font engine in Qt 5.X.
+*/
+
+QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks)
+ : QFontEngineMulti(fallbacks.size()+1),
+ fallbacks(fallbacks)
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << engines.size() << first << first->fontDef.family << fallbacks;
+ engines[0] = first;
+ first->ref.ref();
+ fontDef = engines[0]->fontDef;
+ cache_cost = first->cache_cost;
+}
+
+QWindowsMultiFontEngine::~QWindowsMultiFontEngine()
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s", __FUNCTION__);
+}
+
+void QWindowsMultiFontEngine::loadEngine(int at)
+{
+ Q_ASSERT(at < engines.size());
+ Q_ASSERT(engines.at(at) == 0);
+
+ const QString fam = fallbacks.at(at-1);
+ QWindowsFontEngine *fe = static_cast<QWindowsFontEngine*>(engines.at(0));
+ LOGFONT lf = fe->logfont();
+ memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
+ HFONT hfont = CreateFontIndirect(&lf);
+
+ bool stockFont = false;
+ if (hfont == 0) {
+ hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
+ stockFont = true;
+ }
+ engines[at] = new QWindowsFontEngine(fam, hfont, stockFont, lf, fe->fontEngineData());
+ engines[at]->ref.ref();
+ engines[at]->fontDef = fontDef;
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s %d %s", __FUNCTION__, at, qPrintable(fam));
+
+
+ // TODO: increase cost in QFontCache for the font engine loaded here
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
new file mode 100644
index 0000000000..bed5ecffbd
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSFONTENGINE_H
+#define QWINDOWSFONTENGINE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+// Enable access to HB_Face in harfbuzz includes included by qfontengine_p.h.
+#define QT_BUILD_GUI_LIB
+#include <QtGui/private/qfontengine_p.h>
+#undef QT_BUILD_GUI_LIB
+
+#include <QtGui/QImage>
+#include <QtCore/QSharedPointer>
+
+#include "qtwindows_additional.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsNativeImage;
+class QWindowsFontEngineData;
+
+class QWindowsFontEngine : public QFontEngine
+{
+ Q_DISABLE_COPY(QWindowsFontEngine)
+public:
+ QWindowsFontEngine(const QString &name, HFONT, bool, LOGFONT,
+ QSharedPointer<QWindowsFontEngineData> fontEngineData);
+
+ ~QWindowsFontEngine();
+ void initFontInfo(const QFontDef &request,
+ HDC fontHdc, int dpi);
+
+ virtual QFixed lineThickness() const;
+ virtual Properties properties() const;
+ virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
+ virtual FaceId faceId() const;
+ virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
+ virtual int synthesized() const;
+ virtual QFixed emSquareSize() const;
+
+ virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
+ virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const;
+
+ virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags);
+ virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags);
+
+ HGDIOBJ selectDesignFont() const;
+
+ virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
+ virtual glyph_metrics_t boundingBox(glyph_t g) { return boundingBox(g, QTransform()); }
+ virtual glyph_metrics_t boundingBox(glyph_t g, const QTransform &t);
+
+
+ virtual QFixed ascent() const;
+ virtual QFixed descent() const;
+ virtual QFixed leading() const;
+ virtual QFixed xHeight() const;
+ virtual QFixed averageCharWidth() const;
+ virtual qreal maxCharWidth() const;
+ virtual qreal minLeftBearing() const;
+ virtual qreal minRightBearing() const;
+
+ virtual const char *name() const;
+
+ bool canRender(const QChar *string, int len);
+
+ Type type() const;
+
+ virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); }
+ virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
+ virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
+
+ virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
+
+#ifndef Q_CC_MINGW
+ 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;
+ void getCMap();
+
+ bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const;
+
+ static QFontEngine *createEngine(int script, const QFontDef &request,
+ HDC fontHdc, int dpi, bool rawMode,
+ const QStringList &family_list,
+ const QSharedPointer<QWindowsFontEngineData> &data);
+
+ QSharedPointer<QWindowsFontEngineData> fontEngineData() const { return m_fontEngineData; }
+ LOGFONT logfont() const { return m_logfont; }
+
+private:
+ QWindowsNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform,
+ QImage::Format mask_format);
+
+ const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
+
+ const QString _name;
+ QString uniqueFamilyName;
+ const HFONT hfont;
+ const LOGFONT m_logfont;
+ uint stockFont : 1;
+ uint ttf : 1;
+ uint hasOutline : 1;
+ TEXTMETRIC tm;
+ int lw;
+ const unsigned char *cmap;
+ QByteArray cmapTable;
+ mutable qreal lbearing;
+ mutable qreal rbearing;
+ QFixed designToDevice;
+ int unitsPerEm;
+ QFixed x_height;
+ FaceId _faceId;
+
+ mutable int synthesized_flags;
+ mutable QFixed lineWidth;
+ mutable unsigned char *widthCache;
+ mutable uint widthCacheSize;
+ mutable QFixed *designAdvances;
+ mutable int designAdvancesSize;
+};
+
+class QWindowsMultiFontEngine : public QFontEngineMulti
+{
+public:
+ QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks);
+ virtual ~QWindowsMultiFontEngine();
+ void loadEngine(int at);
+
+ QStringList fallbacks;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSFONTENGINE_H
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
new file mode 100644
index 0000000000..46f0b0c336
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -0,0 +1,737 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_DIRECTWRITE
+
+#include "qwindowsfontenginedirectwrite.h"
+#include "qwindowsfontdatabase.h"
+#include "qwindowscontext.h"
+
+#include <QtCore/QSettings>
+#include <QtCore/QtEndian>
+
+#include <dwrite.h>
+#include <d2d1.h>
+
+QT_BEGIN_NAMESPACE
+
+// Convert from design units to logical pixels
+#define DESIGN_TO_LOGICAL(DESIGN_UNIT_VALUE) \
+ QFixed::fromReal((qreal(DESIGN_UNIT_VALUE) / qreal(m_unitsPerEm)) * fontDef.pixelSize)
+
+namespace {
+
+ class GeometrySink: public IDWriteGeometrySink
+ {
+ public:
+ GeometrySink(QPainterPath *path) : m_path(path), m_refCount(0)
+ {
+ Q_ASSERT(m_path != 0);
+ }
+
+ IFACEMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT *beziers, UINT bezierCount);
+ IFACEMETHOD_(void, AddLines)(const D2D1_POINT_2F *points, UINT pointCount);
+ IFACEMETHOD_(void, BeginFigure)(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin);
+ IFACEMETHOD(Close)();
+ IFACEMETHOD_(void, EndFigure)(D2D1_FIGURE_END figureEnd);
+ IFACEMETHOD_(void, SetFillMode)(D2D1_FILL_MODE fillMode);
+ IFACEMETHOD_(void, SetSegmentFlags)(D2D1_PATH_SEGMENT vertexFlags);
+
+ IFACEMETHOD_(unsigned long, AddRef)();
+ IFACEMETHOD_(unsigned long, Release)();
+ IFACEMETHOD(QueryInterface)(IID const &riid, void **ppvObject);
+
+ private:
+ inline static QPointF fromD2D1_POINT_2F(const D2D1_POINT_2F &inp)
+ {
+ return QPointF(inp.x, inp.y);
+ }
+
+ unsigned long m_refCount;
+ QPointF m_startPoint;
+ QPainterPath *m_path;
+ };
+
+ void GeometrySink::AddBeziers(const D2D1_BEZIER_SEGMENT *beziers,
+ UINT bezierCount)
+ {
+ for (uint i=0; i<bezierCount; ++i) {
+ QPointF c1 = fromD2D1_POINT_2F(beziers[i].point1);
+ QPointF c2 = fromD2D1_POINT_2F(beziers[i].point2);
+ QPointF p2 = fromD2D1_POINT_2F(beziers[i].point3);
+
+ m_path->cubicTo(c1, c2, p2);
+ }
+ }
+
+ void GeometrySink::AddLines(const D2D1_POINT_2F *points, UINT pointsCount)
+ {
+ for (uint i=0; i<pointsCount; ++i)
+ m_path->lineTo(fromD2D1_POINT_2F(points[i]));
+ }
+
+ void GeometrySink::BeginFigure(D2D1_POINT_2F startPoint,
+ D2D1_FIGURE_BEGIN /*figureBegin*/)
+ {
+ m_startPoint = fromD2D1_POINT_2F(startPoint);
+ m_path->moveTo(m_startPoint);
+ }
+
+ IFACEMETHODIMP GeometrySink::Close()
+ {
+ return E_NOTIMPL;
+ }
+
+ void GeometrySink::EndFigure(D2D1_FIGURE_END figureEnd)
+ {
+ if (figureEnd == D2D1_FIGURE_END_CLOSED)
+ m_path->closeSubpath();
+ }
+
+ void GeometrySink::SetFillMode(D2D1_FILL_MODE fillMode)
+ {
+ m_path->setFillRule(fillMode == D2D1_FILL_MODE_ALTERNATE
+ ? Qt::OddEvenFill
+ : Qt::WindingFill);
+ }
+
+ void GeometrySink::SetSegmentFlags(D2D1_PATH_SEGMENT /*vertexFlags*/)
+ {
+ /* Not implemented */
+ }
+
+ IFACEMETHODIMP_(unsigned long) GeometrySink::AddRef()
+ {
+ return InterlockedIncrement(&m_refCount);
+ }
+
+ IFACEMETHODIMP_(unsigned long) GeometrySink::Release()
+ {
+ unsigned long newCount = InterlockedDecrement(&m_refCount);
+ if (newCount == 0)
+ {
+ delete this;
+ return 0;
+ }
+
+ return newCount;
+ }
+
+ IFACEMETHODIMP GeometrySink::QueryInterface(IID const &riid, void **ppvObject)
+ {
+ if (__uuidof(IDWriteGeometrySink) == riid) {
+ *ppvObject = this;
+ } else if (__uuidof(IUnknown) == riid) {
+ *ppvObject = this;
+ } else {
+ *ppvObject = NULL;
+ return E_FAIL;
+ }
+
+ AddRef();
+ return S_OK;
+ }
+
+}
+
+/*!
+ \class QWindowsFontEngineDirectWrite
+ \brief Windows font engine using Direct Write.
+ \ingroup qt-lighthouse-win
+
+ Font engine for subpixel positioned text on Windows Vista
+ (with platform update) and Windows 7. If selected during
+ configuration, the engine will be selected only when the hinting
+ preference of a font is set to None or Vertical hinting. The font
+ database uses most of the same logic but creates a direct write
+ font based on the LOGFONT rather than a GDI handle.
+
+ The engine is currently regarded as experimental, meaning that code
+ using it should do substantial testing to make sure it covers their
+ use cases.
+
+ Will probably be superseded by a common Free Type font engine in Qt 5.X.
+*/
+
+QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
+ qreal pixelSize,
+ const QSharedPointer<QWindowsFontEngineData> &d)
+
+ : m_fontEngineData(d)
+ , m_directWriteFontFace(directWriteFontFace)
+ , m_directWriteBitmapRenderTarget(0)
+ , m_lineThickness(-1)
+ , m_unitsPerEm(-1)
+ , m_ascent(-1)
+ , m_descent(-1)
+ , m_xHeight(-1)
+ , m_lineGap(-1)
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s %g", __FUNCTION__, pixelSize);
+
+ d->directWriteFactory->AddRef();
+ m_directWriteFontFace->AddRef();
+
+ fontDef.pixelSize = pixelSize;
+ collectMetrics();
+}
+
+QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s", __FUNCTION__);
+
+ m_fontEngineData->directWriteFactory->Release();
+ m_directWriteFontFace->Release();
+
+ if (m_directWriteBitmapRenderTarget != 0)
+ m_directWriteBitmapRenderTarget->Release();
+}
+
+void QWindowsFontEngineDirectWrite::collectMetrics()
+{
+ if (m_directWriteFontFace != 0) {
+ DWRITE_FONT_METRICS metrics;
+
+ m_directWriteFontFace->GetMetrics(&metrics);
+ m_unitsPerEm = metrics.designUnitsPerEm;
+
+ m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
+ m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
+ m_descent = DESIGN_TO_LOGICAL(metrics.descent);
+ m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
+ m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
+ }
+}
+
+QFixed QWindowsFontEngineDirectWrite::lineThickness() const
+{
+ if (m_lineThickness > 0)
+ return m_lineThickness;
+ else
+ return QFontEngine::lineThickness();
+}
+
+bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+ if (m_directWriteFontFace) {
+ DWORD t = qbswap<quint32>(tag);
+
+ const void *tableData = 0;
+ void *tableContext = 0;
+ UINT32 tableSize;
+ BOOL exists;
+ HRESULT hr = m_directWriteFontFace->TryGetFontTable(
+ t, &tableData, &tableSize, &tableContext, &exists
+ );
+
+ if (SUCCEEDED(hr)) {
+ if (!exists)
+ return false;
+
+ if (buffer == 0) {
+ *length = tableSize;
+ return true;
+ } else if (*length < tableSize) {
+ return false;
+ }
+
+ qMemCopy(buffer, tableData, tableSize);
+ m_directWriteFontFace->ReleaseFontTable(tableContext);
+
+ return true;
+ } else {
+ qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
+ }
+ }
+
+ return false;
+}
+
+QFixed QWindowsFontEngineDirectWrite::emSquareSize() const
+{
+ if (m_unitsPerEm > 0)
+ return m_unitsPerEm;
+ else
+ return QFontEngine::emSquareSize();
+}
+
+inline unsigned int getChar(const QChar *str, int &i, const int len)
+{
+ unsigned int uc = str[i].unicode();
+ if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
+ uint low = str[i+1].unicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ ++i;
+ }
+ }
+ return uc;
+}
+
+bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
+ int *nglyphs, QTextEngine::ShaperFlags flags) const
+{
+ if (m_directWriteFontFace != 0) {
+ QVarLengthArray<UINT32> codePoints(len);
+ for (int i=0; i<len; ++i) {
+ codePoints[i] = getChar(str, i, len);
+ if (flags & QTextEngine::RightToLeft)
+ codePoints[i] = QChar::mirroredChar(codePoints[i]);
+ }
+
+ QVarLengthArray<UINT16> glyphIndices(len);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(),
+ len,
+ glyphIndices.data());
+
+ if (SUCCEEDED(hr)) {
+ for (int i=0; i<len; ++i)
+ glyphs->glyphs[i] = glyphIndices[i];
+
+ *nglyphs = len;
+
+ if (!(flags & QTextEngine::GlyphIndicesOnly))
+ recalcAdvances(glyphs, 0);
+
+ return true;
+ } else {
+ qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
+ }
+ }
+
+ return false;
+}
+
+void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
+{
+ if (m_directWriteFontFace == 0)
+ return;
+
+ QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
+
+ // ### Caching?
+ for(int i=0; i<glyphs->numGlyphs; i++)
+ glyphIndices[i] = UINT16(glyphs->glyphs[i]);
+
+ QVarLengthArray<DWRITE_GLYPH_METRICS> glyphMetrics(glyphIndices.size());
+ HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(glyphIndices.data(),
+ 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);
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
+ glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances_y[i] = 0;
+ }
+ } else {
+ qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
+ }
+}
+
+void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags)
+{
+ if (m_directWriteFontFace == 0)
+ return;
+
+ QVarLengthArray<UINT16> glyphIndices(nglyphs);
+ QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
+ QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
+
+ for (int i=0; i<nglyphs; ++i) {
+ glyphIndices[i] = glyphs[i];
+ glyphOffsets[i].advanceOffset = positions[i].x.toReal();
+ glyphOffsets[i].ascenderOffset = -positions[i].y.toReal();
+ glyphAdvances[i] = 0.0;
+ }
+
+ GeometrySink geometrySink(path);
+ HRESULT hr = m_directWriteFontFace->GetGlyphRunOutline(
+ fontDef.pixelSize,
+ glyphIndices.data(),
+ glyphAdvances.data(),
+ glyphOffsets.data(),
+ nglyphs,
+ false,
+ flags & QTextItem::RightToLeft,
+ &geometrySink
+ );
+
+ if (FAILED(hr))
+ qErrnoWarning("%s: GetGlyphRunOutline failed", __FUNCTION__);
+}
+
+glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(const QGlyphLayout &glyphs)
+{
+ if (glyphs.numGlyphs == 0)
+ return glyph_metrics_t();
+
+ bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
+
+ QFixed w = 0;
+ for (int i = 0; i < glyphs.numGlyphs; ++i) {
+ w += round ? glyphs.effectiveAdvance(i).round() : glyphs.effectiveAdvance(i);
+
+ }
+
+ return glyph_metrics_t(0, -m_ascent, w - lastRightBearing(glyphs), m_ascent + m_descent, w, 0);
+}
+
+glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
+{
+ if (m_directWriteFontFace == 0)
+ return glyph_metrics_t();
+
+ UINT16 glyphIndex = g;
+
+ DWRITE_GLYPH_METRICS glyphMetrics;
+ HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(&glyphIndex, 1, &glyphMetrics);
+ if (SUCCEEDED(hr)) {
+ QFixed advanceWidth = DESIGN_TO_LOGICAL(glyphMetrics.advanceWidth);
+ QFixed leftSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.leftSideBearing);
+ QFixed rightSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.rightSideBearing);
+ QFixed advanceHeight = DESIGN_TO_LOGICAL(glyphMetrics.advanceHeight);
+ QFixed verticalOriginY = DESIGN_TO_LOGICAL(glyphMetrics.verticalOriginY);
+
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ advanceWidth = advanceWidth.round();
+ advanceHeight = advanceHeight.round();
+ }
+
+ QFixed width = advanceWidth - leftSideBearing - rightSideBearing;
+
+ return glyph_metrics_t(-leftSideBearing, -verticalOriginY,
+ width, m_ascent + m_descent,
+ advanceWidth, advanceHeight);
+ } else {
+ qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
+ }
+
+ return glyph_metrics_t();
+}
+
+QFixed QWindowsFontEngineDirectWrite::ascent() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_ascent.round()
+ : m_ascent;
+}
+
+QFixed QWindowsFontEngineDirectWrite::descent() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? (m_descent - 1).round()
+ : (m_descent - 1);
+}
+
+QFixed QWindowsFontEngineDirectWrite::leading() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_lineGap.round()
+ : m_lineGap;
+}
+
+QFixed QWindowsFontEngineDirectWrite::xHeight() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_xHeight.round()
+ : m_xHeight;
+}
+
+qreal QWindowsFontEngineDirectWrite::maxCharWidth() const
+{
+ // ###
+ return 0;
+}
+
+QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
+{
+ QImage im = imageForGlyph(glyph, subPixelPosition, 0, QTransform());
+
+ QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+ indexed.setColorTable(colors);
+
+ for (int y=0; y<im.height(); ++y) {
+ uint *src = (uint*) im.scanLine(y);
+ uchar *dst = indexed.scanLine(y);
+ for (int x=0; x<im.width(); ++x) {
+ *dst = 255 - (m_fontEngineData->pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.);
+ ++dst;
+ ++src;
+ }
+ }
+
+ return indexed;
+}
+
+bool QWindowsFontEngineDirectWrite::supportsSubPixelPositions() const
+{
+ return true;
+}
+
+QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
+ QFixed subPixelPosition,
+ int margin,
+ const QTransform &xform)
+{
+ glyph_metrics_t metrics = QFontEngine::boundingBox(t, xform);
+ int width = (metrics.width + margin * 2 + 4).ceil().toInt() ;
+ int height = (metrics.height + margin * 2 + 4).ceil().toInt();
+
+ UINT16 glyphIndex = t;
+ FLOAT glyphAdvance = metrics.xoff.toReal();
+
+ DWRITE_GLYPH_OFFSET glyphOffset;
+ glyphOffset.advanceOffset = 0;
+ glyphOffset.ascenderOffset = 0;
+
+ DWRITE_GLYPH_RUN glyphRun;
+ glyphRun.fontFace = m_directWriteFontFace;
+ glyphRun.fontEmSize = fontDef.pixelSize;
+ glyphRun.glyphCount = 1;
+ glyphRun.glyphIndices = &glyphIndex;
+ glyphRun.glyphAdvances = &glyphAdvance;
+ glyphRun.isSideways = false;
+ glyphRun.bidiLevel = 0;
+ glyphRun.glyphOffsets = &glyphOffset;
+
+ QFixed x = margin - metrics.x.round() + subPixelPosition;
+ QFixed y = margin - metrics.y.floor();
+
+ DWRITE_MATRIX transform;
+ transform.dx = x.toReal();
+ transform.dy = y.toReal();
+ transform.m11 = xform.m11();
+ transform.m12 = xform.m12();
+ transform.m21 = xform.m21();
+ transform.m22 = xform.m22();
+
+ IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
+ HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
+ &glyphRun,
+ 1.0f,
+ &transform,
+ DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
+ DWRITE_MEASURING_MODE_NATURAL,
+ 0.0, 0.0,
+ &glyphAnalysis
+ );
+
+ if (SUCCEEDED(hr)) {
+ RECT rect;
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = width;
+ rect.bottom = height;
+
+ int size = width * height * 3;
+ BYTE *alphaValues = new BYTE[size];
+ qMemSet(alphaValues, size, 0);
+
+ hr = glyphAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1,
+ &rect,
+ alphaValues,
+ size);
+
+ if (SUCCEEDED(hr)) {
+ QImage img(width, height, QImage::Format_RGB32);
+ img.fill(0xffffffff);
+
+ for (int y=0; y<height; ++y) {
+ uint *dest = reinterpret_cast<uint *>(img.scanLine(y));
+ BYTE *src = alphaValues + width * 3 * y;
+
+ for (int x=0; x<width; ++x) {
+ dest[x] = *(src) << 16
+ | *(src + 1) << 8
+ | *(src + 2);
+
+ src += 3;
+ }
+ }
+
+ delete[] alphaValues;
+ glyphAnalysis->Release();
+
+ return img;
+ } else {
+ delete[] alphaValues;
+ glyphAnalysis->Release();
+
+ qErrnoWarning("%s: CreateAlphaTexture failed", __FUNCTION__);
+ }
+
+ } else {
+ qErrnoWarning("%s: CreateGlyphRunAnalysis failed", __FUNCTION__);
+ }
+
+ return QImage();
+}
+
+QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t,
+ QFixed subPixelPosition,
+ int margin,
+ const QTransform &xform)
+{
+ QImage mask = imageForGlyph(t, subPixelPosition, margin, xform);
+ return mask.depth() == 32
+ ? mask
+ : mask.convertToFormat(QImage::Format_RGB32);
+}
+
+const char *QWindowsFontEngineDirectWrite::name() const
+{
+ return 0;
+}
+
+bool QWindowsFontEngineDirectWrite::canRender(const QChar *string, int len)
+{
+ QVarLengthArray<UINT32> codePoints(len);
+ int actualLength = 0;
+ for (int i=0; i<len; ++i, actualLength++)
+ codePoints[actualLength] = getChar(string, i, len);
+
+ QVarLengthArray<UINT16> glyphIndices(actualLength);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndices(codePoints.data(), actualLength,
+ glyphIndices.data());
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGlyphIndices failed", __FUNCTION__);
+ return false;
+ } else {
+ for (int i=0; i<glyphIndices.size(); ++i) {
+ if (glyphIndices.at(i) == 0)
+ return false;
+ }
+
+ return true;
+ }
+}
+
+QFontEngine::Type QWindowsFontEngineDirectWrite::type() const
+{
+ return QFontEngine::DirectWrite;
+}
+
+QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
+{
+ QFontEngine *fontEngine = new QWindowsFontEngineDirectWrite(m_directWriteFontFace,
+ pixelSize, m_fontEngineData);
+
+ fontEngine->fontDef = fontDef;
+ fontEngine->fontDef.pixelSize = pixelSize;
+
+ return fontEngine;
+}
+
+void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request,
+ int dpi, IDWriteFont *font)
+{
+ fontDef = request;
+
+ IDWriteFontFamily *fontFamily = NULL;
+ HRESULT hr = font->GetFontFamily(&fontFamily);
+
+ IDWriteLocalizedStrings *familyNames = NULL;
+ if (SUCCEEDED(hr))
+ hr = fontFamily->GetFamilyNames(&familyNames);
+
+ UINT32 index = 0;
+ BOOL exists = false;
+
+ wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
+
+ if (SUCCEEDED(hr)) {
+ int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);
+
+ if (defaultLocaleSuccess)
+ hr = familyNames->FindLocaleName(localeName, &index, &exists);
+
+ if (SUCCEEDED(hr) && !exists)
+ hr = familyNames->FindLocaleName(L"en-us", &index, &exists);
+ }
+
+ if (!exists)
+ index = 0;
+
+ UINT32 length = 0;
+ if (SUCCEEDED(hr))
+ hr = familyNames->GetStringLength(index, &length);
+
+ wchar_t *name = new (std::nothrow) wchar_t[length+1];
+ if (name == NULL)
+ hr = E_OUTOFMEMORY;
+
+ // Get the family name.
+ if (SUCCEEDED(hr))
+ hr = familyNames->GetString(index, name, length + 1);
+
+ if (SUCCEEDED(hr))
+ fontDef.family = QString::fromWCharArray(name);
+
+ delete[] name;
+ if (familyNames != NULL)
+ familyNames->Release();
+
+ if (FAILED(hr))
+ qErrnoWarning(hr, "initFontInfo: Failed to get family name");
+
+ if (fontDef.pointSize < 0)
+ fontDef.pointSize = fontDef.pixelSize * 72. / dpi;
+ else if (fontDef.pixelSize == -1)
+ fontDef.pixelSize = qRound(fontDef.pointSize * dpi / 72.);
+}
+
+QString QWindowsFontEngineDirectWrite::fontNameSubstitute(const QString &familyName)
+{
+ static const char keyC[] = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\"
+ "FontSubstitutes";
+ return QSettings(QLatin1String(keyC), QSettings::NativeFormat).value(familyName, familyName).toString();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DIRECTWRITE
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
new file mode 100644
index 0000000000..1333720481
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSFONTENGINEDIRECTWRITE_H
+#define QWINDOWSFONTENGINEDIRECTWRITE_H
+
+#ifndef QT_NO_DIRECTWRITE
+
+// Enable access to HB_Face in harfbuzz includes included by qfontengine_p.h.
+#define QT_BUILD_GUI_LIB
+#include <QtGui/private/qfontengine_p.h>
+#undef QT_BUILD_GUI_LIB
+
+#include <QtCore/QSharedPointer>
+
+class QWindowsFontEngineData;
+
+struct IDWriteFont ;
+struct IDWriteFontFace ;
+struct IDWriteFactory ;
+struct IDWriteBitmapRenderTarget ;
+struct IDWriteGdiInterop ;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsFontEngineDirectWrite : public QFontEngine
+{
+ Q_OBJECT
+public:
+ explicit QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
+ qreal pixelSize,
+ const QSharedPointer<QWindowsFontEngineData> &d);
+ ~QWindowsFontEngineDirectWrite();
+
+ void initFontInfo(const QFontDef &request, int dpi, IDWriteFont *font);
+
+ QFixed lineThickness() const;
+ bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
+ QFixed emSquareSize() const;
+
+ bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
+ void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const;
+
+ void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags);
+
+ glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
+ glyph_metrics_t boundingBox(glyph_t g);
+
+ QFixed ascent() const;
+ QFixed descent() const;
+ QFixed leading() const;
+ QFixed xHeight() const;
+ qreal maxCharWidth() const;
+
+ const char *name() const;
+
+ bool supportsSubPixelPositions() const;
+
+ QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
+ QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin,
+ const QTransform &xform);
+
+ QFontEngine *cloneWithSize(qreal pixelSize) const;
+
+ bool canRender(const QChar *string, int len);
+ Type type() const;
+
+ static QString fontNameSubstitute(const QString &familyName);
+
+private:
+ friend class QRawFontPrivate;
+
+ QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
+ void collectMetrics();
+
+ const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
+
+ IDWriteFontFace *m_directWriteFontFace;
+ IDWriteBitmapRenderTarget *m_directWriteBitmapRenderTarget;
+
+ QFixed m_lineThickness;
+ int m_unitsPerEm;
+ QFixed m_ascent;
+ QFixed m_descent;
+ QFixed m_xHeight;
+ QFixed m_lineGap;
+ FaceId m_faceId;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DIRECTWRITE
+
+#endif // QWINDOWSFONTENGINEDIRECTWRITE_H
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
new file mode 100644
index 0000000000..4abccfb416
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -0,0 +1,971 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsglcontext.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QSysInfo>
+
+#include <WinGDI.h>
+#if defined(Q_CC_MINGW)
+# include <GL/Gl.h>
+#else
+# include <Gl.h>
+#endif
+
+// #define DEBUG_GL
+
+// ARB extension API
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x0002
+// Error codes returned by GetLastError().
+#define ERROR_INVALID_VERSION_ARB 0x2095
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#endif
+
+QT_BEGIN_NAMESPACE
+
+template <class MaskType, class FlagType> inline bool testFlag(MaskType mask, FlagType flag)
+{
+ return (mask & MaskType(flag)) != 0;
+}
+
+static inline bool hasGLOverlay(const PIXELFORMATDESCRIPTOR &pd)
+{ return (pd.bReserved & 0x0f) != 0; }
+
+static inline bool isDirectRendering(const PIXELFORMATDESCRIPTOR &pfd)
+{ return (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || !(pfd.dwFlags & PFD_GENERIC_FORMAT); }
+
+static inline void initPixelFormatDescriptor(PIXELFORMATDESCRIPTOR *d)
+{
+ memset(d, 0, sizeof(PIXELFORMATDESCRIPTOR));
+ d->nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ d->nVersion = 1;
+}
+
+QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd)
+{
+ QDebug nsp = d.nospace();
+ nsp << "PIXELFORMATDESCRIPTOR "
+ << "dwFlags=" << hex << showbase << pd.dwFlags << dec << noshowbase;
+ if (pd.dwFlags & PFD_DRAW_TO_WINDOW) nsp << " PFD_DRAW_TO_WINDOW";
+ if (pd.dwFlags & PFD_DRAW_TO_BITMAP) nsp << " PFD_DRAW_TO_BITMAP";
+ if (pd.dwFlags & PFD_SUPPORT_GDI) nsp << " PFD_SUPPORT_GDI";
+ if (pd.dwFlags & PFD_SUPPORT_OPENGL) nsp << " PFD_SUPPORT_OPENGL";
+ if (pd.dwFlags & PFD_GENERIC_ACCELERATED) nsp << " PFD_GENERIC_ACCELERATED";
+ if (pd.dwFlags & PFD_SUPPORT_DIRECTDRAW) nsp << " PFD_SUPPORT_DIRECTDRAW";
+ if (pd.dwFlags & PFD_DIRECT3D_ACCELERATED) nsp << " PFD_DIRECT3D_ACCELERATED";
+ if (pd.dwFlags & PFD_SUPPORT_COMPOSITION) nsp << " PFD_SUPPORT_COMPOSITION";
+ if (pd.dwFlags & PFD_GENERIC_FORMAT) nsp << " PFD_GENERIC_FORMAT";
+ if (pd.dwFlags & PFD_NEED_PALETTE) nsp << " PFD_NEED_PALETTE";
+ if (pd.dwFlags & PFD_NEED_SYSTEM_PALETTE) nsp << " PFD_NEED_SYSTEM_PALETTE";
+ if (pd.dwFlags & PFD_DOUBLEBUFFER) nsp << " PFD_DOUBLEBUFFER";
+ if (pd.dwFlags & PFD_STEREO) nsp << " PFD_STEREO";
+ if (pd.dwFlags & PFD_SWAP_LAYER_BUFFERS) nsp << " PFD_SWAP_LAYER_BUFFERS";
+ if (hasGLOverlay(pd)) nsp << " overlay";
+ nsp << " iPixelType=" << pd.iPixelType << " cColorBits=" << pd.cColorBits
+ << " cRedBits=" << pd.cRedBits << " cRedShift=" << pd.cRedShift
+ << " cGreenBits=" << pd.cGreenBits << " cGreenShift=" << pd.cGreenShift
+ << " cBlueBits=" << pd.cBlueBits << " cBlueShift=" << pd.cBlueShift;
+ nsp << " cDepthBits=" << pd.cDepthBits;
+ if (pd.cStencilBits)
+ nsp << " cStencilBits=" << pd.cStencilBits;
+ if (pd.cAuxBuffers)
+ nsp << " cAuxBuffers=" << pd.cAuxBuffers;
+ nsp << " iLayerType=" << pd.iLayerType;
+ if (pd.dwVisibleMask)
+ nsp << " dwVisibleMask=" << pd.dwVisibleMask;
+ if (pd.cAlphaBits)
+ nsp << " cAlphaBits=" << pd.cAlphaBits << " cAlphaShift=" << pd.cAlphaShift;
+ if (pd.cAccumBits)
+ nsp << " cAccumBits=" << pd.cAccumBits << " cAccumRedBits=" << pd.cAccumRedBits
+ << " cAccumGreenBits=" << pd.cAccumGreenBits << " cAccumBlueBits=" << pd.cAccumBlueBits
+ << " cAccumAlphaBits=" << pd.cAccumAlphaBits;
+ return d;
+}
+
+// Check whether an obtained PIXELFORMATDESCRIPTOR matches the request.
+static inline bool
+ isAcceptableFormat(const QWindowsOpenGLAdditionalFormat &additional,
+ const PIXELFORMATDESCRIPTOR &pfd,
+ bool ignoreGLSupport = false) // ARB format may not contain it.
+{
+ const bool pixmapRequested = testFlag(additional.formatFlags, QWindowsGLRenderToPixmap);
+ return (ignoreGLSupport || testFlag(pfd.dwFlags, PFD_SUPPORT_OPENGL))
+ && testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP) == pixmapRequested
+ && hasGLOverlay(pfd) == testFlag(additional.formatFlags, QWindowsGLOverlay)
+ && (!pixmapRequested || pfd.cColorBits == additional.pixmapDepth);
+}
+
+static void describeFormats(HDC hdc)
+{
+ const int pfiMax = DescribePixelFormat(hdc, 0, 0, NULL);
+ for (int i = 0; i < pfiMax; i++) {
+ PIXELFORMATDESCRIPTOR pfd;
+ initPixelFormatDescriptor(&pfd);
+ DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ qDebug() << '#' << i << '/' << pfiMax << ':' << pfd;
+ }
+}
+
+// Classic GDI API
+namespace GDI {
+static QSurfaceFormat
+ qSurfaceFormatFromPixelFormat(const PIXELFORMATDESCRIPTOR &pfd,
+ QWindowsOpenGLAdditionalFormat *additionalIn = 0)
+{
+ QSurfaceFormat format;
+ if (pfd.dwFlags & PFD_DOUBLEBUFFER)
+ format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ format.setDepthBufferSize(pfd.cDepthBits);
+
+ if (pfd.iPixelType == PFD_TYPE_RGBA)
+ format.setAlphaBufferSize(pfd.cAlphaBits);
+ format.setRedBufferSize(pfd.cRedBits);
+ format.setGreenBufferSize(pfd.cGreenBits);
+ format.setBlueBufferSize(pfd.cBlueBits);
+ format.setStencilBufferSize(pfd.cStencilBits);
+ format.setStereo(pfd.dwFlags & PFD_STEREO);
+ if (additionalIn) {
+ QWindowsOpenGLAdditionalFormat additional;
+ if (isDirectRendering(pfd))
+ additional.formatFlags |= QWindowsGLDirectRendering;
+ if (hasGLOverlay(pfd))
+ additional.formatFlags |= QWindowsGLOverlay;
+ if (pfd.cAccumRedBits)
+ additional.formatFlags |= QWindowsGLAccumBuffer;
+ if (testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP)) {
+ additional.formatFlags |= QWindowsGLRenderToPixmap;
+ additional.pixmapDepth = pfd.cColorBits;
+ }
+ *additionalIn = additional;
+ }
+ return format;
+}
+
+static PIXELFORMATDESCRIPTOR
+ qPixelFormatFromSurfaceFormat(const QSurfaceFormat &format,
+ const QWindowsOpenGLAdditionalFormat &additional)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ initPixelFormatDescriptor(&pfd);
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL;
+ if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA)
+ pfd.dwFlags = PFD_SUPPORT_COMPOSITION;
+ const bool isPixmap = (additional.formatFlags & QWindowsGLRenderToPixmap) != 0;
+ pfd.dwFlags |= isPixmap ? PFD_DRAW_TO_BITMAP : PFD_DRAW_TO_WINDOW;
+ if (!(additional.formatFlags & QWindowsGLDirectRendering))
+ pfd.dwFlags |= PFD_GENERIC_FORMAT;
+
+ if (format.stereo())
+ pfd.dwFlags |= PFD_STEREO;
+ if (format.swapBehavior() == QSurfaceFormat::DoubleBuffer && !isPixmap)
+ pfd.dwFlags |= PFD_DOUBLEBUFFER;
+ pfd.cDepthBits =
+ format.depthBufferSize() >= 0 ? format.depthBufferSize() : 32;
+ pfd.cAlphaBits = format.alphaBufferSize() > 0 ? format.alphaBufferSize() : 8;
+ pfd.cStencilBits = format.stencilBufferSize() > 0 ? format.stencilBufferSize() : 8;
+ if (additional.formatFlags & QWindowsGLAccumBuffer)
+ pfd.cAccumRedBits = pfd.cAccumGreenBits = pfd.cAccumBlueBits = pfd.cAccumAlphaBits = 16;
+ return pfd;
+}
+
+// Choose a suitable pixelformat using GDI WinAPI in case ARB
+// functions cannot be found. First tries to find a suitable
+// format using GDI function ChoosePixelFormat(). Since that
+// does not handle overlay and direct-rendering requests, manually loop
+// over the available formats to find the best one.
+// Note: As of Windows 7, it seems direct-rendering is handled, so,
+// the code might be obsolete?
+static int choosePixelFormat(HDC hdc, const QSurfaceFormat &format,
+ const QWindowsOpenGLAdditionalFormat &additional,
+ PIXELFORMATDESCRIPTOR *obtainedPfd)
+{
+ // 1) Try ChoosePixelFormat().
+ PIXELFORMATDESCRIPTOR requestedPfd = qPixelFormatFromSurfaceFormat(format, QWindowsGLDirectRendering);
+ initPixelFormatDescriptor(obtainedPfd);
+ int pixelFormat = ChoosePixelFormat(hdc, &requestedPfd);
+ if (pixelFormat >= 0) {
+ DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
+ if (isAcceptableFormat(additional, *obtainedPfd))
+ return pixelFormat;
+ }
+ // 2) No matching format found, manual search loop.
+ const int pfiMax = DescribePixelFormat(hdc, 0, 0, NULL);
+ int bestScore = -1;
+ int bestPfi = -1;
+ const bool stereoRequested = format.stereo();
+ const bool accumBufferRequested = testFlag(additional.formatFlags, QWindowsGLAccumBuffer);
+ const bool doubleBufferRequested = format.swapBehavior() == QSurfaceFormat::DoubleBuffer;
+ const bool directRenderingRequested = testFlag(additional.formatFlags, QWindowsGLDirectRendering);
+ for (int pfi = 1; pfi <= pfiMax; pfi++) {
+ PIXELFORMATDESCRIPTOR checkPfd;
+ initPixelFormatDescriptor(&checkPfd);
+ DescribePixelFormat(hdc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &checkPfd);
+ if (isAcceptableFormat(additional, checkPfd)) {
+ int score = checkPfd.cColorBits + checkPfd.cAlphaBits + checkPfd.cStencilBits;
+ if (accumBufferRequested)
+ score += checkPfd.cAccumBits;
+ if (doubleBufferRequested == testFlag(checkPfd.dwFlags, PFD_DOUBLEBUFFER))
+ score += 1000;
+ if (stereoRequested == testFlag(checkPfd.dwFlags, PFD_STEREO))
+ score += 2000;
+ if (directRenderingRequested == isDirectRendering(checkPfd))
+ score += 4000;
+ if (checkPfd.iPixelType == PFD_TYPE_RGBA)
+ score += 8000;
+ if (score > bestScore) {
+ bestScore = score;
+ bestPfi = pfi;
+ *obtainedPfd = checkPfd;
+ }
+ if (QWindowsContext::verboseGL)
+ qDebug() << __FUNCTION__ << " checking " << pfi << '/' << pfiMax
+ << " score=" << score << " (best " << bestPfi << '/' << bestScore
+ << ") " << checkPfd;
+ }
+ } // for
+ if (bestPfi > 0)
+ pixelFormat = bestPfi;
+ return pixelFormat;
+}
+
+static inline HGLRC createContext(HDC hdc, HGLRC shared)
+{
+ HGLRC result = wglCreateContext(hdc);
+ if (!result) {
+ qErrnoWarning("%s: wglCreateContext failed.", __FUNCTION__);
+ return 0;
+ }
+ if (shared && !wglShareLists(shared, result))
+ qErrnoWarning("%s: wglShareLists() failed.", __FUNCTION__);
+ return result;
+}
+} // namespace GDI
+
+// ARB OpenGL extension API
+namespace ARB {
+// Choose a suitable pixelformat using ARB extension functions.
+static int choosePixelFormat(HDC hdc,
+ const QOpenGLStaticContext &staticContext,
+ const QSurfaceFormat &format,
+ const QWindowsOpenGLAdditionalFormat &additional,
+ PIXELFORMATDESCRIPTOR *obtainedPfd)
+{
+ enum { attribSize =40 };
+ if ((additional.formatFlags & QWindowsGLRenderToPixmap) || !staticContext.hasExtensions())
+ return 0;
+
+ int iAttributes[attribSize];
+ qFill(iAttributes, iAttributes + attribSize, int(0));
+ int i = 0;
+ iAttributes[i++] = WGL_ACCELERATION_ARB;
+ iAttributes[i++] = testFlag(additional.formatFlags, QWindowsGLDirectRendering) ?
+ WGL_FULL_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB;
+ iAttributes[i++] = WGL_SUPPORT_OPENGL_ARB;
+ iAttributes[i++] = TRUE;
+ iAttributes[i++] = WGL_DRAW_TO_WINDOW_ARB;
+ iAttributes[i++] = TRUE;
+ iAttributes[i++] = WGL_COLOR_BITS_ARB;
+ iAttributes[i++] = 24;
+ switch (format.swapBehavior()) {
+ case QSurfaceFormat::DefaultSwapBehavior:
+ case QSurfaceFormat::TripleBuffer:
+ break;
+ case QSurfaceFormat::SingleBuffer:
+ iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
+ iAttributes[i++] = FALSE;
+ break;
+ case QSurfaceFormat::DoubleBuffer:
+ iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
+ iAttributes[i++] = TRUE;
+ break;
+ }
+ if (format.stereo()) {
+ iAttributes[i++] = WGL_STEREO_ARB;
+ iAttributes[i++] = TRUE;
+ }
+ if (format.depthBufferSize() >= 0) {
+ iAttributes[i++] = WGL_DEPTH_BITS_ARB;
+ iAttributes[i++] = format.depthBufferSize();
+ }
+ iAttributes[i++] = WGL_PIXEL_TYPE_ARB;
+ iAttributes[i++] = WGL_TYPE_RGBA_ARB;
+ if (format.redBufferSize() >= 0) {
+ iAttributes[i++] = WGL_RED_BITS_ARB;
+ iAttributes[i++] = format.redBufferSize();
+ }
+ if (format.greenBufferSize() >= 0) {
+ iAttributes[i++] = WGL_GREEN_BITS_ARB;
+ iAttributes[i++] = format.greenBufferSize();
+ }
+ if (format.blueBufferSize() >= 0) {
+ iAttributes[i++] = WGL_BLUE_BITS_ARB;
+ iAttributes[i++] = format.blueBufferSize();
+ }
+ iAttributes[i++] = WGL_ALPHA_BITS_ARB;
+ iAttributes[i++] = format.alphaBufferSize() >= 0 ? format.alphaBufferSize() : 8;
+ if (additional.formatFlags & QWindowsGLAccumBuffer) {
+ iAttributes[i++] = WGL_ACCUM_BITS_ARB;
+ iAttributes[i++] = 16;
+ }
+ iAttributes[i++] = WGL_STENCIL_BITS_ARB;
+ iAttributes[i++] = 8;
+ if (additional.formatFlags & QWindowsGLOverlay) {
+ iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB;
+ iAttributes[i++] = 1;
+ }
+ const bool sampleBuffersRequested = format.samples() > 1
+ && testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
+ int samplesValuePosition = 0;
+ int samplesEnabledPosition = 0;
+ if (sampleBuffersRequested) {
+ iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
+ samplesEnabledPosition = i;
+ iAttributes[i++] = TRUE;
+ iAttributes[i++] = WGL_SAMPLES_ARB;
+ samplesValuePosition = i;
+ iAttributes[i++] = format.samples();
+ }
+ // If sample buffer request cannot be satisfied, reduce request.
+ int pixelFormat = 0;
+ uint numFormats = 0;
+ while (true) {
+ const bool valid =
+ staticContext.wglChoosePixelFormatARB(hdc, iAttributes, 0, 1,
+ &pixelFormat, &numFormats)
+ && numFormats >= 1;
+ if (valid || !sampleBuffersRequested)
+ break;
+ if (iAttributes[samplesValuePosition] > 1) {
+ iAttributes[samplesValuePosition] /= 2;
+ } else {
+ break;
+ }
+ }
+ // Verify if format is acceptable. Note that the returned
+ // formats have been observed to not contain PFD_SUPPORT_OPENGL, ignore.
+ initPixelFormatDescriptor(obtainedPfd);
+ DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
+ if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
+ if (QWindowsContext::verboseGL)
+ qDebug() << __FUNCTION__ << " obtained px #" << pixelFormat
+ << " not acceptable=" << *obtainedPfd;
+ pixelFormat = 0;
+ }
+
+ if (QWindowsContext::verboseGL) {
+ QDebug nsp = qDebug().nospace();
+ nsp << __FUNCTION__;
+ if (sampleBuffersRequested)
+ nsp << " samples=" << iAttributes[samplesValuePosition];
+ nsp << " Attributes: " << hex << showbase;
+ for (int ii = 0; ii < i; ++ii)
+ nsp << iAttributes[ii] << ',';
+ nsp << noshowbase << dec << "\n obtained px #" << pixelFormat
+ << " of " << numFormats << "\n " << *obtainedPfd;
+ } // Debug
+
+ return pixelFormat;
+}
+
+static QSurfaceFormat
+ qSurfaceFormatFromHDC(const QOpenGLStaticContext &staticContext,
+ HDC hdc, int pixelFormat,
+ QWindowsOpenGLAdditionalFormat *additionalIn = 0)
+{
+ enum { attribSize =40 };
+
+ QSurfaceFormat result;
+ if (!staticContext.hasExtensions())
+ return result;
+ int iAttributes[attribSize];
+ int iValues[attribSize];
+ qFill(iAttributes, iAttributes + attribSize, int(0));
+ qFill(iValues, iValues + attribSize, int(0));
+
+ int i = 0;
+ const bool hasSampleBuffers = testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
+
+ iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0
+ iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1
+ iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2
+ iAttributes[i++] = WGL_RED_BITS_ARB; // 3
+ iAttributes[i++] = WGL_GREEN_BITS_ARB; // 4
+ iAttributes[i++] = WGL_BLUE_BITS_ARB; // 5
+ iAttributes[i++] = WGL_ALPHA_BITS_ARB; // 6
+ iAttributes[i++] = WGL_ACCUM_BITS_ARB; // 7
+ iAttributes[i++] = WGL_STENCIL_BITS_ARB; // 8
+ iAttributes[i++] = WGL_STEREO_ARB; // 9
+ iAttributes[i++] = WGL_ACCELERATION_ARB; // 10
+ iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; // 11
+ if (hasSampleBuffers) {
+ iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12
+ iAttributes[i++] = WGL_SAMPLES_ARB; // 13
+ }
+ if (!staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i,
+ iAttributes, iValues))
+ return result;
+ if (iValues[0])
+ result.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ result.setDepthBufferSize(iValues[1]);
+ result.setRedBufferSize(iValues[3]);
+ result.setGreenBufferSize(iValues[4]);
+ result.setBlueBufferSize(iValues[5]);
+ result.setAlphaBufferSize(iValues[6]);
+ result.setStencilBufferSize(iValues[8]);
+ result.setStereo(iValues[9]);
+ if (hasSampleBuffers)
+ result.setSamples(iValues[13]);
+ if (additionalIn) {
+ if (iValues[7])
+ additionalIn->formatFlags |= QWindowsGLAccumBuffer;
+ if (iValues[10] == WGL_FULL_ACCELERATION_ARB)
+ additionalIn->formatFlags |= QWindowsGLDirectRendering;
+ if (iValues[11])
+ additionalIn->formatFlags |= QWindowsGLOverlay;
+ }
+ return result;
+}
+
+static HGLRC createContext(const QOpenGLStaticContext &staticContext,
+ HDC hdc,
+ const QSurfaceFormat &format,
+ const QWindowsOpenGLAdditionalFormat &additional,
+ int majorVersion = 0,
+ int minorVersion = 0,
+ HGLRC shared = 0)
+{
+ enum { attribSize = 11 };
+
+ if (!staticContext.hasExtensions())
+ return 0;
+ int attributes[attribSize];
+ int attribIndex = 0;
+ qFill(attributes, attributes + attribSize, int(0));
+
+ if (majorVersion) {
+ attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
+ attributes[attribIndex++] = majorVersion;
+ attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
+ attributes[attribIndex++] = minorVersion;
+ }
+ if (majorVersion >= 3 && additional.formatFlags & QWindowsGLDeprecatedFunctions) {
+ attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
+ attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ }
+ if ((staticContext.majorVersion == 3 && staticContext.minorVersion >= 2)
+ || staticContext.majorVersion > 3) {
+ switch (format.profile()) {
+ case QSurfaceFormat::NoProfile:
+ break;
+ case QSurfaceFormat::CoreProfile:
+ attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
+ attributes[attribIndex++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ break;
+ case QSurfaceFormat::CompatibilityProfile:
+ attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
+ attributes[attribIndex++] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ break;
+ }
+ }
+ const HGLRC result =
+ staticContext.wglCreateContextAttribsARB(hdc, shared, attributes);
+ if (!result)
+ qErrnoWarning("%s: wglCreateContextAttribsARB() failed.", __FUNCTION__);
+ return result;
+}
+
+} // namespace ARB
+
+// Helpers for temporary contexts
+static inline HWND createDummyGLWindow()
+{
+ return QWindowsContext::instance()->
+ createDummyWindow(QStringLiteral("QtOpenGLDummyWindow"),
+ L"OpenGLDummyWindow", 0, WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+}
+
+// Create a dummy GL context (see QOpenGLTemporaryContext).
+static inline HGLRC createDummyGLContext(HDC dc)
+{
+ if (!dc)
+ return 0;
+ PIXELFORMATDESCRIPTOR pixelFormDescriptor;
+ initPixelFormatDescriptor(&pixelFormDescriptor);
+ pixelFormDescriptor.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_GENERIC_FORMAT;
+ pixelFormDescriptor.iPixelType = PFD_TYPE_RGBA;
+ const int pixelFormat = ChoosePixelFormat(dc, &pixelFormDescriptor);
+ if (!pixelFormat) {
+ qErrnoWarning("%s: ChoosePixelFormat failed.", __FUNCTION__);
+ return 0;
+ }
+ if (!SetPixelFormat(dc, pixelFormat, &pixelFormDescriptor)) {
+ qErrnoWarning("%s: SetPixelFormat failed.", __FUNCTION__);
+ return 0;
+ }
+ HGLRC rc = wglCreateContext(dc);
+ if (!rc) {
+ qErrnoWarning("%s: wglCreateContext failed.", __FUNCTION__);
+ return 0;
+ }
+ return rc;
+}
+
+static inline QOpenGLContextData currentOpenGLContextData()
+{
+ QOpenGLContextData result;
+ result.hdc = wglGetCurrentDC();
+ result.renderingContext = wglGetCurrentContext();
+ return result;
+}
+
+static inline QOpenGLContextData createDummyWindowOpenGLContextData()
+{
+ QOpenGLContextData result;
+ result.hwnd = createDummyGLWindow();
+ result.hdc = GetDC(result.hwnd);
+ result.renderingContext = createDummyGLContext(result.hdc);
+ return result;
+}
+
+/*!
+ \class QOpenGLTemporaryContext
+ \brief A temporary context that can be instantiated on the stack.
+
+ Functions like wglGetProcAddress() or glGetString() only work if there
+ is a current GL context.
+
+ \ingroup qt-lighthouse-win
+*/
+
+class QOpenGLTemporaryContext
+{
+ Q_DISABLE_COPY(QOpenGLTemporaryContext)
+public:
+ QOpenGLTemporaryContext();
+ ~QOpenGLTemporaryContext();
+
+private:
+ const QOpenGLContextData m_previous;
+ const QOpenGLContextData m_current;
+};
+
+QOpenGLTemporaryContext::QOpenGLTemporaryContext() :
+ m_previous(currentOpenGLContextData()),
+ m_current(createDummyWindowOpenGLContextData())
+{
+ wglMakeCurrent(m_current.hdc, m_current.renderingContext);
+}
+
+QOpenGLTemporaryContext::~QOpenGLTemporaryContext()
+{
+ wglMakeCurrent(m_previous.hdc, m_previous.renderingContext);
+ ReleaseDC(m_current.hwnd, m_current.hdc);
+ DestroyWindow(m_current.hwnd);
+ wglDeleteContext(m_current.renderingContext);
+}
+
+/*!
+ \class QWindowsOpenGLAdditionalFormat
+ \brief Additional format information that is not in QSurfaceFormat
+ \ingroup qt-lighthouse-win
+*/
+
+/*!
+ \class QOpenGLStaticContext
+ \brief Static Open GL context containing version information, extension function pointers, etc.
+
+ Functions pending integration in the next version of OpenGL are post-fixed ARB.
+
+ \note Initialization requires an active context (see create()).
+
+ \sa QWindowsGLContext
+ \ingroup qt-lighthouse-win
+*/
+
+#define SAMPLE_BUFFER_EXTENSION "GL_ARB_multisample"
+
+QOpenGLStaticContext::QOpenGLStaticContext() :
+ vendor(QOpenGLStaticContext::getGlString(GL_VENDOR)),
+ renderer(QOpenGLStaticContext::getGlString(GL_RENDERER)),
+ extensionNames(QOpenGLStaticContext::getGlString(GL_EXTENSIONS)),
+ majorVersion(0), minorVersion(0),
+ extensions(0),
+ wglGetPixelFormatAttribIVARB((WglGetPixelFormatAttribIVARB)wglGetProcAddress("wglGetPixelFormatAttribivARB")),
+ wglChoosePixelFormatARB((WglChoosePixelFormatARB)wglGetProcAddress("wglChoosePixelFormatARB")),
+ wglCreateContextAttribsARB((WglCreateContextAttribsARB)wglGetProcAddress("wglCreateContextAttribsARB"))
+{
+ if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION" ")
+ || extensionNames.indexOf(" "SAMPLE_BUFFER_EXTENSION" ") != -1)
+ extensions |= SampleBuffers;
+ // Get version
+ do {
+ const QByteArray version = QOpenGLStaticContext::getGlString(GL_VERSION);
+ if (version.isEmpty())
+ break;
+ const int majorDot = version.indexOf('.');
+ if (majorDot == -1)
+ break;
+ int minorDot = version.indexOf('.', majorDot + 1);
+ if (minorDot == -1)
+ minorDot = version.size();
+ majorVersion = version.mid(0, majorDot).toInt();
+ minorVersion = version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
+ } while (false);
+}
+
+QByteArray QOpenGLStaticContext::getGlString(unsigned int which)
+{
+ if (const GLubyte *s = glGetString(which))
+ return QByteArray((const char*)s);
+ return QByteArray();
+}
+
+QOpenGLStaticContext *QOpenGLStaticContext::create()
+{
+ // We need a current context for wglGetProcAdress()/getGLString() to work.
+ QScopedPointer<QOpenGLTemporaryContext> temporaryContext;
+ if (!wglGetCurrentContext())
+ temporaryContext.reset(new QOpenGLTemporaryContext);
+ QOpenGLStaticContext *result = new QOpenGLStaticContext;
+ if (QWindowsContext::verboseGL)
+ qDebug() << __FUNCTION__ << *result;
+ return result;
+}
+
+QDebug operator<<(QDebug d, const QOpenGLStaticContext &s)
+{
+ QDebug nsp = d.nospace();
+ nsp << "OpenGL: " << s.vendor << ',' << s.renderer << ",v"
+ << s.majorVersion << '.' << s.minorVersion;
+ if (s.extensions & QOpenGLStaticContext::SampleBuffers)
+ nsp << ",SampleBuffers";
+ if (s.hasExtensions())
+ nsp << ", Extension-API present";
+ nsp << "\nExtensions: " << s.extensionNames;
+ return d;
+}
+
+/*!
+ \class QWindowsGLContext
+ \brief Open GL context.
+
+ An Open GL context for use with several windows.
+ As opposed to other implementations, activating a GL context for
+ a window requires a HDC allocated for it. The first time this
+ HDC is created for the window, the pixel format must be applied,
+ which will affect the window as well. The HDCs are stored in a list of
+ QOpenGLContextData and are released in doneCurrent().
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContext,
+ QOpenGLContext *context) :
+ m_staticContext(staticContext),
+ m_context(context),
+ m_pixelFormat(0), m_extensionsUsed(false)
+{
+ // workaround for matrox driver:
+ // make a cheap call to opengl to force loading of DLL
+ static bool opengl32dll = false;
+ if (!opengl32dll) {
+ GLint params;
+ glGetIntegerv(GL_DEPTH_BITS, &params);
+ opengl32dll = true;
+ }
+
+ // SetPixelFormat (as of Windows 7) requires a real window.
+ // Create a dummy one as we are not associated with a window yet.
+ // Try to find a suitable pixel format using preferably ARB extensions
+ // (default to GDI) and store that.
+ HWND dummyWindow = 0;
+ HDC hdc = 0;
+ do {
+ dummyWindow = createDummyGLWindow();
+ if (!dummyWindow)
+ break;
+ hdc = GetDC(dummyWindow);
+ if (!hdc)
+ break;
+
+ if (QWindowsContext::verboseGL > 1)
+ describeFormats(hdc);
+ // Preferably use direct rendering and ARB extensions (unless pixmap)
+ const QWindowsOpenGLAdditionalFormat
+ requestedAdditional(QWindowsGLDirectRendering|QWindowsGLDeprecatedFunctions);
+ const bool tryExtensions = m_staticContext->hasExtensions()
+ && !testFlag(requestedAdditional.formatFlags, QWindowsGLRenderToPixmap);
+ QWindowsOpenGLAdditionalFormat obtainedAdditional;
+ if (tryExtensions) {
+ m_pixelFormat =
+ ARB::choosePixelFormat(hdc, *m_staticContext, context->format(),
+ requestedAdditional, &m_obtainedPixelFormatDescriptor);
+ if (m_pixelFormat > 0) {
+ m_obtainedFormat =
+ ARB::qSurfaceFormatFromHDC(*m_staticContext, hdc, m_pixelFormat,
+ &obtainedAdditional);
+ m_extensionsUsed = true;
+ }
+ } // tryExtensions
+ if (!m_pixelFormat) { // Failed, try GDI
+ m_pixelFormat = GDI::choosePixelFormat(hdc, context->format(), requestedAdditional,
+ &m_obtainedPixelFormatDescriptor);
+ if (m_pixelFormat)
+ m_obtainedFormat =
+ GDI::qSurfaceFormatFromPixelFormat(m_obtainedPixelFormatDescriptor,
+ &obtainedAdditional);
+ } // try GDI
+ if (!m_pixelFormat) {
+ qWarning("%s: Unable find a suitable pixel format.", __FUNCTION__);
+ break;
+ }
+ if (!SetPixelFormat(hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
+ qErrnoWarning("SetPixelFormat failed.");
+ break;
+ }
+ // Create context with sharing, again preferably using ARB.
+ HGLRC sharingRenderingContext = 0;
+ if (const QPlatformOpenGLContext *sc = context->shareHandle())
+ sharingRenderingContext = static_cast<const QWindowsGLContext *>(sc)->renderingContext();
+
+ if (m_extensionsUsed)
+ m_renderingContext =
+ ARB::createContext(*m_staticContext, hdc, context->format(),
+ requestedAdditional, 0, 0, sharingRenderingContext);
+ if (!m_renderingContext)
+ m_renderingContext = GDI::createContext(hdc, sharingRenderingContext);
+
+ if (!m_renderingContext) {
+ qWarning("Unable to create a GL Context.");
+ break;
+ }
+ } while (false);
+ if (hdc)
+ ReleaseDC(dummyWindow, hdc);
+ if (dummyWindow)
+ DestroyWindow(dummyWindow);
+
+ if (QWindowsContext::verboseGL)
+ qDebug()
+ << __FUNCTION__ << this << " requested: " << context->format()
+ << "\n obtained #" << m_pixelFormat << (m_extensionsUsed ? "ARB" : "GDI")
+ << m_obtainedFormat << "\n " << m_obtainedPixelFormatDescriptor
+ << "\n HGLRC=" << m_renderingContext;
+}
+
+QWindowsGLContext::~QWindowsGLContext()
+{
+ if (m_renderingContext)
+ wglDeleteContext(m_renderingContext);
+ releaseDCs();
+}
+
+void QWindowsGLContext::releaseDCs()
+{
+ const QOpenGLContextData *end = m_windowContexts.end();
+ for (const QOpenGLContextData *p = m_windowContexts.begin(); p < end; ++p)
+ ReleaseDC(p->hwnd, p->hdc);
+ m_windowContexts.resize(0);
+}
+
+static inline QWindowsWindow *glWindowOf(QPlatformSurface *s)
+{
+ return static_cast<QWindowsWindow *>(s);
+}
+
+static inline HWND handleOf(QPlatformSurface *s)
+{
+ return glWindowOf(s)->handle();
+}
+
+// Find a window in a context list.
+static inline const QOpenGLContextData *
+ findByHWND(const Array<QOpenGLContextData> &data, HWND hwnd)
+{
+ const QOpenGLContextData *end = data.end();
+ for (const QOpenGLContextData *p = data.begin(); p < end; ++p)
+ if (p->hwnd == hwnd)
+ return p;
+ return 0;
+}
+
+void QWindowsGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ if (QWindowsContext::verboseGL > 1)
+ qDebug() << __FUNCTION__ << surface;
+ if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, handleOf(surface))) {
+ SwapBuffers(contextData->hdc);
+ } else {
+ qWarning("%s: Cannot find window %p", __FUNCTION__, handleOf(surface));
+ }
+}
+
+bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
+{
+#ifdef DEBUG_GL
+ if (QWindowsContext::verboseGL > 1)
+ qDebug("%s context=%p contexts=%d", __FUNCTION__, this, m_windowContexts.size());
+#endif // DEBUG_GL
+ // Do we already have a DC entry for that window?
+ QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
+ const HWND hwnd = window->handle();
+ if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, hwnd))
+ return wglMakeCurrent(contextData->hdc, contextData->renderingContext);
+ // Create a new entry.
+ const QOpenGLContextData newContext(m_renderingContext, hwnd, GetDC(hwnd));
+ if (!newContext.hdc)
+ return false;
+ // Initialize pixel format first time. This will apply to
+ // the HWND as well and must be done only once.
+ if (!window->testFlag(QWindowsWindow::PixelFormatInitialized)) {
+ if (!SetPixelFormat(newContext.hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
+ qErrnoWarning("%s: SetPixelFormat() failed", __FUNCTION__);
+ ReleaseDC(newContext.hwnd, newContext.hdc);
+ return false;
+ }
+ window->setFlag(QWindowsWindow::PixelFormatInitialized);
+ }
+ m_windowContexts.append(newContext);
+ return wglMakeCurrent(newContext.hdc, newContext.renderingContext);
+}
+
+void QWindowsGLContext::doneCurrent()
+{
+#ifdef DEBUG_GL
+ if (QWindowsContext::verboseGL > 1)
+ qDebug("%s context=%p %d contexts", __FUNCTION__, this, m_windowContexts.size());
+#endif // DEBUG_GL
+ wglMakeCurrent(0, 0);
+ releaseDCs();
+}
+
+QWindowsGLContext::GL_Proc QWindowsGLContext::getProcAddress(const QByteArray &procName)
+{
+ // TODO: Will that work with the calling conventions?
+ GL_Proc procAddress = reinterpret_cast<GL_Proc>(wglGetProcAddress(procName.constData()));
+ if (QWindowsContext::verboseGL)
+ qDebug("%s('%s') with current_hglrc=%p returns %p",
+ __FUNCTION__, procName.constData(),
+ wglGetCurrentContext(), procAddress);
+ return procAddress;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
new file mode 100644
index 0000000000..0bf8ffbbc5
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSGLCONTEXT_H
+#define QWINDOWSGLCONTEXT_H
+
+#include "array.h"
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QOpenGLContext>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+
+enum QWindowsGLFormatFlags
+{
+ QWindowsGLDirectRendering = 0x1,
+ QWindowsGLOverlay = 0x2,
+ QWindowsGLRenderToPixmap = 0x4,
+ QWindowsGLAccumBuffer = 0x8,
+ QWindowsGLDeprecatedFunctions = 0x10
+};
+
+// Additional format information for Windows.
+struct QWindowsOpenGLAdditionalFormat
+{
+ QWindowsOpenGLAdditionalFormat(unsigned formatFlagsIn = 0, unsigned pixmapDepthIn = 0) :
+ formatFlags(formatFlagsIn), pixmapDepth(pixmapDepthIn) {}
+ unsigned formatFlags; // QWindowsGLFormatFlags.
+ unsigned pixmapDepth; // for QWindowsGLRenderToPixmap
+};
+
+// Per-window data for active OpenGL contexts.
+struct QOpenGLContextData
+{
+ QOpenGLContextData(HGLRC r, HWND h, HDC d) : renderingContext(r), hwnd(h), hdc(d) {}
+ QOpenGLContextData() : renderingContext(0), hwnd(0), hdc(0) {}
+
+ HGLRC renderingContext;
+ HWND hwnd;
+ HDC hdc;
+};
+
+class QOpenGLStaticContext
+{
+ Q_DISABLE_COPY(QOpenGLStaticContext)
+ QOpenGLStaticContext();
+public:
+ enum Extensions
+ {
+ SampleBuffers = 0x1
+ };
+
+ typedef bool
+ (APIENTRY *WglGetPixelFormatAttribIVARB)
+ (HDC hdc, int iPixelFormat, int iLayerPlane,
+ uint nAttributes, const int *piAttributes, int *piValues);
+
+ typedef bool
+ (APIENTRY *WglChoosePixelFormatARB)(HDC hdc, const int *piAttribList,
+ const float *pfAttribFList, uint nMaxFormats, int *piFormats,
+ UINT *nNumFormats);
+
+ typedef HGLRC
+ (APIENTRY *WglCreateContextAttribsARB)(HDC, HGLRC, const int *);
+
+ bool hasExtensions() const
+ { return wglGetPixelFormatAttribIVARB && wglChoosePixelFormatARB && wglCreateContextAttribsARB; }
+
+ static QOpenGLStaticContext *create();
+ static QByteArray getGlString(unsigned int which);
+
+ const QByteArray vendor;
+ const QByteArray renderer;
+ const QByteArray extensionNames;
+ int majorVersion;
+ int minorVersion;
+ unsigned extensions;
+
+ WglGetPixelFormatAttribIVARB wglGetPixelFormatAttribIVARB;
+ WglChoosePixelFormatARB wglChoosePixelFormatARB;
+ WglCreateContextAttribsARB wglCreateContextAttribsARB;
+};
+
+QDebug operator<<(QDebug d, const QOpenGLStaticContext &);
+
+class QWindowsGLContext : public QPlatformOpenGLContext
+{
+public:
+ typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
+
+ explicit QWindowsGLContext(const QOpenGLStaticContextPtr &staticContext,
+ QOpenGLContext *context);
+ virtual ~QWindowsGLContext();
+ bool isValid() const { return m_renderingContext; }
+ virtual QSurfaceFormat format() const { return m_obtainedFormat; }
+
+ virtual void swapBuffers(QPlatformSurface *surface);
+
+ virtual bool makeCurrent(QPlatformSurface *surface);
+ virtual void doneCurrent();
+
+ typedef void (*GL_Proc) ();
+
+ virtual GL_Proc getProcAddress(const QByteArray &procName);
+
+ HGLRC renderingContext() const { return m_renderingContext; }
+
+private:
+ inline void releaseDCs();
+
+ const QOpenGLStaticContextPtr m_staticContext;
+ QOpenGLContext *m_context;
+ QSurfaceFormat m_obtainedFormat;
+ HGLRC m_renderingContext;
+ Array<QOpenGLContextData> m_windowContexts;
+ PIXELFORMATDESCRIPTOR m_obtainedPixelFormatDescriptor;
+ int m_pixelFormat;
+ bool m_extensionsUsed;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSGLCONTEXT_H
diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
new file mode 100644
index 0000000000..fe03a7ffe8
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsguieventdispatcher.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtCore/QStack>
+#include <QtCore/QDebug>
+
+#include <windowsx.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsGuiEventDispatcher
+ \brief Event dispatcher for Windows
+
+ Maintains a global stack storing the current event dispatcher and
+ its processing flags for access from the Windows procedure
+ qWindowsWndProc. Handling the Lighthouse gui events should be done
+ from within the qWindowsWndProc to ensure correct processing of messages.
+
+ \ingroup qt-lighthouse-win
+*/
+
+typedef QStack<QWindowsGuiEventDispatcher::DispatchContext> DispatchContextStack;
+
+Q_GLOBAL_STATIC(DispatchContextStack, dispatchContextStack)
+
+QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) :
+ QEventDispatcherWin32(parent)
+{
+ setObjectName(QStringLiteral("QWindowsGuiEventDispatcher_0x") + QString::number((quintptr)this, 16));
+ if (QWindowsContext::verboseEvents)
+ qDebug("%s %s", __FUNCTION__, qPrintable(objectName()));
+ dispatchContextStack()->push(DispatchContext(this, QEventLoop::AllEvents));
+}
+
+QWindowsGuiEventDispatcher::~QWindowsGuiEventDispatcher()
+{
+ if (QWindowsContext::verboseEvents)
+ qDebug("%s %s", __FUNCTION__, qPrintable(objectName()));
+ if (!dispatchContextStack()->isEmpty())
+ dispatchContextStack()->pop();
+}
+
+bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ DispatchContextStack &stack = *dispatchContextStack();
+ if (QWindowsContext::verboseEvents > 2)
+ qDebug(">%s %s %d", __FUNCTION__, qPrintable(objectName()), stack.size());
+ stack.push(DispatchContext(this, flags));
+ const bool rc = QEventDispatcherWin32::processEvents(flags);
+ stack.pop();
+ if (QWindowsContext::verboseEvents > 2)
+ qDebug("<%s %s returns %d", __FUNCTION__, qPrintable(objectName()), rc);
+ return rc;
+}
+
+QWindowsGuiEventDispatcher::DispatchContext QWindowsGuiEventDispatcher::currentDispatchContext()
+{
+ const DispatchContextStack &stack = *dispatchContextStack();
+ if (stack.isEmpty()) {
+ qWarning("%s: No dispatch context", __FUNCTION__);
+ return DispatchContext(0, 0);
+ }
+ return stack.top();
+}
+
+// Helpers for printing debug output for WM_* messages.
+struct MessageDebugEntry
+{
+ UINT message;
+ const char *description;
+ bool interesting;
+};
+
+static const MessageDebugEntry
+messageDebugEntries[] = {
+ {WM_CREATE, "WM_CREATE", true},
+ {WM_PAINT, "WM_PAINT", true},
+ {WM_CLOSE, "WM_CLOSE", true},
+ {WM_DESTROY, "WM_DESTROY", true},
+ {WM_MOVE, "WM_MOVE", true},
+ {WM_SIZE, "WM_SIZE", true},
+ {WM_MOUSEACTIVATE,"WM_MOUSEACTIVATE", true},
+ {WM_CHILDACTIVATE, "WM_CHILDACTIVATE", true},
+ {WM_PARENTNOTIFY, "WM_PARENTNOTIFY", true},
+ {WM_GETICON, "WM_GETICON", false},
+ {WM_KEYDOWN, "WM_KEYDOWN", true},
+ {WM_SYSKEYDOWN, "WM_SYSKEYDOWN", true},
+ {WM_SYSCOMMAND, "WM_SYSCOMMAND", true},
+ {WM_KEYUP, "WM_KEYUP", true},
+ {WM_SYSKEYUP, "WM_SYSKEYUP", true},
+ {WM_IME_CHAR, "WM_IMECHAR", true},
+ {WM_IME_KEYDOWN, "WM_IMECHAR", true},
+ {WM_CANCELMODE, "WM_CANCELMODE", true},
+ {WM_CHAR, "WM_CHAR", true},
+ {WM_DEADCHAR, "WM_DEADCHAR", true},
+ {WM_ACTIVATE, "WM_ACTIVATE", true},
+ {WM_GETMINMAXINFO, "WM_GETMINMAXINFO", true},
+ {WM_SETFOCUS, "WM_SETFOCUS", true},
+ {WM_KILLFOCUS, "WM_KILLFOCUS", true},
+ {WM_ENABLE, "WM_ENABLE", true},
+ {WM_SHOWWINDOW, "WM_SHOWWINDOW", true},
+ {WM_GETMINMAXINFO, "WM_GETMINMAXINFO"},
+ {WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING", true},
+ {WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED", true},
+ {WM_SETCURSOR, "WM_SETCURSOR", false},
+ {WM_GETFONT, "WM_GETFONT", true},
+ {WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE", true},
+ {WM_LBUTTONDOWN, "WM_LBUTTONDOWN", true},
+ {WM_LBUTTONUP, "WM_LBUTTONUP", true},
+ {WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK", true},
+ {WM_RBUTTONDOWN, "WM_RBUTTONDOWN", true},
+ {WM_RBUTTONUP, "WM_RBUTTONUP", true},
+ {WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK", true},
+ {WM_MBUTTONDOWN, "WM_MBUTTONDOWN", true},
+ {WM_MBUTTONUP, "WM_MBUTTONUP", true},
+ {WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK", true},
+ {WM_MOUSEWHEEL, "WM_MOUSEWHEEL", true},
+ {WM_XBUTTONDOWN, "WM_XBUTTONDOWN", true},
+ {WM_XBUTTONUP, "WM_XBUTTONUP", true},
+ {WM_XBUTTONDBLCLK, "WM_XBUTTONDBLCLK", true},
+ {WM_MOUSEHWHEEL, "WM_MOUSEHWHEEL", true},
+ {WM_NCCREATE, "WM_NCCREATE", true},
+ {WM_NCCALCSIZE, "WM_NCCALCSIZE", true},
+ {WM_NCACTIVATE, "WM_NCACTIVATE", true},
+ {WM_NCMOUSELEAVE, "WM_NCMOUSELEAVE", true},
+ {WM_NCLBUTTONDOWN, "WM_NCLBUTTONDOWN", true},
+ {WM_NCLBUTTONUP, "WM_NCLBUTTONUP", true},
+ {WM_ACTIVATEAPP, "WM_ACTIVATEAPP", true},
+ {WM_NCPAINT, "WM_NCPAINT", true},
+ {WM_ERASEBKGND, "WM_ERASEBKGND", true},
+ {WM_MOUSEMOVE, "WM_MOUSEMOVE", true},
+ {WM_MOUSELEAVE, "WM_MOUSELEAVE", true},
+ {WM_NCHITTEST, "WM_NCHITTEST", false},
+ {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true},
+ {WM_INPUTLANGCHANGE, "WM_INPUTLANGCHANGE", true},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
+#if defined(WM_DWMNCRENDERINGCHANGED)
+ {WM_DWMNCRENDERINGCHANGED, "WM_DWMNCRENDERINGCHANGED", true},
+#endif
+ {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
+ {WM_TOUCH, "WM_TOUCH", true},
+ {WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN", true},
+ {WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD", true},
+ {WM_RENDERFORMAT, "WM_RENDERFORMAT", true},
+ {WM_RENDERALLFORMATS, "WM_RENDERALLFORMATS", true},
+ {WM_DESTROYCLIPBOARD, "WM_DESTROYCLIPBOARD", true},
+ {WM_CAPTURECHANGED, "WM_CAPTURECHANGED", true},
+ {WM_IME_STARTCOMPOSITION, "WM_IME_STARTCOMPOSITION"},
+ {WM_IME_COMPOSITION, "WM_IME_COMPOSITION"},
+ {WM_IME_ENDCOMPOSITION, "WM_IME_ENDCOMPOSITION"},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY"},
+ {WM_IME_REQUEST, "WM_IME_REQUEST"}
+};
+
+static inline const MessageDebugEntry *messageDebugEntry(UINT msg)
+{
+ for (size_t i = 0; i < sizeof(messageDebugEntries)/sizeof(MessageDebugEntry); i++)
+ if (messageDebugEntries[i].message == msg)
+ return messageDebugEntries + i;
+ return 0;
+}
+
+const char *QWindowsGuiEventDispatcher::windowsMessageName(UINT msg)
+{
+ if (const MessageDebugEntry *e = messageDebugEntry(msg))
+ return e->description;
+ return "Unknown";
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/gfxdrivers/ahi/qscreenahi_qws.h b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h
index a00cf77abf..00fd234eff 100644
--- a/src/plugins/gfxdrivers/ahi/qscreenahi_qws.h
+++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h
@@ -2,7 +2,7 @@
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: Nokia Corporation (info@qt.nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
@@ -39,46 +39,33 @@
**
****************************************************************************/
-#ifndef QAHISCREEN_H
-#define QAHISCREEN_H
+#ifndef QWINDOWSGUIEVENTDISPATCHER_H
+#define QWINDOWSGUIEVENTDISPATCHER_H
-#include <QtGui/qscreenlinuxfb_qws.h>
+#include "qtwindowsglobal.h"
+#include "qtwindows_additional.h"
-#ifndef QT_NO_QWS_AHI
-
-QT_BEGIN_HEADER
+#include <QtCore/QPair>
+#include <QtCore/private/qeventdispatcher_win_p.h>
QT_BEGIN_NAMESPACE
-QT_MODULE(Gui)
-
-class QAhiScreenPrivate;
-
-class QAhiScreen : public QScreen
+class QWindowsGuiEventDispatcher : public QEventDispatcherWin32
{
+ Q_OBJECT
public:
- QAhiScreen(int displayId);
- ~QAhiScreen();
+ explicit QWindowsGuiEventDispatcher(QObject *parent = 0);
+ ~QWindowsGuiEventDispatcher();
- bool connect(const QString &displaySpec);
- void disconnect();
- bool initDevice();
- void shutdownDevice();
- void setMode(int width, int height, int depth);
+ typedef QPair<QAbstractEventDispatcher *, QEventLoop::ProcessEventsFlags> DispatchContext;
- void blit(const QImage &image, const QPoint &topLeft,
- const QRegion &region);
- void solidFill(const QColor &color, const QRegion &region);
+ static DispatchContext currentDispatchContext();
-private:
- bool configure();
+ static const char *windowsMessageName(UINT msg);
- QAhiScreenPrivate *d_ptr;
+ virtual bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags);
};
QT_END_NAMESPACE
-QT_END_HEADER
-
-#endif // QT_NO_QWS_AHI
-#endif // QAHISCREEN_H
+#endif // QWINDOWSGUIEVENTDISPATCHER_H
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
new file mode 100644
index 0000000000..e3dc100805
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -0,0 +1,598 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsinputcontext.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsintegration.h"
+#include "qwindowsmousehandler.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QObject>
+#include <QtCore/QRect>
+#include <QtCore/QTextBoundaryFinder>
+
+#include <QtGui/QInputMethodEvent>
+#include <QtGui/QTextCharFormat>
+#include <QtGui/QPalette>
+#include <QtGui/QGuiApplication>
+
+QT_BEGIN_NAMESPACE
+
+static inline QByteArray debugComposition(int lParam)
+{
+ QByteArray str;
+ if (lParam & GCS_RESULTSTR)
+ str += "RESULTSTR ";
+ if (lParam & GCS_COMPSTR)
+ str += "COMPSTR ";
+ if (lParam & GCS_COMPATTR)
+ str += "COMPATTR ";
+ if (lParam & GCS_CURSORPOS)
+ str += "CURSORPOS ";
+ if (lParam & GCS_COMPCLAUSE)
+ str += "COMPCLAUSE ";
+ if (lParam & CS_INSERTCHAR)
+ str += "INSERTCHAR ";
+ if (lParam & CS_NOMOVECARET)
+ str += "NOMOVECARET ";
+ return str;
+}
+
+// Cancel current IME composition.
+static inline void imeNotifyCancelComposition(HWND hwnd)
+{
+ const HIMC himc = ImmGetContext(hwnd);
+ ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
+ ImmReleaseContext(hwnd, himc);
+}
+
+// Query a QObject for an InputMethod-related value
+// by sending a QInputMethodQueryEvent.
+template <class T>
+ bool inputMethodQuery(QObject *fo, Qt::InputMethodQuery query, T *result)
+{
+ QInputMethodQueryEvent queryEvent(query);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return false;
+ *result = qvariant_cast<T>(queryEvent.value());
+ return true;
+}
+
+/*!
+ \class QWindowsInputContext
+ \brief Windows Input context implementation
+
+ Handles input of foreign characters (particularly East Asian)
+ languages.
+
+ \section1 Testing
+
+ \list
+ \o Install the East Asian language support and choose Japanese (say).
+ \o Compile the \a mainwindows/mdi example and open a text window.
+ \o In the language bar, switch to Japanese and choose the
+ Input method 'Hiragana'.
+ \o In a text editor control, type the syllable \a 'la'.
+ Underlined characters show up, indicating that there is completion
+ available. Press the Space key two times. A completion popup occurs
+ which shows the options.
+ \endlist
+
+ Reconversion: Input texts can be 'converted' into different
+ input modes or more completion suggestions can be made based on
+ context to correct errors. This is bound to the 'Conversion key'
+ (F13-key in Japanese, which can be changed in the
+ configuration). After writing text, pressing the key selects text
+ and triggers a conversion popup, which shows the alternatives for
+ the word.
+
+ \section1 Interaction
+
+ When the user activates input methods, Windows sends
+ WM_IME_STARTCOMPOSITION, WM_IME_COMPOSITION,
+ WM_IME_ENDCOMPOSITION messages that trigger startComposition(),
+ composition(), endComposition(), respectively. No key events are sent.
+
+ composition() determines the markup of the pre-edit or selected
+ text and/or the final text and sends that to the focus object.
+
+ In between startComposition(), endComposition(), multiple
+ compositions may happen (isComposing).
+
+ update() is called to synchronize the position of the candidate
+ window with the microfocus rectangle of the focus object.
+ Also, a hidden caret is moved along with that position,
+ which is important for some Chinese input methods.
+
+ reset() is called to cancel a composition if the mouse is
+ moved outside or for example some Undo/Redo operation is
+ invoked.
+
+ \note Mouse interaction of popups with
+ QtWindows::InputMethodOpenCandidateWindowEvent and
+ QtWindows::InputMethodCloseCandidateWindowEvent
+ needs to be checked (mouse grab might interfere with candidate window).
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsInputContext::CompositionContext::CompositionContext() :
+ hwnd(0), haveCaret(false), position(0), isComposing(false)
+{
+}
+
+QWindowsInputContext::QWindowsInputContext() :
+ m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")),
+ m_endCompositionRecursionGuard(false)
+{
+}
+
+QWindowsInputContext::~QWindowsInputContext()
+{
+}
+
+/*!
+ \brief Cancels a composition.
+*/
+
+void QWindowsInputContext::reset()
+{
+ QPlatformInputContext::reset();
+ if (!m_compositionContext.hwnd)
+ return;
+ QObject *fo = focusObject();
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__<< fo;
+ if (!fo)
+ return;
+ if (m_compositionContext.isComposing) {
+ QInputMethodEvent event;
+ if (!m_compositionContext.composition.isEmpty())
+ event.setCommitString(m_compositionContext.composition);
+ QCoreApplication::sendEvent(fo, &event);
+ endContextComposition();
+ }
+ imeNotifyCancelComposition(m_compositionContext.hwnd);
+ doneContext();
+}
+
+/*!
+ \brief Moves the candidate window along with microfocus of the focus object.
+*/
+
+void QWindowsInputContext::update()
+{
+ QPlatformInputContext::update();
+ if (!m_compositionContext.hwnd)
+ return;
+ QObject *fo = focusObject();
+ if (!fo)
+ return;
+ const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
+ if (!himc)
+ return;
+ // Move candidate list window to the microfocus position.
+ QRect globalMicroFocusRect;
+ if (!inputMethodQuery(fo, Qt::ImCursorRectangle, &globalMicroFocusRect) || !globalMicroFocusRect.isValid())
+ return;
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << himc << globalMicroFocusRect;
+
+ if (globalMicroFocusRect.isValid()) {
+ const QRect microFocusRect(QWindowsGeometryHint::mapFromGlobal(m_compositionContext.hwnd,
+ globalMicroFocusRect.topLeft()),
+ globalMicroFocusRect.size());
+ COMPOSITIONFORM cf;
+ // ### need X-like inputStyle config settings
+ cf.dwStyle = CFS_FORCE_POSITION;
+ cf.ptCurrentPos.x = microFocusRect.x();
+ cf.ptCurrentPos.y = microFocusRect.y();
+
+ CANDIDATEFORM candf;
+ candf.dwIndex = 0;
+ candf.dwStyle = CFS_EXCLUDE;
+ candf.ptCurrentPos.x = microFocusRect.x();
+ candf.ptCurrentPos.y = microFocusRect.y() + microFocusRect.height();
+ candf.rcArea.left = microFocusRect.x();
+ candf.rcArea.top = microFocusRect.y();
+ candf.rcArea.right = microFocusRect.x() + microFocusRect.width();
+ candf.rcArea.bottom = microFocusRect.y() + microFocusRect.height();
+
+ if (m_compositionContext.haveCaret)
+ SetCaretPos(microFocusRect.x(), microFocusRect.y());
+
+ ImmSetCompositionWindow(himc, &cf);
+ ImmSetCandidateWindow(himc, &candf);
+ }
+ ImmReleaseContext(m_compositionContext.hwnd, himc);
+}
+
+void QWindowsInputContext::mouseHandler(int pos, QMouseEvent *event)
+{
+ if (event->type() != QEvent::MouseButtonPress || !m_compositionContext.hwnd)
+ return;
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << pos << event;
+
+ if (pos < 0 || pos > m_compositionContext.composition.size())
+ reset();
+
+ // Magic code that notifies Japanese IME about the cursor
+ // position.
+ const DWORD button = QWindowsMouseHandler::mouseButtonsToKeyState(event->buttons());
+ const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
+ const HWND imeWindow = ImmGetDefaultIMEWnd(m_compositionContext.hwnd);
+ SendMessage(imeWindow, m_WM_MSIME_MOUSE, MAKELONG(MAKEWORD(button, pos == 0 ? 2 : 1), pos), (LPARAM)himc);
+ ImmReleaseContext(m_compositionContext.hwnd, himc);
+}
+
+void QWindowsInputContext::setFocusObject(QObject *object)
+{
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << object;
+
+ QPlatformInputContext::setFocusObject(object);
+}
+
+QWindowsInputContext *QWindowsInputContext::instance()
+{
+ return static_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
+}
+
+static inline QString getCompositionString(HIMC himc, DWORD dwIndex)
+{
+ enum { bufferSize = 256 };
+ wchar_t buffer[bufferSize];
+ const int length = ImmGetCompositionString(himc, dwIndex, buffer, bufferSize * sizeof(wchar_t));
+ return QString::fromWCharArray(buffer, length / sizeof(wchar_t));
+}
+
+// Determine the converted string range as pair of start/length to be selected.
+static inline void getCompositionStringConvertedRange(HIMC himc, int *selStart, int *selLength)
+{
+ enum { bufferSize = 256 };
+ // Find the range of bytes with ATTR_TARGET_CONVERTED set.
+ char attrBuffer[bufferSize];
+ *selStart = *selLength = 0;
+ if (const int attrLength = ImmGetCompositionString(himc, GCS_COMPATTR, attrBuffer, bufferSize)) {
+ int start = 0;
+ while (start < attrLength && !(attrBuffer[start] & ATTR_TARGET_CONVERTED))
+ start++;
+ if (start < attrLength) {
+ int end = start + 1;
+ while (end < attrLength && (attrBuffer[end] & ATTR_TARGET_CONVERTED))
+ end++;
+ *selStart = start;
+ *selLength = end - start;
+ }
+ }
+}
+
+enum StandardFormat {
+ PreeditFormat,
+ SelectionFormat
+};
+
+static inline QTextFormat standardFormat(StandardFormat format)
+{
+ QTextCharFormat result;
+ switch (format) {
+ case PreeditFormat:
+ result.setUnderlineStyle(QTextCharFormat::DashUnderline);
+ break;
+ case SelectionFormat: {
+ // TODO: Should be that of the widget?
+ const QPalette palette = QGuiApplication::palette();
+ const QColor background = palette.text().color();
+ result.setBackground(QBrush(background));
+ result.setForeground(palette.background());
+ break;
+ }
+ }
+ return result;
+}
+
+bool QWindowsInputContext::startComposition(HWND hwnd)
+{
+ const QObject *fo = focusObject();
+ if (!fo)
+ return false;
+ // This should always match the object.
+ QWindow *window = QGuiApplication::activeWindow();
+ if (!window)
+ return false;
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << fo << window;
+ if (!fo || QWindowsWindow::handleOf(window) != hwnd)
+ return false;
+ initContext(hwnd);
+ startContextComposition();
+ return true;
+}
+
+void QWindowsInputContext::startContextComposition()
+{
+ if (m_compositionContext.isComposing) {
+ qWarning("%s: Called out of sequence.", __FUNCTION__);
+ return;
+ }
+ m_compositionContext.isComposing = true;
+ m_compositionContext.composition.clear();
+ m_compositionContext.position = 0;
+ update();
+}
+
+void QWindowsInputContext::endContextComposition()
+{
+ if (!m_compositionContext.isComposing) {
+ qWarning("%s: Called out of sequence.", __FUNCTION__);
+ return;
+ }
+ m_compositionContext.composition.clear();
+ m_compositionContext.position = 0;
+ m_compositionContext.isComposing = false;
+}
+
+// Create a list of markup attributes for QInputMethodEvent
+// to display the selected part of the intermediate composition
+// result differently.
+static inline QList<QInputMethodEvent::Attribute>
+ intermediateMarkup(int position, int compositionLength,
+ int selStart, int selLength)
+{
+ QList<QInputMethodEvent::Attribute> attributes;
+ if (selStart > 0)
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selStart,
+ standardFormat(PreeditFormat));
+ if (selLength)
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart, selLength,
+ standardFormat(SelectionFormat));
+ if (selStart + selLength < compositionLength)
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart + selLength,
+ compositionLength - selStart - selLength,
+ standardFormat(PreeditFormat));
+ if (position >= 0)
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, position, selLength ? 0 : 1, QVariant());
+ return attributes;
+}
+
+/*!
+ \brief Notify focus object about markup or final text.
+*/
+
+bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
+{
+ QObject *fo = focusObject();
+ const int lParam = int(lParamIn);
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << '>' << __FUNCTION__ << fo << debugComposition(lParam)
+ << " composing=" << m_compositionContext.isComposing;
+ if (!fo || m_compositionContext.hwnd != hwnd || !lParam)
+ return false;
+ const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
+ if (!himc)
+ return false;
+
+ QScopedPointer<QInputMethodEvent> event;
+ if (lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS)) {
+ if (!m_compositionContext.isComposing)
+ startContextComposition();
+ // Some intermediate composition result. Parametrize event with
+ // attribute sequence specifying the formatting of the converted part.
+ int selStart, selLength;
+ m_compositionContext.composition = getCompositionString(himc, GCS_COMPSTR);
+ m_compositionContext.position = ImmGetCompositionString(himc, GCS_CURSORPOS, 0, 0);
+ getCompositionStringConvertedRange(himc, &selStart, &selLength);
+ if ((lParam & CS_INSERTCHAR) && (lParam & CS_NOMOVECARET)) {
+ // make Korean work correctly. Hope this is correct for all IMEs
+ selStart = 0;
+ selLength = m_compositionContext.composition.size();
+ }
+ if (!selLength)
+ selStart = 0;
+
+ event.reset(new QInputMethodEvent(m_compositionContext.composition,
+ intermediateMarkup(m_compositionContext.position,
+ m_compositionContext.composition.size(),
+ selStart, selLength)));
+ }
+ if (event.isNull())
+ event.reset(new QInputMethodEvent);
+
+ if (lParam & GCS_RESULTSTR) {
+ // A fixed result, return the converted string
+ event->setCommitString(getCompositionString(himc, GCS_RESULTSTR));
+ 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;
+ update();
+ ImmReleaseContext(m_compositionContext.hwnd, himc);
+ return result;
+}
+
+bool QWindowsInputContext::endComposition(HWND hwnd)
+{
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __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.
+ if (m_endCompositionRecursionGuard || m_compositionContext.hwnd != hwnd)
+ return false;
+ QObject *fo = focusObject();
+ if (!fo)
+ return false;
+
+ m_endCompositionRecursionGuard = true;
+
+ imeNotifyCancelComposition(m_compositionContext.hwnd);
+ if (m_compositionContext.isComposing) {
+ QInputMethodEvent event;
+ QCoreApplication::sendEvent(fo, &event);
+ }
+ doneContext();
+
+ m_endCompositionRecursionGuard = false;
+ return true;
+}
+
+void QWindowsInputContext::initContext(HWND hwnd)
+{
+ if (m_compositionContext.hwnd)
+ doneContext();
+ m_compositionContext.hwnd = hwnd;
+ // Create a hidden caret which is kept at the microfocus
+ // position in update(). This is important for some
+ // Chinese input methods.
+ m_compositionContext.haveCaret = CreateCaret(hwnd, 0, 1, 1);
+ HideCaret(hwnd);
+ update();
+ m_compositionContext.isComposing = false;
+ m_compositionContext.position = 0;
+}
+
+void QWindowsInputContext::doneContext()
+{
+ if (!m_compositionContext.hwnd)
+ return;
+ if (m_compositionContext.haveCaret)
+ DestroyCaret();
+ m_compositionContext.hwnd = 0;
+ m_compositionContext.composition.clear();
+ m_compositionContext.position = 0;
+ m_compositionContext.isComposing = m_compositionContext.haveCaret = false;
+}
+
+bool QWindowsInputContext::handleIME_Request(WPARAM wParam,
+ LPARAM lParam,
+ LRESULT *result)
+{
+ switch (int(wParam)) {
+ case IMR_RECONVERTSTRING: {
+ const int size = reconvertString(reinterpret_cast<RECONVERTSTRING *>(lParam));
+ if (size < 0)
+ return false;
+ *result = size;
+ return true;
+ }
+ break;
+ case IMR_CONFIRMRECONVERTSTRING:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \brief Determines the string for reconversion with selection.
+
+ This is triggered twice by WM_IME_REQUEST, first with reconv=0
+ to determine the length and later with a reconv struct to obtain
+ the string with the position of the selection to be reconverted.
+
+ Obtains the text from the focus object and marks the word
+ for selection (might not be entirely correct for Japanese).
+*/
+
+int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
+{
+ QObject *fo = focusObject();
+ if (!fo)
+ return false;
+
+ QString surroundingText;
+ if (!inputMethodQuery(fo, Qt::ImSurroundingText, &surroundingText))
+ return -1;
+ const DWORD memSize = sizeof(RECONVERTSTRING)
+ + (surroundingText.length() + 1) * sizeof(ushort);
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << " reconv=" << reconv
+ << " surroundingText=" << surroundingText
+ << " size=" << memSize;
+ // If memory is not allocated, return the required size.
+ if (!reconv)
+ return surroundingText.isEmpty() ? -1 : int(memSize);
+
+ int pos = 0;
+ inputMethodQuery(fo, Qt::ImCursorPosition, &pos);
+ // Find the word in the surrounding text.
+ QTextBoundaryFinder bounds(QTextBoundaryFinder::Word, surroundingText);
+ bounds.setPosition(pos);
+ if (bounds.isAtBoundary()) {
+ if (QTextBoundaryFinder::EndWord == bounds.boundaryReasons())
+ bounds.toPreviousBoundary();
+ } else {
+ bounds.toPreviousBoundary();
+ }
+ const int startPos = bounds.position();
+ bounds.toNextBoundary();
+ const int endPos = bounds.position();
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __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());
+ QInputMethodEvent selectEvent(QString(), attributes);
+ QCoreApplication::sendEvent(fo, &selectEvent);
+
+ reconv->dwSize = memSize;
+ reconv->dwVersion = 0;
+
+ reconv->dwStrLen = surroundingText.size();
+ reconv->dwStrOffset = sizeof(RECONVERTSTRING);
+ reconv->dwCompStrLen = endPos - startPos; // TCHAR count.
+ reconv->dwCompStrOffset = startPos * sizeof(ushort); // byte count.
+ reconv->dwTargetStrLen = reconv->dwCompStrLen;
+ reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
+ ushort *pastReconv = reinterpret_cast<ushort *>(reconv + 1);
+ qCopy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(),
+ pastReconv);
+ return memSize;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h
new file mode 100644
index 0000000000..8ea66774d4
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSINPUTCONTEXT_H
+#define QWINDOWSINPUTCONTEXT_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPlatformInputContext>
+
+QT_BEGIN_NAMESPACE
+
+class QInputMethodEvent;
+
+class QWindowsInputContext : public QPlatformInputContext
+{
+ struct CompositionContext
+ {
+ CompositionContext();
+
+ HWND hwnd;
+ bool haveCaret;
+ QString composition;
+ int position;
+ bool isComposing;
+ };
+public:
+ explicit QWindowsInputContext();
+ ~QWindowsInputContext();
+
+ virtual void reset();
+ virtual void update();
+
+ virtual void mouseHandler(int x, QMouseEvent *event);
+ virtual void setFocusObject(QObject *o);
+
+ static QWindowsInputContext *instance();
+
+ bool startComposition(HWND hwnd);
+ bool composition(HWND hwnd, LPARAM lParam);
+ bool endComposition(HWND hwnd);
+
+ int reconvertString(RECONVERTSTRING *reconv);
+
+ bool handleIME_Request(WPARAM wparam, LPARAM lparam, LRESULT *result);
+
+private:
+ void initContext(HWND hwnd);
+ void doneContext();
+ void startContextComposition();
+ void endContextComposition();
+
+ const DWORD m_WM_MSIME_MOUSE;
+ CompositionContext m_compositionContext;
+ bool m_endCompositionRecursionGuard;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSINPUTCONTEXT_H
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
new file mode 100644
index 0000000000..cde6da671a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsintegration.h"
+#include "qwindowsbackingstore.h"
+#include "qwindowswindow.h"
+#include "qwindowscontext.h"
+#include "qwindowsglcontext.h"
+#include "qwindowsscreen.h"
+#include "qwindowsfontdatabase.h"
+#include "qwindowsguieventdispatcher.h"
+#include "qwindowsclipboard.h"
+#include "qwindowsdrag.h"
+#include "qwindowsinputcontext.h"
+
+#include <QtGui/QPlatformNativeInterface>
+#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QBackingStore>
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+
+#include <QtCore/private/qeventdispatcher_win_p.h>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsNativeInterface
+ \brief Provides access to native handles.
+
+ Currently implemented keys
+ \list
+ \o handle (HWND)
+ \o getDC (DC)
+ \o releaseDC Releases the previously acquired DC and returns 0.
+ \endlist
+
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsNativeInterface : public QPlatformNativeInterface
+{
+public:
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
+ virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs);
+};
+
+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;
+}
+
+/*!
+ \class QWindowsIntegration
+ \brief QPlatformIntegration implementation for Windows.
+ \ingroup qt-lighthouse-win
+*/
+
+struct QWindowsIntegrationPrivate
+{
+ typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
+
+ explicit QWindowsIntegrationPrivate(bool openGL);
+
+ const bool m_openGL;
+ QWindowsContext m_context;
+ QWindowsFontDatabase m_fontDatabase;
+ QWindowsNativeInterface m_nativeInterface;
+ QWindowsClipboard m_clipboard;
+ QWindowsDrag m_drag;
+ QWindowsGuiEventDispatcher *m_eventDispatcher;
+ QOpenGLStaticContextPtr m_staticOpenGLContext;
+ QWindowsInputContext m_inputContext;
+};
+
+QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(bool openGL)
+ : m_openGL(openGL)
+ , m_context(openGL)
+ , m_eventDispatcher(new QWindowsGuiEventDispatcher)
+{
+}
+
+QWindowsIntegration::QWindowsIntegration(bool openGL) :
+ d(new QWindowsIntegrationPrivate(openGL))
+{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(d->m_eventDispatcher);
+ d->m_clipboard.registerViewer();
+ foreach (QPlatformScreen *pscr, QWindowsScreen::screens())
+ screenAdded(pscr);
+}
+
+QWindowsIntegration::~QWindowsIntegration()
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug("%s", __FUNCTION__);
+}
+
+bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps:
+ return true;
+ case OpenGL:
+ return true;
+ case ThreadedOpenGL:
+ return true;
+ default:
+ return QPlatformIntegration::hasCapability(cap);
+ }
+ return false;
+}
+
+QPlatformPixmap *QWindowsIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << type;
+ return new QRasterPlatformPixmap(type);
+}
+
+QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
+{
+ const bool isGL = window->surfaceType() == QWindow::OpenGLSurface;
+ QWindowsWindow::WindowData requested;
+ requested.flags = window->windowFlags();
+ requested.geometry = window->geometry();
+ const QWindowsWindow::WindowData obtained
+ = QWindowsWindow::WindowData::create(window, requested, window->windowTitle(), isGL);
+ if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
+ qDebug().nospace()
+ << __FUNCTION__ << ' ' << window << '\n'
+ << " Requested: " << requested.geometry << " 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->setWindowFlags(obtained.flags);
+ if (requested.geometry != obtained.geometry)
+ QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
+ return new QWindowsWindow(window, obtained);
+}
+
+QPlatformBackingStore *QWindowsIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << window;
+ return new QWindowsBackingStore(window);
+}
+
+QPlatformOpenGLContext
+ *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << context->format();
+ if (d->m_staticOpenGLContext.isNull())
+ d->m_staticOpenGLContext =
+ QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
+ QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
+ if (result->isValid())
+ return result.take();
+ return 0;
+}
+
+QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const
+{
+ return &d->m_fontDatabase;
+}
+
+QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const
+{
+ return &d->m_nativeInterface;
+}
+
+QPlatformClipboard * QWindowsIntegration::clipboard() const
+{
+ return &d->m_clipboard;
+}
+
+QPlatformDrag *QWindowsIntegration::drag() const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug("%s", __FUNCTION__ );
+ return &d->m_drag;
+}
+
+QPlatformInputContext * QWindowsIntegration::inputContext() const
+{
+ return &d->m_inputContext;
+}
+
+QWindowsIntegration *QWindowsIntegration::instance()
+{
+ return static_cast<QWindowsIntegration *>(QGuiApplicationPrivate::platformIntegration());
+}
+
+QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const
+{
+ return d->m_eventDispatcher;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
new file mode 100644
index 0000000000..14a65c67e0
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSINTEGRATION_H
+#define QWINDOWSINTEGRATION_H
+
+#include <QtGui/QPlatformIntegration>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+struct QWindowsIntegrationPrivate;
+
+class QWindowsIntegration : public QPlatformIntegration
+{
+public:
+ QWindowsIntegration(bool openGL = false);
+ virtual ~QWindowsIntegration();
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+
+ virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
+ virtual QPlatformClipboard *clipboard() const;
+ virtual QPlatformDrag *drag() const;
+ virtual QPlatformInputContext *inputContext() const;
+ virtual QPlatformNativeInterface *nativeInterface() const;
+ virtual QPlatformFontDatabase *fontDatabase() const;
+
+ static QWindowsIntegration *instance();
+
+private:
+ QScopedPointer<QWindowsIntegrationPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
index 12004571cb..49fc69059b 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
@@ -2,7 +2,7 @@
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: Nokia Corporation (info@qt.nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
@@ -39,37 +39,32 @@
**
****************************************************************************/
-#ifndef QDIRECTFBMOUSE_H
-#define QDIRECTFBMOUSE_H
+#ifndef QWINDOWSINTERNALMIME_H
+#define QWINDOWSINTERNALMIME_H
-#include <qglobal.h>
-#include <QtGui/qmouse_qws.h>
+#include "qtwindows_additional.h"
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_HEADER
+#include <QtGui/private/qdnd_p.h> // QInternalMime
+#include <QtCore/QVariant>
QT_BEGIN_NAMESPACE
-QT_MODULE(Gui)
-
-class QDirectFBMouseHandlerPrivate;
+class QDebug;
-class QDirectFBMouseHandler : public QWSMouseHandler
-{
+// Implementation in qwindowsclipboard.cpp.
+class QWindowsInternalMimeData : public QInternalMimeData {
public:
- explicit QDirectFBMouseHandler(const QString &driver = QString(),
- const QString &device = QString());
- ~QDirectFBMouseHandler();
+ virtual bool hasFormat_sys(const QString &mimetype) const;
+ virtual QStringList formats_sys() const;
+ virtual QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const;
- void suspend();
- void resume();
protected:
- QDirectFBMouseHandlerPrivate *d;
+ virtual IDataObject *retrieveDataObject() const = 0;
+ virtual void releaseDataObject(IDataObject *) const {}
};
+QDebug operator<<(QDebug d, const QMimeData &m);
+
QT_END_NAMESPACE
-QT_END_HEADER
-#endif // QT_NO_QWS_DIRECTFB
-#endif // QDIRECTFBMOUSE_H
+#endif // QWINDOWSINTERNALMIME_H
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
new file mode 100644
index 0000000000..40613ea1f1
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -0,0 +1,1075 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowskeymapper.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsguieventdispatcher.h"
+
+#include <QtGui/QWindow>
+#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QKeyEvent>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsKeyMapper
+ \brief Translates Windows keys to QWindowSystemInterface events.
+ \ingroup qt-lighthouse-win
+
+ In addition, handles some special keys to display system menus, etc.
+ The code originates from \c qkeymapper_win.cpp.
+*/
+
+QWindowsKeyMapper::QWindowsKeyMapper()
+ : m_useRTLExtensions(false), m_keyGrabber(0)
+{
+ memset(keyLayout, 0, sizeof(keyLayout));
+}
+
+QWindowsKeyMapper::~QWindowsKeyMapper()
+{
+ deleteLayouts();
+}
+
+#ifndef LANG_PASHTO
+#define LANG_PASHTO 0x63
+#endif
+#ifndef LANG_SYRIAC
+#define LANG_SYRIAC 0x5a
+#endif
+#ifndef LANG_DIVEHI
+#define LANG_DIVEHI 0x65
+#endif
+#ifndef VK_OEM_PLUS
+#define VK_OEM_PLUS 0xBB
+#endif
+#ifndef VK_OEM_3
+#define VK_OEM_3 0xC0
+#endif
+
+// Key recorder ------------------------------------------------------------------------[ start ] --
+struct KeyRecord {
+ KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {}
+ KeyRecord() {}
+
+ int code;
+ int ascii;
+ int state;
+ QString text;
+};
+
+static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers...
+struct KeyRecorder
+{
+ KeyRecorder() : nrecs(0) {}
+
+ inline KeyRecord *findKey(int code, bool remove);
+ inline void storeKey(int code, int ascii, int state, const QString& text);
+ inline void clearKeys();
+
+ int nrecs;
+ KeyRecord deleted_record; // A copy of last entry removed from records[]
+ KeyRecord records[QT_MAX_KEY_RECORDINGS];
+};
+static KeyRecorder key_recorder;
+
+KeyRecord *KeyRecorder::findKey(int code, bool remove)
+{
+ KeyRecord *result = 0;
+ for (int i = 0; i < nrecs; ++i) {
+ if (records[i].code == code) {
+ if (remove) {
+ deleted_record = records[i];
+ // Move rest down, and decrease count
+ while (i + 1 < nrecs) {
+ records[i] = records[i + 1];
+ ++i;
+ }
+ --nrecs;
+ result = &deleted_record;
+ } else {
+ result = &records[i];
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+void KeyRecorder::storeKey(int code, int ascii, int state, const QString& text)
+{
+ Q_ASSERT_X(nrecs != QT_MAX_KEY_RECORDINGS,
+ "Internal KeyRecorder",
+ "Keyboard recorder buffer overflow, consider increasing QT_MAX_KEY_RECORDINGS");
+
+ if (nrecs == QT_MAX_KEY_RECORDINGS) {
+ qWarning("Qt: Internal keyboard buffer overflow");
+ return;
+ }
+ records[nrecs++] = KeyRecord(code,ascii,state,text);
+}
+
+void KeyRecorder::clearKeys()
+{
+ nrecs = 0;
+}
+// Key recorder --------------------------------------------------------------------------[ end ] --
+
+
+// Key translation ---------------------------------------------------------------------[ start ] --
+// Meaning of values:
+// 0 = Character output key, needs keyboard driver mapping
+// Key_unknown = Unknown Virtual Key, no translation possible, ignore
+static const uint KeyTbl[] = { // Keyboard mapping table
+ // Dec | Hex | Windows Virtual key
+ Qt::Key_unknown, // 0 0x00
+ Qt::Key_unknown, // 1 0x01 VK_LBUTTON | Left mouse button
+ Qt::Key_unknown, // 2 0x02 VK_RBUTTON | Right mouse button
+ Qt::Key_Cancel, // 3 0x03 VK_CANCEL | Control-Break processing
+ Qt::Key_unknown, // 4 0x04 VK_MBUTTON | Middle mouse button
+ Qt::Key_unknown, // 5 0x05 VK_XBUTTON1 | X1 mouse button
+ Qt::Key_unknown, // 6 0x06 VK_XBUTTON2 | X2 mouse button
+ Qt::Key_unknown, // 7 0x07 -- unassigned --
+ Qt::Key_Backspace, // 8 0x08 VK_BACK | BackSpace key
+ Qt::Key_Tab, // 9 0x09 VK_TAB | Tab key
+ Qt::Key_unknown, // 10 0x0A -- reserved --
+ Qt::Key_unknown, // 11 0x0B -- reserved --
+ Qt::Key_Clear, // 12 0x0C VK_CLEAR | Clear key
+ Qt::Key_Return, // 13 0x0D VK_RETURN | Enter key
+ Qt::Key_unknown, // 14 0x0E -- unassigned --
+ Qt::Key_unknown, // 15 0x0F -- unassigned --
+ Qt::Key_Shift, // 16 0x10 VK_SHIFT | Shift key
+ Qt::Key_Control, // 17 0x11 VK_CONTROL | Ctrl key
+ Qt::Key_Alt, // 18 0x12 VK_MENU | Alt key
+ Qt::Key_Pause, // 19 0x13 VK_PAUSE | Pause key
+ Qt::Key_CapsLock, // 20 0x14 VK_CAPITAL | Caps-Lock
+ Qt::Key_unknown, // 21 0x15 VK_KANA / VK_HANGUL | IME Kana or Hangul mode
+ Qt::Key_unknown, // 22 0x16 -- unassigned --
+ Qt::Key_unknown, // 23 0x17 VK_JUNJA | IME Junja mode
+ Qt::Key_unknown, // 24 0x18 VK_FINAL | IME final mode
+ Qt::Key_unknown, // 25 0x19 VK_HANJA / VK_KANJI | IME Hanja or Kanji mode
+ Qt::Key_unknown, // 26 0x1A -- unassigned --
+ Qt::Key_Escape, // 27 0x1B VK_ESCAPE | Esc key
+ Qt::Key_unknown, // 28 0x1C VK_CONVERT | IME convert
+ Qt::Key_unknown, // 29 0x1D VK_NONCONVERT | IME non-convert
+ Qt::Key_unknown, // 30 0x1E VK_ACCEPT | IME accept
+ Qt::Key_Mode_switch,// 31 0x1F VK_MODECHANGE | IME mode change request
+ Qt::Key_Space, // 32 0x20 VK_SPACE | Spacebar
+ Qt::Key_PageUp, // 33 0x21 VK_PRIOR | Page Up key
+ Qt::Key_PageDown, // 34 0x22 VK_NEXT | Page Down key
+ Qt::Key_End, // 35 0x23 VK_END | End key
+ Qt::Key_Home, // 36 0x24 VK_HOME | Home key
+ Qt::Key_Left, // 37 0x25 VK_LEFT | Left arrow key
+ Qt::Key_Up, // 38 0x26 VK_UP | Up arrow key
+ Qt::Key_Right, // 39 0x27 VK_RIGHT | Right arrow key
+ Qt::Key_Down, // 40 0x28 VK_DOWN | Down arrow key
+ Qt::Key_Select, // 41 0x29 VK_SELECT | Select key
+ Qt::Key_Printer, // 42 0x2A VK_PRINT | Print key
+ Qt::Key_Execute, // 43 0x2B VK_EXECUTE | Execute key
+ Qt::Key_Print, // 44 0x2C VK_SNAPSHOT | Print Screen key
+ Qt::Key_Insert, // 45 0x2D VK_INSERT | Ins key
+ Qt::Key_Delete, // 46 0x2E VK_DELETE | Del key
+ Qt::Key_Help, // 47 0x2F VK_HELP | Help key
+ 0, // 48 0x30 (VK_0) | 0 key
+ 0, // 49 0x31 (VK_1) | 1 key
+ 0, // 50 0x32 (VK_2) | 2 key
+ 0, // 51 0x33 (VK_3) | 3 key
+ 0, // 52 0x34 (VK_4) | 4 key
+ 0, // 53 0x35 (VK_5) | 5 key
+ 0, // 54 0x36 (VK_6) | 6 key
+ 0, // 55 0x37 (VK_7) | 7 key
+ 0, // 56 0x38 (VK_8) | 8 key
+ 0, // 57 0x39 (VK_9) | 9 key
+ Qt::Key_unknown, // 58 0x3A -- unassigned --
+ Qt::Key_unknown, // 59 0x3B -- unassigned --
+ Qt::Key_unknown, // 60 0x3C -- unassigned --
+ Qt::Key_unknown, // 61 0x3D -- unassigned --
+ Qt::Key_unknown, // 62 0x3E -- unassigned --
+ Qt::Key_unknown, // 63 0x3F -- unassigned --
+ Qt::Key_unknown, // 64 0x40 -- unassigned --
+ 0, // 65 0x41 (VK_A) | A key
+ 0, // 66 0x42 (VK_B) | B key
+ 0, // 67 0x43 (VK_C) | C key
+ 0, // 68 0x44 (VK_D) | D key
+ 0, // 69 0x45 (VK_E) | E key
+ 0, // 70 0x46 (VK_F) | F key
+ 0, // 71 0x47 (VK_G) | G key
+ 0, // 72 0x48 (VK_H) | H key
+ 0, // 73 0x49 (VK_I) | I key
+ 0, // 74 0x4A (VK_J) | J key
+ 0, // 75 0x4B (VK_K) | K key
+ 0, // 76 0x4C (VK_L) | L key
+ 0, // 77 0x4D (VK_M) | M key
+ 0, // 78 0x4E (VK_N) | N key
+ 0, // 79 0x4F (VK_O) | O key
+ 0, // 80 0x50 (VK_P) | P key
+ 0, // 81 0x51 (VK_Q) | Q key
+ 0, // 82 0x52 (VK_R) | R key
+ 0, // 83 0x53 (VK_S) | S key
+ 0, // 84 0x54 (VK_T) | T key
+ 0, // 85 0x55 (VK_U) | U key
+ 0, // 86 0x56 (VK_V) | V key
+ 0, // 87 0x57 (VK_W) | W key
+ 0, // 88 0x58 (VK_X) | X key
+ 0, // 89 0x59 (VK_Y) | Y key
+ 0, // 90 0x5A (VK_Z) | Z key
+ Qt::Key_Meta, // 91 0x5B VK_LWIN | Left Windows - MS Natural kbd
+ Qt::Key_Meta, // 92 0x5C VK_RWIN | Right Windows - MS Natural kbd
+ Qt::Key_Menu, // 93 0x5D VK_APPS | Application key-MS Natural kbd
+ Qt::Key_unknown, // 94 0x5E -- reserved --
+ Qt::Key_Sleep, // 95 0x5F VK_SLEEP
+ Qt::Key_0, // 96 0x60 VK_NUMPAD0 | Numeric keypad 0 key
+ Qt::Key_1, // 97 0x61 VK_NUMPAD1 | Numeric keypad 1 key
+ Qt::Key_2, // 98 0x62 VK_NUMPAD2 | Numeric keypad 2 key
+ Qt::Key_3, // 99 0x63 VK_NUMPAD3 | Numeric keypad 3 key
+ Qt::Key_4, // 100 0x64 VK_NUMPAD4 | Numeric keypad 4 key
+ Qt::Key_5, // 101 0x65 VK_NUMPAD5 | Numeric keypad 5 key
+ Qt::Key_6, // 102 0x66 VK_NUMPAD6 | Numeric keypad 6 key
+ Qt::Key_7, // 103 0x67 VK_NUMPAD7 | Numeric keypad 7 key
+ Qt::Key_8, // 104 0x68 VK_NUMPAD8 | Numeric keypad 8 key
+ Qt::Key_9, // 105 0x69 VK_NUMPAD9 | Numeric keypad 9 key
+ Qt::Key_Asterisk, // 106 0x6A VK_MULTIPLY | Multiply key
+ Qt::Key_Plus, // 107 0x6B VK_ADD | Add key
+ Qt::Key_Comma, // 108 0x6C VK_SEPARATOR | Separator key
+ Qt::Key_Minus, // 109 0x6D VK_SUBTRACT | Subtract key
+ Qt::Key_Period, // 110 0x6E VK_DECIMAL | Decimal key
+ Qt::Key_Slash, // 111 0x6F VK_DIVIDE | Divide key
+ Qt::Key_F1, // 112 0x70 VK_F1 | F1 key
+ Qt::Key_F2, // 113 0x71 VK_F2 | F2 key
+ Qt::Key_F3, // 114 0x72 VK_F3 | F3 key
+ Qt::Key_F4, // 115 0x73 VK_F4 | F4 key
+ Qt::Key_F5, // 116 0x74 VK_F5 | F5 key
+ Qt::Key_F6, // 117 0x75 VK_F6 | F6 key
+ Qt::Key_F7, // 118 0x76 VK_F7 | F7 key
+ Qt::Key_F8, // 119 0x77 VK_F8 | F8 key
+ Qt::Key_F9, // 120 0x78 VK_F9 | F9 key
+ Qt::Key_F10, // 121 0x79 VK_F10 | F10 key
+ Qt::Key_F11, // 122 0x7A VK_F11 | F11 key
+ Qt::Key_F12, // 123 0x7B VK_F12 | F12 key
+ Qt::Key_F13, // 124 0x7C VK_F13 | F13 key
+ Qt::Key_F14, // 125 0x7D VK_F14 | F14 key
+ Qt::Key_F15, // 126 0x7E VK_F15 | F15 key
+ Qt::Key_F16, // 127 0x7F VK_F16 | F16 key
+ Qt::Key_F17, // 128 0x80 VK_F17 | F17 key
+ Qt::Key_F18, // 129 0x81 VK_F18 | F18 key
+ Qt::Key_F19, // 130 0x82 VK_F19 | F19 key
+ Qt::Key_F20, // 131 0x83 VK_F20 | F20 key
+ Qt::Key_F21, // 132 0x84 VK_F21 | F21 key
+ Qt::Key_F22, // 133 0x85 VK_F22 | F22 key
+ Qt::Key_F23, // 134 0x86 VK_F23 | F23 key
+ Qt::Key_F24, // 135 0x87 VK_F24 | F24 key
+ Qt::Key_unknown, // 136 0x88 -- unassigned --
+ Qt::Key_unknown, // 137 0x89 -- unassigned --
+ Qt::Key_unknown, // 138 0x8A -- unassigned --
+ Qt::Key_unknown, // 139 0x8B -- unassigned --
+ Qt::Key_unknown, // 140 0x8C -- unassigned --
+ Qt::Key_unknown, // 141 0x8D -- unassigned --
+ Qt::Key_unknown, // 142 0x8E -- unassigned --
+ Qt::Key_unknown, // 143 0x8F -- unassigned --
+ Qt::Key_NumLock, // 144 0x90 VK_NUMLOCK | Num Lock key
+ Qt::Key_ScrollLock, // 145 0x91 VK_SCROLL | Scroll Lock key
+ // Fujitsu/OASYS kbd --------------------
+ 0, //Qt::Key_Jisho, // 146 0x92 VK_OEM_FJ_JISHO | 'Dictionary' key /
+ // VK_OEM_NEC_EQUAL = key on numpad on NEC PC-9800 kbd
+ Qt::Key_Massyo, // 147 0x93 VK_OEM_FJ_MASSHOU | 'Unregister word' key
+ Qt::Key_Touroku, // 148 0x94 VK_OEM_FJ_TOUROKU | 'Register word' key
+ 0, //Qt::Key_Oyayubi_Left,//149 0x95 VK_OEM_FJ_LOYA | 'Left OYAYUBI' key
+ 0, //Qt::Key_Oyayubi_Right,//150 0x96 VK_OEM_FJ_ROYA | 'Right OYAYUBI' key
+ Qt::Key_unknown, // 151 0x97 -- unassigned --
+ Qt::Key_unknown, // 152 0x98 -- unassigned --
+ Qt::Key_unknown, // 153 0x99 -- unassigned --
+ Qt::Key_unknown, // 154 0x9A -- unassigned --
+ Qt::Key_unknown, // 155 0x9B -- unassigned --
+ Qt::Key_unknown, // 156 0x9C -- unassigned --
+ Qt::Key_unknown, // 157 0x9D -- unassigned --
+ Qt::Key_unknown, // 158 0x9E -- unassigned --
+ Qt::Key_unknown, // 159 0x9F -- unassigned --
+ Qt::Key_Shift, // 160 0xA0 VK_LSHIFT | Left Shift key
+ Qt::Key_Shift, // 161 0xA1 VK_RSHIFT | Right Shift key
+ Qt::Key_Control, // 162 0xA2 VK_LCONTROL | Left Ctrl key
+ Qt::Key_Control, // 163 0xA3 VK_RCONTROL | Right Ctrl key
+ Qt::Key_Alt, // 164 0xA4 VK_LMENU | Left Menu key
+ Qt::Key_Alt, // 165 0xA5 VK_RMENU | Right Menu key
+ Qt::Key_Back, // 166 0xA6 VK_BROWSER_BACK | Browser Back key
+ Qt::Key_Forward, // 167 0xA7 VK_BROWSER_FORWARD | Browser Forward key
+ Qt::Key_Refresh, // 168 0xA8 VK_BROWSER_REFRESH | Browser Refresh key
+ Qt::Key_Stop, // 169 0xA9 VK_BROWSER_STOP | Browser Stop key
+ Qt::Key_Search, // 170 0xAA VK_BROWSER_SEARCH | Browser Search key
+ Qt::Key_Favorites, // 171 0xAB VK_BROWSER_FAVORITES| Browser Favorites key
+ Qt::Key_HomePage, // 172 0xAC VK_BROWSER_HOME | Browser Start and Home key
+ Qt::Key_VolumeMute, // 173 0xAD VK_VOLUME_MUTE | Volume Mute key
+ Qt::Key_VolumeDown, // 174 0xAE VK_VOLUME_DOWN | Volume Down key
+ Qt::Key_VolumeUp, // 175 0xAF VK_VOLUME_UP | Volume Up key
+ Qt::Key_MediaNext, // 176 0xB0 VK_MEDIA_NEXT_TRACK | Next Track key
+ Qt::Key_MediaPrevious, //177 0xB1 VK_MEDIA_PREV_TRACK | Previous Track key
+ Qt::Key_MediaStop, // 178 0xB2 VK_MEDIA_STOP | Stop Media key
+ Qt::Key_MediaPlay, // 179 0xB3 VK_MEDIA_PLAY_PAUSE | Play/Pause Media key
+ Qt::Key_LaunchMail, // 180 0xB4 VK_LAUNCH_MAIL | Start Mail key
+ Qt::Key_LaunchMedia,// 181 0xB5 VK_LAUNCH_MEDIA_SELECT Select Media key
+ Qt::Key_Launch0, // 182 0xB6 VK_LAUNCH_APP1 | Start Application 1 key
+ Qt::Key_Launch1, // 183 0xB7 VK_LAUNCH_APP2 | Start Application 2 key
+ Qt::Key_unknown, // 184 0xB8 -- reserved --
+ Qt::Key_unknown, // 185 0xB9 -- reserved --
+ 0, // 186 0xBA VK_OEM_1 | ';:' for US
+ 0, // 187 0xBB VK_OEM_PLUS | '+' any country
+ 0, // 188 0xBC VK_OEM_COMMA | ',' any country
+ 0, // 189 0xBD VK_OEM_MINUS | '-' any country
+ 0, // 190 0xBE VK_OEM_PERIOD | '.' any country
+ 0, // 191 0xBF VK_OEM_2 | '/?' for US
+ 0, // 192 0xC0 VK_OEM_3 | '`~' for US
+ Qt::Key_unknown, // 193 0xC1 -- reserved --
+ Qt::Key_unknown, // 194 0xC2 -- reserved --
+ Qt::Key_unknown, // 195 0xC3 -- reserved --
+ Qt::Key_unknown, // 196 0xC4 -- reserved --
+ Qt::Key_unknown, // 197 0xC5 -- reserved --
+ Qt::Key_unknown, // 198 0xC6 -- reserved --
+ Qt::Key_unknown, // 199 0xC7 -- reserved --
+ Qt::Key_unknown, // 200 0xC8 -- reserved --
+ Qt::Key_unknown, // 201 0xC9 -- reserved --
+ Qt::Key_unknown, // 202 0xCA -- reserved --
+ Qt::Key_unknown, // 203 0xCB -- reserved --
+ Qt::Key_unknown, // 204 0xCC -- reserved --
+ Qt::Key_unknown, // 205 0xCD -- reserved --
+ Qt::Key_unknown, // 206 0xCE -- reserved --
+ Qt::Key_unknown, // 207 0xCF -- reserved --
+ Qt::Key_unknown, // 208 0xD0 -- reserved --
+ Qt::Key_unknown, // 209 0xD1 -- reserved --
+ Qt::Key_unknown, // 210 0xD2 -- reserved --
+ Qt::Key_unknown, // 211 0xD3 -- reserved --
+ Qt::Key_unknown, // 212 0xD4 -- reserved --
+ Qt::Key_unknown, // 213 0xD5 -- reserved --
+ Qt::Key_unknown, // 214 0xD6 -- reserved --
+ Qt::Key_unknown, // 215 0xD7 -- reserved --
+ Qt::Key_unknown, // 216 0xD8 -- unassigned --
+ Qt::Key_unknown, // 217 0xD9 -- unassigned --
+ Qt::Key_unknown, // 218 0xDA -- unassigned --
+ 0, // 219 0xDB VK_OEM_4 | '[{' for US
+ 0, // 220 0xDC VK_OEM_5 | '\|' for US
+ 0, // 221 0xDD VK_OEM_6 | ']}' for US
+ 0, // 222 0xDE VK_OEM_7 | ''"' for US
+ 0, // 223 0xDF VK_OEM_8
+ Qt::Key_unknown, // 224 0xE0 -- reserved --
+ Qt::Key_unknown, // 225 0xE1 VK_OEM_AX | 'AX' key on Japanese AX kbd
+ Qt::Key_unknown, // 226 0xE2 VK_OEM_102 | "<>" or "\|" on RT 102-key kbd
+ Qt::Key_unknown, // 227 0xE3 VK_ICO_HELP | Help key on ICO
+ Qt::Key_unknown, // 228 0xE4 VK_ICO_00 | 00 key on ICO
+ Qt::Key_unknown, // 229 0xE5 VK_PROCESSKEY | IME Process key
+ Qt::Key_unknown, // 230 0xE6 VK_ICO_CLEAR |
+ Qt::Key_unknown, // 231 0xE7 VK_PACKET | Unicode char as keystrokes
+ Qt::Key_unknown, // 232 0xE8 -- unassigned --
+ // Nokia/Ericsson definitions ---------------
+ Qt::Key_unknown, // 233 0xE9 VK_OEM_RESET
+ Qt::Key_unknown, // 234 0xEA VK_OEM_JUMP
+ Qt::Key_unknown, // 235 0xEB VK_OEM_PA1
+ Qt::Key_unknown, // 236 0xEC VK_OEM_PA2
+ Qt::Key_unknown, // 237 0xED VK_OEM_PA3
+ Qt::Key_unknown, // 238 0xEE VK_OEM_WSCTRL
+ Qt::Key_unknown, // 239 0xEF VK_OEM_CUSEL
+ Qt::Key_unknown, // 240 0xF0 VK_OEM_ATTN
+ Qt::Key_unknown, // 241 0xF1 VK_OEM_FINISH
+ Qt::Key_unknown, // 242 0xF2 VK_OEM_COPY
+ Qt::Key_unknown, // 243 0xF3 VK_OEM_AUTO
+ Qt::Key_unknown, // 244 0xF4 VK_OEM_ENLW
+ Qt::Key_unknown, // 245 0xF5 VK_OEM_BACKTAB
+ Qt::Key_unknown, // 246 0xF6 VK_ATTN | Attn key
+ Qt::Key_unknown, // 247 0xF7 VK_CRSEL | CrSel key
+ Qt::Key_unknown, // 248 0xF8 VK_EXSEL | ExSel key
+ Qt::Key_unknown, // 249 0xF9 VK_EREOF | Erase EOF key
+ Qt::Key_Play, // 250 0xFA VK_PLAY | Play key
+ Qt::Key_Zoom, // 251 0xFB VK_ZOOM | Zoom key
+ Qt::Key_unknown, // 252 0xFC VK_NONAME | Reserved
+ Qt::Key_unknown, // 253 0xFD VK_PA1 | PA1 key
+ Qt::Key_Clear, // 254 0xFE VK_OEM_CLEAR | Clear key
+ 0
+};
+
+// Possible modifier states.
+// NOTE: The order of these states match the order in QWindowsKeyMapper::updatePossibleKeyCodes()!
+static const Qt::KeyboardModifiers ModsTbl[] = {
+ Qt::NoModifier, // 0
+ Qt::ShiftModifier, // 1
+ Qt::ControlModifier, // 2
+ Qt::ControlModifier | Qt::ShiftModifier, // 3
+ Qt::AltModifier, // 4
+ Qt::AltModifier | Qt::ShiftModifier, // 5
+ Qt::AltModifier | Qt::ControlModifier, // 6
+ Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
+ Qt::NoModifier, // Fall-back to raw Key_*
+};
+
+/**
+ Remap return or action key to select key for windows mobile.
+*/
+inline int winceKeyBend(int keyCode)
+{
+ return KeyTbl[keyCode];
+}
+
+// Translate a VK into a Qt key code, or unicode character
+static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, bool *isDeadkey = 0)
+{
+ Q_ASSERT(vk > 0 && vk < 256);
+ int code = 0;
+ QChar unicodeBuffer[5];
+ int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
+ if (res)
+ code = unicodeBuffer[0].toUpper().unicode();
+
+ // Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a
+ // proper Qt::Key_ code
+ if (code < 0x20 || code == 0x7f) // Handles res==0 too
+ code = winceKeyBend(vk);
+
+ if (isDeadkey)
+ *isDeadkey = (res == -1);
+
+ return code == Qt::Key_unknown ? 0 : code;
+}
+
+int qt_translateKeyCode(int vk)
+{
+ int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk);
+ return code == Qt::Key_unknown ? 0 : code;
+}
+
+static inline int asciiToKeycode(char a, int state)
+{
+ if (a >= 'a' && a <= 'z')
+ a = toupper(a);
+ if ((state & Qt::ControlModifier) != 0) {
+ if (a >= 0 && a <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
+ a += '@'; // to @..A..Z.._
+ }
+ return a & 0xff;
+}
+
+static inline bool isModifierKey(int code)
+{
+ return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock);
+}
+// Key translation -----------------------------------------------------------------------[ end ]---
+
+
+// Keyboard map private ----------------------------------------------------------------[ start ]---
+
+/*
+ \internal
+ A Windows KeyboardLayoutItem has 8 possible states:
+ 1. Unmodified
+ 2. Shift
+ 3. Control
+ 4. Control + Shift
+ 5. Alt
+ 6. Alt + Shift
+ 7. Alt + Control
+ 8. Alt + Control + Shift
+*/
+struct KeyboardLayoutItem {
+ bool dirty;
+ quint8 deadkeys;
+ quint32 qtKey[9]; // Can by any Qt::Key_<foo>, or unicode character
+};
+
+void QWindowsKeyMapper::deleteLayouts()
+{
+ for (int i = 0; i < 255; ++i) {
+ if (keyLayout[i]) {
+ delete keyLayout[i];
+ keyLayout[i] = 0;
+ }
+ }
+}
+
+void QWindowsKeyMapper::changeKeyboard()
+{
+ deleteLayouts();
+
+ /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout()
+ * returns a DWORD. */
+
+ LCID newLCID = MAKELCID((quintptr)GetKeyboardLayout(0), SORT_DEFAULT);
+// keyboardInputLocale = qt_localeFromLCID(newLCID);
+
+ bool bidi = false;
+ wchar_t LCIDFontSig[16];
+ if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t))
+ && (LCIDFontSig[7] & (wchar_t)0x0800))
+ bidi = true;
+
+ keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight;
+}
+
+void QWindowsKeyMapper::clearRecordedKeys()
+{
+ key_recorder.clearKeys();
+}
+
+
+inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt)
+{
+ kbd[VK_LSHIFT ] = (shift ? 0x80 : 0);
+ kbd[VK_SHIFT ] = (shift ? 0x80 : 0);
+ kbd[VK_LCONTROL] = (ctrl ? 0x80 : 0);
+ kbd[VK_CONTROL ] = (ctrl ? 0x80 : 0);
+ kbd[VK_RMENU ] = (alt ? 0x80 : 0);
+ kbd[VK_MENU ] = (alt ? 0x80 : 0);
+}
+
+void QWindowsKeyMapper::updateKeyMap(const MSG &msg)
+{
+ unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
+ GetKeyboardState(kbdBuffer);
+ quint32 scancode = (msg.lParam >> 16) & 0xfff;
+ updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam);
+}
+
+void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode,
+ quint32 vk_key)
+{
+ if (!vk_key || (keyLayout[vk_key] && !keyLayout[vk_key]->dirty))
+ return;
+
+ if (!keyLayout[vk_key])
+ keyLayout[vk_key] = new KeyboardLayoutItem;
+
+ // Copy keyboard state, so we can modify and query output for each possible permutation
+ unsigned char buffer[256];
+ memcpy(buffer, kbdBuffer, sizeof(buffer));
+ // Always 0, as Windows doesn't treat these as modifiers;
+ buffer[VK_LWIN ] = 0;
+ buffer[VK_RWIN ] = 0;
+ buffer[VK_CAPITAL ] = 0;
+ buffer[VK_NUMLOCK ] = 0;
+ buffer[VK_SCROLL ] = 0;
+ // Always 0, since we'll only change the other versions
+ buffer[VK_RSHIFT ] = 0;
+ buffer[VK_RCONTROL] = 0;
+ buffer[VK_LMENU ] = 0; // Use right Alt, since left Ctrl + right Alt is considered AltGraph
+
+ bool isDeadKey = false;
+ keyLayout[vk_key]->deadkeys = 0;
+ keyLayout[vk_key]->dirty = false;
+ setKbdState(buffer, false, false, false);
+ keyLayout[vk_key]->qtKey[0] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x01 : 0;
+ setKbdState(buffer, true, false, false);
+ keyLayout[vk_key]->qtKey[1] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x02 : 0;
+ setKbdState(buffer, false, true, false);
+ keyLayout[vk_key]->qtKey[2] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x04 : 0;
+ setKbdState(buffer, true, true, false);
+ keyLayout[vk_key]->qtKey[3] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x08 : 0;
+ setKbdState(buffer, false, false, true);
+ keyLayout[vk_key]->qtKey[4] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x10 : 0;
+ setKbdState(buffer, true, false, true);
+ keyLayout[vk_key]->qtKey[5] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x20 : 0;
+ setKbdState(buffer, false, true, true);
+ keyLayout[vk_key]->qtKey[6] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x40 : 0;
+ setKbdState(buffer, true, true, true);
+ keyLayout[vk_key]->qtKey[7] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x80 : 0;
+ // Add a fall back key for layouts which don't do composition and show non-latin1 characters
+ int fallbackKey = winceKeyBend(vk_key);
+ if (!fallbackKey || fallbackKey == Qt::Key_unknown) {
+ fallbackKey = 0;
+ if (vk_key != keyLayout[vk_key]->qtKey[0] && vk_key < 0x5B && vk_key > 0x2F)
+ fallbackKey = vk_key;
+ }
+ keyLayout[vk_key]->qtKey[8] = fallbackKey;
+
+ // If this vk_key a Dead Key
+ if (MapVirtualKey(vk_key, 2) & 0x80000000) {
+ // Push a Space, then the original key through the low-level ToAscii functions.
+ // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of
+ // the keyboard driver By doing the following, we set the keyboard driver state back to what
+ // it was before we wrecked it with the code above.
+ // We need to push the space with an empty keystate map, since the driver checks the map for
+ // transitions in modifiers, so this helps us capture all possible deadkeys.
+ unsigned char emptyBuffer[256];
+ memset(emptyBuffer, 0, sizeof(emptyBuffer));
+ ::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);
+ for (int i = 0; i < 9; ++i) {
+ qDebug(" [%d] (%d,0x%02x,'%c') %s", 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" : "");
+ }
+ }
+}
+
+bool QWindowsKeyMapper::isADeadKey(unsigned int vk_key, unsigned int modifiers)
+{
+ if (keyLayout && (vk_key < 256) && keyLayout[vk_key]) {
+ for (register int i = 0; i < 9; ++i) {
+ if (uint(ModsTbl[i]) == modifiers)
+ return bool(keyLayout[vk_key]->deadkeys & 1<<i);
+ }
+ }
+ return false;
+}
+
+static inline QString messageKeyText(const MSG &msg)
+{
+ const QChar ch = QChar((ushort)msg.wParam);
+ return ch.isNull() ? QString() : QString(ch);
+}
+
+static void showSystemMenu(QWindow* w)
+{
+ QWindow *topLevel = QWindowsWindow::topLevelOf(w);
+ HWND topLevelHwnd = QWindowsWindow::handleOf(topLevel);
+ HMENU menu = GetSystemMenu(topLevelHwnd, FALSE);
+ if (!menu)
+ return; // no menu for this window
+
+#define enabled (MF_BYCOMMAND | MF_ENABLED)
+#define disabled (MF_BYCOMMAND | MF_GRAYED)
+
+ EnableMenuItem(menu, SC_MINIMIZE, (topLevel->windowFlags() & Qt::WindowMinimizeButtonHint)?enabled:disabled);
+ bool maximized = IsZoomed(topLevelHwnd);
+
+ EnableMenuItem(menu, SC_MAXIMIZE, ! (topLevel->windowFlags() & Qt::WindowMaximizeButtonHint) || maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_RESTORE, maximized?enabled:disabled);
+
+ // We should _not_ check with the setFixedSize(x,y) case here, since Windows is not able to check
+ // this and our menu here would be out-of-sync with the menu produced by mouse-click on the
+ // System Menu, or right-click on the title bar.
+ EnableMenuItem(menu, SC_SIZE, (topLevel->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) || maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_MOVE, maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_CLOSE, enabled);
+ // Set bold on close menu item
+ MENUITEMINFO closeItem;
+ closeItem.cbSize = sizeof(MENUITEMINFO);
+ closeItem.fMask = MIIM_STATE;
+ closeItem.fState = MFS_DEFAULT;
+ SetMenuItemInfo(menu, SC_CLOSE, FALSE, &closeItem);
+
+#undef enabled
+#undef disabled
+ const int ret = TrackPopupMenuEx(menu,
+ TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
+ topLevel->geometry().x(), topLevel->geometry().y(),
+ topLevelHwnd,
+ 0);
+ if (ret)
+ qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, ret, 0);
+}
+
+static inline void sendExtendedPressRelease(QWindow *w, int k,
+ Qt::KeyboardModifiers mods,
+ quint32 nativeScanCode,
+ quint32 nativeVirtualKey,
+ quint32 nativeModifiers,
+ const QString & text = QString(),
+ bool autorep = false,
+ ushort count = 1)
+{
+ QWindowSystemInterface::handleExtendedKeyEvent(w, QEvent::KeyPress, k, mods, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
+ QWindowSystemInterface::handleExtendedKeyEvent(w, QEvent::KeyRelease, k, mods, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
+}
+
+/*!
+ \brief To be called from the window procedure.
+*/
+
+bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd,
+ const MSG &msg, LRESULT *result)
+{
+ *result = 0;
+ MSG peekedMsg;
+ // consume dead chars?(for example, typing '`','a' resulting in a-accent).
+ if (PeekMessage(&peekedMsg, hwnd, 0, 0, PM_NOREMOVE) && peekedMsg.message == WM_DEADCHAR)
+ return true;
+ if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
+ updateKeyMap(msg);
+ return translateKeyEventInternal(widget, msg, false);
+}
+
+bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &msg, bool /* grab */)
+{
+ const int msgType = msg.message;
+
+ const quint32 scancode = (msg.lParam >> 16) & 0xfff;
+ const quint32 vk_key = MapVirtualKey(scancode, 1);
+ const bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9);
+ quint32 nModifiers = 0;
+
+ QWindow *receiver = m_keyGrabber ? m_keyGrabber : window;
+
+ // Map native modifiers to some bit representation
+ nModifiers |= (GetKeyState(VK_LSHIFT ) & 0x80 ? ShiftLeft : 0);
+ nModifiers |= (GetKeyState(VK_RSHIFT ) & 0x80 ? ShiftRight : 0);
+ nModifiers |= (GetKeyState(VK_LCONTROL) & 0x80 ? ControlLeft : 0);
+ nModifiers |= (GetKeyState(VK_RCONTROL) & 0x80 ? ControlRight : 0);
+ nModifiers |= (GetKeyState(VK_LMENU ) & 0x80 ? AltLeft : 0);
+ nModifiers |= (GetKeyState(VK_RMENU ) & 0x80 ? AltRight : 0);
+ nModifiers |= (GetKeyState(VK_LWIN ) & 0x80 ? MetaLeft : 0);
+ nModifiers |= (GetKeyState(VK_RWIN ) & 0x80 ? MetaRight : 0);
+ // Add Lock keys to the same bits
+ nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0);
+ nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0);
+ nModifiers |= (GetKeyState(VK_SCROLL ) & 0x01 ? ScrollLock : 0);
+
+ if (msg.lParam & ExtendedKey)
+ nModifiers |= msg.lParam & ExtendedKey;
+
+ // Get the modifier states (may be altered later, depending on key code)
+ int state = 0;
+ state |= (nModifiers & ShiftAny ? Qt::ShiftModifier : 0);
+ state |= (nModifiers & ControlAny ? Qt::ControlModifier : 0);
+ state |= (nModifiers & AltAny ? Qt::AltModifier : 0);
+ state |= (nModifiers & MetaAny ? Qt::MetaModifier : 0);
+
+ // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey
+ const bool isDeadKey = isADeadKey(msg.wParam, state)
+ || MapVirtualKey(msg.wParam, 2) & 0x80000000;
+
+ // A multi-character key or a Input method character
+ // not found by our look-ahead
+ if (msgType == WM_CHAR || msgType == WM_IME_CHAR) {
+ sendExtendedPressRelease(receiver, 0, Qt::KeyboardModifier(state), scancode, vk_key, nModifiers, messageKeyText(msg), false, 0);
+ return true;
+ }
+
+ bool result = false;
+ // handle Directionality changes (BiDi) with RTL extensions
+ if (m_useRTLExtensions) {
+ static int dirStatus = 0;
+ if (!dirStatus && state == Qt::ControlModifier
+ && msg.wParam == VK_CONTROL
+ && msgType == WM_KEYDOWN) {
+ if (GetKeyState(VK_LCONTROL) < 0)
+ dirStatus = VK_LCONTROL;
+ else if (GetKeyState(VK_RCONTROL) < 0)
+ dirStatus = VK_RCONTROL;
+ } else if (dirStatus) {
+ if (msgType == WM_KEYDOWN) {
+ if (msg.wParam == VK_SHIFT) {
+ if (dirStatus == VK_LCONTROL && GetKeyState(VK_LSHIFT) < 0)
+ dirStatus = VK_LSHIFT;
+ else if (dirStatus == VK_RCONTROL && GetKeyState(VK_RSHIFT) < 0)
+ dirStatus = VK_RSHIFT;
+ } else {
+ dirStatus = 0;
+ }
+ } else if (msgType == WM_KEYUP) {
+ if (dirStatus == VK_LSHIFT
+ && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL))
+ || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) {
+ sendExtendedPressRelease(receiver, Qt::Key_Direction_L, 0, scancode, msg.wParam, nModifiers, QString(), false, 0);
+ result = true;
+ dirStatus = 0;
+ } else if (dirStatus == VK_RSHIFT
+ && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL))
+ || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) {
+ sendExtendedPressRelease(receiver, Qt::Key_Direction_R, 0, scancode, msg.wParam, nModifiers, QString(), false, 0);
+ result = true;
+ dirStatus = 0;
+ } else {
+ dirStatus = 0;
+ }
+ } else {
+ dirStatus = 0;
+ }
+ }
+ } // RTL
+
+ // IME will process these keys, so simply return
+ if (msg.wParam == VK_PROCESSKEY)
+ return true;
+
+ // Ignore invalid virtual keycodes (see bugs 127424, QTBUG-3630)
+ if (msg.wParam == 0 || msg.wParam == 0xFF)
+ return true;
+
+ // Translate VK_* (native) -> Key_* (Qt) keys
+ // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change
+ // the internal state of the keyboard driver, resulting in that dead keys no longer works.
+ // ..also if we're typing numbers on the keypad, while holding down the Alt modifier.
+ int code = 0;
+ if (isNumpad && (nModifiers & AltAny)) {
+ code = winceKeyBend(msg.wParam);
+ } else if (!isDeadKey) {
+ unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
+ GetKeyboardState(kbdBuffer);
+ code = toKeyOrUnicode(msg.wParam, scancode, kbdBuffer);
+ }
+
+ // Invert state logic:
+ // If the key actually pressed is a modifier key, then we remove its modifier key from the
+ // state, since a modifier-key can't have itself as a modifier
+ if (code == Qt::Key_Control)
+ state = state ^ Qt::ControlModifier;
+ else if (code == Qt::Key_Shift)
+ state = state ^ Qt::ShiftModifier;
+ else if (code == Qt::Key_Alt)
+ state = state ^ Qt::AltModifier;
+
+ // If the bit 24 of lParm is set you received a enter,
+ // otherwise a Return. (This is the extended key bit)
+ if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
+ code = Qt::Key_Enter;
+
+ // All cursor keys without extended bit
+ if (!(msg.lParam & 0x1000000)) {
+ switch (code) {
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Insert:
+ case Qt::Key_Delete:
+ case Qt::Key_Asterisk:
+ case Qt::Key_Plus:
+ case Qt::Key_Minus:
+ case Qt::Key_Period:
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ state |= ((msg.wParam >= '0' && msg.wParam <= '9')
+ || (msg.wParam >= VK_OEM_PLUS && msg.wParam <= VK_OEM_3))
+ ? 0 : Qt::KeypadModifier;
+ default:
+ if ((uint)msg.lParam == 0x004c0001 || (uint)msg.lParam == 0xc04c0001)
+ state |= Qt::KeypadModifier;
+ break;
+ }
+ }
+ // Other keys with with extended bit
+ else {
+ switch (code) {
+ case Qt::Key_Enter:
+ case Qt::Key_Slash:
+ case Qt::Key_NumLock:
+ state |= Qt::KeypadModifier;
+ default:
+ break;
+ }
+ }
+
+ // KEYDOWN ---------------------------------------------------------------------------------
+ if (msgType == WM_KEYDOWN || msgType == WM_IME_KEYDOWN || msgType == WM_SYSKEYDOWN) {
+ // Get the last record of this key press, so we can validate the current state
+ // The record is not removed from the list
+ KeyRecord *rec = key_recorder.findKey(msg.wParam, false);
+
+ // If rec's state doesn't match the current state, something has changed behind our back
+ // (Consumed by modal widget is one possibility) So, remove the record from the list
+ // This will stop the auto-repeat of the key, should a modifier change, for example
+ if (rec && rec->state != state) {
+ key_recorder.findKey(msg.wParam, true);
+ rec = 0;
+ }
+
+ // Find unicode character from Windows Message Queue
+ MSG wm_char;
+ UINT charType = (msgType == WM_KEYDOWN
+ ? WM_CHAR
+ : msgType == WM_IME_KEYDOWN ? WM_IME_CHAR : WM_SYSCHAR);
+
+ QChar uch;
+ if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) {
+ // Found a ?_CHAR
+ uch = QChar((ushort)wm_char.wParam);
+ if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN))
+ uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter
+ if (!code && !uch.row())
+ code = asciiToKeycode(uch.cell(), state);
+ }
+
+ // Special handling for the WM_IME_KEYDOWN message. Microsoft IME (Korean) will not
+ // generate a WM_IME_CHAR message corresponding to this message. We might get wrong
+ // results, if we map this virtual key-code directly (for eg '?' US layouts). So try
+ // to find the correct key using the current message parameters & keyboard state.
+ if (uch.isNull() && msgType == WM_IME_KEYDOWN) {
+ BYTE keyState[256];
+ wchar_t newKey[3] = {0};
+ GetKeyboardState(keyState);
+ int val = ToUnicode(vk_key, scancode, keyState, newKey, 2, 0);
+ if (val == 1) {
+ uch = QChar(newKey[0]);
+ } else {
+ // If we are still not able to find a unicode key, pass the WM_IME_KEYDOWN
+ // message to DefWindowProc() for generating a proper WM_KEYDOWN.
+ return false;
+ }
+ }
+
+ // If no ?_CHAR was found in the queue; deduct character from the ?_KEYDOWN parameters
+ if (uch.isNull()) {
+ if (msg.wParam == VK_DELETE) {
+ uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one.
+ } else {
+ if (msgType != WM_SYSKEYDOWN || !code) {
+ UINT map = MapVirtualKey(msg.wParam, 2);
+ // If the high bit of the return value is set, it's a deadkey
+ if (!(map & 0x80000000))
+ uch = QChar((ushort)map);
+ }
+ }
+ if (!code && !uch.row())
+ code = asciiToKeycode(uch.cell(), state);
+ }
+
+ // Special handling of global Windows hotkeys
+ if (state == Qt::AltModifier) {
+ switch (code) {
+ case Qt::Key_Escape:
+ case Qt::Key_Tab:
+ case Qt::Key_Enter:
+ case Qt::Key_F4:
+ return false; // Send the event on to Windows
+ case Qt::Key_Space:
+ // do not pass this key to windows, we will process it ourselves
+ showSystemMenu(receiver);
+ return true;
+ default:
+ break;
+ }
+ }
+
+ // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
+ if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
+ code = Qt::Key_Backtab;
+
+ // If we have a record, it means that the key is already pressed, the state is the same
+ // so, we have an auto-repeating key
+ if (rec) {
+ if (code < Qt::Key_Shift || code > Qt::Key_ScrollLock) {
+ QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code,
+ Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, rec->text, true, 0);
+ QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code,
+ Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, rec->text, true, 0);
+ result = true;
+ }
+ }
+ // No record of the key being previous pressed, so we now send a QEvent::KeyPress event,
+ // and store the key data into our records.
+ else {
+ const QString text = uch.isNull() ? QString() : QString(uch);
+ const char a = uch.row() ? 0 : uch.cell();
+ key_recorder.storeKey(msg.wParam, a, state, text);
+ QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code,
+ Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, text, false, 0);
+ result =true;
+ bool store = true;
+ // Alt+<alphanumerical> go to the Win32 menu system if unhandled by Qt
+ if (msgType == WM_SYSKEYDOWN && !result && a) {
+ HWND parent = GetParent(QWindowsWindow::handleOf(receiver));
+ while (parent) {
+ if (GetMenu(parent)) {
+ SendMessage(parent, WM_SYSCOMMAND, SC_KEYMENU, a);
+ store = false;
+ result = true;
+ break;
+ }
+ parent = GetParent(parent);
+ }
+ }
+ if (!store)
+ key_recorder.findKey(msg.wParam, true);
+ }
+ }
+
+ // KEYUP -----------------------------------------------------------------------------------
+ else {
+ // Try to locate the key in our records, and remove it if it exists.
+ // The key may not be in our records if, for example, the down event was handled by
+ // win32 natively, or our window gets focus while a key is already press, but now gets
+ // the key release event.
+ KeyRecord* rec = key_recorder.findKey(msg.wParam, true);
+ if (!rec && !(code == Qt::Key_Shift
+ || code == Qt::Key_Control
+ || code == Qt::Key_Meta
+ || code == Qt::Key_Alt)) {
+ // Someone ate the key down event
+ } else {
+ if (!code)
+ code = asciiToKeycode(rec->ascii ? rec->ascii : msg.wParam, state);
+
+ // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
+ if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
+ code = Qt::Key_Backtab;
+ QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code,
+ Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers,
+ (rec ? rec->text : QString()), false, 0);
+ result = true;
+ // don't pass Alt to Windows unless we are embedded in a non-Qt window
+ if (code == Qt::Key_Alt) {
+ const QWindowsContext *context = QWindowsContext::instance();
+ HWND parent = GetParent(QWindowsWindow::handleOf(receiver));
+ while (parent) {
+ if (!context->findPlatformWindow(parent) && GetMenu(parent)) {
+ result = false;
+ break;
+ }
+ parent = GetParent(parent);
+ }
+ }
+ }
+ }
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h
new file mode 100644
index 0000000000..0d50193730
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowskeymapper.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSKEYMAPPER_H
+#define QWINDOWSKEYMAPPER_H
+
+#include "qtwindows_additional.h"
+
+#include <QtCore/QLocale>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+
+struct KeyboardLayoutItem;
+
+class QWindowsKeyMapper
+{
+ Q_DISABLE_COPY(QWindowsKeyMapper)
+public:
+ explicit QWindowsKeyMapper();
+ ~QWindowsKeyMapper();
+
+ void changeKeyboard();
+
+ void setUseRTLExtensions(bool e) { m_useRTLExtensions = e; }
+ bool useRTLExtensions() const { return m_useRTLExtensions; }
+
+ bool translateKeyEvent(QWindow *widget, HWND hwnd, const MSG &msg, LRESULT *result);
+
+ QWindow *keyGrabber() const { return m_keyGrabber; }
+ void setKeyGrabber(QWindow *w) { m_keyGrabber = w; }
+
+private:
+ bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab);
+ void updateKeyMap(const MSG &msg);
+
+ bool m_useRTLExtensions;
+
+ QLocale keyboardInputLocale;
+ Qt::LayoutDirection keyboardInputDirection;
+
+ void clearRecordedKeys();
+ void updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode, quint32 vk_key);
+ bool isADeadKey(unsigned int vk_key, unsigned int modifiers);
+ void deleteLayouts();
+
+ KeyboardLayoutItem *keyLayout[256];
+ QWindow *m_keyGrabber;
+};
+
+enum WindowsNativeModifiers {
+ ShiftLeft = 0x00000001,
+ ControlLeft = 0x00000002,
+ AltLeft = 0x00000004,
+ MetaLeft = 0x00000008,
+ ShiftRight = 0x00000010,
+ ControlRight = 0x00000020,
+ AltRight = 0x00000040,
+ MetaRight = 0x00000080,
+ CapsLock = 0x00000100,
+ NumLock = 0x00000200,
+ ScrollLock = 0x00000400,
+ ExtendedKey = 0x01000000,
+
+ // Convenience mappings
+ ShiftAny = 0x00000011,
+ ControlAny = 0x00000022,
+ AltAny = 0x00000044,
+ MetaAny = 0x00000088,
+ LockAny = 0x00000700
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSKEYMAPPER_H
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
new file mode 100644
index 0000000000..09104a43cf
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -0,0 +1,1557 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsmime.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/private/qdnd_p.h>
+#include <QtCore/QTextCodec>
+#include <QtCore/QMap>
+#include <QtCore/QUrl>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QBuffer>
+#include <QtGui/QImageReader>
+#include <QtGui/QImageWriter>
+
+#include <shlobj.h>
+
+QT_BEGIN_NAMESPACE
+
+/* The MSVC compilers allows multi-byte characters, that has the behavior of
+ * that each character gets shifted into position. 0x73524742 below is for MSVC
+ * equivalent to doing 'sRGB', but this does of course not work
+ * on conformant C++ compilers. */
+#define BMP_LCS_sRGB 0x73524742
+#define BMP_LCS_GM_IMAGES 0x00000004L
+
+struct _CIEXYZ {
+ long ciexyzX, ciexyzY, ciexyzZ;
+};
+
+struct _CIEXYZTRIPLE {
+ _CIEXYZ ciexyzRed, ciexyzGreen, ciexyzBlue;
+};
+
+struct BMP_BITMAPV5HEADER {
+ DWORD bV5Size;
+ LONG bV5Width;
+ LONG bV5Height;
+ WORD bV5Planes;
+ WORD bV5BitCount;
+ DWORD bV5Compression;
+ DWORD bV5SizeImage;
+ LONG bV5XPelsPerMeter;
+ LONG bV5YPelsPerMeter;
+ DWORD bV5ClrUsed;
+ DWORD bV5ClrImportant;
+ DWORD bV5RedMask;
+ DWORD bV5GreenMask;
+ DWORD bV5BlueMask;
+ DWORD bV5AlphaMask;
+ DWORD bV5CSType;
+ _CIEXYZTRIPLE bV5Endpoints;
+ DWORD bV5GammaRed;
+ DWORD bV5GammaGreen;
+ DWORD bV5GammaBlue;
+ DWORD bV5Intent;
+ DWORD bV5ProfileData;
+ DWORD bV5ProfileSize;
+ DWORD bV5Reserved;
+};
+static const int BMP_BITFIELDS = 3;
+
+static const char dibFormatC[] = "dib";
+
+static inline QByteArray msgConversionError(const char *func, const char *format)
+{
+ QByteArray msg = func;
+ msg += ": Unable to convert DIB image. The image converter plugin for '";
+ msg += format;
+ msg += "' is not available. Available formats: ";
+ foreach (const QByteArray &af, QImageReader::supportedImageFormats()) {
+ msg += af;
+ msg += ' ';
+ }
+ return msg;
+}
+
+static inline QImage readDib(QByteArray data)
+{
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+ QImageReader reader(&buffer, dibFormatC);
+ if (!reader.canRead()) {
+ qWarning("%s", msgConversionError(__FUNCTION__, dibFormatC).constData());
+ return QImage();
+ }
+ return reader.read();
+}
+
+static QByteArray writeDib(const QImage &img)
+{
+ QByteArray ba;
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::ReadWrite);
+ QImageWriter writer(&buffer, dibFormatC);
+ if (!writer.canWrite()) {
+ qWarning("%s", msgConversionError(__FUNCTION__, dibFormatC).constData());
+ return ba;
+ }
+ if (!writer.write(img))
+ ba.clear();
+ return ba;
+}
+
+static bool qt_write_dibv5(QDataStream &s, QImage image)
+{
+ QIODevice* d = s.device();
+ if (!d->isWritable())
+ return false;
+
+ //depth will be always 32
+ int bpl_bmp = image.width()*4;
+
+ BMP_BITMAPV5HEADER bi ={0};
+ bi.bV5Size = sizeof(BMP_BITMAPV5HEADER);
+ bi.bV5Width = image.width();
+ bi.bV5Height = image.height();
+ bi.bV5Planes = 1;
+ bi.bV5BitCount = 32;
+ bi.bV5Compression = BI_BITFIELDS;
+ bi.bV5SizeImage = bpl_bmp*image.height();
+ bi.bV5XPelsPerMeter = 0;
+ bi.bV5YPelsPerMeter = 0;
+ bi.bV5ClrUsed = 0;
+ bi.bV5ClrImportant = 0;
+ bi.bV5BlueMask = 0x000000ff;
+ bi.bV5GreenMask = 0x0000ff00;
+ bi.bV5RedMask = 0x00ff0000;
+ bi.bV5AlphaMask = 0xff000000;
+ bi.bV5CSType = BMP_LCS_sRGB; //LCS_sRGB
+ bi.bV5Intent = BMP_LCS_GM_IMAGES; //LCS_GM_IMAGES
+
+ d->write(reinterpret_cast<const char*>(&bi), bi.bV5Size);
+ if (s.status() != QDataStream::Ok)
+ return false;
+
+ DWORD colorSpace[3] = {0x00ff0000,0x0000ff00,0x000000ff};
+ d->write(reinterpret_cast<const char*>(colorSpace), sizeof(colorSpace));
+ if (s.status() != QDataStream::Ok)
+ return false;
+
+ if (image.format() != QImage::Format_ARGB32)
+ image = image.convertToFormat(QImage::Format_ARGB32);
+
+ uchar *buf = new uchar[bpl_bmp];
+ uchar *b;
+
+ memset(buf, 0, bpl_bmp);
+ for (int y=image.height()-1; y>=0; y--) {
+ // write the image bits
+ QRgb *p = (QRgb *)image.scanLine(y);
+ QRgb *end = p + image.width();
+ b = buf;
+ while (p < end) {
+ int alpha = qAlpha(*p);
+ if (alpha) {
+ *b++ = qBlue(*p);
+ *b++ = qGreen(*p);
+ *b++ = qRed(*p);
+ } else {
+ //white for fully transparent pixels.
+ *b++ = 0xff;
+ *b++ = 0xff;
+ *b++ = 0xff;
+ }
+ *b++ = alpha;
+ p++;
+ }
+ d->write((char*)buf, bpl_bmp);
+ if (s.status() != QDataStream::Ok) {
+ delete[] buf;
+ return false;
+ }
+ }
+ delete[] buf;
+ return true;
+}
+
+static int calc_shift(int mask)
+{
+ int result = 0;
+ while (!(mask & 1)) {
+ result++;
+ mask >>= 1;
+ }
+ return result;
+}
+
+//Supports only 32 bit DIBV5
+static bool qt_read_dibv5(QDataStream &s, QImage &image)
+{
+ BMP_BITMAPV5HEADER bi;
+ QIODevice* d = s.device();
+ if (d->atEnd())
+ return false;
+
+ d->read((char *)&bi, sizeof(bi)); // read BITMAPV5HEADER header
+ if (s.status() != QDataStream::Ok)
+ return false;
+
+ int nbits = bi.bV5BitCount;
+ int comp = bi.bV5Compression;
+ if (nbits != 32 || bi.bV5Planes != 1 || comp != BMP_BITFIELDS)
+ return false; //Unsupported DIBV5 format
+
+ int w = bi.bV5Width, h = bi.bV5Height;
+ int red_mask = bi.bV5RedMask;
+ int green_mask = bi.bV5GreenMask;
+ int blue_mask = bi.bV5BlueMask;
+ int alpha_mask = bi.bV5AlphaMask;
+ int red_shift = 0;
+ int green_shift = 0;
+ int blue_shift = 0;
+ int alpha_shift = 0;
+ QImage::Format format = QImage::Format_ARGB32;
+
+ if (bi.bV5Height < 0)
+ h = -h; // support images with negative height
+ if (image.size() != QSize(w, h) || image.format() != format) {
+ image = QImage(w, h, format);
+ if (image.isNull()) // could not create image
+ return false;
+ }
+ image.setDotsPerMeterX(bi.bV5XPelsPerMeter);
+ image.setDotsPerMeterY(bi.bV5YPelsPerMeter);
+ // read color table
+ DWORD colorSpace[3];
+ if (d->read((char *)colorSpace, sizeof(colorSpace)) != sizeof(colorSpace))
+ return false;
+
+ red_shift = calc_shift(red_mask);
+ green_shift = calc_shift(green_mask);
+ blue_shift = calc_shift(blue_mask);
+ if (alpha_mask) {
+ alpha_shift = calc_shift(alpha_mask);
+ }
+
+ int bpl = image.bytesPerLine();
+ uchar *data = image.bits();
+ register QRgb *p;
+ QRgb *end;
+ uchar *buf24 = new uchar[bpl];
+ int bpl24 = ((w*nbits+31)/32)*4;
+ uchar *b;
+ unsigned int c;
+
+ while (--h >= 0) {
+ p = (QRgb *)(data + h*bpl);
+ end = p + w;
+ if (d->read((char *)buf24,bpl24) != bpl24)
+ break;
+ b = buf24;
+ while (p < end) {
+ c = *b | (*(b+1))<<8 | (*(b+2))<<16 | (*(b+3))<<24;
+ *p++ = qRgba(((c & red_mask) >> red_shift) ,
+ ((c & green_mask) >> green_shift),
+ ((c & blue_mask) >> blue_shift),
+ ((c & alpha_mask) >> alpha_shift));
+ b += 4;
+ }
+ }
+ delete[] buf24;
+
+ if (bi.bV5Height < 0) {
+ // Flip the image
+ uchar *buf = new uchar[bpl];
+ h = -bi.bV5Height;
+ for (int y = 0; y < h/2; ++y) {
+ memcpy(buf, data + y*bpl, bpl);
+ memcpy(data + y*bpl, data + (h-y-1)*bpl, bpl);
+ memcpy(data + (h-y-1)*bpl, buf, bpl);
+ }
+ delete [] buf;
+ }
+
+ return true;
+}
+
+//#define QMIME_DEBUG
+
+// helpers for using global memory
+
+static int getCf(const FORMATETC &formatetc)
+{
+ return formatetc.cfFormat;
+}
+
+static FORMATETC setCf(int cf)
+{
+ FORMATETC formatetc;
+ formatetc.cfFormat = cf;
+ formatetc.dwAspect = DVASPECT_CONTENT;
+ formatetc.lindex = -1;
+ formatetc.ptd = NULL;
+ formatetc.tymed = TYMED_HGLOBAL;
+ return formatetc;
+}
+
+static bool setData(const QByteArray &data, STGMEDIUM *pmedium)
+{
+ HGLOBAL hData = GlobalAlloc(0, data.size());
+ if (!hData)
+ return false;
+
+ void *out = GlobalLock(hData);
+ memcpy(out, data.data(), data.size());
+ GlobalUnlock(hData);
+ pmedium->tymed = TYMED_HGLOBAL;
+ pmedium->hGlobal = hData;
+ pmedium->pUnkForRelease = 0;
+ return true;
+}
+
+static QByteArray getData(int cf, IDataObject *pDataObj)
+{
+ QByteArray data;
+ FORMATETC formatetc = setCf(cf);
+ STGMEDIUM s;
+ if (pDataObj->GetData(&formatetc, &s) == S_OK) {
+ DWORD * val = (DWORD*)GlobalLock(s.hGlobal);
+ data = QByteArray::fromRawData((char*)val, GlobalSize(s.hGlobal));
+ data.detach();
+ GlobalUnlock(s.hGlobal);
+ ReleaseStgMedium(&s);
+ } else {
+ //Try reading IStream data
+ formatetc.tymed = TYMED_ISTREAM;
+ if (pDataObj->GetData(&formatetc, &s) == S_OK) {
+ char szBuffer[4096];
+ ULONG actualRead = 0;
+ LARGE_INTEGER pos = {{0, 0}};
+ //Move to front (can fail depending on the data model implemented)
+ HRESULT hr = s.pstm->Seek(pos, STREAM_SEEK_SET, NULL);
+ while(SUCCEEDED(hr)){
+ hr = s.pstm->Read(szBuffer, sizeof(szBuffer), &actualRead);
+ if (SUCCEEDED(hr) && actualRead > 0) {
+ data += QByteArray::fromRawData(szBuffer, actualRead);
+ }
+ if (actualRead != sizeof(szBuffer))
+ break;
+ }
+ data.detach();
+ ReleaseStgMedium(&s);
+ }
+ }
+ return data;
+}
+
+static bool canGetData(int cf, IDataObject * pDataObj)
+{
+ FORMATETC formatetc = setCf(cf);
+ if (pDataObj->QueryGetData(&formatetc) != S_OK){
+ formatetc.tymed = TYMED_ISTREAM;
+ return pDataObj->QueryGetData(&formatetc) == S_OK;
+ }
+ return true;
+}
+
+/*!
+ \class QWindowsMime
+ \brief The QWindowsMime class maps open-standard MIME to Window Clipboard formats.
+ \ingroup qt-lighthouse-win
+
+ Qt's drag-and-drop and clipboard facilities use the MIME standard.
+ On X11, this maps trivially to the Xdnd protocol, but on Windows
+ although some applications use MIME types to describe clipboard
+ formats, others use arbitrary non-standardized naming conventions,
+ or unnamed built-in formats of Windows.
+
+ By instantiating subclasses of QWindowsMime that provide conversions
+ between Windows Clipboard and MIME formats, you can convert
+ proprietary clipboard formats to MIME formats.
+
+ Qt has predefined support for the following Windows Clipboard formats:
+
+ \table
+ \header \o Windows Format \o Equivalent MIME type
+ \row \o \c CF_UNICODETEXT \o \c text/plain
+ \row \o \c CF_TEXT \o \c text/plain
+ \row \o \c CF_DIB \o \c{image/xyz}, where \c xyz is
+ a \l{QImageWriter::supportedImageFormats()}{Qt image format}
+ \row \o \c CF_HDROP \o \c text/uri-list
+ \row \o \c CF_INETURL \o \c text/uri-list
+ \row \o \c CF_HTML \o \c text/html
+ \endtable
+
+ An example use of this class would be to map the Windows Metafile
+ clipboard format (\c CF_METAFILEPICT) to and from the MIME type
+ \c{image/x-wmf}. This conversion might simply be adding or removing
+ a header, or even just passing on the data. See \l{Drag and Drop}
+ for more information on choosing and definition MIME types.
+
+ You can check if a MIME type is convertible using canConvertFromMime() and
+ can perform conversions with convertToMime() and convertFromMime().
+
+ \sa QWindowsMimeConverter
+*/
+
+/*!
+Constructs a new conversion object, adding it to the globally accessed
+list of available converters.
+*/
+QWindowsMime::QWindowsMime()
+{
+}
+
+/*!
+Destroys a conversion object, removing it from the global
+list of available converters.
+*/
+QWindowsMime::~QWindowsMime()
+{
+}
+
+/*!
+ Registers the MIME type \a mime, and returns an ID number
+ identifying the format on Windows.
+*/
+int QWindowsMime::registerMimeType(const QString &mime)
+{
+ int f = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (mime.utf16()));
+ if (!f)
+ qErrnoWarning("QWindowsMime::registerMimeType: Failed to register clipboard format");
+
+ return f;
+}
+
+/*!
+\fn bool QWindowsMime::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+
+ Returns true if the converter can convert from the \a mimeData to
+ the format specified in \a formatetc.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn bool QWindowsMime::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+
+ Returns true if the converter can convert to the \a mimeType from
+ the available formats in \a pDataObj.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+\fn QString QWindowsMime::mimeForFormat(const FORMATETC &formatetc) const
+
+ Returns the mime type that will be created form the format specified
+ in \a formatetc, or an empty string if this converter does not support
+ \a formatetc.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+\fn QVector<FORMATETC> QWindowsMime::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+
+ Returns a QVector of FORMATETC structures representing the different windows clipboard
+ formats that can be provided for the \a mimeType from the \a mimeData.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QVariant QWindowsMime::convertToMime(const QString &mimeType, IDataObject *pDataObj,
+ QVariant::Type preferredType) const
+
+ Returns a QVariant containing the converted data for \a mimeType from \a pDataObj.
+ If possible the QVariant should be of the \a preferredType to avoid needless conversions.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+\fn bool QWindowsMime::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+
+ Convert the \a mimeData to the format specified in \a formatetc.
+ The converted data should then be placed in \a pmedium structure.
+
+ Return true if the conversion was successful.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+class QWindowsMimeText : public QWindowsMime
+{
+public:
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+};
+
+bool QWindowsMimeText::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ int cf = getCf(formatetc);
+ return (cf == CF_UNICODETEXT || cf == CF_TEXT) && mimeData->hasText();
+}
+
+/*
+text/plain is defined as using CRLF, but so many programs don't,
+and programmers just look for '\n' in strings.
+Windows really needs CRLF, so we ensure it here.
+*/
+bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
+{
+ if (canConvertFromMime(formatetc, mimeData)) {
+ QByteArray data;
+ int cf = getCf(formatetc);
+ if (cf == CF_TEXT) {
+ data = mimeData->text().toLocal8Bit();
+ // Anticipate required space for CRLFs at 1/40
+ int maxsize=data.size()+data.size()/40+3;
+ QByteArray r(maxsize, '\0');
+ char* o = r.data();
+ const char* d = data.data();
+ const int s = data.size();
+ bool cr=false;
+ int j=0;
+ for (int i=0; i<s; i++) {
+ char c = d[i];
+ if (c=='\r')
+ cr=true;
+ else {
+ if (c=='\n') {
+ if (!cr)
+ o[j++]='\r';
+ }
+ cr=false;
+ }
+ o[j++]=c;
+ if (j+3 >= maxsize) {
+ maxsize += maxsize/4;
+ r.resize(maxsize);
+ o = r.data();
+ }
+ }
+ o[j]=0;
+ return setData(r, pmedium);
+ } else if (cf == CF_UNICODETEXT) {
+ QString str = mimeData->text();
+ const QChar *u = str.unicode();
+ QString res;
+ const int s = str.length();
+ int maxsize = s + s/40 + 3;
+ res.resize(maxsize);
+ int ri = 0;
+ bool cr = false;
+ for (int i=0; i < s; ++i) {
+ if (*u == QLatin1Char('\r'))
+ cr = true;
+ else {
+ if (*u == QLatin1Char('\n') && !cr)
+ res[ri++] = QLatin1Char('\r');
+ cr = false;
+ }
+ res[ri++] = *u;
+ if (ri+3 >= maxsize) {
+ maxsize += maxsize/4;
+ res.resize(maxsize);
+ }
+ ++u;
+ }
+ res.truncate(ri);
+ const int byteLength = res.length() * sizeof(ushort);
+ QByteArray r(byteLength + 2, '\0');
+ memcpy(r.data(), res.unicode(), byteLength);
+ r[byteLength] = 0;
+ r[byteLength+1] = 0;
+ return setData(r, pmedium);
+ }
+ }
+ return false;
+}
+
+bool QWindowsMimeText::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ return mimeType.startsWith(QStringLiteral("text/plain"))
+ && (canGetData(CF_UNICODETEXT, pDataObj)
+ || canGetData(CF_TEXT, pDataObj));
+}
+
+QString QWindowsMimeText::mimeForFormat(const FORMATETC &formatetc) const
+{
+ int cf = getCf(formatetc);
+ if (cf == CF_UNICODETEXT || cf == CF_TEXT)
+ return QStringLiteral("text/plain");
+ return QString();
+}
+
+
+QVector<FORMATETC> QWindowsMimeText::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatics;
+ if (mimeType.startsWith(QStringLiteral("text/plain")) && mimeData->hasText()) {
+ formatics += setCf(CF_UNICODETEXT);
+ formatics += setCf(CF_TEXT);
+ }
+ return formatics;
+}
+
+QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
+{
+ QVariant ret;
+
+ if (canConvertToMime(mime, pDataObj)) {
+ QString str;
+ QByteArray data = getData(CF_UNICODETEXT, pDataObj);
+ if (!data.isEmpty()) {
+ str = QString::fromWCharArray((const wchar_t *)data.data());
+ str.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
+ } else {
+ data = getData(CF_TEXT, pDataObj);
+ if (!data.isEmpty()) {
+ const char* d = data.data();
+ const int s = qstrlen(d);
+ QByteArray r(data.size()+1, '\0');
+ char* o = r.data();
+ int j=0;
+ for (int i=0; i<s; i++) {
+ char c = d[i];
+ if (c!='\r')
+ o[j++]=c;
+ }
+ o[j]=0;
+ str = QString::fromLocal8Bit(r);
+ }
+ }
+ if (preferredType == QVariant::String)
+ ret = str;
+ else
+ ret = str.toUtf8();
+ }
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << ret;
+ return ret;
+}
+
+class QWindowsMimeURI : public QWindowsMime
+{
+public:
+ QWindowsMimeURI();
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+private:
+ int CF_INETURL_W; // wide char version
+ int CF_INETURL;
+};
+
+QWindowsMimeURI::QWindowsMimeURI()
+{
+ CF_INETURL_W = QWindowsMime::registerMimeType(QStringLiteral("UniformResourceLocatorW"));
+ CF_INETURL = QWindowsMime::registerMimeType(QStringLiteral("UniformResourceLocator"));
+}
+
+bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ if (getCf(formatetc) == CF_HDROP) {
+ QList<QUrl> urls = mimeData->urls();
+ for (int i=0; i<urls.size(); i++) {
+ if (!urls.at(i).toLocalFile().isEmpty())
+ return true;
+ }
+ }
+ return (getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL) && mimeData->hasFormat(QStringLiteral("text/uri-list"));
+}
+
+bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
+{
+ if (canConvertFromMime(formatetc, mimeData)) {
+ if (getCf(formatetc) == CF_HDROP) {
+ QList<QUrl> urls = mimeData->urls();
+ QStringList fileNames;
+ int size = sizeof(DROPFILES)+2;
+ for (int i=0; i<urls.size(); i++) {
+ QString fn = QDir::toNativeSeparators(urls.at(i).toLocalFile());
+ if (!fn.isEmpty()) {
+ size += sizeof(ushort) * (fn.length() + 1);
+ fileNames.append(fn);
+ }
+ }
+
+ QByteArray result(size, '\0');
+ DROPFILES* d = (DROPFILES*)result.data();
+ d->pFiles = sizeof(DROPFILES);
+ GetCursorPos(&d->pt); // try
+ d->fNC = true;
+ char* files = ((char*)d) + d->pFiles;
+
+ d->fWide = true;
+ wchar_t* f = (wchar_t*)files;
+ for (int i=0; i<fileNames.size(); i++) {
+ int l = fileNames.at(i).length();
+ memcpy(f, fileNames.at(i).utf16(), l * sizeof(ushort));
+ f += l;
+ *f++ = 0;
+ }
+ *f = 0;
+
+ return setData(result, pmedium);
+ } else if (getCf(formatetc) == CF_INETURL_W) {
+ QList<QUrl> urls = mimeData->urls();
+ QByteArray result;
+ if (!urls.isEmpty()) {
+ QString url = urls.at(0).toString();
+ result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort));
+ }
+ result.append('\0');
+ result.append('\0');
+ return setData(result, pmedium);
+ } else if (getCf(formatetc) == CF_INETURL) {
+ QList<QUrl> urls = mimeData->urls();
+ QByteArray result;
+ if (!urls.isEmpty())
+ result = urls.at(0).toString().toLocal8Bit();
+ return setData(result, pmedium);
+ }
+ }
+
+ return false;
+}
+
+bool QWindowsMimeURI::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ return mimeType == QStringLiteral("text/uri-list")
+ && (canGetData(CF_HDROP, pDataObj) || canGetData(CF_INETURL_W, pDataObj) || canGetData(CF_INETURL, pDataObj));
+}
+
+QString QWindowsMimeURI::mimeForFormat(const FORMATETC &formatetc) const
+{
+ QString format;
+ if (getCf(formatetc) == CF_HDROP || getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL)
+ format = QStringLiteral("text/uri-list");
+ return format;
+}
+
+QVector<FORMATETC> QWindowsMimeURI::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatics;
+ if (mimeType == QStringLiteral("text/uri-list")) {
+ if (canConvertFromMime(setCf(CF_HDROP), mimeData))
+ formatics += setCf(CF_HDROP);
+ if (canConvertFromMime(setCf(CF_INETURL_W), mimeData))
+ formatics += setCf(CF_INETURL_W);
+ if (canConvertFromMime(setCf(CF_INETURL), mimeData))
+ formatics += setCf(CF_INETURL);
+ }
+ return formatics;
+}
+
+QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
+{
+ if (mimeType == QStringLiteral("text/uri-list")) {
+ if (canGetData(CF_HDROP, pDataObj)) {
+ QByteArray texturi;
+ QList<QVariant> urls;
+
+ QByteArray data = getData(CF_HDROP, pDataObj);
+ if (data.isEmpty())
+ return QVariant();
+
+ LPDROPFILES hdrop = (LPDROPFILES)data.data();
+ if (hdrop->fWide) {
+ const wchar_t* filesw = (const wchar_t *)(data.data() + hdrop->pFiles);
+ int i = 0;
+ while (filesw[i]) {
+ QString fileurl = QString::fromWCharArray(filesw + i);
+ urls += QUrl::fromLocalFile(fileurl);
+ i += fileurl.length()+1;
+ }
+ } else {
+ const char* files = (const char *)data.data() + hdrop->pFiles;
+ int i=0;
+ while (files[i]) {
+ urls += QUrl::fromLocalFile(QString::fromLocal8Bit(files+i));
+ i += int(strlen(files+i))+1;
+ }
+ }
+
+ if (preferredType == QVariant::Url && urls.size() == 1)
+ return urls.at(0);
+ else if (!urls.isEmpty())
+ return urls;
+ } else if (canGetData(CF_INETURL_W, pDataObj)) {
+ QByteArray data = getData(CF_INETURL_W, pDataObj);
+ if (data.isEmpty())
+ return QVariant();
+ return QUrl(QString::fromWCharArray((const wchar_t *)data.constData()));
+ } else if (canGetData(CF_INETURL, pDataObj)) {
+ QByteArray data = getData(CF_INETURL, pDataObj);
+ if (data.isEmpty())
+ return QVariant();
+ return QUrl(QString::fromLocal8Bit(data.constData()));
+ }
+ }
+ return QVariant();
+}
+
+class QWindowsMimeHtml : public QWindowsMime
+{
+public:
+ QWindowsMimeHtml();
+
+ // for converting from Qt
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+
+ // for converting to Qt
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+
+private:
+ int CF_HTML;
+};
+
+QWindowsMimeHtml::QWindowsMimeHtml()
+{
+ CF_HTML = QWindowsMime::registerMimeType(QStringLiteral("HTML Format"));
+}
+
+QVector<FORMATETC> QWindowsMimeHtml::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatetcs;
+ if (mimeType == QStringLiteral("text/html") && (!mimeData->html().isEmpty()))
+ formatetcs += setCf(CF_HTML);
+ return formatetcs;
+}
+
+QString QWindowsMimeHtml::mimeForFormat(const FORMATETC &formatetc) const
+{
+ if (getCf(formatetc) == CF_HTML)
+ return QStringLiteral("text/html");
+ return QString();
+}
+
+bool QWindowsMimeHtml::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ return mimeType == QStringLiteral("text/html") && canGetData(CF_HTML, pDataObj);
+}
+
+
+bool QWindowsMimeHtml::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ return getCf(formatetc) == CF_HTML && (!mimeData->html().isEmpty());
+}
+
+/*
+The windows HTML clipboard format is as follows (xxxxxxxxxx is a 10 integer number giving the positions
+in bytes). Charset used is mostly utf8, but can be different, ie. we have to look for the <meta> charset tag
+
+ Version: 1.0
+ StartHTML:xxxxxxxxxx
+ EndHTML:xxxxxxxxxx
+ StartFragment:xxxxxxxxxx
+ EndFragment:xxxxxxxxxx
+ ...html...
+
+*/
+QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const
+{
+ Q_UNUSED(preferredType);
+ QVariant result;
+ if (canConvertToMime(mime, pDataObj)) {
+ QByteArray html = getData(CF_HTML, pDataObj);
+#ifdef QMIME_DEBUG
+ qDebug("QWindowsMimeHtml::convertToMime");
+ qDebug("raw :");
+ qDebug(html);
+#endif
+ int start = html.indexOf("StartFragment:");
+ int end = html.indexOf("EndFragment:");
+
+ if (start != -1) {
+ int startOffset = start + 14;
+ int i = startOffset;
+ while (html.at(i) != '\r' && html.at(i) != '\n')
+ ++i;
+ QByteArray bytecount = html.mid(startOffset, i - startOffset);
+ start = bytecount.toInt();
+ }
+
+ if (end != -1) {
+ int endOffset = end + 12;
+ int i = endOffset ;
+ while (html.at(i) != '\r' && html.at(i) != '\n')
+ ++i;
+ QByteArray bytecount = html.mid(endOffset , i - endOffset);
+ end = bytecount.toInt();
+ }
+
+ if (end > start && start > 0) {
+ html = "<!--StartFragment-->" + html.mid(start, end - start);
+ html += "<!--EndFragment-->";
+ html.replace('\r', "");
+ result = QString::fromUtf8(html);
+ }
+ }
+ return result;
+}
+
+bool QWindowsMimeHtml::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+{
+ if (canConvertFromMime(formatetc, mimeData)) {
+ QByteArray data = mimeData->html().toUtf8();
+ QByteArray result =
+ "Version:1.0\r\n" // 0-12
+ "StartHTML:0000000105\r\n" // 13-35
+ "EndHTML:0000000000\r\n" // 36-55
+ "StartFragment:0000000000\r\n" // 58-86
+ "EndFragment:0000000000\r\n\r\n"; // 87-105
+
+ if (data.indexOf("<!--StartFragment-->") == -1)
+ result += "<!--StartFragment-->";
+ result += data;
+ if (data.indexOf("<!--EndFragment-->") == -1)
+ result += "<!--EndFragment-->";
+
+ // set the correct number for EndHTML
+ QByteArray pos = QString::number(result.size()).toLatin1();
+ memcpy((char *)(result.data() + 53 - pos.length()), pos.constData(), pos.length());
+
+ // set correct numbers for StartFragment and EndFragment
+ pos = QString::number(result.indexOf("<!--StartFragment-->") + 20).toLatin1();
+ memcpy((char *)(result.data() + 79 - pos.length()), pos.constData(), pos.length());
+ pos = QString::number(result.indexOf("<!--EndFragment-->")).toLatin1();
+ memcpy((char *)(result.data() + 103 - pos.length()), pos.constData(), pos.length());
+
+ return setData(result, pmedium);
+ }
+ return false;
+}
+
+
+#ifndef QT_NO_IMAGEFORMAT_BMP
+class QWindowsMimeImage : public QWindowsMime
+{
+public:
+ QWindowsMimeImage();
+ // for converting from Qt
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+
+ // for converting to Qt
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+private:
+ bool hasOriginalDIBV5(IDataObject *pDataObj) const;
+ UINT CF_PNG;
+};
+
+QWindowsMimeImage::QWindowsMimeImage()
+{
+ CF_PNG = RegisterClipboardFormat(L"PNG");
+}
+
+QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatetcs;
+ if (mimeData->hasImage() && mimeType == QStringLiteral("application/x-qt-image")) {
+ //add DIBV5 if image has alpha channel
+ QImage image = qvariant_cast<QImage>(mimeData->imageData());
+ if (!image.isNull() && image.hasAlphaChannel())
+ formatetcs += setCf(CF_DIBV5);
+ formatetcs += setCf(CF_DIB);
+ }
+ return formatetcs;
+}
+
+QString QWindowsMimeImage::mimeForFormat(const FORMATETC &formatetc) const
+{
+ int cf = getCf(formatetc);
+ if (cf == CF_DIB || cf == CF_DIBV5 || cf == int(CF_PNG))
+ return QStringLiteral("application/x-qt-image");
+ return QString();
+}
+
+bool QWindowsMimeImage::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ if ((mimeType == QStringLiteral("application/x-qt-image")) &&
+ (canGetData(CF_DIB, pDataObj) || canGetData(CF_PNG, pDataObj)))
+ return true;
+ return false;
+}
+
+bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ int cf = getCf(formatetc);
+ if (mimeData->hasImage()) {
+ if (cf == CF_DIB)
+ return true;
+ else if (cf == CF_DIBV5) {
+ //support DIBV5 conversion only if the image has alpha channel
+ QImage image = qvariant_cast<QImage>(mimeData->imageData());
+ if (!image.isNull() && image.hasAlphaChannel())
+ return true;
+ }
+ }
+ return false;
+}
+
+bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+{
+ int cf = getCf(formatetc);
+ if ((cf == CF_DIB || cf == CF_DIBV5) && mimeData->hasImage()) {
+ QImage img = qvariant_cast<QImage>(mimeData->imageData());
+ if (img.isNull())
+ return false;
+ QByteArray ba;
+ if (cf == CF_DIB) {
+ if (img.format() > QImage::Format_ARGB32)
+ img = img.convertToFormat(QImage::Format_RGB32);
+ const QByteArray ba = writeDib(img);
+ if (!ba.isEmpty())
+ return setData(ba, pmedium);
+ } else {
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ s.setByteOrder(QDataStream::LittleEndian);// Intel byte order ####
+ if (qt_write_dibv5(s, img))
+ return setData(ba, pmedium);
+ }
+ }
+ return false;
+}
+
+bool QWindowsMimeImage::hasOriginalDIBV5(IDataObject *pDataObj) const
+{
+ bool isSynthesized = true;
+ IEnumFORMATETC *pEnum =NULL;
+ HRESULT res = pDataObj->EnumFormatEtc(1, &pEnum);
+ if (res == S_OK && pEnum) {
+ FORMATETC fc;
+ while ((res = pEnum->Next(1, &fc, 0)) == S_OK) {
+ if (fc.ptd)
+ CoTaskMemFree(fc.ptd);
+ if (fc.cfFormat == CF_DIB)
+ break;
+ else if (fc.cfFormat == CF_DIBV5) {
+ isSynthesized = false;
+ break;
+ }
+ }
+ pEnum->Release();
+ }
+ return !isSynthesized;
+}
+
+QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
+{
+ Q_UNUSED(preferredType);
+ QVariant result;
+ if (mimeType != QStringLiteral("application/x-qt-image"))
+ return result;
+ //Try to convert from a format which has more data
+ //DIBV5, use only if its is not synthesized
+ if (canGetData(CF_DIBV5, pDataObj) && hasOriginalDIBV5(pDataObj)) {
+ QImage img;
+ QByteArray data = getData(CF_DIBV5, pDataObj);
+ QDataStream s(&data, QIODevice::ReadOnly);
+ s.setByteOrder(QDataStream::LittleEndian);
+ if (qt_read_dibv5(s, img)) { // #### supports only 32bit DIBV5
+ return img;
+ }
+ }
+ //PNG, MS Office place this (undocumented)
+ if (canGetData(CF_PNG, pDataObj)) {
+ QImage img;
+ QByteArray data = getData(CF_PNG, pDataObj);
+ if (img.loadFromData(data, "PNG")) {
+ return img;
+ }
+ }
+ //Fallback to DIB
+ if (canGetData(CF_DIB, pDataObj)) {
+ const QImage img = readDib(getData(CF_DIB, pDataObj));
+ if (!img.isNull())
+ return img;
+ }
+ // Failed
+ return result;
+}
+#endif
+
+class QBuiltInMimes : public QWindowsMime
+{
+public:
+ QBuiltInMimes();
+
+ // for converting from Qt
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+
+ // for converting to Qt
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+
+private:
+ QMap<int, QString> outFormats;
+ QMap<int, QString> inFormats;
+};
+
+QBuiltInMimes::QBuiltInMimes()
+: QWindowsMime()
+{
+ outFormats.insert(QWindowsMime::registerMimeType(QStringLiteral("application/x-color")), QStringLiteral("application/x-color"));
+ inFormats.insert(QWindowsMime::registerMimeType(QStringLiteral("application/x-color")), QStringLiteral("application/x-color"));
+}
+
+bool QBuiltInMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ // really check
+ return formatetc.tymed & TYMED_HGLOBAL
+ && outFormats.contains(formatetc.cfFormat)
+ && mimeData->formats().contains(outFormats.value(formatetc.cfFormat));
+}
+
+bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+{
+ if (canConvertFromMime(formatetc, mimeData)) {
+ QByteArray data;
+ if (outFormats.value(getCf(formatetc)) == QStringLiteral("text/html")) {
+ // text/html is in wide chars on windows (compatible with mozillia)
+ QString html = mimeData->html();
+ // same code as in the text converter up above
+ const QChar *u = html.unicode();
+ QString res;
+ const int s = html.length();
+ int maxsize = s + s/40 + 3;
+ res.resize(maxsize);
+ int ri = 0;
+ bool cr = false;
+ for (int i=0; i < s; ++i) {
+ if (*u == QLatin1Char('\r'))
+ cr = true;
+ else {
+ if (*u == QLatin1Char('\n') && !cr)
+ res[ri++] = QLatin1Char('\r');
+ cr = false;
+ }
+ res[ri++] = *u;
+ if (ri+3 >= maxsize) {
+ maxsize += maxsize/4;
+ res.resize(maxsize);
+ }
+ ++u;
+ }
+ res.truncate(ri);
+ const int byteLength = res.length() * sizeof(ushort);
+ QByteArray r(byteLength + 2, '\0');
+ memcpy(r.data(), res.unicode(), byteLength);
+ r[byteLength] = 0;
+ r[byteLength+1] = 0;
+ data = r;
+ } else {
+#ifndef QT_NO_DRAGANDDROP
+ data = QInternalMimeData::renderDataHelper(outFormats.value(getCf(formatetc)), mimeData);
+#endif //QT_NO_DRAGANDDROP
+ }
+ return setData(data, pmedium);
+ }
+ return false;
+}
+
+QVector<FORMATETC> QBuiltInMimes::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatetcs;
+ if (!outFormats.keys(mimeType).isEmpty() && mimeData->formats().contains(mimeType))
+ formatetcs += setCf(outFormats.key(mimeType));
+ return formatetcs;
+}
+
+bool QBuiltInMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ return (!inFormats.keys(mimeType).isEmpty())
+ && canGetData(inFormats.key(mimeType), pDataObj);
+}
+
+QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
+{
+ QVariant val;
+ if (canConvertToMime(mimeType, pDataObj)) {
+ QByteArray data = getData(inFormats.key(mimeType), pDataObj);
+ if (!data.isEmpty()) {
+#ifdef QMIME_DEBUG
+ qDebug("QBuiltInMimes::convertToMime()");
+#endif
+ if (mimeType == QStringLiteral("text/html") && preferredType == QVariant::String) {
+ // text/html is in wide chars on windows (compatible with Mozilla)
+ val = QString::fromWCharArray((const wchar_t *)data.data());
+ } else {
+ val = data; // it should be enough to return the data and let QMimeData do the rest.
+ }
+ }
+ }
+ return val;
+}
+
+QString QBuiltInMimes::mimeForFormat(const FORMATETC &formatetc) const
+{
+ return inFormats.value(getCf(formatetc));
+}
+
+
+class QLastResortMimes : public QWindowsMime
+{
+public:
+
+ QLastResortMimes();
+ // for converting from Qt
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+
+ // for converting to Qt
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+
+private:
+ QMap<int, QString> formats;
+ static QStringList ianaTypes;
+ static QStringList excludeList;
+};
+
+QStringList QLastResortMimes::ianaTypes;
+QStringList QLastResortMimes::excludeList;
+
+QLastResortMimes::QLastResortMimes()
+{
+ //MIME Media-Types
+ if (!ianaTypes.size()) {
+ ianaTypes.append(QStringLiteral("application/"));
+ ianaTypes.append(QStringLiteral("audio/"));
+ ianaTypes.append(QStringLiteral("example/"));
+ ianaTypes.append(QStringLiteral("image/"));
+ ianaTypes.append(QStringLiteral("message/"));
+ ianaTypes.append(QStringLiteral("model/"));
+ ianaTypes.append(QStringLiteral("multipart/"));
+ ianaTypes.append(QStringLiteral("text/"));
+ ianaTypes.append(QStringLiteral("video/"));
+ }
+ //Types handled by other classes
+ if (!excludeList.size()) {
+ excludeList.append(QStringLiteral("HTML Format"));
+ excludeList.append(QStringLiteral("UniformResourceLocator"));
+ excludeList.append(QStringLiteral("text/html"));
+ excludeList.append(QStringLiteral("text/plain"));
+ excludeList.append(QStringLiteral("text/uri-list"));
+ excludeList.append(QStringLiteral("application/x-qt-image"));
+ excludeList.append(QStringLiteral("application/x-color"));
+ }
+}
+
+bool QLastResortMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ // really check
+#ifndef QT_NO_DRAGANDDROP
+ return formatetc.tymed & TYMED_HGLOBAL
+ && (formats.contains(formatetc.cfFormat)
+ && QInternalMimeData::hasFormatHelper(formats.value(formatetc.cfFormat), mimeData));
+#else
+ Q_UNUSED(mimeData);
+ Q_UNUSED(formatetc);
+ return formatetc.tymed & TYMED_HGLOBAL
+ && formats.contains(formatetc.cfFormat);
+#endif //QT_NO_DRAGANDDROP
+}
+
+bool QLastResortMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+{
+#ifndef QT_NO_DRAGANDDROP
+ return canConvertFromMime(formatetc, mimeData)
+ && setData(QInternalMimeData::renderDataHelper(formats.value(getCf(formatetc)), mimeData), pmedium);
+#else
+ Q_UNUSED(mimeData);
+ Q_UNUSED(formatetc);
+ Q_UNUSED(pmedium);
+ return false;
+#endif //QT_NO_DRAGANDDROP
+}
+
+QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, const QMimeData * /*mimeData*/) const
+{
+ QVector<FORMATETC> formatetcs;
+ if (!formats.keys(mimeType).isEmpty()) {
+ formatetcs += setCf(formats.key(mimeType));
+ } else if (!excludeList.contains(mimeType, Qt::CaseInsensitive)){
+ // register any other available formats
+ int cf = QWindowsMime::registerMimeType(mimeType);
+ QLastResortMimes *that = const_cast<QLastResortMimes *>(this);
+ that->formats.insert(cf, mimeType);
+ formatetcs += setCf(cf);
+ }
+ return formatetcs;
+}
+static const char x_qt_windows_mime[] = "application/x-qt-windows-mime;value=\"";
+
+static bool isCustomMimeType(const QString &mimeType)
+{
+ return mimeType.startsWith(QLatin1String(x_qt_windows_mime), Qt::CaseInsensitive);
+}
+
+static QString customMimeType(const QString &mimeType)
+{
+ int len = sizeof(x_qt_windows_mime) - 1;
+ int n = mimeType.lastIndexOf(QLatin1Char('\"'))-len;
+ return mimeType.mid(len, n);
+}
+
+bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ if (isCustomMimeType(mimeType)) {
+ QString clipFormat = customMimeType(mimeType);
+ int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
+ return canGetData(cf, pDataObj);
+ } else if (formats.keys(mimeType).isEmpty()) {
+ // if it is not in there then register it an see if we can get it
+ int cf = QWindowsMime::registerMimeType(mimeType);
+ return canGetData(cf, pDataObj);
+ } else {
+ return canGetData(formats.key(mimeType), pDataObj);
+ }
+ return false;
+}
+
+QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
+{
+ Q_UNUSED(preferredType);
+ QVariant val;
+ if (canConvertToMime(mimeType, pDataObj)) {
+ QByteArray data;
+ if (isCustomMimeType(mimeType)) {
+ QString clipFormat = customMimeType(mimeType);
+ int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
+ data = getData(cf, pDataObj);
+ } else if (formats.keys(mimeType).isEmpty()) {
+ int cf = QWindowsMime::registerMimeType(mimeType);
+ data = getData(cf, pDataObj);
+ } else {
+ data = getData(formats.key(mimeType), pDataObj);
+ }
+ if (!data.isEmpty())
+ val = data; // it should be enough to return the data and let QMimeData do the rest.
+ }
+ return val;
+}
+
+QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const
+{
+ QString format = formats.value(getCf(formatetc));
+ if (!format.isEmpty())
+ return format;
+
+ wchar_t buffer[256];
+ int len = GetClipboardFormatName(getCf(formatetc), buffer, 256);
+
+ if (len) {
+ QString clipFormat = QString::fromWCharArray(buffer, len);
+#ifndef QT_NO_DRAGANDDROP
+ if (QInternalMimeData::canReadData(clipFormat))
+ format = clipFormat;
+ else if((formatetc.cfFormat >= 0xC000)){
+ //create the mime as custom. not registered.
+ if (!excludeList.contains(clipFormat, Qt::CaseInsensitive)) {
+ //check if this is a mime type
+ bool ianaType = false;
+ int sz = ianaTypes.size();
+ for (int i = 0; i < sz; i++) {
+ if (clipFormat.startsWith(ianaTypes[i], Qt::CaseInsensitive)) {
+ ianaType = true;
+ break;
+ }
+ }
+ if (!ianaType)
+ format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"');
+ else
+ format = clipFormat;
+ }
+ }
+#endif //QT_NO_DRAGANDDROP
+ }
+
+ return format;
+}
+
+/*!
+ \class QWindowsMimeConverter
+ \brief Manages the list of QWindowsMime instances.
+ \ingroup qt-lighthouse-win
+ \sa QWindowsMime
+*/
+
+QWindowsMimeConverter::QWindowsMimeConverter()
+{
+}
+
+QWindowsMimeConverter::~QWindowsMimeConverter()
+{
+ qDeleteAll(m_mimes);
+}
+
+QWindowsMime * QWindowsMimeConverter::converterToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ ensureInitialized();
+ for (int i = m_mimes.size()-1; i >= 0; --i) {
+ if (m_mimes.at(i)->canConvertToMime(mimeType, pDataObj))
+ return m_mimes.at(i);
+ }
+ return 0;
+}
+
+QStringList QWindowsMimeConverter::allMimesForFormats(IDataObject *pDataObj) const
+{
+ ensureInitialized();
+ QStringList formats;
+ LPENUMFORMATETC FAR fmtenum;
+ HRESULT hr = pDataObj->EnumFormatEtc(DATADIR_GET, &fmtenum);
+
+ if (hr == NOERROR) {
+ FORMATETC fmtetc;
+ while (S_OK == fmtenum->Next(1, &fmtetc, 0)) {
+#if defined(QMIME_DEBUG)
+ qDebug("QWindowsMime::allMimesForFormats()");
+ wchar_t buf[256] = {0};
+ GetClipboardFormatName(fmtetc.cfFormat, buf, 255);
+ qDebug("CF = %d : %s", fmtetc.cfFormat, QString::fromWCharArray(buf));
+#endif
+ for (int i= m_mimes.size() - 1; i >= 0; --i) {
+ QString format = m_mimes.at(i)->mimeForFormat(fmtetc);
+ if (!format.isEmpty() && !formats.contains(format)) {
+ formats += format;
+ }
+ }
+ // as documented in MSDN to avoid possible memleak
+ if (fmtetc.ptd)
+ CoTaskMemFree(fmtetc.ptd);
+ }
+ fmtenum->Release();
+ }
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << pDataObj << formats;
+ return formats;
+}
+
+QWindowsMime * QWindowsMimeConverter::converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ ensureInitialized();
+ for (int i = m_mimes.size()-1; i >= 0; --i) {
+ if (m_mimes.at(i)->canConvertFromMime(formatetc, mimeData))
+ return m_mimes.at(i);
+ }
+ return 0;
+}
+
+QVector<FORMATETC> QWindowsMimeConverter::allFormatsForMime(const QMimeData *mimeData) const
+{
+ ensureInitialized();
+ QVector<FORMATETC> formatics;
+#ifdef QT_NO_DRAGANDDROP
+ Q_UNUSED(mimeData);
+#else
+ formatics.reserve(20);
+ const QStringList formats = QInternalMimeData::formatsHelper(mimeData);
+ for (int f = 0; f < formats.size(); ++f) {
+ for (int i = m_mimes.size() - 1; i >= 0; --i)
+ formatics += m_mimes.at(i)->formatsForMime(formats.at(f), mimeData);
+ }
+#endif //QT_NO_DRAGANDDROP
+ return formatics;
+}
+
+void QWindowsMimeConverter::ensureInitialized() const
+{
+ if (m_mimes.isEmpty()) {
+ m_mimes << new QWindowsMimeImage << new QLastResortMimes
+ << new QWindowsMimeText << new QWindowsMimeURI
+ << new QWindowsMimeHtml << new QBuiltInMimes;
+ }
+}
+
+QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
+ IDataObject *pDataObj,
+ QVariant::Type preferredType,
+ QString *formatIn /* = 0 */) const
+{
+ foreach (const QString &format, mimeTypes) {
+ if (const QWindowsMime *converter = converterToMime(format, pDataObj)) {
+ 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;
+ if (formatIn)
+ *formatIn = format;
+ return dataV;
+ }
+ }
+ }
+ }
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << "fails" << mimeTypes << pDataObj << preferredType;
+ return QVariant();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h
new file mode 100644
index 0000000000..85f61a91e2
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsmime.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSMIME_H
+#define QWINDOWSMIME_H
+
+#include "qtwindows_additional.h"
+
+#include <QtCore/QVector>
+#include <QtCore/QList>
+#include <QtCore/QVariant>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QMimeData;
+
+class QWindowsMime
+{
+ Q_DISABLE_COPY(QWindowsMime)
+public:
+ QWindowsMime();
+ virtual ~QWindowsMime();
+
+ // for converting from Qt
+ virtual bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const = 0;
+ virtual bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const = 0;
+ virtual QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const = 0;
+
+ // for converting to Qt
+ virtual bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const = 0;
+ virtual QVariant convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const = 0;
+ virtual QString mimeForFormat(const FORMATETC &formatetc) const = 0;
+
+ static int registerMimeType(const QString &mime);
+};
+
+class QWindowsMimeConverter
+{
+ Q_DISABLE_COPY(QWindowsMimeConverter)
+public:
+ QWindowsMimeConverter();
+ ~QWindowsMimeConverter();
+
+ QWindowsMime *converterToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QStringList allMimesForFormats(IDataObject *pDataObj) const;
+ QWindowsMime *converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ QVector<FORMATETC> allFormatsForMime(const QMimeData *mimeData) const;
+
+ // Convenience.
+ QVariant convertToMime(const QStringList &mimeTypes, IDataObject *pDataObj, QVariant::Type preferredType,
+ QString *format = 0) const;
+
+private:
+ typedef QSharedPointer<QWindowsMime> MimePtr;
+
+ void ensureInitialized() const;
+
+ mutable QList<QWindowsMime *> m_mimes;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSMIME_H
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
new file mode 100644
index 0000000000..dea965b439
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsmousehandler.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsintegration.h"
+
+#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+
+#include <QtCore/QDebug>
+#include <QtCore/QScopedArrayPointer>
+
+#include <windowsx.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline void compressMouseMove(MSG *msg)
+{
+ // Compress mouse move events
+ if (msg->message == WM_MOUSEMOVE) {
+ MSG mouseMsg;
+ while (PeekMessage(&mouseMsg, msg->hwnd, WM_MOUSEFIRST,
+ WM_MOUSELAST, PM_NOREMOVE)) {
+ if (mouseMsg.message == WM_MOUSEMOVE) {
+#define PEEKMESSAGE_IS_BROKEN 1
+#ifdef PEEKMESSAGE_IS_BROKEN
+ // Since the Windows PeekMessage() function doesn't
+ // correctly return the wParam for WM_MOUSEMOVE events
+ // if there is a key release event in the queue
+ // _before_ the mouse event, we have to also consider
+ // key release events (kls 2003-05-13):
+ MSG keyMsg;
+ bool done = false;
+ while (PeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST,
+ PM_NOREMOVE)) {
+ if (keyMsg.time < mouseMsg.time) {
+ if ((keyMsg.lParam & 0xC0000000) == 0x40000000) {
+ PeekMessage(&keyMsg, 0, keyMsg.message,
+ keyMsg.message, PM_REMOVE);
+ } else {
+ done = true;
+ break;
+ }
+ } else {
+ break; // no key event before the WM_MOUSEMOVE event
+ }
+ }
+ if (done)
+ break;
+#else
+ // Actually the following 'if' should work instead of
+ // the above key event checking, but apparently
+ // PeekMessage() is broken :-(
+ if (mouseMsg.wParam != msg.wParam)
+ break; // leave the message in the queue because
+ // the key state has changed
+#endif
+ // Update the passed in MSG structure with the
+ // most recent one.
+ msg->lParam = mouseMsg.lParam;
+ msg->wParam = mouseMsg.wParam;
+ // Extract the x,y coordinates from the lParam as we do in the WndProc
+ msg->pt.x = GET_X_LPARAM(mouseMsg.lParam);
+ msg->pt.y = GET_Y_LPARAM(mouseMsg.lParam);
+ ClientToScreen(msg->hwnd, &(msg->pt));
+ // Remove the mouse move message
+ PeekMessage(&mouseMsg, msg->hwnd, WM_MOUSEMOVE,
+ WM_MOUSEMOVE, PM_REMOVE);
+ } else {
+ break; // there was no more WM_MOUSEMOVE event
+ }
+ }
+ }
+}
+
+/*!
+ \class QWindowsMouseHandler
+ \brief Windows mouse handler
+
+ Dispatches mouse and touch events. Separate for code cleanliness.
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsMouseHandler::QWindowsMouseHandler() :
+ m_windowUnderMouse(0)
+{
+}
+
+bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
+ QtWindows::WindowsEventType et,
+ MSG msg, LRESULT *result)
+{
+ if (et & QtWindows::NonClientEventFlag)
+ return false;
+ if (et == QtWindows::MouseWheelEvent)
+ return translateMouseWheelEvent(window, hwnd, msg, result);
+ *result = 0;
+ if (msg.message == WM_MOUSELEAVE) {
+ // When moving out of a child, MouseMove within parent is received first
+ // (see below)
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "WM_MOUSELEAVE for " << window << " current= " << m_windowUnderMouse;
+ if (window == m_windowUnderMouse) {
+ QWindowSystemInterface::handleLeaveEvent(window);
+ m_windowUnderMouse = 0;
+ }
+ return true;
+ }
+ compressMouseMove(&msg);
+ const QPoint client(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
+ // Enter new window: track to generate leave event.
+ if (m_windowUnderMouse != window) {
+ // The tracking on m_windowUnderMouse might still be active and
+ // trigger later on.
+ if (m_windowUnderMouse) {
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Synthetic leave for " << m_windowUnderMouse;
+ QWindowSystemInterface::handleLeaveEvent(m_windowUnderMouse);
+ }
+ m_windowUnderMouse = window;
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Entering " << window;
+ QWindowsWindow::baseWindowOf(window)->applyCursor();
+ QWindowSystemInterface::handleEnterEvent(window);
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = HOVER_DEFAULT; //
+ if (!TrackMouseEvent(&tme))
+ qWarning("TrackMouseEvent failed.");
+ }
+ QWindowSystemInterface::handleMouseEvent(window, client,
+ QWindowsGeometryHint::mapToGlobal(hwnd, client),
+ keyStateToMouseButtons((int)msg.wParam));
+ return true;
+}
+
+bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND,
+ MSG msg, LRESULT *)
+{
+ const Qt::MouseButtons buttons = keyStateToMouseButtons((int)msg.wParam);
+ int delta;
+ if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL)
+ delta = (short) HIWORD (msg.wParam);
+ else
+ delta = (int) msg.wParam;
+
+ Qt::Orientation orientation = (msg.message == WM_MOUSEHWHEEL
+ || (buttons & Qt::AltModifier)) ?
+ Qt::Horizontal : Qt::Vertical;
+
+ // according to the MSDN documentation on WM_MOUSEHWHEEL:
+ // a positive value indicates that the wheel was rotated to the right;
+ // a negative value indicates that the wheel was rotated to the left.
+ // Qt defines this value as the exact opposite, so we have to flip the value!
+ if (msg.message == WM_MOUSEHWHEEL)
+ delta = -delta;
+
+ const QPoint globalPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
+ // TODO: if there is a widget under the mouse and it is not shadowed
+ // QWindow *receiver = windowAt(pos);
+ // by modality, we send the event to it first.
+ //synaptics touchpad shows its own widget at this position
+ //so widgetAt() will fail with that HWND, try child of this widget
+ // if (!receiver) receiver = window->childAt(pos);
+ QWindow *receiver = window;
+ QWindowSystemInterface::handleWheelEvent(receiver,
+ QWindowsGeometryHint::mapFromGlobal(receiver, globalPos),
+ globalPos,
+ delta, orientation);
+ return true;
+}
+
+// from bool QApplicationPrivate::translateTouchEvent()
+bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
+ QtWindows::WindowsEventType,
+ MSG msg, LRESULT *)
+{
+ typedef QWindowSystemInterface::TouchPoint QTouchPoint;
+ typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList;
+
+ const QRect screenGeometry = window->screen()->geometry();
+
+ const int winTouchPointCount = msg.wParam;
+ QScopedArrayPointer<TOUCHINPUT> winTouchInputs(new TOUCHINPUT[winTouchPointCount]);
+ memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchPointCount);
+
+ QTouchPointList touchPoints;
+ touchPoints.reserve(winTouchPointCount);
+ Qt::TouchPointStates allStates = 0;
+
+ Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo);
+
+ QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
+ for (int i = 0; i < winTouchPointCount; ++i) {
+ const TOUCHINPUT &winTouchInput = winTouchInputs[i];
+ QTouchPoint touchPoint;
+ touchPoint.pressure = 1.0;
+ touchPoint.isPrimary = (winTouchInput.dwFlags & TOUCHEVENTF_PRIMARY) != 0;
+ touchPoint.id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1);
+ if (touchPoint.id == -1) {
+ touchPoint.id = m_touchInputIDToTouchPointID.size();
+ m_touchInputIDToTouchPointID.insert(winTouchInput.dwID, touchPoint.id);
+ }
+
+ QPointF screenPos = QPointF(qreal(winTouchInput.x) / qreal(100.), qreal(winTouchInput.y) / qreal(100.));
+ if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
+ touchPoint.area.setSize(QSizeF(qreal(winTouchInput.cxContact) / qreal(100.),
+ qreal(winTouchInput.cyContact) / qreal(100.)));
+ touchPoint.area.moveCenter(screenPos);
+
+ if (winTouchInput.dwFlags & TOUCHEVENTF_DOWN) {
+ touchPoint.state = Qt::TouchPointPressed;
+ } else if (winTouchInput.dwFlags & TOUCHEVENTF_UP) {
+ touchPoint.state = Qt::TouchPointReleased;
+ } else {
+ // TODO: Previous code checked"
+ // screenPos == touchPoint.normalPosition -> Qt::TouchPointStationary, but
+ // but touchPoint.normalPosition was never initialized?
+ touchPoint.state = touchPoint.state;
+ }
+
+ touchPoint.normalPosition = QPointF(screenPos.x() / screenGeometry.width(),
+ screenPos.y() / screenGeometry.height());
+
+ allStates |= touchPoint.state;
+
+ touchPoints.append(touchPoint);
+ }
+
+ QWindowsContext::user32dll.closeTouchInputHandle((HANDLE) msg.lParam);
+
+ // all touch points released, forget the ids we've seen, they may not be reused
+ if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased)
+ m_touchInputIDToTouchPointID.clear();
+
+ // TODO: Device used to be hardcoded to screen in previous code.
+ // What is the correct event type? Which parts of translateRawTouchEvent() are required?
+ QWindowSystemInterface::handleTouchEvent(window, QEvent::TouchBegin,
+ QTouchEvent::TouchScreen,
+ touchPoints);
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
new file mode 100644
index 0000000000..953649102a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSMOUSEHANDLER_H
+#define QWINDOWSMOUSEHANDLER_H
+
+#include "qtwindowsglobal.h"
+#include "qtwindows_additional.h"
+
+#include <QtCore/QPointer>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+
+class QWindowsMouseHandler
+{
+ Q_DISABLE_COPY(QWindowsMouseHandler)
+public:
+ QWindowsMouseHandler();
+
+ bool translateMouseEvent(QWindow *widget, HWND hwnd,
+ QtWindows::WindowsEventType t, MSG msg,
+ LRESULT *result);
+ bool translateTouchEvent(QWindow *widget, HWND hwnd,
+ QtWindows::WindowsEventType t, MSG msg,
+ LRESULT *result);
+
+ static inline Qt::MouseButtons keyStateToMouseButtons(int);
+ static inline int mouseButtonsToKeyState(Qt::MouseButtons);
+
+ QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); }
+
+private:
+ inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd,
+ MSG msg, LRESULT *result);
+
+ QPointer<QWindow> m_windowUnderMouse;
+ QHash<DWORD, int> m_touchInputIDToTouchPointID;
+};
+
+Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam)
+{
+ Qt::MouseButtons mb(Qt::NoButton);
+ if (wParam & MK_LBUTTON)
+ mb |= Qt::LeftButton;
+ if (wParam & MK_MBUTTON)
+ mb |= Qt::MiddleButton;
+ if (wParam & MK_RBUTTON)
+ mb |= Qt::RightButton;
+ if (wParam & MK_XBUTTON1)
+ mb |= Qt::XButton1;
+ if (wParam & MK_XBUTTON2)
+ mb |= Qt::XButton2;
+ return mb;
+}
+
+int QWindowsMouseHandler::mouseButtonsToKeyState(Qt::MouseButtons mb)
+{
+ int result = 0;
+ if (mb & Qt::LeftButton)
+ result |= MK_LBUTTON;
+ if (mb & Qt::MiddleButton)
+ result |= MK_MBUTTON;
+ if (mb & Qt::RightButton)
+ result |= MK_RBUTTON;
+ if (mb & Qt::XButton1)
+ result |= MK_XBUTTON1;
+ if (mb & Qt::XButton2)
+ result |= MK_XBUTTON2;
+ return result;
+}
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSMOUSEHANDLER_H
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.cpp b/src/plugins/platforms/windows/qwindowsnativeimage.cpp
new file mode 100644
index 0000000000..2ecf334b39
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsnativeimage.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsnativeimage.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/private/qpaintengine_p.h>
+#include <QtGui/private/qpaintengine_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef struct {
+ BITMAPINFOHEADER bmiHeader;
+ DWORD redMask;
+ DWORD greenMask;
+ DWORD blueMask;
+} BITMAPINFO_MASK;
+
+/*!
+ \class QWindowsNativeImage
+ \brief Windows Native image
+
+ Note that size can be 0 (widget autotests with zero size), which
+ causes CreateDIBSection() to fail.
+
+ \sa QWindowsBackingStore
+ \ingroup qt-lighthouse-win
+*/
+
+static inline HDC createDC()
+{
+ HDC display_dc = GetDC(0);
+ HDC hdc = CreateCompatibleDC(display_dc);
+ ReleaseDC(0, display_dc);
+ Q_ASSERT(hdc);
+ return hdc;
+}
+
+static inline HBITMAP createDIB(HDC hdc, int width, int height,
+ QImage::Format format,
+ uchar **bitsIn)
+{
+ BITMAPINFO_MASK bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = width;
+ bmi.bmiHeader.biHeight = -height; // top-down.
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biSizeImage = 0;
+
+ if (format == QImage::Format_RGB16) {
+ bmi.bmiHeader.biBitCount = 16;
+ bmi.bmiHeader.biCompression = BI_BITFIELDS;
+ bmi.redMask = 0xF800;
+ bmi.greenMask = 0x07E0;
+ bmi.blueMask = 0x001F;
+ } else {
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.redMask = 0;
+ bmi.greenMask = 0;
+ bmi.blueMask = 0;
+ }
+
+ void *bits = 0;
+ HBITMAP bitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bmi),
+ DIB_RGB_COLORS, &bits, 0, 0);
+ if (!bitmap || !bits)
+ qFatal("%s: CreateDIBSection failed.", __FUNCTION__);
+
+ *bitsIn = (uchar*)bits;
+ return bitmap;
+}
+
+QWindowsNativeImage::QWindowsNativeImage(int width, int height,
+ QImage::Format format) :
+ m_hdc(createDC()),
+ m_bitmap(0),
+ m_null_bitmap(0)
+{
+ if (width != 0 && height != 0) {
+ uchar *bits;
+ m_bitmap = createDIB(m_hdc, width, height, format, &bits);
+ m_null_bitmap = (HBITMAP)SelectObject(m_hdc, m_bitmap);
+ m_image = QImage(bits, width, height, format);
+ Q_ASSERT(m_image.paintEngine()->type() == QPaintEngine::Raster);
+ static_cast<QRasterPaintEngine *>(m_image.paintEngine())->setDC(m_hdc);
+ } else {
+ m_image = QImage(width, height, format);
+ }
+
+ GdiFlush();
+}
+
+QWindowsNativeImage::~QWindowsNativeImage()
+{
+ if (m_hdc) {
+ if (m_bitmap) {
+ if (m_null_bitmap)
+ SelectObject(m_hdc, m_null_bitmap);
+ DeleteObject(m_bitmap);
+ }
+ DeleteDC(m_hdc);
+ }
+}
+
+QImage::Format QWindowsNativeImage::systemFormat()
+{
+ static const int depth = QWindowsContext::instance()->screenDepth();
+ return depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.h b/src/plugins/platforms/windows/qwindowsnativeimage.h
new file mode 100644
index 0000000000..c77805a10a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsnativeimage.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSNATIVEIMAGE_H
+#define QWINDOWSNATIVEIMAGE_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QImage>
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsNativeImage
+{
+ Q_DISABLE_COPY(QWindowsNativeImage)
+public:
+ QWindowsNativeImage(int width, int height,
+ QImage::Format format);
+
+ ~QWindowsNativeImage();
+
+ inline int width() const { return m_image.width(); }
+ inline int height() const { return m_image.height(); }
+
+ QImage &image() { return m_image; }
+ const QImage &image() const { return m_image; }
+
+ HDC hdc() const { return m_hdc; }
+
+ static QImage::Format systemFormat();
+
+private:
+ const HDC m_hdc;
+ QImage m_image;
+
+ HBITMAP m_bitmap;
+ HBITMAP m_null_bitmap;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSNATIVEIMAGE_H
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
new file mode 100644
index 0000000000..864dc3dbb7
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -0,0 +1,476 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsole.h"
+#include "qwindowsmime.h"
+#include "qwindowscontext.h"
+\
+#include <QtGui/QMouseEvent>
+#include <QtGui/QWindow>
+#include <QtGui/QPainter>
+#include <QtGui/QCursor>
+#include <QtGui/QGuiApplication>
+
+#include <QtCore/QMimeData>
+#include <QtCore/QDebug>
+
+#include <shlobj.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsOleDataObject
+ \brief OLE data container
+
+ The following methods are NOT supported for data transfer using the
+ clipboard or drag-drop:
+ \list
+ \o IDataObject::SetData -- return E_NOTIMPL
+ \o IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED
+ \o ::DUnadvise
+ \o ::EnumDAdvise
+ \o IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL
+ (NOTE: must set pformatetcOut->ptd = NULL)
+ \endlist
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsOleDataObject::QWindowsOleDataObject(QMimeData *mimeData) :
+ m_refs(1), data(mimeData),
+ CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)),
+ performedEffect(DROPEFFECT_NONE)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s '%s'", __FUNCTION__, qPrintable(mimeData->formats().join(QStringLiteral(", "))));
+}
+
+QWindowsOleDataObject::~QWindowsOleDataObject()
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s", __FUNCTION__);
+}
+
+void QWindowsOleDataObject::releaseQt()
+{
+ data = 0;
+}
+
+QMimeData *QWindowsOleDataObject::mimeData() const
+{
+ return data.data();
+}
+
+DWORD QWindowsOleDataObject::reportedPerformedEffect() const
+{
+ return performedEffect;
+}
+
+//---------------------------------------------------------------------
+// IUnknown Methods
+//---------------------------------------------------------------------
+
+STDMETHODIMP
+QWindowsOleDataObject::QueryInterface(REFIID iid, void FAR* FAR* ppv)
+{
+ if (iid == IID_IUnknown || iid == IID_IDataObject) {
+ *ppv = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDataObject::AddRef(void)
+{
+ return ++m_refs;
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDataObject::Release(void)
+{
+ if (--m_refs == 0) {
+ releaseQt();
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
+{
+ HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
+
+ if (QWindowsContext::verboseOLE) {
+ wchar_t buf[256] = {0};
+ GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
+ qDebug("%s CF = %d : %s", __FUNCTION__, pformatetc->cfFormat, qPrintable(QString::fromWCharArray(buf)));
+ }
+
+ if (data) {
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ if (QWindowsMime *converter = mc.converterFromMime(*pformatetc, data))
+ if (converter->convertFromMime(*pformatetc, data, pmedium))
+ hr = ResultFromScode(S_OK);
+ }
+
+ if (QWindowsContext::verboseOLE) {
+ 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));
+ }
+
+ return hr;
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::GetDataHere(LPFORMATETC, LPSTGMEDIUM)
+{
+ return ResultFromScode(DATA_E_FORMATETC);
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::QueryGetData(LPFORMATETC pformatetc)
+{
+ HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
+
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __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));
+ return hr;
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetcOut)
+{
+ pformatetcOut->ptd = NULL;
+ return ResultFromScode(E_NOTIMPL);
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease)
+{
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+
+ HRESULT hr = ResultFromScode(E_NOTIMPL);
+
+ if (pFormatetc->cfFormat == CF_PERFORMEDDROPEFFECT && pMedium->tymed == TYMED_HGLOBAL) {
+ DWORD * val = (DWORD*)GlobalLock(pMedium->hGlobal);
+ performedEffect = *val;
+ GlobalUnlock(pMedium->hGlobal);
+ if (fRelease)
+ ReleaseStgMedium(pMedium);
+ hr = ResultFromScode(S_OK);
+ }
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s returns 0x%x", __FUNCTION__, int(hr));
+ return hr;
+}
+
+
+STDMETHODIMP
+QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
+{
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+
+ if (!data)
+ return ResultFromScode(DATA_E_FORMATETC);
+
+ SCODE sc = S_OK;
+
+ QVector<FORMATETC> fmtetcs;
+ if (dwDirection == DATADIR_GET) {
+ QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ fmtetcs = mc.allFormatsForMime(data);
+ } else {
+ FORMATETC formatetc;
+ formatetc.cfFormat = CF_PERFORMEDDROPEFFECT;
+ formatetc.dwAspect = DVASPECT_CONTENT;
+ formatetc.lindex = -1;
+ formatetc.ptd = NULL;
+ formatetc.tymed = TYMED_HGLOBAL;
+ fmtetcs.append(formatetc);
+ }
+
+ QWindowsOleEnumFmtEtc *enumFmtEtc = new QWindowsOleEnumFmtEtc(fmtetcs);
+ *ppenumFormatEtc = enumFmtEtc;
+ if (enumFmtEtc->isNull()) {
+ delete enumFmtEtc;
+ *ppenumFormatEtc = NULL;
+ sc = E_OUTOFMEMORY;
+ }
+
+ return ResultFromScode(sc);
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::DAdvise(FORMATETC FAR*, DWORD,
+ LPADVISESINK, DWORD FAR*)
+{
+ return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
+}
+
+
+STDMETHODIMP
+QWindowsOleDataObject::DUnadvise(DWORD)
+{
+ return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*)
+{
+ return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
+}
+
+/*!
+ \class QWindowsOleEnumFmtEtc
+ \brief Enumerates the FORMATETC structures supported by QWindowsOleDataObject.
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) :
+ m_dwRefs(1), m_nIndex(0), m_isNull(false)
+{
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+ m_lpfmtetcs.reserve(fmtetcs.count());
+ for (int idx = 0; idx < fmtetcs.count(); ++idx) {
+ LPFORMATETC destetc = new FORMATETC();
+ if (copyFormatEtc(destetc, (LPFORMATETC)&(fmtetcs.at(idx)))) {
+ m_lpfmtetcs.append(destetc);
+ } else {
+ m_isNull = true;
+ delete destetc;
+ break;
+ }
+ }
+}
+
+QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs) :
+ m_dwRefs(1), m_nIndex(0), m_isNull(false)
+{
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+ m_lpfmtetcs.reserve(lpfmtetcs.count());
+ for (int idx = 0; idx < lpfmtetcs.count(); ++idx) {
+ LPFORMATETC srcetc = lpfmtetcs.at(idx);
+ LPFORMATETC destetc = new FORMATETC();
+ if (copyFormatEtc(destetc, srcetc)) {
+ m_lpfmtetcs.append(destetc);
+ } else {
+ m_isNull = true;
+ delete destetc;
+ break;
+ }
+ }
+}
+
+QWindowsOleEnumFmtEtc::~QWindowsOleEnumFmtEtc()
+{
+ LPMALLOC pmalloc;
+
+ if (CoGetMalloc(MEMCTX_TASK, &pmalloc) == NOERROR) {
+ for (int idx = 0; idx < m_lpfmtetcs.count(); ++idx) {
+ LPFORMATETC tmpetc = m_lpfmtetcs.at(idx);
+ if (tmpetc->ptd)
+ pmalloc->Free(tmpetc->ptd);
+ delete tmpetc;
+ }
+
+ pmalloc->Release();
+ }
+ m_lpfmtetcs.clear();
+}
+
+bool QWindowsOleEnumFmtEtc::isNull() const
+{
+ return m_isNull;
+}
+
+// IUnknown methods
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::QueryInterface(REFIID riid, void FAR* FAR* ppvObj)
+{
+ if (riid == IID_IUnknown || riid == IID_IEnumFORMATETC) {
+ *ppvObj = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppvObj = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleEnumFmtEtc::AddRef(void)
+{
+ return ++m_dwRefs;
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleEnumFmtEtc::Release(void)
+{
+ if (--m_dwRefs == 0) {
+ delete this;
+ return 0;
+ }
+ return m_dwRefs;
+}
+
+// IEnumFORMATETC methods
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched)
+{
+ ULONG i=0;
+ ULONG nOffset;
+
+ if (rgelt == NULL)
+ return ResultFromScode(E_INVALIDARG);
+
+ while (i < celt) {
+ nOffset = m_nIndex + i;
+
+ if (nOffset < ULONG(m_lpfmtetcs.count())) {
+ copyFormatEtc((LPFORMATETC)&(rgelt[i]), m_lpfmtetcs.at(nOffset));
+ i++;
+ } else {
+ break;
+ }
+ }
+
+ m_nIndex += (WORD)i;
+
+ if (pceltFetched != NULL)
+ *pceltFetched = i;
+
+ if (i != celt)
+ return ResultFromScode(S_FALSE);
+
+ return NOERROR;
+}
+
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::Skip(ULONG celt)
+{
+ ULONG i=0;
+ ULONG nOffset;
+
+ while (i < celt) {
+ nOffset = m_nIndex + i;
+
+ if (nOffset < ULONG(m_lpfmtetcs.count())) {
+ i++;
+ } else {
+ break;
+ }
+ }
+
+ m_nIndex += (WORD)i;
+
+ if (i != celt)
+ return ResultFromScode(S_FALSE);
+
+ return NOERROR;
+}
+
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::Reset()
+{
+ m_nIndex = 0;
+ return NOERROR;
+}
+
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::Clone(LPENUMFORMATETC FAR* newEnum)
+{
+ if (newEnum == NULL)
+ return ResultFromScode(E_INVALIDARG);
+
+ QWindowsOleEnumFmtEtc *result = new QWindowsOleEnumFmtEtc(m_lpfmtetcs);
+ result->m_nIndex = m_nIndex;
+
+ if (result->isNull()) {
+ delete result;
+ return ResultFromScode(E_OUTOFMEMORY);
+ } else {
+ *newEnum = result;
+ }
+
+ return NOERROR;
+}
+
+bool QWindowsOleEnumFmtEtc::copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const
+{
+ if (dest == NULL || src == NULL)
+ return false;
+
+ *dest = *src;
+
+ if (src->ptd) {
+ LPVOID pout;
+ LPMALLOC pmalloc;
+
+ if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR)
+ return false;
+
+ pout = (LPVOID)pmalloc->Alloc(src->ptd->tdSize);
+ memcpy(dest->ptd, src->ptd, size_t(src->ptd->tdSize));
+
+ pmalloc->Release();
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsole.h b/src/plugins/platforms/windows/qwindowsole.h
new file mode 100644
index 0000000000..d979af3b31
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsole.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSOLE_H
+#define QWINDOWSOLE_H
+
+#include "qtwindows_additional.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtCore/QPoint>
+#include <QtCore/QPointer>
+#include <QtCore/QVector>
+#include <QtCore/QRect>
+
+#include <objidl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMimeData;
+class QWindow;
+
+class QWindowsOleDataObject : public IDataObject
+{
+public:
+ explicit QWindowsOleDataObject(QMimeData *mimeData);
+ virtual ~QWindowsOleDataObject();
+
+ void releaseQt();
+ QMimeData *mimeData() const;
+ DWORD reportedPerformedEffect() const;
+
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
+ STDMETHOD_(ULONG,AddRef)(void);
+ STDMETHOD_(ULONG,Release)(void);
+
+ // IDataObject methods
+ STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium);
+ STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium);
+ STDMETHOD(QueryGetData)(LPFORMATETC pformatetc);
+ STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut);
+ STDMETHOD(SetData)(LPFORMATETC pformatetc, STGMEDIUM FAR * pmedium,
+ BOOL fRelease);
+ STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc);
+ STDMETHOD(DAdvise)(FORMATETC FAR* pFormatetc, DWORD advf,
+ LPADVISESINK pAdvSink, DWORD FAR* pdwConnection);
+ STDMETHOD(DUnadvise)(DWORD dwConnection);
+ STDMETHOD(EnumDAdvise)(LPENUMSTATDATA FAR* ppenumAdvise);
+
+private:
+ ULONG m_refs;
+ QPointer<QMimeData> data;
+ int CF_PERFORMEDDROPEFFECT;
+ DWORD performedEffect;
+};
+
+class QWindowsOleEnumFmtEtc : public IEnumFORMATETC
+{
+public:
+ explicit QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs);
+ explicit QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs);
+ virtual ~QWindowsOleEnumFmtEtc();
+
+ bool isNull() const;
+
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
+ STDMETHOD_(ULONG,AddRef)(void);
+ STDMETHOD_(ULONG,Release)(void);
+
+ // IEnumFORMATETC methods
+ STDMETHOD(Next)(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched);
+ STDMETHOD(Skip)(ULONG celt);
+ STDMETHOD(Reset)(void);
+ STDMETHOD(Clone)(LPENUMFORMATETC FAR* newEnum);
+
+private:
+ bool copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const;
+
+ ULONG m_dwRefs;
+ ULONG m_nIndex;
+ QVector<LPFORMATETC> m_lpfmtetcs;
+ bool m_isNull;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSOLE_H
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
new file mode 100644
index 0000000000..3de508a1c7
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsscreen.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "pixmaputils.h"
+#include "qwindowscursor.h"
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPixmap>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+typedef QPair<int, int> DPI;
+
+QWindowsScreenData::QWindowsScreenData() :
+ dpi(96, 96),
+ depth(32),
+ format(QImage::Format_ARGB32_Premultiplied), primary(false)
+{
+}
+
+static inline DPI deviceDPI(HDC hdc)
+{
+ return DPI(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY));
+}
+
+static inline QSize deviceSizeMM(const QSize &pixels, const DPI &dpi)
+{
+ const qreal inchToMM = 25.4;
+ const qreal h = qreal(pixels.width()) / qreal(dpi.first) * inchToMM;
+ const qreal v = qreal(pixels.height()) / qreal(dpi.second) * inchToMM;
+ return QSize(qRound(h), qRound(v));
+}
+
+static inline DPI deviceDPI(const QSize &pixels, const QSize &physicalSizeMM)
+{
+ const qreal inchToMM = 25.4;
+ const qreal h = qreal(pixels.width()) / (qreal(physicalSizeMM.width()) / inchToMM);
+ const qreal v = qreal(pixels.height()) / (qreal(physicalSizeMM.height()) / inchToMM);
+ return DPI(qRound(v), qRound(h));
+}
+
+typedef QList<QWindowsScreenData> WindowsScreenDataList;
+
+// from QDesktopWidget, taking WindowsScreenDataList as LPARAM
+BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p)
+{
+ MONITORINFOEX info;
+ memset(&info, 0, sizeof(MONITORINFOEX));
+ info.cbSize = sizeof(MONITORINFOEX);
+ if (GetMonitorInfo(hMonitor, &info) == FALSE)
+ return TRUE;
+
+ WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p);
+ QWindowsScreenData data;
+ data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
+ if (HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL)) {
+ data.dpi = deviceDPI(hdc);
+ DeleteDC(hdc);
+ } else {
+ qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %d DPI.",
+ __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
+ data.dpi.first);
+ }
+ data.physicalSizeMM = deviceSizeMM(data.geometry.size(), data.dpi);
+ data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
+ data.availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
+ data.primary = (info.dwFlags & MONITORINFOF_PRIMARY) != 0;
+ result->append(data);
+ return TRUE;
+}
+
+/*!
+ \class QWindowsScreen
+ \brief Windows screen.
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
+ m_data(data), m_cursor(this)
+{
+}
+
+QList<QPlatformScreen *> QWindowsScreen::screens()
+{
+ // Retrieve monitors and add static depth information to each.
+ WindowsScreenDataList data;
+ EnumDisplayMonitors(0, 0, monitorEnumCallback, (LPARAM)&data);
+
+ const int depth = QWindowsContext::instance()->screenDepth();
+ const QImage::Format format = depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
+ QList<QPlatformScreen *> result;
+
+ const WindowsScreenDataList::const_iterator scend = data.constEnd();
+ for (WindowsScreenDataList::const_iterator it = data.constBegin(); it != scend; ++it) {
+ QWindowsScreenData d = *it;
+ d.depth = depth;
+ d.format = format;
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << "Screen" << d.geometry << d.availableGeometry << d.primary
+ << " physical " << d.physicalSizeMM << " DPI" << d.dpi
+ << "Depth: " << d.depth << " Format: " << d.format;
+ result.append(new QWindowsScreen(d));
+ }
+ return result;
+}
+
+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 = (HWND)window;
+ GetClientRect(hwnd, &r);
+
+ if (width < 0) width = r.right - r.left;
+ if (height < 0) height = r.bottom - r.top;
+
+ // Create and setup bitmap
+ HDC display_dc = GetDC(0);
+ HDC bitmap_dc = CreateCompatibleDC(display_dc);
+ HBITMAP bitmap = CreateCompatibleBitmap(display_dc, width, height);
+ HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap);
+
+ // copy data
+ HDC window_dc = GetDC(hwnd);
+ BitBlt(bitmap_dc, 0, 0, width, height, window_dc, x, y, SRCCOPY | CAPTUREBLT);
+
+ // clean up all but bitmap
+ ReleaseDC(hwnd, window_dc);
+ SelectObject(bitmap_dc, null_bitmap);
+ DeleteDC(bitmap_dc);
+
+ const QPixmap pixmap = qPixmapFromWinHBITMAP(bitmap, HBitmapNoAlpha);
+
+ DeleteObject(bitmap);
+ ReleaseDC(0, display_dc);
+
+ return pixmap;
+}
+
+/*!
+ \brief Find a top level window taking the flags of ChildWindowFromPointEx.
+*/
+
+QWindow *QWindowsScreen::findTopLevelAt(const QPoint &point, unsigned flags)
+{
+ QWindow* result = 0;
+ if (QPlatformWindow *bw = QWindowsContext::instance()->
+ findPlatformWindowAt(GetDesktopWindow(), point, flags))
+ result = QWindowsWindow::topLevelOf(bw->window());
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << point << flags << result;
+ return result;
+}
+
+QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags)
+{
+ QWindow* result = 0;
+ if (QPlatformWindow *bw = QWindowsContext::instance()->
+ findPlatformWindowAt(GetDesktopWindow(), screenPoint, flags))
+ result = bw->window();
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << screenPoint << " returns " << result;
+ return result;
+}
+
+QWindow *QWindowsScreen::windowUnderMouse(unsigned flags)
+{
+ return QWindowsScreen::windowAt(QWindowsCursor::mousePosition(), flags);
+}
+
+QWindowsScreen *QWindowsScreen::screenOf(const QWindow *w)
+{
+ if (w)
+ if (const QScreen *s = w->screen())
+ if (QPlatformScreen *pscr = s->handle())
+ return static_cast<QWindowsScreen *>(pscr);
+ if (const QScreen *ps = QGuiApplication::primaryScreen())
+ if (QPlatformScreen *ppscr = ps->handle())
+ return static_cast<QWindowsScreen *>(ppscr);
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
new file mode 100644
index 0000000000..e24af7af09
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSSCREEN_H
+#define QWINDOWSSCREEN_H
+
+#include "qwindowscursor.h"
+
+#include <QtCore/QList>
+#include <QtCore/QPair>
+#include <QtGui/QPlatformScreen>
+
+QT_BEGIN_NAMESPACE
+
+struct QWindowsScreenData
+{
+ QWindowsScreenData();
+
+ QRect geometry;
+ QRect availableGeometry;
+ QPair<int, int> dpi;
+ QSize physicalSizeMM;
+ int depth;
+ QImage::Format format;
+ bool primary;
+};
+
+class QWindowsScreen : public QPlatformScreen
+{
+public:
+ explicit QWindowsScreen(const QWindowsScreenData &data);
+
+ static QWindowsScreen *screenOf(const QWindow *w = 0);
+
+ virtual QRect geometry() const { return m_data.geometry; }
+ virtual QRect availableGeometry() const { return m_data.availableGeometry; }
+ virtual int depth() const { return m_data.depth; }
+ virtual QImage::Format format() const { return m_data.format; }
+ virtual QSize physicalSize() const { return m_data.physicalSizeMM; }
+
+ virtual QWindow *topLevelAt(const QPoint &point) const
+ { return QWindowsScreen::findTopLevelAt(point, CWP_SKIPINVISIBLE); }
+
+ static QWindow *findTopLevelAt(const QPoint &point, unsigned flags);
+ static QWindow *windowAt(const QPoint &point, unsigned flags = CWP_SKIPINVISIBLE);
+ static QWindow *windowUnderMouse(unsigned flags = CWP_SKIPINVISIBLE);
+
+ static QList<QPlatformScreen *> screens();
+
+ virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+
+ const QWindowsCursor &cursor() const { return m_cursor; }
+ QWindowsCursor &cursor() { return m_cursor; }
+
+private:
+ const QWindowsScreenData m_data;
+ QWindowsCursor m_cursor;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSSCREEN_H
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
new file mode 100644
index 0000000000..8e10ae694a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -0,0 +1,1317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowswindow.h"
+#include "qwindowsnativeimage.h"
+#include "qwindowscontext.h"
+#include "qwindowsdrag.h"
+#include "qwindowsscreen.h"
+#include "qwindowscursor.h"
+
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+#include <QtGui/QWindow>
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static QByteArray debugWinStyle(DWORD style)
+{
+
+ QByteArray rc = "0x";
+ rc += QByteArray::number(qulonglong(style), 16);
+ if (style & WS_POPUP)
+ rc += " WS_POPUP";
+ if (style & WS_CHILD)
+ rc += " WS_CHILD";
+ if (style & WS_OVERLAPPED)
+ rc += " WS_OVERLAPPED";
+ if (style & WS_CLIPSIBLINGS)
+ rc += " WS_CLIPSIBLINGS";
+ if (style & WS_CLIPCHILDREN)
+ rc += " WS_CLIPCHILDREN";
+ if (style & WS_THICKFRAME)
+ rc += " WS_THICKFRAME";
+ if (style & WS_DLGFRAME)
+ rc += " WS_DLGFRAME";
+ if (style & WS_SYSMENU)
+ rc += " WS_SYSMENU";
+ if (style & WS_MINIMIZEBOX)
+ rc += " WS_MINIMIZEBOX";
+ if (style & WS_MAXIMIZEBOX)
+ rc += " WS_MAXIMIZEBOX";
+ return rc;
+}
+
+static QByteArray debugWindowStates(Qt::WindowStates s)
+{
+
+ QByteArray rc = "0x";
+ rc += QByteArray::number(int(s), 16);
+ if (s & Qt::WindowMinimized)
+ rc += " WindowMinimized";
+ if (s & Qt::WindowMaximized)
+ rc += " WindowMaximized";
+ if (s & Qt::WindowFullScreen)
+ rc += " WindowFullScreen";
+ if (s & Qt::WindowActive)
+ rc += " WindowActive";
+ return rc;
+}
+
+QDebug operator<<(QDebug d, const MINMAXINFO &i)
+{
+ d.nospace() << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ','
+ << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x
+ << ',' << i.ptMaxPosition.y << " mintrack="
+ << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y
+ << " maxtrack=" << i.ptMaxTrackSize.x << ','
+ << i.ptMaxTrackSize.y;
+ return d;
+}
+
+static inline QSize qSizeOfRect(const RECT &rect)
+{
+ return QSize(rect.right -rect.left, rect.bottom - rect.top);
+}
+
+static inline QRect qrectFromRECT(const RECT &rect)
+{
+ return QRect(QPoint(rect.left, rect.top), qSizeOfRect(rect));
+}
+
+QDebug operator<<(QDebug d, const RECT &r)
+{
+ d.nospace() << "RECT: left/top=" << r.left << ',' << r.top
+ << " right/bottom=" << r.right << ',' << r.bottom;
+ return d;
+}
+
+QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
+{
+ qDebug().nospace() << "NCCALCSIZE_PARAMS "
+ << qrectFromRECT(p.rgrc[0])
+ << ' ' << qrectFromRECT(p.rgrc[1]) << ' '
+ << qrectFromRECT(p.rgrc[2]);
+ return d;
+}
+
+static inline QRect frameGeometry(HWND hwnd)
+{
+ RECT rect = { 0, 0, 0, 0 };
+ GetWindowRect(hwnd, &rect);
+ return qrectFromRECT(rect);
+}
+
+QSize clientSize(HWND hwnd)
+{
+ RECT rect = { 0, 0, 0, 0 };
+ GetClientRect(hwnd, &rect); // Always returns point 0,0, thus unusable for geometry.
+ return qSizeOfRect(rect);
+}
+
+// from qwidget_win.cpp/maximum layout size check removed.
+static bool shouldShowMaximizeButton(Qt::WindowFlags flags)
+{
+ if (flags & Qt::MSWindowsFixedSizeDialogHint)
+ return false;
+ // if the user explicitly asked for the maximize button, we try to add
+ // it even if the window has fixed size.
+ if (flags & Qt::CustomizeWindowHint &&
+ flags & Qt::WindowMaximizeButtonHint)
+ return true;
+ return flags & Qt::WindowMaximizeButtonHint;
+}
+
+/*!
+ \class WindowCreationData
+ \brief Window creation code.
+
+ This struct gathers all information required to create a window.
+ Window creation is split in 3 steps:
+
+ \list
+ \o fromWindow() Gather all required information
+ \o create() Create the system handle.
+ \o initialize() Post creation initialization steps.
+ \endlist
+
+ The reason for this split is to also enable changing the QWindowFlags
+ by calling:
+
+ \list
+ \o fromWindow() Gather information and determine new system styles
+ \o applyWindowFlags() to apply the new window system styles.
+ \o initialize() Post creation initialization steps.
+ \endlist
+
+ Contains the window creation code formerly in qwidget_win.cpp.
+
+ \sa QWindowCreationContext
+ \ingroup qt-lighthouse-win
+*/
+
+struct WindowCreationData
+{
+ typedef QWindowsWindow::WindowData WindowData;
+
+ WindowCreationData() : parentHandle(0), type(Qt::Widget), style(0), exStyle(0),
+ topLevel(false), popup(false), dialog(false), desktop(false),
+ tool(false) {}
+
+ void fromWindow(const QWindow *w, const Qt::WindowFlags flags, bool isGL);
+ inline WindowData create(const QWindow *w, const QRect &geometry, QString title) const;
+ inline void applyWindowFlags(HWND hwnd) const;
+ void initialize(HWND h, bool frameChange) const;
+
+ Qt::WindowFlags flags;
+ HWND parentHandle;
+ Qt::WindowType type;
+ unsigned style;
+ unsigned exStyle;
+ bool isGL;
+ bool topLevel;
+ bool popup;
+ bool dialog;
+ bool desktop;
+ bool tool;
+};
+
+QDebug operator<<(QDebug debug, const WindowCreationData &d)
+{
+ debug.nospace() << QWindowsWindow::debugWindowFlags(d.flags)
+ << " gs=" << d.isGL << " topLevel=" << d.topLevel << " popup="
+ << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop
+ << " tool=" << d.tool << " style=" << debugWinStyle(d.style)
+ << " exStyle=0x" << QString::number(d.exStyle, 16)
+ << " parent=" << d.parentHandle;
+ return debug;
+}
+
+void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flagsIn,
+ bool isGLin)
+{
+ isGL = isGLin;
+ flags = flagsIn;
+ topLevel = w->isTopLevel();
+
+ if (topLevel && flags == 1) {
+ qWarning("Remove me: fixing toplevel window flags");
+ flags |= Qt::WindowTitleHint|Qt::WindowSystemMenuHint|Qt::WindowMinimizeButtonHint
+ |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
+ }
+
+ type = static_cast<Qt::WindowType>(int(flags) & Qt::WindowType_Mask);
+ switch (type) {
+ case Qt::Dialog:
+ case Qt::Sheet:
+ dialog = true;
+ break;
+ case Qt::Drawer:
+ case Qt::Tool:
+ tool = true;
+ break;
+ case Qt::Popup:
+ popup = true;
+ break;
+ case Qt::Desktop:
+ desktop = true;
+ break;
+ default:
+ break;
+ }
+ if ((flags & Qt::MSWindowsFixedSizeDialogHint))
+ dialog = true;
+
+ // Parent: Use transient parent for top levels.
+ if (popup) {
+ flags |= Qt::WindowStaysOnTopHint; // a popup stays on top, no parent.
+ } else {
+ if (const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
+ parentHandle = QWindowsWindow::handleOf(parentWindow);
+ }
+
+ if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
+ style = WS_POPUP;
+ } else if (topLevel && !desktop) {
+ if (flags & Qt::FramelessWindowHint)
+ style = WS_POPUP; // no border
+ else if (flags & Qt::WindowTitleHint)
+ style = WS_OVERLAPPED;
+ else
+ style = 0;
+ } else {
+ style = WS_CHILD;
+ }
+
+ if (!desktop) {
+ // if (!testAttribute(Qt::WA_PaintUnclipped))
+ // ### Commented out for now as it causes some problems, but
+ // this should be correct anyway, so dig some more into this
+#ifdef Q_FLATTEN_EXPOSE
+ if (isGL)
+ style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // see SetPixelFormat
+#else
+ style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
+#endif
+ if (topLevel) {
+ if ((type == Qt::Window || dialog || tool)) {
+ if (!(flags & Qt::FramelessWindowHint)) {
+ style |= WS_POPUP;
+ if (flags & Qt::MSWindowsFixedSizeDialogHint) {
+ style |= WS_DLGFRAME;
+ } else {
+ style |= WS_THICKFRAME;
+ }
+ }
+ if (flags & Qt::WindowTitleHint)
+ style |= WS_CAPTION;
+ if (flags & Qt::WindowSystemMenuHint)
+ style |= WS_SYSMENU;
+ if (flags & Qt::WindowMinimizeButtonHint)
+ style |= WS_MINIMIZEBOX;
+ if (shouldShowMaximizeButton(flags))
+ style |= WS_MAXIMIZEBOX;
+ if (tool)
+ exStyle |= WS_EX_TOOLWINDOW;
+ if (flags & Qt::WindowContextHelpButtonHint)
+ exStyle |= WS_EX_CONTEXTHELP;
+ } else {
+ exStyle |= WS_EX_TOOLWINDOW;
+ }
+ }
+ }
+}
+
+QWindowsWindow::WindowData
+ WindowCreationData::create(const QWindow *w, const QRect &geometry, QString title) const
+{
+ typedef QSharedPointer<QWindowCreationContext> QWindowCreationContextPtr;
+
+ WindowData result;
+ result.flags = flags;
+
+ if (desktop) { // desktop widget. No frame, hopefully?
+ result.hwnd = GetDesktopWindow();
+ result.geometry = frameGeometry(result.hwnd);
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << "Created desktop window " << w << result.hwnd;
+ return result;
+ }
+
+ const HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
+
+ const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w, isGL);
+
+ if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
+ title = topLevel ? qAppName() : w->objectName();
+
+ const wchar_t *titleUtf16 = reinterpret_cast<const wchar_t *>(title.utf16());
+ const wchar_t *classNameUtf16 = reinterpret_cast<const wchar_t *>(windowClassName.utf16());
+
+ // Capture events before CreateWindowEx() returns.
+ const QWindowCreationContextPtr context(new QWindowCreationContext(w, geometry, style, exStyle));
+ QWindowsContext::instance()->setWindowCreationContext(context);
+
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace()
+ << "CreateWindowEx: " << w << *this
+ << " class=" <<windowClassName << " title=" << title
+ << "\nrequested: " << geometry << ": "
+ << context->frameWidth << 'x' << context->frameHeight
+ << '+' << context->frameX << '+' << context->frameY;
+
+ result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
+ style,
+ context->frameX, context->frameY,
+ context->frameWidth, context->frameHeight,
+ parentHandle, NULL, appinst, NULL);
+ QWindowsContext::instance()->setWindowCreationContext(QWindowCreationContextPtr());
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace()
+ << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
+ << context->obtainedGeometry << context->margins;
+
+ if (!result.hwnd) {
+ qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
+ return result;
+ }
+
+ result.geometry = context->obtainedGeometry;
+ result.frame = context->margins;
+ return result;
+}
+
+void WindowCreationData::applyWindowFlags(HWND hwnd) const
+{
+ // Keep enabled and visible from the current style.
+ const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
+ const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
+
+ const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
+ if (oldStyle != newStyle)
+ SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
+ const LONG_PTR newExStyle = exStyle;
+ if (newExStyle != oldExStyle)
+ SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << __FUNCTION__ << hwnd << *this
+ << "\n Style from " << debugWinStyle(oldStyle) << "\n to "
+ << debugWinStyle(newStyle) << "\n ExStyle from 0x"
+ << QByteArray::number(qulonglong(oldExStyle), 16) << " to 0x"
+ << QByteArray::number(qulonglong(newExStyle), 16);
+}
+
+void WindowCreationData::initialize(HWND hwnd, bool frameChange) const
+{
+ if (desktop || !hwnd)
+ return;
+ UINT flags = SWP_NOMOVE | SWP_NOSIZE;
+ if (frameChange)
+ flags |= SWP_FRAMECHANGED;
+ if (topLevel) {
+ flags |= SWP_NOACTIVATE;
+ if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
+ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, flags);
+ if (flags & Qt::WindowStaysOnBottomHint)
+ qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
+ } else if (flags & Qt::WindowStaysOnBottomHint) {
+ SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, flags);
+ }
+ if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) {
+ HMENU systemMenu = GetSystemMenu(hwnd, FALSE);
+ if (flags & Qt::WindowCloseButtonHint)
+ EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
+ else
+ EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
+ }
+ } else { // child.
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
+ }
+}
+
+/*!
+ \class QWindowsGeometryHint
+ \brief Stores geometry constraints and provides utility functions.
+
+ Geometry constraints ready to apply to a MINMAXINFO taking frame
+ into account.
+
+ \ingroup qt-lighthouse-win
+*/
+
+#define QWINDOWSIZE_MAX ((1<<24)-1)
+
+QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w) :
+ minimumSize(w->minimumSize()),
+ maximumSize(w->maximumSize())
+{
+}
+
+bool QWindowsGeometryHint::validSize(const QSize &s) const
+{
+ const int width = s.width();
+ const int height = s.height();
+ return width >= minimumSize.width() && width <= maximumSize.width()
+ && height >= minimumSize.height() && height <= maximumSize.height();
+}
+
+QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle)
+{
+ RECT rect = {0,0,0,0};
+ style &= ~(WS_OVERLAPPED); // Not permitted, see docs.
+ if (!AdjustWindowRectEx(&rect, style, FALSE, 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;
+
+ return result;
+}
+
+void QWindowsGeometryHint::applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const
+{
+ return applyToMinMaxInfo(GetWindowLong(hwnd, GWL_STYLE),
+ GetWindowLong(hwnd, GWL_EXSTYLE), mmi);
+}
+
+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;
+
+ const QMargins margins = QWindowsGeometryHint::frame(style, exStyle);
+ const int frameWidth = margins.left() + margins.right();
+ const int frameHeight = margins.top() + margins.bottom();
+ if (minimumSize.width() > 0)
+ mmi->ptMinTrackSize.x = minimumSize.width() + frameWidth;
+ if (minimumSize.height() > 0)
+ mmi->ptMinTrackSize.y = minimumSize.height() + frameHeight;
+
+ const int maximumWidth = qMax(maximumSize.width(), minimumSize.width());
+ const int maximumHeight = qMax(maximumSize.height(), minimumSize.height());
+ if (maximumWidth < QWINDOWSIZE_MAX)
+ mmi->ptMaxTrackSize.x = maximumWidth + frameWidth;
+ // 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;
+}
+
+/*!
+ \class QWindowCreationContext
+ \brief Active Context for creating windows.
+
+ There is a phase in window creation (WindowCreationData::create())
+ in which events are sent before the system API CreateWindowEx() returns
+ the handle. These cannot be handled by the platform window as the association
+ of the unknown handle value to the window does not exist yet and as not
+ to trigger recursive handle creation, etc.
+
+ In that phase, an instance of QWindowCreationContext is set on
+ QWindowsContext.
+
+ QWindowCreationContext stores the information to answer the initial
+ WM_GETMINMAXINFO and obtains the corrected size/position.
+
+ \sa WindowCreationData, QWindowsContext
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowCreationContext::QWindowCreationContext(const QWindow *w,
+ const QRect &geometry,
+ DWORD style_, DWORD exStyle_) :
+ geometryHint(w), style(style_), exStyle(exStyle_),
+ requestedGeometry(geometry), obtainedGeometry(geometry),
+ margins(QWindowsGeometryHint::frame(style, exStyle)),
+ frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT),
+ frameWidth(CW_USEDEFAULT), frameHeight(CW_USEDEFAULT)
+{
+ // Geometry of toplevels does not consider window frames.
+ // TODO: No concept of WA_wasMoved yet that would indicate a
+ // CW_USEDEFAULT unless set. For now, assume that 0,0 means 'default'
+ // for toplevels.
+ if (geometry.isValid()) {
+ if (!w->isTopLevel() || geometry.y() >= margins.top()) {
+ frameX = geometry.x() - margins.left();
+ frameY = geometry.y() - margins.top();
+ }
+ frameWidth = geometry.width() + margins.left() + margins.right();
+ frameHeight = geometry.height() + margins.top() + margins.bottom();
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace()
+ << __FUNCTION__ << ' ' << w << " min" << geometryHint.minimumSize
+ << " min" << geometryHint.maximumSize;
+}
+
+/*!
+ \class QWindowsBaseWindow
+ \brief Raster or OpenGL Window.
+
+ \list
+ \o Raster type: handleWmPaint() is implemented to
+ to bitblt the image. The DC can be accessed
+ via getDC/Relase DC, which has a special handling
+ when within a paint event (in that case, the DC obtained
+ from BeginPaint() is returned).
+
+ \o Open GL: The first time QWindowsGLContext accesses
+ the handle, it sets up the pixelformat on the DC
+ which in turn sets it on the window (see flag
+ PixelFormatInitialized).
+ handleWmPaint() is empty (although required).
+ \endlist
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
+ QPlatformWindow(aWindow),
+ m_data(data),
+ m_flags(0),
+ m_hdc(0),
+ m_windowState(aWindow->windowState()),
+ m_opacity(1.0),
+ m_mouseGrab(false),
+ m_cursor(QWindowsScreen::screenOf(aWindow)->cursor().standardWindowCursor()),
+ m_dropTarget(0)
+{
+ if (aWindow->surfaceType() == QWindow::OpenGLSurface)
+ setFlag(OpenGL_Surface);
+ QWindowsContext::instance()->addWindow(m_data.hwnd, this);
+ if (aWindow->isTopLevel()) {
+ switch (aWindow->windowType()) {
+ case Qt::Window:
+ case Qt::Dialog:
+ case Qt::Sheet:
+ case Qt::Drawer:
+ case Qt::Popup:
+ case Qt::Tool:
+ registerDropSite();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+QWindowsWindow::~QWindowsWindow()
+{
+ destroyWindow();
+}
+
+void QWindowsWindow::destroyWindow()
+{
+ if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << m_data.hwnd;
+ if (m_data.hwnd) {
+ unregisterDropSite();
+ if (m_data.hwnd != GetDesktopWindow())
+ DestroyWindow(m_data.hwnd);
+ QWindowsContext::instance()->removeWindow(m_data.hwnd);
+ m_data.hwnd = 0;
+ }
+}
+
+void QWindowsWindow::registerDropSite()
+{
+ if (m_data.hwnd && !m_dropTarget) {
+ m_dropTarget = new QWindowsOleDropTarget(window());
+ RegisterDragDrop(m_data.hwnd, m_dropTarget);
+ CoLockObjectExternal(m_dropTarget, true, true);
+ }
+}
+
+void QWindowsWindow::unregisterDropSite()
+{
+ if (m_data.hwnd && m_dropTarget) {
+ m_dropTarget->Release();
+ CoLockObjectExternal(m_dropTarget, false, true);
+ RevokeDragDrop(m_data.hwnd);
+ m_dropTarget = 0;
+ }
+}
+
+QWindow *QWindowsWindow::topLevelOf(QWindow *w)
+{
+ while (QWindow *parent = w->parent())
+ w = parent;
+ return w;
+}
+
+QWindowsWindow::WindowData
+ QWindowsWindow::WindowData::create(const QWindow *w,
+ const WindowData &parameters,
+ const QString &title,
+ bool isGL)
+{
+ WindowCreationData creationData;
+ creationData.fromWindow(w, parameters.flags, isGL);
+ WindowData result = creationData.create(w, parameters.geometry, title);
+ creationData.initialize(result.hwnd, false);
+ return result;
+}
+
+void QWindowsWindow::setVisible(bool visible)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << m_data.hwnd << visible;
+ if (m_data.hwnd) {
+ if (visible) {
+ show_sys();
+ } else {
+ hide_sys();
+ }
+ }
+}
+
+bool QWindowsWindow::isVisible() const
+{
+ return m_data.hwnd && IsWindowVisible(m_data.hwnd);
+}
+
+// partially from QWidgetPrivate::show_sys()
+void QWindowsWindow::show_sys() const
+{
+ int sm = SW_SHOWNORMAL;
+ bool fakedMaximize = false;
+ const QWindow *w = window();
+ const Qt::WindowFlags flags = w->windowFlags();
+ const Qt::WindowType type = w->windowType();
+ if (w->isTopLevel()) {
+ const Qt::WindowState state = w->windowState();
+ if (state & Qt::WindowMinimized) {
+ sm = SW_SHOWMINIMIZED;
+ if (!isVisible())
+ sm = SW_SHOWMINNOACTIVE;
+ } else if (state & Qt::WindowMaximized) {
+ sm = SW_SHOWMAXIMIZED;
+ // Windows will not behave correctly when we try to maximize a window which does not
+ // have minimize nor maximize buttons in the window frame. Windows would then ignore
+ // non-available geometry, and rather maximize the widget to the full screen, minus the
+ // window frame (caption). So, we do a trick here, by adding a maximize button before
+ // maximizing the widget, and then remove the maximize button afterwards.
+ if (flags & Qt::WindowTitleHint &&
+ !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
+ fakedMaximize = TRUE;
+ setStyle(style() | WS_MAXIMIZEBOX);
+ }
+ }
+ }
+ if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::Tool)
+ sm = SW_SHOWNOACTIVATE;
+
+ ShowWindow(m_data.hwnd, sm);
+
+ if (fakedMaximize) {
+ setStyle(style() & ~WS_MAXIMIZEBOX);
+ SetWindowPos(m_data.hwnd, 0, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
+ | SWP_FRAMECHANGED);
+ }
+}
+
+// partially from QWidgetPrivate::hide_sys()
+void QWindowsWindow::hide_sys() const
+{
+ const Qt::WindowFlags flags = window()->windowFlags();
+ if (flags != Qt::Desktop) {
+ 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);
+ }
+}
+
+void QWindowsWindow::setParent(const QPlatformWindow *newParent)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << window() << newParent;
+
+ if (newParent != parent() && m_data.hwnd)
+ setParent_sys(newParent);
+}
+
+void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
+{
+ HWND parentHWND = 0;
+ if (parent) {
+ const QWindowsWindow *parentW = static_cast<const QWindowsWindow *>(parent);
+ parentHWND = parentW->handle();
+ }
+ SetParent(m_data.hwnd, parentHWND);
+}
+
+void QWindowsWindow::handleShown()
+{
+ QWindowSystemInterface::handleMapEvent(window());
+}
+
+void QWindowsWindow::handleHidden()
+{
+ QWindowSystemInterface::handleUnmapEvent(window());
+}
+
+void QWindowsWindow::setGeometry(const QRect &rect)
+{
+ const QSize oldSize = m_data.geometry.size();
+ m_data.geometry = rect;
+ const QSize newSize = rect.size();
+ // Check on hint.
+ if (newSize != oldSize) {
+ const QWindowsGeometryHint hint(window());
+ if (!hint.validSize(newSize)) {
+ qWarning("%s: Attempt to set a size (%dx%d) violating the constraints"
+ "(%dx%d - %dx%d) on window '%s'.", __FUNCTION__,
+ newSize.width(), newSize.height(),
+ hint.minimumSize.width(), hint.minimumSize.height(),
+ hint.maximumSize.width(), hint.maximumSize.height(),
+ qPrintable(window()->objectName()));
+ }
+ }
+ if (m_data.hwnd) {
+ // A ResizeEvent with resulting geometry will be sent. If we cannot
+ // achieve that size (for example, window title minimal constraint),
+ // notify and warn.
+ setGeometry_sys(rect);
+ if (m_data.geometry != rect) {
+ qWarning("%s: Unable to set geometry %dx%d+%d+%d on '%s'."
+ " Resulting geometry: %dx%d+%d+%d.",
+ __FUNCTION__,
+ rect.width(), rect.height(), rect.x(), rect.y(),
+ qPrintable(window()->objectName()),
+ m_data.geometry.width(), m_data.geometry.height(),
+ m_data.geometry.x(), m_data.geometry.y());
+ }
+ } else {
+ QPlatformWindow::setGeometry(rect);
+ }
+}
+
+void QWindowsWindow::handleMoved()
+{
+ if (!IsIconic(m_data.hwnd)) // Minimize can send nonsensical move events.
+ handleGeometryChange();
+}
+
+void QWindowsWindow::handleResized(int wParam)
+{
+ switch (wParam) {
+ case SIZE_MAXHIDE: // Some other window affected.
+ case SIZE_MAXSHOW:
+ return;
+ case SIZE_MINIMIZED:
+ handleWindowStateChange(Qt::WindowMinimized);
+ return;
+ case SIZE_MAXIMIZED:
+ handleWindowStateChange(Qt::WindowMaximized);
+ handleGeometryChange();
+ break;
+ case SIZE_RESTORED:
+ if (m_windowState != Qt::WindowNoState)
+ handleWindowStateChange(Qt::WindowNoState);
+ handleGeometryChange();
+ break;
+ }
+}
+
+void QWindowsWindow::handleGeometryChange()
+{
+ m_data.geometry = geometry_sys();
+ QPlatformWindow::setGeometry(m_data.geometry);
+ QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
+
+ if (QWindowsContext::verboseEvents || QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << m_data.geometry;
+}
+
+void QWindowsWindow::setGeometry_sys(const QRect &rect) const
+{
+ const QRect frameGeometry = rect + frameMargins();
+
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '>' << __FUNCTION__ << this << window()
+ << " \n from " << geometry_sys() << " 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();
+}
+
+QRect QWindowsWindow::geometry_sys() const
+{
+ // Warning: Returns bogus values when minimized.
+ return frameGeometry(m_data.hwnd) - frameMargins();
+}
+
+/*!
+ Allocates a HDC for the window or returns the temporary one
+ obtained from WinAPI BeginPaint within a WM_PAINT event.
+
+ \sa releaseDC()
+*/
+
+HDC QWindowsWindow::getDC()
+{
+ if (!m_hdc)
+ m_hdc = GetDC(handle());
+ return m_hdc;
+}
+
+/*!
+ Relases the HDC for the window or does nothing in
+ case it was obtained from WinAPI BeginPaint within a WM_PAINT event.
+
+ \sa getDC()
+*/
+
+void QWindowsWindow::releaseDC()
+{
+ if (m_hdc && !testFlag(WithinWmPaint)) {
+ ReleaseDC(handle(), m_hdc);
+ m_hdc = 0;
+ }
+}
+
+void QWindowsWindow::handleWmPaint(HWND hwnd, UINT,
+ WPARAM, LPARAM)
+{
+ PAINTSTRUCT ps;
+ if (testFlag(OpenGL_Surface)) {
+ BeginPaint(hwnd, &ps); // WM_ERASEBKGND needs to be handled.
+ EndPaint(hwnd, &ps);
+ } else {
+ releaseDC();
+ m_hdc = BeginPaint(hwnd, &ps);
+ setFlag(WithinWmPaint);
+
+ const QRect updateRect = qrectFromRECT(ps.rcPaint);
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << this << window() << updateRect;
+
+ QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRegion(updateRect));
+ clearFlag(WithinWmPaint);
+ m_hdc = 0;
+ EndPaint(hwnd, &ps);
+ }
+}
+
+void QWindowsWindow::setWindowTitle(const QString &title)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() <<title;
+ if (m_data.hwnd)
+ SetWindowText(m_data.hwnd, (const wchar_t*)title.utf16());
+}
+
+Qt::WindowFlags QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '>' << __FUNCTION__ << this << window() << "\n from: "
+ << QWindowsWindow::debugWindowFlags(m_data.flags)
+ << "\n to: " << QWindowsWindow::debugWindowFlags(flags);
+ if (m_data.flags != flags) {
+ m_data.flags = flags;
+ if (m_data.hwnd)
+ m_data = setWindowFlags_sys(flags);
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '<' << __FUNCTION__ << "\n returns: "
+ << QWindowsWindow::debugWindowFlags(m_data.flags);
+ return m_data.flags;
+}
+
+QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt) const
+{
+ // Geometry changes have not been observed here. Frames change, though.
+ WindowCreationData creationData;
+ creationData.fromWindow(window(), wt, window()->surfaceType() == QWindow::OpenGLSurface);
+ creationData.applyWindowFlags(m_data.hwnd);
+ creationData.initialize(m_data.hwnd, true);
+ WindowData result = m_data;
+ result.flags = creationData.flags;
+ setFlag(FrameDirty);
+ return result;
+}
+
+void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window()
+ << "\n from " << debugWindowStates(m_windowState)
+ << " to " << debugWindowStates(state);
+ setFlag(FrameDirty);
+ m_windowState = state;
+ QWindowSystemInterface::handleWindowStateChanged(window(), state);
+}
+
+Qt::WindowState QWindowsWindow::setWindowState(Qt::WindowState state)
+{
+ if (m_data.hwnd) {
+ setWindowState_sys(state);
+ m_windowState = state;
+ }
+ return state;
+}
+
+Qt::WindowState QWindowsWindow::windowState_sys() const
+{
+ if (IsIconic(m_data.hwnd))
+ return Qt::WindowMinimized;
+ if (IsZoomed(m_data.hwnd))
+ return Qt::WindowMaximized;
+ if (geometry_sys() == window()->screen()->geometry())
+ return Qt::WindowFullScreen;
+ return Qt::WindowNoState;
+}
+
+Qt::WindowStates QWindowsWindow::windowStates_sys() const
+{
+ Qt::WindowStates result = windowState_sys();
+ if (GetActiveWindow() == m_data.hwnd)
+ result |= Qt::WindowActive;
+ return result;
+}
+
+/*!
+ \brief Change the window state.
+
+ \note Window frames change when maximized;
+ the top margin shrinks somewhat but that cannot be obtained using
+ AdjustWindowRectEx().
+
+ \note Some calls to SetWindowLong require a subsequent call
+ to ShowWindow.
+*/
+
+void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
+{
+ const Qt::WindowStates oldStates = windowStates_sys();
+ // Maintain the active flag as the platform window API does not
+ // use it.
+ Qt::WindowStates newStates = newState;
+ if (oldStates & Qt::WindowActive)
+ newStates |= Qt::WindowActive;
+ if (oldStates == newStates)
+ return;
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '>' << __FUNCTION__ << this << window()
+ << " from " << debugWindowStates(oldStates)
+ << " to " << debugWindowStates(newStates);
+
+ const bool isActive = newStates & Qt::WindowActive;
+ const int max = isActive ? SW_SHOWMAXIMIZED : SW_MAXIMIZE;
+ const int normal = isActive ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
+ const int min = isActive ? SW_SHOWMINIMIZED : SW_MINIMIZE;
+ const bool visible = isVisible();
+
+ setFlag(FrameDirty);
+
+ if ((oldStates & Qt::WindowMaximized) != (newStates & Qt::WindowMaximized)) {
+ if (visible && !(newStates & Qt::WindowMinimized))
+ ShowWindow(m_data.hwnd, (newStates & Qt::WindowMaximized) ? max : normal);
+ }
+
+ if ((oldStates & Qt::WindowFullScreen) != (newStates & Qt::WindowFullScreen)) {
+ if (newStates & Qt::WindowFullScreen) {
+#ifndef Q_FLATTEN_EXPOSE
+ UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
+#else
+ UINT newStyle = WS_POPUP;
+#endif
+ if (style() & WS_SYSMENU)
+ newStyle |= WS_SYSMENU;
+ if (visible)
+ newStyle |= WS_VISIBLE;
+ setStyle(newStyle);
+
+ const QRect r = window()->screen()->geometry();
+ UINT swpf = SWP_FRAMECHANGED;
+ if (newStates & Qt::WindowActive)
+ swpf |= SWP_NOACTIVATE;
+
+ SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
+ } else {
+ if (visible)
+ setStyle(style() | WS_VISIBLE);
+ UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE;
+ if (newStates & Qt::WindowActive)
+ swpf |= SWP_NOACTIVATE;
+ SetWindowPos(m_data.hwnd, 0, 0, 0, 0, 0, swpf);
+
+ // preserve maximized state
+ if (visible)
+ ShowWindow(m_data.hwnd, (newStates & Qt::WindowMaximized) ? max : normal);
+ }
+ }
+
+ if ((oldStates & Qt::WindowMinimized) != (newStates & Qt::WindowMinimized)) {
+ if (visible)
+ ShowWindow(m_data.hwnd, (newStates & Qt::WindowMinimized) ? min :
+ (newStates & Qt::WindowMaximized) ? max : normal);
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '<' << __FUNCTION__ << this << window()
+ << debugWindowStates(newStates);
+}
+
+void QWindowsWindow::setStyle(unsigned s) const
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << debugWinStyle(s);
+ setFlag(FrameDirty);
+ SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
+}
+
+void QWindowsWindow::setExStyle(unsigned s) const
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << __FUNCTION__ << ' ' << this << ' ' << window()
+ << " 0x" << QByteArray::number(s, 16);
+ setFlag(FrameDirty);
+ SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
+}
+
+void QWindowsWindow::raise()
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __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();
+ if (m_data.hwnd)
+ SetWindowPos(m_data.hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+}
+
+void QWindowsWindow::propagateSizeHints()
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window();
+}
+
+QMargins QWindowsWindow::frameMargins() const
+{
+ // Frames are invalidated by style changes (window state, flags).
+ // As they are also required for geometry calculations in resize
+ // event sequences, introduce a dirty flag mechanism to be able
+ // to cache results.
+ if (testFlag(FrameDirty)) {
+ m_data.frame = QWindowsGeometryHint::frame(style(), exStyle());
+ clearFlag(FrameDirty);
+ }
+ return m_data.frame;
+}
+
+void QWindowsWindow::setOpacity(qreal level)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << level;
+ if (m_opacity != level) {
+ m_opacity = level;
+ if (m_data.hwnd)
+ setOpacity_sys(level);
+ }
+}
+
+void QWindowsWindow::setOpacity_sys(qreal level) const
+{
+ const long wl = GetWindowLong(m_data.hwnd, GWL_EXSTYLE);
+ const bool isOpaque = level == 1.0;
+
+ if (isOpaque) {
+ if (wl & WS_EX_LAYERED)
+ SetWindowLong(m_data.hwnd, GWL_EXSTYLE, wl & ~WS_EX_LAYERED);
+ } else {
+ if ((wl & WS_EX_LAYERED) == 0)
+ SetWindowLong(m_data.hwnd, GWL_EXSTYLE, wl | WS_EX_LAYERED);
+ if (m_data.flags & Qt::FramelessWindowHint) {
+ BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), AC_SRC_ALPHA};
+ QWindowsContext::user32dll.updateLayeredWindow(m_data.hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA);
+ } else {
+ QWindowsContext::user32dll.setLayeredWindowAttributes(m_data.hwnd, 0, (int)(level * 255), LWA_ALPHA);
+ }
+ }
+}
+
+void QWindowsWindow::requestActivateWindow()
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window();
+ if (m_data.hwnd)
+ SetForegroundWindow(m_data.hwnd);
+}
+
+bool QWindowsWindow::setKeyboardGrabEnabled(bool grab)
+{
+ if (!m_data.hwnd) {
+ qWarning("%s: No handle", __FUNCTION__);
+ return false;
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << grab;
+
+ QWindowsContext *context = QWindowsContext::instance();
+ if (grab) {
+ context->setKeyGrabber(window());
+ } else {
+ if (context->keyGrabber() == window())
+ context->setKeyGrabber(0);
+ }
+ return true;
+}
+
+bool QWindowsWindow::setMouseGrabEnabled(bool grab)
+{
+ bool result = false;
+ if (!m_data.hwnd) {
+ qWarning("%s: No handle", __FUNCTION__);
+ return result;
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << window() << grab;
+
+ if (m_mouseGrab != grab) {
+ m_mouseGrab = grab;
+ if (isVisible())
+ setMouseGrabEnabled_sys(grab);
+ }
+ return grab;
+}
+
+void QWindowsWindow::setMouseGrabEnabled_sys(bool grab)
+{
+ if (grab) {
+ SetCapture(m_data.hwnd);
+ } else {
+ ReleaseCapture();
+ }
+}
+
+void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
+{
+ const QWindowsGeometryHint hint(window());
+ hint.applyToMinMaxInfo(m_data.hwnd, mmi);
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << window() << *mmi;
+}
+
+/*!
+ \brief Applies to cursor property set on the window to the global cursor
+ unless there is an override cursor.
+
+ \sa QWindowsCursor
+*/
+
+void QWindowsWindow::applyCursor()
+{
+ if (!QGuiApplication::overrideCursor())
+ SetCursor(m_cursor.handle());
+}
+
+void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
+{
+ if (c.handle() != m_cursor.handle()) {
+ const bool underMouse = QWindowsContext::instance()->windowUnderMouse() == window();
+ if (QWindowsContext::verboseWindows)
+ qDebug() << window() << __FUNCTION__ << "Shape=" << c.cursor().shape()
+ << " isWUM=" << underMouse;
+ m_cursor = c;
+ if (underMouse)
+ applyCursor();
+ }
+}
+
+/*!
+ \brief Find a child window using flags from ChildWindowFromPointEx.
+*/
+
+QWindowsWindow *QWindowsWindow::childAtScreenPoint(const QPoint &screenPoint,
+ unsigned cwexflags) const
+{
+ if (m_data.hwnd)
+ return QWindowsContext::instance()->findPlatformWindowAt(m_data.hwnd, screenPoint, cwexflags);
+ return 0;
+}
+
+QWindowsWindow *QWindowsWindow::childAt(const QPoint &clientPoint, unsigned cwexflags) const
+{
+ if (m_data.hwnd)
+ return childAtScreenPoint(QWindowsGeometryHint::mapToGlobal(m_data.hwnd, clientPoint),
+ cwexflags);
+ return 0;
+}
+
+QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf)
+{
+ const int iwf = int(wf);
+ QByteArray rc = "0x";
+ rc += QByteArray::number(iwf, 16);
+ rc += " [";
+
+ switch ((iwf & Qt::WindowType_Mask)) {
+ case Qt::Widget:
+ rc += " Widget";
+ break;
+ case Qt::Window:
+ rc += " Window";
+ break;
+ case Qt::Dialog:
+ rc += " Dialog";
+ break;
+ case Qt::Sheet:
+ rc += " Sheet";
+ break;
+ case Qt::Popup:
+ rc += " Popup";
+ break;
+ case Qt::Tool:
+ rc += " Tool";
+ break;
+ case Qt::ToolTip:
+ rc += " ToolTip";
+ break;
+ case Qt::SplashScreen:
+ rc += " SplashScreen";
+ break;
+ case Qt::Desktop:
+ rc += " Desktop";
+ break;
+ case Qt::SubWindow:
+ rc += " SubWindow";
+ break;
+ }
+ if (iwf & Qt::MSWindowsFixedSizeDialogHint) rc += " MSWindowsFixedSizeDialogHint";
+ if (iwf & Qt::MSWindowsOwnDC) rc += " MSWindowsOwnDC";
+ if (iwf & Qt::FramelessWindowHint) rc += " FramelessWindowHint";
+ if (iwf & Qt::WindowTitleHint) rc += " WindowTitleHint";
+ if (iwf & Qt::WindowSystemMenuHint) rc += " WindowSystemMenuHint";
+ if (iwf & Qt::WindowMinimizeButtonHint) rc += " WindowMinimizeButtonHint";
+ if (iwf & Qt::WindowMaximizeButtonHint) rc += " WindowMaximizeButtonHint";
+ if (iwf & Qt::WindowContextHelpButtonHint) rc += " WindowContextHelpButtonHint";
+ if (iwf & Qt::WindowShadeButtonHint) rc += " WindowShadeButtonHint";
+ if (iwf & Qt::WindowStaysOnTopHint) rc += " WindowStaysOnTopHint";
+ if (iwf & Qt::CustomizeWindowHint) rc += " CustomizeWindowHint";
+ if (iwf & Qt::WindowStaysOnBottomHint) rc += " WindowStaysOnBottomHint";
+ if (iwf & Qt::WindowCloseButtonHint) rc += " WindowCloseButtonHint";
+ rc += ']';
+ return rc;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
new file mode 100644
index 0000000000..dfaeb2a86d
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSWINDOW_H
+#define QWINDOWSWINDOW_H
+
+#include "qtwindows_additional.h"
+#include "qwindowscursor.h"
+
+#include <QtGui/QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsOleDropTarget;
+class QDebug;
+
+struct QWindowsGeometryHint
+{
+ QWindowsGeometryHint() {}
+ explicit QWindowsGeometryHint(const QWindow *w);
+ static QMargins frame(DWORD style, DWORD exStyle);
+ void applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXINFO *mmi) const;
+ void applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const;
+ bool validSize(const QSize &s) const;
+
+ static inline QPoint mapToGlobal(HWND hwnd, const QPoint &);
+ static inline QPoint mapToGlobal(const QWindow *w, const QPoint &);
+ static inline QPoint mapFromGlobal(const HWND hwnd, const QPoint &);
+ static inline QPoint mapFromGlobal(const QWindow *w, const QPoint &);
+
+ QSize minimumSize;
+ QSize maximumSize;
+};
+
+struct QWindowCreationContext
+{
+ QWindowCreationContext(const QWindow *w, const QRect &r,
+ DWORD style, DWORD exStyle);
+
+ void applyToMinMaxInfo(MINMAXINFO *mmi) const
+ { geometryHint.applyToMinMaxInfo(style, exStyle, mmi); }
+
+ QWindowsGeometryHint geometryHint;
+ DWORD style;
+ DWORD exStyle;
+ QRect requestedGeometry;
+ QRect obtainedGeometry;
+ QMargins margins;
+ int frameX; // Passed on to CreateWindowEx(), including frame.
+ int frameY;
+ int frameWidth;
+ int frameHeight;
+};
+
+class QWindowsWindow : public QPlatformWindow
+{
+public:
+ enum Flags
+ {
+ OpenGL_Surface = 0x1,
+ WithinWmPaint = 0x2,
+ PixelFormatInitialized = 0x4,
+ FrameDirty = 0x8 //! Frame outdated by setStyle, recalculate in next query.
+ };
+
+ struct WindowData
+ {
+ WindowData() : hwnd(0) {}
+
+ Qt::WindowFlags flags;
+ QRect geometry;
+ QMargins frame; // Do not use directly for windows, see FrameDirty.
+ HWND hwnd;
+
+ static WindowData create(const QWindow *w,
+ const WindowData &parameters,
+ const QString &title,
+ bool isGL);
+ };
+
+ QWindowsWindow(QWindow *window, const WindowData &data);
+ ~QWindowsWindow();
+
+ virtual void setGeometry(const QRect &rect);
+ virtual QRect geometry() const { return m_data.geometry; }
+
+ virtual void setVisible(bool visible);
+ bool isVisible() const;
+ virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ virtual Qt::WindowState setWindowState(Qt::WindowState state);
+
+ HWND handle() const { return m_data.hwnd; }
+
+ virtual WId winId() const { return WId(m_data.hwnd); }
+ virtual void setParent(const QPlatformWindow *window);
+
+ virtual void setWindowTitle(const QString &title);
+ virtual void raise();
+ virtual void lower();
+
+ virtual void propagateSizeHints();
+ virtual QMargins frameMargins() const;
+
+ virtual void setOpacity(qreal level);
+ virtual void requestActivateWindow();
+
+ virtual bool setKeyboardGrabEnabled(bool grab);
+ virtual bool setMouseGrabEnabled(bool grab);
+
+ Qt::WindowState windowState_sys() const;
+ Qt::WindowStates windowStates_sys() const;
+
+ inline unsigned style() const
+ { return GetWindowLongPtr(m_data.hwnd, GWL_STYLE); }
+ void setStyle(unsigned s) const;
+ inline unsigned exStyle() const
+ { return GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE); }
+ void setExStyle(unsigned s) const;
+
+ void handleWmPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+ void handleMoved();
+ void handleResized(int wParam);
+ void handleShown();
+ void handleHidden();
+
+ static inline HWND handleOf(const QWindow *w);
+ static inline QWindowsWindow *baseWindowOf(const QWindow *w);
+ static QWindow *topLevelOf(QWindow *w);
+ static inline void *userDataOf(HWND hwnd);
+ static inline void setUserDataOf(HWND hwnd, void *ud);
+
+ HDC getDC();
+ void releaseDC();
+
+ void getSizeHints(MINMAXINFO *mmi) const;
+
+ QWindowsWindowCursor cursor() const { return m_cursor; }
+ void setCursor(const QWindowsWindowCursor &c);
+ void applyCursor();
+
+ QWindowsWindow *childAt(const QPoint &clientPoint,
+ unsigned cwexflags = CWP_SKIPINVISIBLE) const;
+ QWindowsWindow *childAtScreenPoint(const QPoint &screenPoint,
+ unsigned cwexflags = CWP_SKIPINVISIBLE) const;
+
+ static QByteArray debugWindowFlags(Qt::WindowFlags wf);
+
+ inline bool testFlag(unsigned f) const { return (m_flags & f) != 0; }
+ inline void setFlag(unsigned f) const { m_flags |= f; }
+ inline void clearFlag(unsigned f) const { m_flags &= ~f; }
+
+private:
+ inline void show_sys() const;
+ inline void hide_sys() const;
+ inline void setGeometry_sys(const QRect &rect) const;
+ inline QRect geometry_sys() const;
+ inline WindowData setWindowFlags_sys(Qt::WindowFlags wt) const;
+ inline void setWindowState_sys(Qt::WindowState newState);
+ inline void setParent_sys(const QPlatformWindow *parent) const;
+ inline void setOpacity_sys(qreal level) const;
+ inline void setMouseGrabEnabled_sys(bool grab);
+ void destroyWindow();
+ void registerDropSite();
+ void unregisterDropSite();
+ void handleGeometryChange();
+ void handleWindowStateChange(Qt::WindowState state);
+
+ mutable WindowData m_data;
+ mutable unsigned m_flags;
+ HDC m_hdc;
+ Qt::WindowState m_windowState;
+ qreal m_opacity;
+ bool m_mouseGrab;
+ QWindowsWindowCursor m_cursor;
+ QWindowsOleDropTarget *m_dropTarget;
+};
+
+// Conveniences for window frames.
+inline QRect operator+(const QRect &r, const QMargins &m)
+{
+ return r.adjusted(-m.left(), -m.top(), m.right(), m.bottom());
+}
+
+inline QRect operator-(const QRect &r, const QMargins &m)
+{
+ return r.adjusted(m.left(), m.top(), -m.right(), -m.bottom());
+}
+
+// Debug
+QDebug operator<<(QDebug d, const RECT &r);
+QDebug operator<<(QDebug d, const MINMAXINFO &i);
+QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p);
+
+// ---------- QWindowsGeometryHint inline functions.
+QPoint QWindowsGeometryHint::mapToGlobal(HWND hwnd, const QPoint &qp)
+{
+ POINT p = { qp.x(), qp.y() };
+ ClientToScreen(hwnd, &p);
+ return QPoint(p.x, p.y);
+}
+
+QPoint QWindowsGeometryHint::mapFromGlobal(const HWND hwnd, const QPoint &qp)
+{
+ POINT p = { qp.x(), qp.y() };
+ ScreenToClient(hwnd, &p);
+ return QPoint(p.x, p.y);
+}
+
+QPoint QWindowsGeometryHint::mapToGlobal(const QWindow *w, const QPoint &p)
+ { return QWindowsGeometryHint::mapToGlobal(QWindowsWindow::handleOf(w), p); }
+
+QPoint QWindowsGeometryHint::mapFromGlobal(const QWindow *w, const QPoint &p)
+ { return QWindowsGeometryHint::mapFromGlobal(QWindowsWindow::handleOf(w), p); }
+
+
+// ---------- QWindowsBaseWindow inline functions.
+
+QWindowsWindow *QWindowsWindow::baseWindowOf(const QWindow *w)
+{
+ if (w)
+ if (QPlatformWindow *pw = w->handle())
+ return static_cast<QWindowsWindow *>(pw);
+ return 0;
+}
+
+HWND QWindowsWindow::handleOf(const QWindow *w)
+{
+ if (const QWindowsWindow *bw = QWindowsWindow::baseWindowOf(w))
+ return bw->handle();
+ return 0;
+}
+
+void *QWindowsWindow::userDataOf(HWND hwnd)
+{
+ return (void *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+}
+
+void QWindowsWindow::setUserDataOf(HWND hwnd, void *ud)
+{
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, LONG_PTR(ud));
+}
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSWINDOW_H
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
new file mode 100644
index 0000000000..e5627ae574
--- /dev/null
+++ b/src/plugins/platforms/windows/windows.pro
@@ -0,0 +1,70 @@
+TARGET = windows
+load(qt_plugin)
+
+QT *= core-private
+QT *= gui-private
+
+INCLUDEPATH += ../../../3rdparty/harfbuzz/src
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+# Note: OpenGL32 must precede Gdi32 as it overwrites some functions.
+LIBS *= -lOpenGL32 -lGdi32 -lUser32 -lOle32 -lWinspool -lImm32
+win32-g++: LIBS *= -luuid
+
+contains(QT_CONFIG, directwrite) {
+ LIBS *= -ldwrite
+ SOURCES += qwindowsfontenginedirectwrite.cpp
+ HEADERS += qwindowsfontenginedirectwrite.h
+} else {
+ DEFINES *= QT_NO_DIRECTWRITE
+}
+
+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 \
+ qwindowsglcontext.cpp \
+ qwindowsclipboard.cpp \
+ qwindowsole.cpp \
+ qwindowsmime.cpp \
+ qwindowsdrag.cpp \
+ qwindowscursor.cpp \
+ pixmaputils.cpp \
+ qwindowsinputcontext.cpp
+
+HEADERS += \
+ qwindowsnativeimage.h \
+ qwindowswindow.h \
+ qwindowsintegration.h \
+ qwindowscontext.h \
+ qwindowsbackingstore.h \
+ qwindowsscreen.h \
+ qwindowskeymapper.h \
+ qwindowsfontengine.h \
+ qwindowsfontdatabase.h \
+ qwindowsmousehandler.h \
+ qwindowsguieventdispatcher.h \
+ qtwindowsglobal.h \
+ qtwindows_additional.h \
+ qwindowsglcontext.h \
+ qwindowsclipboard.h \
+ qwindowsole.h \
+ qwindowsmime.h \
+ qwindowsdrag.h \
+ qwindowsinternalmimedata.h \
+ qwindowscursor.h \
+ pixmaputils.h \
+ array.h \
+ qwindowsinputcontext.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
index 17a86e6d08..d2884f109c 100644
--- a/src/plugins/platforms/xcb/README
+++ b/src/plugins/platforms/xcb/README
@@ -1,3 +1,3 @@
Required packages:
-libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev
+libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev
diff --git a/src/plugins/platforms/xcb/main.cpp b/src/plugins/platforms/xcb/main.cpp
index 7fee7455be..c544f7073d 100644
--- a/src/plugins/platforms/xcb/main.cpp
+++ b/src/plugins/platforms/xcb/main.cpp
@@ -58,11 +58,10 @@ QStringList QXcbIntegrationPlugin::keys() const
return list;
}
-QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters)
{
- Q_UNUSED(paramList);
if (system.toLower() == "xcb")
- return new QXcbIntegration;
+ return new QXcbIntegration(parameters);
return 0;
}
diff --git a/src/plugins/platforms/xcb/qdri2context.cpp b/src/plugins/platforms/xcb/qdri2context.cpp
index 8bcdacb92b..5f4aff5455 100644
--- a/src/plugins/platforms/xcb/qdri2context.cpp
+++ b/src/plugins/platforms/xcb/qdri2context.cpp
@@ -45,7 +45,7 @@
#include "qxcbconnection.h"
#include <QtCore/QDebug>
-#include <QtGui/QWidget>
+#include <QtWidgets/QWidget>
#include <xcb/dri2.h>
#include <xcb/xfixes.h>
@@ -134,9 +134,9 @@ QDri2Context::QDri2Context(QXcbWindow *window)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERER,d->depth);
//restore the old current context
- const QPlatformGLContext *currentContext = QPlatformGLContext::currentContext();
+ const QPlatformOpenGLContext *currentContext = QPlatformOpenGLContext::currentContext();
if (currentContext)
- const_cast<QPlatformGLContext*>(currentContext)->makeCurrent();
+ const_cast<QPlatformOpenGLContext*>(currentContext)->makeCurrent();
}
QDri2Context::~QDri2Context()
@@ -146,7 +146,6 @@ QDri2Context::~QDri2Context()
void QDri2Context::makeCurrent()
{
- QPlatformGLContext::makeCurrent();
Q_D(QDri2Context);
eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,d->eglContext);
@@ -156,7 +155,6 @@ void QDri2Context::makeCurrent()
void QDri2Context::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
Q_D(QDri2Context);
eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
}
diff --git a/src/plugins/platforms/xcb/qdri2context.h b/src/plugins/platforms/xcb/qdri2context.h
index be7d637643..ec8b251c3f 100644
--- a/src/plugins/platforms/xcb/qdri2context.h
+++ b/src/plugins/platforms/xcb/qdri2context.h
@@ -42,14 +42,14 @@
#ifndef QDRI2CONTEXT_H
#define QDRI2CONTEXT_H
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
class QXcbWindow;
class QDri2ContextPrivate;
struct xcb_dri2_dri2_buffer_t;
-class QDri2Context : public QPlatformGLContext
+class QDri2Context : public QPlatformOpenGLContext
{
Q_DECLARE_PRIVATE(QDri2Context);
public:
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index 8e04cbcb71..41bceaf406 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -41,7 +41,6 @@
#include <QDebug>
#include <QLibrary>
-#include <QGLFormat>
#include "qxcbwindow.h"
#include "qxcbscreen.h"
@@ -50,72 +49,56 @@
#include <X11/Xutil.h>
#include <GL/glx.h>
+#include <QtGui/QOpenGLContext>
+
#include "qglxintegration.h"
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
#include <dlfcn.h>
#endif
-QGLXContext::QGLXContext(Window window, QXcbScreen *screen, const QPlatformWindowFormat &format)
- : QPlatformGLContext()
+QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : QPlatformOpenGLContext()
, m_screen(screen)
- , m_drawable((Drawable)window)
, m_context(0)
{
- Q_XCB_NOOP(m_screen->connection());
- const QPlatformGLContext *sharePlatformContext;
- sharePlatformContext = format.sharedGLContext();
GLXContext shareGlxContext = 0;
- if (sharePlatformContext)
- shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext();
+ if (share)
+ shareGlxContext = static_cast<const QGLXContext*>(share)->glxContext();
GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format);
m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE);
- m_windowFormat = qglx_platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
- Q_XCB_NOOP(m_screen->connection());
-}
-
-QGLXContext::QGLXContext(QXcbScreen *screen, Drawable drawable, GLXContext context)
- : QPlatformGLContext(), m_screen(screen), m_drawable(drawable), m_context(context)
-{
-
+ m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
}
QGLXContext::~QGLXContext()
{
- Q_XCB_NOOP(m_screen->connection());
- if (m_context)
- glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
- Q_XCB_NOOP(m_screen->connection());
+ glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
}
-void QGLXContext::makeCurrent()
+bool QGLXContext::makeCurrent(QPlatformSurface *surface)
{
- Q_XCB_NOOP(m_screen->connection());
- QPlatformGLContext::makeCurrent();
- glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), m_drawable, m_context);
- Q_XCB_NOOP(m_screen->connection());
+ Q_ASSERT(surface);
+
+ GLXDrawable glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
+
+ return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), glxDrawable, m_context);
}
void QGLXContext::doneCurrent()
{
- Q_XCB_NOOP(m_screen->connection());
- QPlatformGLContext::doneCurrent();
glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0);
- Q_XCB_NOOP(m_screen->connection());
}
-void QGLXContext::swapBuffers()
+void QGLXContext::swapBuffers(QPlatformSurface *surface)
{
- Q_XCB_NOOP(m_screen->connection());
- glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable);
- Q_XCB_NOOP(m_screen->connection());
+ GLXDrawable glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
+ glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable);
}
-void* QGLXContext::getProcAddress(const QString& procName)
+void (*QGLXContext::getProcAddress(const QByteArray &procName)) ()
{
- Q_XCB_NOOP(m_screen->connection());
typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
static bool resolved = false;
@@ -144,10 +127,10 @@ void* QGLXContext::getProcAddress(const QString& procName)
}
if (!glXGetProcAddressARB)
return 0;
- return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data()));
+ return (void (*)())glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData()));
}
-QPlatformWindowFormat QGLXContext::platformWindowFormat() const
+QSurfaceFormat QGLXContext::format() const
{
- return m_windowFormat;
+ return m_format;
}
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index 84de7b7143..bbe67b653a 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -43,36 +43,34 @@
#define QGLXINTEGRATION_H
#include "qxcbwindow.h"
+#include "qxcbscreen.h"
-#include <QtGui/QPlatformGLContext>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QSurfaceFormat>
#include <QtCore/QMutex>
#include <GL/glx.h>
-class QGLXContext : public QPlatformGLContext
+class QGLXContext : public QPlatformOpenGLContext
{
public:
- QGLXContext(Window window, QXcbScreen *xd, const QPlatformWindowFormat &format);
+ QGLXContext(QXcbScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QGLXContext();
- virtual void makeCurrent();
- virtual void doneCurrent();
- virtual void swapBuffers();
- virtual void* getProcAddress(const QString& procName);
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ void swapBuffers(QPlatformSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
- GLXContext glxContext() const { return m_context; }
+ QSurfaceFormat format() const;
- QPlatformWindowFormat platformWindowFormat() const;
+ GLXContext glxContext() const { return m_context; }
private:
QXcbScreen *m_screen;
- Drawable m_drawable;
GLXContext m_context;
- QPlatformWindowFormat m_windowFormat;
-
- QGLXContext (QXcbScreen *screen, Drawable drawable, GLXContext context);
+ QSurfaceFormat m_format;
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 4fcd207df3..fadcb4d5b8 100644
--- a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qxcbwindowsurface.h"
+#include "qxcbbackingstore.h"
#include "qxcbconnection.h"
#include "qxcbscreen.h"
@@ -52,9 +52,11 @@
#include <sys/shm.h>
#include <stdio.h>
+#include <errno.h>
#include <qdebug.h>
#include <qpainter.h>
+#include <qscreen.h>
class QXcbShmImage : public QXcbObject
{
@@ -63,6 +65,7 @@ public:
~QXcbShmImage() { destroy(); }
QImage *image() { return &m_qimage; }
+ QSize size() const { return m_qimage.size(); }
void put(xcb_window_t window, const QPoint &dst, const QRect &source);
void preparePaint(const QRegion &region);
@@ -97,30 +100,54 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI
~0,
0);
- m_shm_info.shmid = shmget (IPC_PRIVATE,
- m_xcb_image->stride * m_xcb_image->height, IPC_CREAT|0777);
+ const int segmentSize = m_xcb_image->stride * m_xcb_image->height;
+ if (!segmentSize)
+ return;
+ int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0777);
+ if (id == -1)
+ qWarning("QXcbShmImage: shmget() failed (%d) for size %d (%dx%d)",
+ errno, segmentSize, size.width(), size.height());
+ else
+ m_shm_info.shmid = id;
m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
m_shm_info.shmseg = xcb_generate_id(xcb_connection());
xcb_generic_error_t *error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
if (error) {
- qWarning() << "QXcbWindowSurface: Unable to attach to shared memory segment";
free(error);
- }
- if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
- qWarning() << "QXcbWindowSurface: Error while marking the shared memory segment to be destroyed";
+ shmdt(m_shm_info.shmaddr);
+ shmctl(m_shm_info.shmid, IPC_RMID, 0);
+
+ m_shm_info.shmaddr = 0;
+
+ m_xcb_image->data = (uint8_t *)qMalloc(segmentSize);
+ } else {
+ if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
+ qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed";
+ }
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
void QXcbShmImage::destroy()
{
- Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg));
+ const int segmentSize = m_xcb_image ? (m_xcb_image->stride * m_xcb_image->height) : 0;
+ if (segmentSize && m_shm_info.shmaddr)
+ Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg));
+
xcb_image_destroy(m_xcb_image);
- shmdt(m_shm_info.shmaddr);
- shmctl(m_shm_info.shmid, IPC_RMID, 0);
+
+ if (segmentSize) {
+ if (m_shm_info.shmaddr) {
+ shmdt(m_shm_info.shmaddr);
+ shmctl(m_shm_info.shmid, IPC_RMID, 0);
+ } else {
+ qFree(m_xcb_image->data);
+ }
+ }
+
if (m_gc)
Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
}
@@ -139,18 +166,32 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
}
Q_XCB_NOOP(connection());
- xcb_image_shm_put(xcb_connection(),
+ if (m_shm_info.shmaddr) {
+ xcb_image_shm_put(xcb_connection(),
+ window,
+ m_gc,
+ m_xcb_image,
+ m_shm_info,
+ source.x(),
+ source.y(),
+ target.x(),
+ target.y(),
+ source.width(),
+ source.height(),
+ false);
+ } else {
+ xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, source.x(), source.y(), source.width(), source.height(),
+ 0, 0, 0);
+ xcb_image_put(xcb_connection(),
window,
m_gc,
- m_xcb_image,
- m_shm_info,
- source.x(),
- source.y(),
+ subimage,
target.x(),
target.y(),
- source.width(),
- source.height(),
- false);
+ 0);
+
+ xcb_image_destroy(subimage);
+ }
Q_XCB_NOOP(connection());
m_dirty = m_dirty | source;
@@ -168,29 +209,30 @@ void QXcbShmImage::preparePaint(const QRegion &region)
}
}
-QXcbWindowSurface::QXcbWindowSurface(QWidget *widget, bool setDefaultSurface)
- : QWindowSurface(widget, setDefaultSurface)
+QXcbBackingStore::QXcbBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
, m_image(0)
, m_syncingResize(false)
{
- QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(widget));
+ QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle());
setConnection(screen->connection());
}
-QXcbWindowSurface::~QXcbWindowSurface()
+QXcbBackingStore::~QXcbBackingStore()
{
delete m_image;
}
-QPaintDevice *QXcbWindowSurface::paintDevice()
+QPaintDevice *QXcbBackingStore::paintDevice()
{
return m_image->image();
}
-void QXcbWindowSurface::beginPaint(const QRegion &region)
+void QXcbBackingStore::beginPaint(const QRegion &region)
{
m_image->preparePaint(region);
+#if 0
if (m_image->image()->hasAlphaChannel()) {
QPainter p(m_image->image());
p.setCompositionMode(QPainter::CompositionMode_Source);
@@ -200,29 +242,27 @@ void QXcbWindowSurface::beginPaint(const QRegion &region)
p.fillRect(*it, blank);
}
}
+#endif
}
-void QXcbWindowSurface::endPaint(const QRegion &)
+void QXcbBackingStore::endPaint(const QRegion &)
{
}
-void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
QRect bounds = region.boundingRect();
- if (size().isEmpty() || !geometry().contains(bounds))
+ if (!m_image || m_image->size().isEmpty())
return;
Q_XCB_NOOP(connection());
- QXcbWindow *window = static_cast<QXcbWindow *>(widget->window()->platformWindow());
-
- extern QWidgetData* qt_widget_data(QWidget *);
- QPoint widgetOffset = qt_qwidget_data(widget)->wrect.topLeft();
+ QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
QVector<QRect> rects = region.rects();
for (int i = 0; i < rects.size(); ++i)
- m_image->put(window->window(), rects.at(i).topLeft() - widgetOffset, rects.at(i).translated(offset));
+ m_image->put(platformWindow->xcb_window(), rects.at(i).topLeft(), rects.at(i).translated(offset));
Q_XCB_NOOP(connection());
@@ -230,23 +270,22 @@ void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoi
xcb_flush(xcb_connection());
connection()->sync();
m_syncingResize = false;
- window->updateSyncRequestCounter();
+ platformWindow->updateSyncRequestCounter();
}
}
-void QXcbWindowSurface::resize(const QSize &size)
+void QXcbBackingStore::resize(const QSize &size, const QRegion &)
{
- if (size == QWindowSurface::size())
+ if (m_image && size == m_image->size())
return;
Q_XCB_NOOP(connection());
- QWindowSurface::resize(size);
- QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window()));
- QXcbWindow* win = static_cast<QXcbWindow *>(window()->platformWindow());
+ QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle());
+ QXcbWindow* win = static_cast<QXcbWindow *>(window()->handle());
delete m_image;
- m_image = new QXcbShmImage(screen, size, win->depth(), win->format());
+ m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat());
Q_XCB_NOOP(connection());
m_syncingResize = true;
@@ -254,9 +293,9 @@ void QXcbWindowSurface::resize(const QSize &size)
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-bool QXcbWindowSurface::scroll(const QRegion &area, int dx, int dy)
+bool QXcbBackingStore::scroll(const QRegion &area, int dx, int dy)
{
- if (m_image->image()->isNull())
+ if (!m_image || m_image->image()->isNull())
return false;
m_image->preparePaint(area);
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.h b/src/plugins/platforms/xcb/qxcbbackingstore.h
index 5f61815b65..db94d26b09 100644
--- a/src/plugins/platforms/xcb/qxcbwindowsurface.h
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.h
@@ -39,10 +39,10 @@
**
****************************************************************************/
-#ifndef QXCBWINDOWSURFACE_H
-#define QXCBWINDOWSURFACE_H
+#ifndef QXCBBACKINGSTORE_H
+#define QXCBBACKINGSTORE_H
-#include <private/qwindowsurface_p.h>
+#include <qplatformbackingstore_qpa.h>
#include <xcb/xcb.h>
@@ -50,15 +50,15 @@
class QXcbShmImage;
-class QXcbWindowSurface : public QXcbObject, public QWindowSurface
+class QXcbBackingStore : public QXcbObject, public QPlatformBackingStore
{
public:
- QXcbWindowSurface(QWidget *widget, bool setDefaultSurface = true);
- ~QXcbWindowSurface();
+ QXcbBackingStore(QWindow *widget);
+ ~QXcbBackingStore();
QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
bool scroll(const QRegion &area, int dx, int dy);
void beginPaint(const QRegion &);
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
new file mode 100644
index 0000000000..550b8cbd73
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -0,0 +1,848 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbclipboard.h"
+
+#include "qxcbconnection.h"
+#include "qxcbscreen.h"
+#include "qxcbmime.h"
+
+#include <private/qguiapplication_p.h>
+#include <QElapsedTimer>
+
+#include <QtCore/QDebug>
+
+#include <xcb/xcb_icccm.h>
+
+class QXcbClipboardMime : public QXcbMime
+{
+ Q_OBJECT
+public:
+ QXcbClipboardMime(QClipboard::Mode mode, QXcbClipboard *clipboard)
+ : QXcbMime()
+ , m_clipboard(clipboard)
+ {
+ switch (mode) {
+ case QClipboard::Selection:
+ modeAtom = XCB_ATOM_PRIMARY;
+ break;
+
+ case QClipboard::Clipboard:
+ modeAtom = m_clipboard->atom(QXcbAtom::CLIPBOARD);
+ break;
+
+ default:
+ qWarning("QTestLiteMime: Internal error: Unsupported clipboard mode");
+ break;
+ }
+ }
+
+protected:
+ QStringList formats_sys() const
+ {
+ if (empty())
+ return QStringList();
+
+ if (!formatList.count()) {
+ QXcbClipboardMime *that = const_cast<QXcbClipboardMime *>(this);
+ // get the list of targets from the current clipboard owner - we do this
+ // once so that multiple calls to this function don't require multiple
+ // server round trips...
+ that->format_atoms = m_clipboard->getDataInFormat(modeAtom, m_clipboard->atom(QXcbAtom::TARGETS));
+
+ if (format_atoms.size() > 0) {
+ xcb_atom_t *targets = (xcb_atom_t *) format_atoms.data();
+ int size = format_atoms.size() / sizeof(xcb_atom_t);
+
+ for (int i = 0; i < size; ++i) {
+ if (targets[i] == 0)
+ continue;
+
+ QString format = mimeAtomToString(m_clipboard->connection(), targets[i]);
+ if (!formatList.contains(format))
+ that->formatList.append(format);
+ }
+ }
+ }
+
+ return formatList;
+ }
+
+ bool hasFormat_sys(const QString &format) const
+ {
+ QStringList list = formats();
+ return list.contains(format);
+ }
+
+ QVariant retrieveData_sys(const QString &fmt, QVariant::Type requestedType) const
+ {
+ if (fmt.isEmpty() || empty())
+ return QByteArray();
+
+ (void)formats(); // trigger update of format list
+
+ QList<xcb_atom_t> atoms;
+ xcb_atom_t *targets = (xcb_atom_t *) format_atoms.data();
+ int size = format_atoms.size() / sizeof(xcb_atom_t);
+ for (int i = 0; i < size; ++i)
+ atoms.append(targets[i]);
+
+ QByteArray encoding;
+ xcb_atom_t fmtatom = mimeAtomForFormat(m_clipboard->connection(), fmt, requestedType, atoms, &encoding);
+
+ if (fmtatom == 0)
+ return QVariant();
+
+ return mimeConvertToFormat(m_clipboard->connection(), fmtatom, m_clipboard->getDataInFormat(modeAtom, fmtatom), fmt, requestedType, encoding);
+ }
+private:
+ bool empty() const
+ {
+ return m_clipboard->getSelectionOwner(modeAtom) == XCB_NONE;
+ }
+
+
+ xcb_atom_t modeAtom;
+ QXcbClipboard *m_clipboard;
+ QStringList formatList;
+ QByteArray format_atoms;
+};
+
+const int QXcbClipboard::clipboard_timeout = 5000;
+
+QXcbClipboard::QXcbClipboard(QXcbConnection *c)
+ : QXcbObject(c), QPlatformClipboard()
+ , m_requestor(XCB_NONE)
+ , m_owner(XCB_NONE)
+{
+ Q_ASSERT(QClipboard::Clipboard == 0);
+ Q_ASSERT(QClipboard::Selection == 1);
+ m_xClipboard[QClipboard::Clipboard] = 0;
+ m_xClipboard[QClipboard::Selection] = 0;
+ m_clientClipboard[QClipboard::Clipboard] = 0;
+ m_clientClipboard[QClipboard::Selection] = 0;
+ m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME;
+ m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME;
+
+ m_screen = connection()->screens().at(connection()->primaryScreen());
+
+ int x = 0, y = 0, w = 3, h = 3;
+
+ m_owner = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ m_owner, // window id
+ m_screen->screen()->root, // parent window id
+ x, y, w, h,
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_screen->screen()->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
+
+ if (connection()->hasXFixes()) {
+ const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
+ XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
+ XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;
+ Q_XCB_CALL(xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, XCB_ATOM_PRIMARY, mask));
+ Q_XCB_CALL(xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask));
+ }
+}
+
+QXcbClipboard::~QXcbClipboard()
+{
+ // Transfer the clipboard content to the clipboard manager if we own a selection
+ if (m_timestamp[QClipboard::Clipboard] != XCB_CURRENT_TIME ||
+ m_timestamp[QClipboard::Selection] != XCB_CURRENT_TIME) {
+
+ // First we check if there is a clipboard manager.
+ xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));
+ xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0);
+ if (reply && reply->owner != XCB_NONE) {
+ // we delete the property so the manager saves all TARGETS.
+ xcb_delete_property(xcb_connection(), m_owner, atom(QXcbAtom::_QT_SELECTION));
+ xcb_convert_selection(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD_MANAGER), atom(QXcbAtom::SAVE_TARGETS),
+ atom(QXcbAtom::_QT_SELECTION), connection()->time());
+ connection()->sync();
+
+ // waiting until the clipboard manager fetches the content.
+ if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, 5000)) {
+ qWarning("QClipboard: Unable to receive an event from the "
+ "clipboard manager in a reasonable time");
+ }
+ }
+ }
+}
+
+
+xcb_window_t QXcbClipboard::getSelectionOwner(xcb_atom_t atom) const
+{
+ xcb_connection_t *c = xcb_connection();
+ xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom);
+ xcb_get_selection_owner_reply_t *reply;
+ reply = xcb_get_selection_owner_reply(c, cookie, 0);
+ xcb_window_t win = reply->owner;
+ free(reply);
+ return win;
+}
+
+xcb_atom_t QXcbClipboard::atomForMode(QClipboard::Mode mode) const
+{
+ if (mode == QClipboard::Clipboard)
+ return atom(QXcbAtom::CLIPBOARD);
+ if (mode == QClipboard::Selection)
+ return XCB_ATOM_PRIMARY;
+ return XCB_NONE;
+}
+
+QClipboard::Mode QXcbClipboard::modeForAtom(xcb_atom_t a) const
+{
+ if (a == XCB_ATOM_PRIMARY)
+ return QClipboard::Selection;
+ if (a == atom(QXcbAtom::CLIPBOARD))
+ return QClipboard::Clipboard;
+ // not supported enum value, used to detect errors
+ return QClipboard::FindBuffer;
+}
+
+
+QMimeData * QXcbClipboard::mimeData(QClipboard::Mode mode)
+{
+ if (mode > QClipboard::Selection)
+ return 0;
+
+ xcb_window_t clipboardOwner = getSelectionOwner(atomForMode(mode));
+ if (clipboardOwner == owner()) {
+ return m_clientClipboard[mode];
+ } else {
+ if (!m_xClipboard[mode])
+ m_xClipboard[mode] = new QXcbClipboardMime(mode, this);
+
+ return m_xClipboard[mode];
+ }
+}
+
+void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
+{
+ if (mode > QClipboard::Selection)
+ return;
+
+ xcb_atom_t modeAtom = atomForMode(mode);
+
+ if (m_clientClipboard[mode] == data)
+ return;
+
+ xcb_window_t newOwner = XCB_NONE;
+
+ if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
+ delete m_clientClipboard[mode];
+ m_clientClipboard[mode] = 0;
+ m_timestamp[mode] = XCB_CURRENT_TIME;
+
+ if (data) {
+ newOwner = owner();
+
+ m_clientClipboard[mode] = data;
+ m_timestamp[mode] = connection()->time();
+ }
+
+ xcb_set_selection_owner(xcb_connection(), newOwner, modeAtom, connection()->time());
+
+ if (getSelectionOwner(modeAtom) != newOwner) {
+ qWarning("QClipboard::setData: Cannot set X11 selection owner");
+ }
+
+}
+
+bool QXcbClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ if (mode <= QClipboard::Selection)
+ return true;
+ return false;
+}
+
+bool QXcbClipboard::ownsMode(QClipboard::Mode mode) const
+{
+ if (m_owner == XCB_NONE || mode > QClipboard::Selection)
+ return false;
+
+ Q_ASSERT(m_timestamp[mode] == XCB_CURRENT_TIME || getSelectionOwner(atomForMode(mode)) == m_owner);
+
+ return m_timestamp[mode] != XCB_CURRENT_TIME;
+}
+
+xcb_window_t QXcbClipboard::requestor() const
+{
+ if (!m_requestor) {
+ const int x = 0, y = 0, w = 3, h = 3;
+ QXcbClipboard *that = const_cast<QXcbClipboard *>(this);
+
+ xcb_window_t window = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ window, // window id
+ m_screen->screen()->root, // parent window id
+ x, y, w, h,
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_screen->screen()->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
+
+ uint32_t mask = XCB_EVENT_MASK_PROPERTY_CHANGE;
+ xcb_change_window_attributes(xcb_connection(), window, XCB_CW_EVENT_MASK, &mask);
+
+ that->setRequestor(window);
+ }
+ return m_requestor;
+}
+
+void QXcbClipboard::setRequestor(xcb_window_t window)
+{
+ if (m_requestor != XCB_NONE) {
+ xcb_destroy_window(xcb_connection(), m_requestor);
+ }
+ m_requestor = window;
+}
+
+xcb_window_t QXcbClipboard::owner() const
+{
+ return m_owner;
+}
+
+xcb_atom_t QXcbClipboard::sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property)
+{
+ QVector<xcb_atom_t> types;
+ QStringList formats = QInternalMimeData::formatsHelper(d);
+ for (int i = 0; i < formats.size(); ++i) {
+ QList<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), formats.at(i));
+ for (int j = 0; j < atoms.size(); ++j) {
+ if (!types.contains(atoms.at(j)))
+ types.append(atoms.at(j));
+ }
+ }
+ types.append(atom(QXcbAtom::TARGETS));
+ types.append(atom(QXcbAtom::MULTIPLE));
+ types.append(atom(QXcbAtom::TIMESTAMP));
+ types.append(atom(QXcbAtom::SAVE_TARGETS));
+
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, XCB_ATOM_ATOM,
+ 32, types.size(), (const void *)types.constData());
+ return property;
+}
+
+xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property)
+{
+ xcb_atom_t atomFormat = target;
+ int dataFormat = 0;
+ QByteArray data;
+
+ QString fmt = QXcbMime::mimeAtomToString(connection(), target);
+ if (fmt.isEmpty()) { // Not a MIME type we have
+// qDebug() << "QClipboard: send_selection(): converting to type" << connection()->atomName(target) << "is not supported";
+ return XCB_NONE;
+ }
+// qDebug() << "QClipboard: send_selection(): converting to type" << fmt;
+
+ if (QXcbMime::mimeDataForAtom(connection(), target, d, &data, &atomFormat, &dataFormat)) {
+
+ // don't allow INCR transfers when using MULTIPLE or to
+ // Motif clients (since Motif doesn't support INCR)
+ static xcb_atom_t motif_clip_temporary = atom(QXcbAtom::CLIP_TEMPORARY);
+ bool allow_incr = property != motif_clip_temporary;
+
+ // X_ChangeProperty protocol request is 24 bytes
+ const int increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24;
+ if (data.size() > increment && allow_incr) {
+ long bytes = data.size();
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property,
+ atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes);
+
+// (void)new QClipboardINCRTransaction(window, property, atomFormat, dataFormat, data, increment);
+ qWarning() << "not implemented INCR just YET!";
+ return property;
+ }
+
+ // make sure we can perform the XChangeProperty in a single request
+ if (data.size() > increment)
+ return XCB_NONE; // ### perhaps use several XChangeProperty calls w/ PropModeAppend?
+ int dataSize = data.size() / (dataFormat / 8);
+ // use a single request to transfer data
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, atomFormat,
+ dataFormat, dataSize, (const void *)data.constData());
+ }
+ return property;
+}
+
+void QXcbClipboard::handleSelectionClearRequest(xcb_selection_clear_event_t *event)
+{
+ QClipboard::Mode mode = modeForAtom(event->selection);
+ if (mode > QClipboard::Selection)
+ return;
+
+ // ignore the event if it was generated before we gained selection ownership
+ if (m_timestamp[mode] != XCB_CURRENT_TIME && event->time <= m_timestamp[mode])
+ return;
+
+// DEBUG("QClipboard: new selection owner 0x%lx at time %lx (ours %lx)",
+// XGetSelectionOwner(dpy, XA_PRIMARY),
+// xevent->xselectionclear.time, d->timestamp);
+
+// if (!waiting_for_data) {
+ setMimeData(0, mode);
+ emitChanged(mode);
+// } else {
+// pending_selection_changed = true;
+// if (! pending_timer_id)
+// pending_timer_id = QApplication::clipboard()->startTimer(0);
+// }
+}
+
+void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
+{
+ if (requestor() && req->requestor == requestor()) {
+ qDebug() << "This should be caught before";
+ return;
+ }
+
+ xcb_selection_notify_event_t event;
+ event.response_type = XCB_SELECTION_NOTIFY;
+ event.requestor = req->requestor;
+ event.selection = req->selection;
+ event.target = req->target;
+ event.property = XCB_NONE;
+ event.time = req->time;
+
+ QMimeData *d;
+ QClipboard::Mode mode = modeForAtom(req->selection);
+ if (mode > QClipboard::Selection) {
+ qWarning() << "QClipboard: Unknown selection" << connection()->atomName(req->selection);
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ return;
+ }
+
+ d = m_clientClipboard[mode];
+
+ if (!d) {
+ qWarning("QClipboard: Cannot transfer data, no data available");
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ return;
+ }
+
+ if (m_timestamp[mode] == XCB_CURRENT_TIME // we don't own the selection anymore
+ || (req->time != XCB_CURRENT_TIME && req->time < m_timestamp[mode])) {
+ qDebug("QClipboard: SelectionRequest too old");
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ return;
+ }
+
+ xcb_atom_t xa_targets = atom(QXcbAtom::TARGETS);
+ xcb_atom_t xa_multiple = atom(QXcbAtom::MULTIPLE);
+ xcb_atom_t xa_timestamp = atom(QXcbAtom::TIMESTAMP);
+
+ struct AtomPair { xcb_atom_t target; xcb_atom_t property; } *multi = 0;
+ xcb_atom_t multi_type = XCB_NONE;
+ int multi_format = 0;
+ int nmulti = 0;
+ int imulti = -1;
+ bool multi_writeback = false;
+
+ if (req->target == xa_multiple) {
+ QByteArray multi_data;
+ if (req->property == XCB_NONE
+ || !clipboardReadProperty(req->requestor, req->property, false, &multi_data,
+ 0, &multi_type, &multi_format)
+ || multi_format != 32) {
+ // MULTIPLE property not formatted correctly
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ return;
+ }
+ nmulti = multi_data.size()/sizeof(*multi);
+ multi = new AtomPair[nmulti];
+ memcpy(multi,multi_data.data(),multi_data.size());
+ imulti = 0;
+ }
+
+ for (; imulti < nmulti; ++imulti) {
+ xcb_atom_t target;
+ xcb_atom_t property;
+
+ if (multi) {
+ target = multi[imulti].target;
+ property = multi[imulti].property;
+ } else {
+ target = req->target;
+ property = req->property;
+ if (property == XCB_NONE) // obsolete client
+ property = target;
+ }
+
+ xcb_atom_t ret = XCB_NONE;
+ if (target == XCB_NONE || property == XCB_NONE) {
+ ;
+ } else if (target == xa_timestamp) {
+ if (m_timestamp[mode] != XCB_CURRENT_TIME) {
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, req->requestor,
+ property, XCB_ATOM_INTEGER, 32, 1, &m_timestamp[mode]);
+ ret = property;
+ } else {
+ qWarning("QClipboard: Invalid data timestamp");
+ }
+ } else if (target == xa_targets) {
+ ret = sendTargetsSelection(d, req->requestor, property);
+ } else {
+ ret = sendSelection(d, target, req->requestor, property);
+ }
+
+ if (nmulti > 0) {
+ if (ret == XCB_NONE) {
+ multi[imulti].property = XCB_NONE;
+ multi_writeback = true;
+ }
+ } else {
+ event.property = ret;
+ break;
+ }
+ }
+
+ if (nmulti > 0) {
+ if (multi_writeback) {
+ // according to ICCCM 2.6.2 says to put None back
+ // into the original property on the requestor window
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, req->requestor, req->property,
+ multi_type, 32, nmulti*2, (const void *)multi);
+ }
+
+ delete [] multi;
+ event.property = req->property;
+ }
+
+ // send selection notify to requestor
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+}
+
+void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event)
+{
+ QClipboard::Mode mode = modeForAtom(event->selection);
+ if (event->owner != owner() && m_clientClipboard[mode] && m_timestamp[mode] < event->selection_timestamp) {
+ setMimeData(0, mode);
+ emitChanged(mode);
+ }
+}
+
+
+static inline int maxSelectionIncr(xcb_connection_t *c)
+{
+ int l = xcb_get_maximum_request_length(c);
+ return (l > 65536 ? 65536*4 : l*4) - 100;
+}
+
+bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format) const
+{
+ int maxsize = maxSelectionIncr(xcb_connection());
+ ulong bytes_left; // bytes_after
+ xcb_atom_t dummy_type;
+ int dummy_format;
+
+ if (!type) // allow null args
+ type = &dummy_type;
+ if (!format)
+ format = &dummy_format;
+
+ // Don't read anything, just get the size of the property data
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ if (!reply || reply->type == XCB_NONE) {
+ buffer->resize(0);
+ return false;
+ }
+ *type = reply->type;
+ *format = reply->format;
+ bytes_left = reply->bytes_after;
+ free(reply);
+
+ int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left;
+
+ switch (*format) {
+ case 8:
+ default:
+ format_inc = sizeof(char) / 1;
+ break;
+
+ case 16:
+ format_inc = sizeof(short) / 2;
+ proplen *= sizeof(short) / 2;
+ break;
+
+ case 32:
+ format_inc = sizeof(long) / 4;
+ proplen *= sizeof(long) / 4;
+ break;
+ }
+
+ int newSize = proplen;
+ buffer->resize(newSize);
+
+ bool ok = (buffer->size() == newSize);
+
+ if (ok && newSize) {
+ // could allocate buffer
+
+ while (bytes_left) {
+ // more to read...
+
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4));
+ reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ if (!reply || reply->type == XCB_NONE) {
+ free(reply);
+ break;
+ }
+ *type = reply->type;
+ *format = reply->format;
+ bytes_left = reply->bytes_after;
+ char *data = (char *)xcb_get_property_value(reply);
+ int length = xcb_get_property_value_length(reply);
+
+ offset += length / (32 / *format);
+ length *= format_inc * (*format) / 8;
+
+ // Here we check if we get a buffer overflow and tries to
+ // recover -- this shouldn't normally happen, but it doesn't
+ // hurt to be defensive
+ if ((int)(buffer_offset + length) > buffer->size()) {
+ length = buffer->size() - buffer_offset;
+
+ // escape loop
+ bytes_left = 0;
+ }
+
+ memcpy(buffer->data() + buffer_offset, data, length);
+ buffer_offset += length;
+
+ free(reply);
+ }
+ }
+
+
+ // correct size, not 0-term.
+ if (size)
+ *size = buffer_offset;
+
+ if (deleteProperty)
+ xcb_delete_property(xcb_connection(), win, property);
+
+ connection()->flush();
+
+ return ok;
+}
+
+
+namespace
+{
+ class Notify {
+ public:
+ Notify(xcb_window_t win, int t)
+ : window(win), type(t) {}
+ xcb_window_t window;
+ int type;
+ bool check(xcb_generic_event_t *event) const {
+ if (!event)
+ return false;
+ int t = event->response_type & 0x7f;
+ if (t != type)
+ return false;
+ if (t == XCB_PROPERTY_NOTIFY) {
+ xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ if (pn->window == window)
+ return true;
+ } else if (t == XCB_SELECTION_NOTIFY) {
+ xcb_selection_notify_event_t *sn = (xcb_selection_notify_event_t *)event;
+ if (sn->requestor == window)
+ return true;
+ }
+ return false;
+ }
+ };
+ class ClipboardEvent {
+ public:
+ ClipboardEvent(QXcbConnection *c)
+ { clipboard = c->internAtom("CLIPBOARD"); }
+ xcb_atom_t clipboard;
+ bool check(xcb_generic_event_t *e) const {
+ if (!e)
+ return false;
+ int type = e->response_type & 0x7f;
+ if (type == XCB_SELECTION_REQUEST) {
+ xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)e;
+ return sr->selection == XCB_ATOM_PRIMARY || sr->selection == clipboard;
+ } else if (type == XCB_SELECTION_CLEAR) {
+ xcb_selection_clear_event_t *sc = (xcb_selection_clear_event_t *)e;
+ return sc->selection == XCB_ATOM_PRIMARY || sc->selection == clipboard;
+ }
+ return false;
+ }
+ };
+}
+
+xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout)
+{
+ QElapsedTimer timer;
+ timer.start();
+ do {
+ Notify notify(win, type);
+ xcb_generic_event_t *e = connection()->checkEvent(notify);
+ if (e)
+ return e;
+
+ // process other clipboard events, since someone is probably requesting data from us
+ ClipboardEvent clipboard(connection());
+ e = connection()->checkEvent(clipboard);
+ if (e) {
+ connection()->handleXcbEvent(e);
+ free(e);
+ }
+
+ connection()->flush();
+
+ // sleep 50 ms, so we don't use up CPU cycles all the time.
+ struct timeval usleep_tv;
+ usleep_tv.tv_sec = 0;
+ usleep_tv.tv_usec = 50000;
+ select(0, 0, 0, 0, &usleep_tv);
+ } while (timer.elapsed() < timeout);
+
+ return 0;
+}
+
+QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm)
+{
+ QByteArray buf;
+ QByteArray tmp_buf;
+ bool alloc_error = false;
+ int length;
+ int offset = 0;
+
+ if (nbytes > 0) {
+ // Reserve buffer + zero-terminator (for text data)
+ // We want to complete the INCR transfer even if we cannot
+ // allocate more memory
+ buf.resize(nbytes+1);
+ alloc_error = buf.size() != nbytes+1;
+ }
+
+ for (;;) {
+ connection()->flush();
+ xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY, clipboard_timeout);
+ if (!ge)
+ break;
+
+ xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge;
+ if (event->atom != property || event->state != XCB_PROPERTY_NEW_VALUE)
+ continue;
+ if (clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0)) {
+ if (length == 0) { // no more data, we're done
+ if (nullterm) {
+ buf.resize(offset+1);
+ buf[offset] = '\0';
+ } else {
+ buf.resize(offset);
+ }
+ return buf;
+ } else if (!alloc_error) {
+ if (offset+length > (int)buf.size()) {
+ buf.resize(offset+length+65535);
+ if (buf.size() != offset+length+65535) {
+ alloc_error = true;
+ length = buf.size() - offset;
+ }
+ }
+ memcpy(buf.data()+offset, tmp_buf.constData(), length);
+ tmp_buf.resize(0);
+ offset += length;
+ }
+ } else {
+ break;
+ }
+
+ free(ge);
+ }
+
+ // timed out ... create a new requestor window, otherwise the requestor
+ // could consider next request to be still part of this timed out request
+ setRequestor(0);
+
+ return QByteArray();
+}
+
+QByteArray QXcbClipboard::getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtAtom)
+{
+ return getSelection(modeAtom, fmtAtom, atom(QXcbAtom::_QT_SELECTION));
+}
+
+QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property)
+{
+ QByteArray buf;
+ xcb_window_t win = requestor();
+
+ xcb_delete_property(xcb_connection(), win, property);
+ xcb_convert_selection(xcb_connection(), win, selection, target, property, connection()->time());
+
+ connection()->sync();
+
+ xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_SELECTION_NOTIFY, clipboard_timeout);
+ bool no_selection = !ge || ((xcb_selection_notify_event_t *)ge)->property == XCB_NONE;
+ free(ge);
+
+ if (no_selection)
+ return buf;
+
+ xcb_atom_t type;
+ if (clipboardReadProperty(win, property, true, &buf, 0, &type, 0)) {
+ if (type == atom(QXcbAtom::INCR)) {
+ int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
+ buf = clipboardReadIncrementalProperty(win, property, nbytes, false);
+ }
+ }
+
+ return buf;
+}
+
+#include "qxcbclipboard.moc"
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h
new file mode 100644
index 0000000000..d23f93529b
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbclipboard.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBCLIPBOARD_H
+#define QXCBCLIPBOARD_H
+
+#include <QPlatformClipboard>
+#include <qxcbobject.h>
+#include <xcb/xcb.h>
+#include <xcb/xfixes.h>
+
+class QXcbConnection;
+class QXcbScreen;
+class QXcbClipboardMime;
+
+class QXcbClipboard : public QXcbObject, public QPlatformClipboard
+{
+public:
+ QXcbClipboard(QXcbConnection *connection);
+ ~QXcbClipboard();
+
+ QMimeData *mimeData(QClipboard::Mode mode);
+ void setMimeData(QMimeData *data, QClipboard::Mode mode);
+
+ bool supportsMode(QClipboard::Mode mode) const;
+ bool ownsMode(QClipboard::Mode mode) const;
+
+ QXcbScreen *screen() const { return m_screen; }
+
+ xcb_window_t requestor() const;
+ void setRequestor(xcb_window_t window);
+
+ xcb_window_t owner() const;
+
+ void handleSelectionRequest(xcb_selection_request_event_t *event);
+ void handleSelectionClearRequest(xcb_selection_clear_event_t *event);
+ void handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event);
+
+ bool clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format) const;
+ QByteArray clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm);
+
+ QByteArray getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtatom);
+
+ xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
+ QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property);
+
+private:
+ xcb_generic_event_t *waitForClipboardEvent(xcb_window_t win, int type, int timeout);
+
+ xcb_atom_t sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property);
+ xcb_atom_t sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property);
+
+ xcb_atom_t atomForMode(QClipboard::Mode mode) const;
+ QClipboard::Mode modeForAtom(xcb_atom_t atom) const;
+
+ QXcbScreen *m_screen;
+
+ // Selection and Clipboard
+ QXcbClipboardMime *m_xClipboard[2];
+ QMimeData *m_clientClipboard[2];
+ xcb_timestamp_t m_timestamp[2];
+
+ xcb_window_t m_requestor;
+ xcb_window_t m_owner;
+
+ static const int clipboard_timeout;
+
+};
+
+#endif // QXCBCLIPBOARD_H
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 80a1624380..a0b894602d 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -39,33 +39,41 @@
**
****************************************************************************/
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtCore/QDebug>
+
#include "qxcbconnection.h"
#include "qxcbkeyboard.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
+#include "qxcbclipboard.h"
+#include "qxcbdrag.h"
+#include "qxcbwmsupport.h"
#include <QtAlgorithms>
#include <QSocketNotifier>
-#include <QtGui/private/qapplication_p.h>
#include <QAbstractEventDispatcher>
-
-#include <QtCore/QDebug>
+#include <QTimer>
#include <stdio.h>
#include <errno.h>
+#include <xcb/xfixes.h>
#ifdef XCB_USE_XLIB
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#endif
+#ifdef XCB_USE_RENDER
+#include <xcb/render.h>
+#endif
+
#ifdef XCB_USE_EGL //dont pull in eglext prototypes
#include <EGL/egl.h>
#endif
#ifdef XCB_USE_DRI2
#include <xcb/dri2.h>
-#include <xcb/xfixes.h>
extern "C" {
#include <xf86drm.h>
}
@@ -83,12 +91,13 @@ QXcbConnection::QXcbConnection(const char *displayName)
, m_dri2_support_probed(false)
, m_has_support_for_dri2(false)
#endif
+ , xfixes_first_event(0)
{
- int primaryScreen = 0;
+ m_primaryScreen = 0;
#ifdef XCB_USE_XLIB
Display *dpy = XOpenDisplay(m_displayName.constData());
- primaryScreen = DefaultScreen(dpy);
+ m_primaryScreen = DefaultScreen(dpy);
m_connection = XGetXCBConnection(dpy);
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
m_xlib_display = dpy;
@@ -100,13 +109,33 @@ QXcbConnection::QXcbConnection(const char *displayName)
m_has_egl = eglInitialize(eglDisplay,&major,&minor);
#endif //XCB_USE_EGL
#else
- m_connection = xcb_connect(m_displayName.constData(), &primaryScreen);
-
+ m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen);
#endif //XCB_USE_XLIB
+
+ if (m_connection)
+ printf("Successfully connected to display %s\n", m_displayName.constData());
+
+ m_reader = new QXcbEventReader(m_connection);
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+ connect(m_reader, SIGNAL(eventPending()), this, SLOT(processXcbEvents()), Qt::QueuedConnection);
+ m_reader->start();
+#else
+ QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
+
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
+ connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
+ connect(dispatcher, SIGNAL(awake()), this, SLOT(processXcbEvents()));
+#endif
+
+ xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
+
m_setup = xcb_get_setup(xcb_connection());
initializeAllAtoms();
+ m_time = XCB_CURRENT_TIME;
+
xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
int screenNumber = 0;
@@ -115,25 +144,38 @@ QXcbConnection::QXcbConnection(const char *displayName)
xcb_screen_next(&it);
}
+ 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);
+
+ initializeXFixes();
+ initializeXRender();
+
+ m_wmSupport = new QXcbWMSupport(this);
m_keyboard = new QXcbKeyboard(this);
+ m_clipboard = new QXcbClipboard(this);
+ m_drag = new QXcbDrag(this);
#ifdef XCB_USE_DRI2
initializeDri2();
#endif
-
- QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
-
- QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(qApp->thread());
- connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
-
sync();
}
QXcbConnection::~QXcbConnection()
{
+ delete m_clipboard;
+
qDeleteAll(m_screens);
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+ sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION);
+ m_reader->wait();
+#endif
+ delete m_reader;
+
#ifdef XCB_USE_XLIB
XCloseDisplay((Display *)m_xlib_display);
#else
@@ -143,22 +185,26 @@ QXcbConnection::~QXcbConnection()
delete m_keyboard;
}
-QXcbWindow *platformWindowFromId(xcb_window_t id)
+void QXcbConnection::addWindow(xcb_window_t id, QXcbWindow *window)
{
- QWidget *widget = QWidget::find(id);
- if (widget)
- return static_cast<QXcbWindow *>(widget->platformWindow());
- return 0;
+ m_mapper.insert(id, window);
+}
+
+void QXcbConnection::removeWindow(xcb_window_t id)
+{
+ m_mapper.remove(id);
+}
+
+QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
+{
+ return m_mapper.value(id, 0);
}
-#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, window, handler) \
+#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
{ \
event_t *e = (event_t *)event; \
- if (QXcbWindow *platformWindow = platformWindowFromId(e->window)) { \
- QObjectPrivate *d = QObjectPrivate::get(platformWindow->widget()); \
- if (!d->wasDeleted) \
- platformWindow->handler(e); \
- } \
+ if (QXcbWindow *platformWindow = platformWindowFromId(e->windowMember)) \
+ platformWindow->handler(e); \
} \
break;
@@ -166,7 +212,7 @@ break;
{ \
event_t *e = (event_t *)event; \
if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) \
- m_keyboard->handler(platformWindow->widget(), e); \
+ m_keyboard->handler(platformWindow, e); \
} \
break;
@@ -373,6 +419,7 @@ const char *xcb_protocol_request_codes[] =
#ifdef Q_XCB_DEBUG
void QXcbConnection::log(const char *file, int line, int sequence)
{
+ QMutexLocker locker(&m_callLogMutex);
CallInfo info;
info.sequence = sequence;
info.file = file;
@@ -392,6 +439,7 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
int(error->minor_code));
#ifdef Q_XCB_DEBUG
+ QMutexLocker locker(&m_callLogMutex);
int i = 0;
for (; i < m_callLog.size(); ++i) {
if (m_callLog.at(i).sequence == error->sequence) {
@@ -409,67 +457,236 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
#endif
}
+void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+{
+#ifdef Q_XCB_DEBUG
+ {
+ QMutexLocker locker(&m_callLogMutex);
+ int i = 0;
+ for (; i < m_callLog.size(); ++i)
+ if (m_callLog.at(i).sequence >= event->sequence)
+ break;
+ m_callLog.remove(0, i);
+ }
+#endif
+ bool handled = true;
+
+ uint response_type = event->response_type & ~0x80;
+
+ switch (response_type) {
+ case XCB_EXPOSE:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
+ case XCB_BUTTON_PRESS:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
+ case XCB_BUTTON_RELEASE:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
+ case XCB_MOTION_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
+ case XCB_CONFIGURE_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
+ case XCB_MAP_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
+ case XCB_UNMAP_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
+ case XCB_CLIENT_MESSAGE:
+ handleClientMessageEvent((xcb_client_message_event_t *)event);
+ case XCB_ENTER_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
+ case XCB_LEAVE_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
+ case XCB_FOCUS_IN:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
+ case XCB_FOCUS_OUT:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
+ case XCB_KEY_PRESS:
+ HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
+ case XCB_KEY_RELEASE:
+ HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
+ case XCB_MAPPING_NOTIFY:
+ m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
+ break;
+ case XCB_SELECTION_REQUEST:
+ {
+ xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event;
+ if (sr->selection == atom(QXcbAtom::XdndSelection))
+ m_drag->handleSelectionRequest(sr);
+ else
+ m_clipboard->handleSelectionRequest(sr);
+ break;
+ }
+ case XCB_SELECTION_CLEAR:
+ setTime(((xcb_selection_clear_event_t *)event)->time);
+ m_clipboard->handleSelectionClearRequest((xcb_selection_clear_event_t *)event);
+ handled = true;
+ break;
+ case XCB_SELECTION_NOTIFY:
+ setTime(((xcb_selection_notify_event_t *)event)->time);
+ qDebug() << "XCB_SELECTION_NOTIFY";
+ handled = false;
+ break;
+ case XCB_PROPERTY_NOTIFY:
+ setTime(((xcb_property_notify_event_t *)event)->time);
+// qDebug() << "XCB_PROPERTY_NOTIFY";
+ handled = false;
+ break;
+ default:
+ handled = false;
+ break;
+ }
+
+ if (!handled) {
+ if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
+ setTime(((xcb_xfixes_selection_notify_event_t *)event)->timestamp);
+ m_clipboard->handleXFixesSelectionRequest((xcb_xfixes_selection_notify_event_t *)event);
+ handled = true;
+ }
+ }
+
+ if (handled)
+ printXcbEvent("Handled XCB event", event);
+ else
+ printXcbEvent("Unhandled XCB event", event);
+}
+
+void QXcbConnection::addPeekFunc(PeekFunc f)
+{
+ m_peekFuncs.append(f);
+}
+
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+void QXcbEventReader::run()
+{
+ xcb_generic_event_t *event;
+ while (m_connection && (event = xcb_wait_for_event(m_connection))) {
+ m_mutex.lock();
+ addEvent(event);
+ while (m_connection && (event = xcb_poll_for_queued_event(m_connection)))
+ addEvent(event);
+ m_mutex.unlock();
+ emit eventPending();
+ }
+
+ for (int i = 0; i < m_events.size(); ++i)
+ free(m_events.at(i));
+}
+#endif
+
+void QXcbEventReader::addEvent(xcb_generic_event_t *event)
+{
+ if ((event->response_type & ~0x80) == XCB_CLIENT_MESSAGE
+ && ((xcb_client_message_event_t *)event)->type == QXcbAtom::_QT_CLOSE_CONNECTION)
+ m_connection = 0;
+ m_events << event;
+}
+
+QList<xcb_generic_event_t *> *QXcbEventReader::lock()
+{
+ m_mutex.lock();
+#ifndef XCB_POLL_FOR_QUEUED_EVENT
+ while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection))
+ m_events << event;
+#endif
+ return &m_events;
+}
+
+void QXcbEventReader::unlock()
+{
+ m_mutex.unlock();
+}
+
+void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom atom, uint id)
+{
+ xcb_client_message_event_t event;
+ memset(&event, 0, sizeof(event));
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.sequence = 0;
+ event.window = m_connectionEventListener;
+ event.type = atom;
+ event.data.data32[0] = id;
+
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_connectionEventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ xcb_flush(xcb_connection());
+}
+
void QXcbConnection::processXcbEvents()
{
- while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection())) {
- bool handled = true;
+ QList<xcb_generic_event_t *> *eventqueue = m_reader->lock();
+
+ for(int i = 0; i < eventqueue->size(); ++i) {
+ xcb_generic_event_t *event = eventqueue->at(i);
+ if (!event)
+ continue;
+ (*eventqueue)[i] = 0;
uint response_type = event->response_type & ~0x80;
if (!response_type) {
handleXcbError((xcb_generic_error_t *)event);
- continue;
+ } else {
+ QVector<PeekFunc>::iterator it = m_peekFuncs.begin();
+ while (it != m_peekFuncs.end()) {
+ // These callbacks return true if the event is what they were
+ // waiting for, remove them from the list in that case.
+ if ((*it)(event))
+ it = m_peekFuncs.erase(it);
+ else
+ ++it;
+ }
+ handleXcbEvent(event);
}
-#ifdef Q_XCB_DEBUG
- {
- int i = 0;
- for (; i < m_callLog.size(); ++i)
- if (m_callLog.at(i).sequence >= event->sequence)
- break;
- m_callLog.remove(0, i);
- }
-#endif
+ free(event);
+ }
- switch (response_type) {
- case XCB_EXPOSE:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
- case XCB_BUTTON_PRESS:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
- case XCB_BUTTON_RELEASE:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
- case XCB_MOTION_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
- case XCB_CONFIGURE_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
- case XCB_CLIENT_MESSAGE:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
- case XCB_ENTER_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
- case XCB_LEAVE_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
- case XCB_FOCUS_IN:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
- case XCB_FOCUS_OUT:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
- case XCB_KEY_PRESS:
- HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
- case XCB_KEY_RELEASE:
- HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
- case XCB_MAPPING_NOTIFY:
- m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
- break;
- default:
- handled = false;
- break;
+ eventqueue->clear();
+
+ m_reader->unlock();
+
+ // Indicate with a null event that the event the callbacks are waiting for
+ // is not in the queue currently.
+ Q_FOREACH (PeekFunc f, m_peekFuncs)
+ f(0);
+ m_peekFuncs.clear();
+
+ xcb_flush(xcb_connection());
+}
+
+void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t *event)
+{
+ if (event->format != 32)
+ return;
+
+ if (event->type == atom(QXcbAtom::XdndStatus)) {
+ drag()->handleStatus(event, false);
+ } else if (event->type == atom(QXcbAtom::XdndFinished)) {
+ drag()->handleFinished(event, false);
+ }
+
+ QXcbWindow *window = platformWindowFromId(event->window);
+ if (!window)
+ return;
+
+ window->handleClientMessageEvent(event);
+}
+
+xcb_generic_event_t *QXcbConnection::checkEvent(int type)
+{
+ QList<xcb_generic_event_t *> *eventqueue = m_reader->lock();
+
+ for (int i = 0; i < eventqueue->size(); ++i) {
+ xcb_generic_event_t *event = eventqueue->at(i);
+ if (event->response_type == type) {
+ (*eventqueue)[i] = 0;
+ m_reader->unlock();
+ return event;
}
- if (handled)
- printXcbEvent("Handled XCB event", event);
- else
- printXcbEvent("Unhandled XCB event", event);
}
- xcb_flush(xcb_connection());
+ m_reader->unlock();
+
+ return 0;
}
static const char * xcb_atomnames = {
@@ -511,6 +728,8 @@ static const char * xcb_atomnames = {
"_QT_SCROLL_DONE\0"
"_QT_INPUT_ENCODING\0"
+ "_QT_CLOSE_CONNECTION\0"
+
"_MOTIF_WM_HINTS\0"
"DTWM_IS_RUNNING\0"
@@ -579,7 +798,6 @@ static const char * xcb_atomnames = {
"_NET_ACTIVE_WINDOW\0"
// Property formats
- "COMPOUND_TEXT\0"
"TEXT\0"
"UTF8_STRING\0"
@@ -659,8 +877,57 @@ void QXcbConnection::initializeAllAtoms() {
for (i = 0; i < QXcbAtom::NAtoms; ++i)
cookies[i] = xcb_intern_atom(xcb_connection(), false, strlen(names[i]), names[i]);
- for (i = 0; i < QXcbAtom::NAtoms; ++i)
- m_allAtoms[i] = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0)->atom;
+ for (i = 0; i < QXcbAtom::NAtoms; ++i) {
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0);
+ m_allAtoms[i] = reply->atom;
+ free(reply);
+ }
+}
+
+xcb_atom_t QXcbConnection::internAtom(const char *name)
+{
+ if (!name || *name == 0)
+ return XCB_NONE;
+
+ xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_connection(), false, strlen(name), name);
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookie, 0);
+ int atom = reply->atom;
+ free(reply);
+ return atom;
+}
+
+QByteArray QXcbConnection::atomName(xcb_atom_t atom)
+{
+ if (!atom)
+ return QByteArray();
+
+ xcb_generic_error_t *error = 0;
+ xcb_get_atom_name_cookie_t cookie = Q_XCB_CALL(xcb_get_atom_name(xcb_connection(), atom));
+ xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(xcb_connection(), cookie, &error);
+ if (error) {
+ qWarning() << "QXcbConnection::atomName: bad Atom" << atom;
+ }
+ if (reply) {
+ QByteArray result(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply));
+ free(reply);
+ return result;
+ }
+ return QByteArray();
+}
+
+const xcb_format_t *QXcbConnection::formatForDepth(uint8_t depth) const
+{
+ xcb_format_iterator_t iterator =
+ xcb_setup_pixmap_formats_iterator(m_setup);
+
+ while (iterator.rem) {
+ xcb_format_t *format = iterator.data;
+ if (format->depth == depth)
+ return format;
+ xcb_format_next(&iterator);
+ }
+
+ return 0;
}
void QXcbConnection::sync()
@@ -670,6 +937,43 @@ void QXcbConnection::sync()
free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
}
+void QXcbConnection::initializeXFixes()
+{
+ xcb_generic_error_t *error = 0;
+ const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xfixes_id);
+ xfixes_first_event = reply->first_event;
+
+ xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection,
+ XCB_XFIXES_MAJOR_VERSION,
+ XCB_XFIXES_MINOR_VERSION);
+ xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
+ xfixes_query_cookie, &error);
+ if (!xfixes_query || error || xfixes_query->major_version < 2) {
+ qWarning("Failed to initialize XFixes");
+ free(error);
+ xfixes_first_event = 0;
+ }
+ free(xfixes_query);
+
+}
+
+void QXcbConnection::initializeXRender()
+{
+#ifdef XCB_USE_RENDER
+ xcb_generic_error_t *error = 0;
+ xcb_render_query_version_cookie_t xrender_query_cookie = xcb_render_query_version(m_connection,
+ XCB_RENDER_MAJOR_VERSION,
+ XCB_RENDER_MINOR_VERSION);
+ xcb_render_query_version_reply_t *xrender_query = xcb_render_query_version_reply(m_connection,
+ xrender_query_cookie, &error);
+ if (!xrender_query || error || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) {
+ qWarning("Failed to initialize XRender");
+ free(error);
+ }
+ free(xrender_query);
+#endif
+}
+
#if defined(XCB_USE_EGL)
bool QXcbConnection::hasEgl() const
{
@@ -740,26 +1044,12 @@ bool QXcbConnection::hasSupportForDri2() const
if (!m_dri2_support_probed) {
xcb_generic_error_t *error = 0;
- xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
xcb_prefetch_extension_data (m_connection, &xcb_dri2_id);
- xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection,
- XCB_XFIXES_MAJOR_VERSION,
- XCB_XFIXES_MINOR_VERSION);
-
xcb_dri2_query_version_cookie_t dri2_query_cookie = xcb_dri2_query_version (m_connection,
XCB_DRI2_MAJOR_VERSION,
XCB_DRI2_MINOR_VERSION);
- xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
- xfixes_query_cookie, &error);
- if (!xfixes_query || error || xfixes_query->major_version < 2) {
- delete error;
- delete xfixes_query;
- return false;
- }
- delete xfixes_query;
-
xcb_dri2_query_version_reply_t *dri2_query = xcb_dri2_query_version_reply (m_connection,
dri2_query_cookie, &error);
if (!dri2_query || error) {
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 01bc719546..6d93093072 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -44,13 +44,23 @@
#include <xcb/xcb.h>
+#include <QHash>
#include <QList>
+#include <QMutex>
#include <QObject>
+#include <QThread>
#include <QVector>
#define Q_XCB_DEBUG
class QXcbScreen;
+class QXcbWindow;
+class QXcbDrag;
+class QXcbKeyboard;
+class QXcbClipboard;
+class QXcbWMSupport;
+
+typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
namespace QXcbAtom {
enum Atom {
@@ -92,6 +102,9 @@ namespace QXcbAtom {
_QT_SCROLL_DONE,
_QT_INPUT_ENCODING,
+ // Qt/XCB specific
+ _QT_CLOSE_CONNECTION,
+
_MOTIF_WM_HINTS,
DTWM_IS_RUNNING,
@@ -160,7 +173,6 @@ namespace QXcbAtom {
_NET_ACTIVE_WINDOW,
// Property formats
- COMPOUND_TEXT,
TEXT,
UTF8_STRING,
@@ -215,8 +227,34 @@ namespace QXcbAtom {
};
}
-class QXcbKeyboard;
+class QXcbEventReader : public QThread
+{
+ Q_OBJECT
+public:
+ QXcbEventReader(xcb_connection_t *connection)
+ : m_connection(connection)
+ {
+ }
+
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+ void run();
+#endif
+ QList<xcb_generic_event_t *> *lock();
+ void unlock();
+
+signals:
+ void eventPending();
+
+private:
+ void addEvent(xcb_generic_event_t *event);
+
+ QMutex m_mutex;
+ QList<xcb_generic_event_t *> m_events;
+ xcb_connection_t *m_connection;
+};
+
+class QAbstractEventDispatcher;
class QXcbConnection : public QObject
{
Q_OBJECT
@@ -226,17 +264,26 @@ public:
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
- QList<QXcbScreen *> screens() const { return m_screens; }
+ const QList<QXcbScreen *> &screens() const { return m_screens; }
int primaryScreen() const { return m_primaryScreen; }
xcb_atom_t atom(QXcbAtom::Atom atom);
+ xcb_atom_t internAtom(const char *name);
+ QByteArray atomName(xcb_atom_t atom);
const char *displayName() const { return m_displayName.constData(); }
xcb_connection_t *xcb_connection() const { return m_connection; }
+ const xcb_setup_t *setup() const { return m_setup; }
+ const xcb_format_t *formatForDepth(uint8_t depth) const;
QXcbKeyboard *keyboard() const { return m_keyboard; }
+ QXcbClipboard *clipboard() const { return m_clipboard; }
+ QXcbDrag *drag() const { return m_drag; }
+
+ QXcbWMSupport *wmSupport() const { return m_wmSupport; }
+
#ifdef XCB_USE_XLIB
void *xlib_display() const { return m_xlib_display; }
#endif
@@ -253,7 +300,26 @@ public:
#endif
void sync();
+ void flush() { xcb_flush(m_connection); }
+
void handleXcbError(xcb_generic_error_t *error);
+ void handleXcbEvent(xcb_generic_event_t *event);
+
+ void addWindow(xcb_window_t id, QXcbWindow *window);
+ void removeWindow(xcb_window_t id);
+ QXcbWindow *platformWindowFromId(xcb_window_t id);
+
+ xcb_generic_event_t *checkEvent(int type);
+ template<typename T>
+ inline xcb_generic_event_t *checkEvent(const T &checker);
+
+ typedef bool (*PeekFunc)(xcb_generic_event_t *);
+ void addPeekFunc(PeekFunc f);
+
+ inline xcb_timestamp_t time() const { return m_time; }
+ inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; }
+
+ bool hasXFixes() const { return xfixes_first_event > 0; }
private slots:
void processXcbEvents();
@@ -261,9 +327,12 @@ private slots:
private:
void initializeAllAtoms();
void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
+ void initializeXFixes();
+ void initializeXRender();
#ifdef XCB_USE_DRI2
void initializeDri2();
#endif
+ void handleClientMessageEvent(const xcb_client_message_event_t *event);
xcb_connection_t *m_connection;
const xcb_setup_t *m_setup;
@@ -273,14 +342,21 @@ private:
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
+ xcb_timestamp_t m_time;
+
QByteArray m_displayName;
+ xcb_window_t m_connectionEventListener;
+
QXcbKeyboard *m_keyboard;
+ QXcbClipboard *m_clipboard;
+ QXcbDrag *m_drag;
+ QXcbWMSupport *m_wmSupport;
#if defined(XCB_USE_XLIB)
void *m_xlib_display;
#endif
-
+ QXcbEventReader *m_reader;
#ifdef XCB_USE_DRI2
uint32_t m_dri2_major;
uint32_t m_dri2_minor;
@@ -299,14 +375,39 @@ private:
int line;
};
QVector<CallInfo> m_callLog;
+ QMutex m_callLogMutex;
void log(const char *file, int line, int sequence);
template <typename cookie_t>
friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
#endif
+
+ WindowMapper m_mapper;
+
+ QVector<PeekFunc> m_peekFuncs;
+
+ uint32_t xfixes_first_event;
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
+template<typename T>
+xcb_generic_event_t *QXcbConnection::checkEvent(const T &checker)
+{
+ QList<xcb_generic_event_t *> *eventqueue = m_reader->lock();
+
+ for (int i = 0; i < eventqueue->size(); ++i) {
+ xcb_generic_event_t *event = eventqueue->at(i);
+ if (checker.check(event)) {
+ (*eventqueue)[i] = 0;
+ m_reader->unlock();
+ return event;
+ }
+ }
+ m_reader->unlock();
+ return 0;
+}
+
+
#ifdef Q_XCB_DEBUG
template <typename cookie_t>
cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
new file mode 100644
index 0000000000..f6856d5694
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -0,0 +1,546 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbcursor.h"
+#include "qxcbconnection.h"
+#include "qxcbwindow.h"
+#include "qxcbimage.h"
+#include <QtCore/QLibrary>
+#include <QtGui/QWindow>
+#include <QtGui/QBitmap>
+#include <QtGui/private/qguiapplication_p.h>
+#include <X11/cursorfont.h>
+#include <xcb/xfixes.h>
+#include <xcb/xcb_image.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef int (*PtrXcursorLibraryLoadCursor)(void *, const char *);
+static PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor = 0;
+static xcb_font_t cursorFont = 0;
+static int cursorCount = 0;
+
+static uint8_t cur_blank_bits[] = {
+ 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 uint8_t cur_ver_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
+ 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
+static const uint8_t mcur_ver_bits[] = {
+ 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
+ 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
+ 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
+static const uint8_t cur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
+ 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
+ 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
+ 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
+static const uint8_t cur_bdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
+ 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
+ 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_bdiag_bits[] = {
+ 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
+ 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
+ 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t cur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
+ 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
+ 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
+ 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
+ 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
+static const uint8_t *cursor_bits16[] = {
+ cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
+ cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
+ 0, 0, cur_blank_bits, cur_blank_bits };
+
+static const uint8_t vsplit_bits[] = {
+ 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, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 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 uint8_t vsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t hsplit_bits[] = {
+ 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, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
+ 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 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 uint8_t hsplitm_bits[] = {
+ 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, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
+ 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
+ 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
+ 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 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 uint8_t whatsthis_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
+ 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
+ 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
+ 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
+ 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
+ 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
+ 0x80, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+static const uint8_t whatsthism_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
+ 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
+ 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
+ 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
+ 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
+ 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
+ 0x80, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+static const uint8_t busy_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+ 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
+ 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
+ 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
+ 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
+ 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 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 uint8_t busym_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
+ 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
+ 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
+ 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
+ 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
+ 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 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 uint8_t * const cursor_bits32[] = {
+ vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
+ 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
+};
+
+static const uint8_t forbidden_bits[] = {
+ 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
+ 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
+ 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
+ 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
+
+static const uint8_t forbiddenm_bits[] = {
+ 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
+ 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
+ 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
+ 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
+
+static const uint8_t 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,
+ 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
+static const uint8_t openhandm_bits[] = {
+ 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
+ 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
+ 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
+static const uint8_t closedhand_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
+ 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
+ 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
+static const uint8_t closedhandm_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
+ 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
+ 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
+
+static const uint8_t * const cursor_bits20[] = {
+ forbidden_bits, forbiddenm_bits
+};
+
+static const char * const cursorNames[] = {
+ "left_ptr",
+ "up_arrow",
+ "cross",
+ "wait",
+ "ibeam",
+ "size_ver",
+ "size_hor",
+ "size_bdiag",
+ "size_fdiag",
+ "size_all",
+ "blank",
+ "split_v",
+ "split_h",
+ "pointing_hand",
+ "forbidden",
+ "whats_this",
+ "left_ptr_watch",
+ "openhand",
+ "closedhand",
+ "copy",
+ "move",
+ "link"
+};
+
+QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen)
+ : QXcbObject(conn), QPlatformCursor(screen), m_screen(screen)
+{
+ if (cursorCount++)
+ return;
+
+ cursorFont = xcb_generate_id(xcb_connection());
+ const char *cursorStr = "cursor";
+ xcb_open_font(xcb_connection(), cursorFont, strlen(cursorStr), cursorStr);
+
+#ifdef XCB_USE_XLIB
+ QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
+ bool xcursorFound = xcursorLib.load();
+ if (!xcursorFound) { // try without the version number
+ xcursorLib.setFileName(QLatin1String("Xcursor"));
+ xcursorFound = xcursorLib.load();
+ }
+ if (xcursorFound)
+ ptrXcursorLibraryLoadCursor =
+ (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
+#endif
+}
+
+QXcbCursor::~QXcbCursor()
+{
+ if (!--cursorCount)
+ xcb_close_font(xcb_connection(), cursorFont);
+}
+
+void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget)
+{
+ QXcbWindow *w = 0;
+ if (widget && widget->handle())
+ w = static_cast<QXcbWindow *>(widget->handle());
+ else
+ // No X11 cursor control when there is no widget under the cursor
+ return;
+
+ xcb_cursor_t c;
+ if (cursor->shape() == Qt::BitmapCursor) {
+ qint64 id = cursor->pixmap().cacheKey();
+ if (!m_bitmapCursorMap.contains(id))
+ m_bitmapCursorMap.insert(id, createBitmapCursor(cursor));
+ c = m_bitmapCursorMap.value(id);
+ } else {
+ int id = cursor->handle();
+ if (!m_shapeCursorMap.contains(id))
+ m_shapeCursorMap.insert(id, createFontCursor(cursor->shape()));
+ c = m_shapeCursorMap.value(id);
+ }
+
+ w->setCursor(c);
+}
+
+static int cursorIdForShape(int cshape)
+{
+ int cursorId = 0;
+ switch (cshape) {
+ case Qt::ArrowCursor:
+ cursorId = XC_left_ptr;
+ break;
+ case Qt::UpArrowCursor:
+ cursorId = XC_center_ptr;
+ break;
+ case Qt::CrossCursor:
+ cursorId = XC_crosshair;
+ break;
+ case Qt::WaitCursor:
+ cursorId = XC_watch;
+ break;
+ case Qt::IBeamCursor:
+ cursorId = XC_xterm;
+ break;
+ case Qt::SizeAllCursor:
+ cursorId = XC_fleur;
+ break;
+ case Qt::PointingHandCursor:
+ cursorId = XC_hand2;
+ break;
+ case Qt::SizeBDiagCursor:
+ cursorId = XC_top_right_corner;
+ break;
+ case Qt::SizeFDiagCursor:
+ cursorId = XC_bottom_right_corner;
+ break;
+ case Qt::SizeVerCursor:
+ case Qt::SplitVCursor:
+ cursorId = XC_sb_v_double_arrow;
+ break;
+ case Qt::SizeHorCursor:
+ case Qt::SplitHCursor:
+ cursorId = XC_sb_h_double_arrow;
+ break;
+ case Qt::WhatsThisCursor:
+ cursorId = XC_question_arrow;
+ break;
+ case Qt::ForbiddenCursor:
+ cursorId = XC_circle;
+ break;
+ case Qt::BusyCursor:
+ cursorId = XC_watch;
+ break;
+ default:
+ break;
+ }
+ return cursorId;
+}
+
+xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
+{
+ xcb_cursor_t cursor = 0;
+ xcb_connection_t *conn = xcb_connection();
+
+ if (cshape == Qt::BlankCursor) {
+ xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16,
+ 1, 0, 0, 0);
+ xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16,
+ 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if (cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor) {
+ int i = (cshape - Qt::SizeVerCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits16[i]),
+ 16, 16, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits16[i + 1]),
+ 16, 16, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
+ || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
+ int i = (cshape - Qt::SplitVCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits32[i]),
+ 32, 32, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits32[i + 1]),
+ 32, 32, 1, 0, 0, 0);
+ int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
+ || cshape == Qt::BusyCursor) ? 0 : 16;
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, hs, hs);
+ } else if (cshape == Qt::ForbiddenCursor) {
+ int i = (cshape - Qt::ForbiddenCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits20[i]),
+ 20, 20, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits20[i + 1]),
+ 20, 20, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 10, 10);
+ } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
+ bool open = cshape == Qt::OpenHandCursor;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(open ? openhand_bits : closedhand_bits),
+ 16, 16, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(open ? openhandm_bits : closedhandm_bits),
+ 16, 16, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
+ || cshape == Qt::DragLinkCursor) {
+ QImage image = QGuiApplicationPrivate::instance()->getPixmapCursor(static_cast<Qt::CursorShape>(cshape)).toImage();
+ xcb_pixmap_t pm = qt_xcb_XPixmapFromBitmap(m_screen, image);
+ xcb_pixmap_t pmm = qt_xcb_XPixmapFromBitmap(m_screen, image.createAlphaMask());
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ }
+
+ return cursor;
+}
+
+xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
+{
+ xcb_connection_t *conn = xcb_connection();
+ int cursorId = cursorIdForShape(cshape);
+ xcb_cursor_t cursor = XCB_NONE;
+
+ // Try Xcursor first
+#ifdef XCB_USE_XLIB
+ if (ptrXcursorLibraryLoadCursor && cshape >= 0 && cshape < Qt::LastCursor) {
+ void *dpy = connection()->xlib_display();
+ // special case for non-standard dnd-* cursors
+ switch (cshape) {
+ case Qt::DragCopyCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-copy");
+ break;
+ case Qt::DragMoveCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-move");
+ break;
+ case Qt::DragLinkCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-link");
+ break;
+ default:
+ break;
+ }
+ if (!cursor)
+ cursor = ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
+ }
+ if (cursor)
+ return cursor;
+#endif
+
+ // Non-standard X11 cursors are created from bitmaps
+ cursor = createNonStandardCursor(cshape);
+
+ // Create a glpyh cursor if everything else failed
+ if (!cursor && cursorId) {
+ cursor = xcb_generate_id(conn);
+ xcb_create_glyph_cursor(conn, cursor, cursorFont, cursorFont,
+ cursorId, cursorId + 1,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0);
+ }
+
+ if (cursor && cshape >= 0 && cshape < Qt::LastCursor) {
+ const char *name = cursorNames[cshape];
+ xcb_xfixes_set_cursor_name(conn, cursor, strlen(name), name);
+ }
+
+ return cursor;
+}
+
+xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor)
+{
+ xcb_connection_t *conn = xcb_connection();
+ QPoint spot = cursor->hotSpot();
+ xcb_cursor_t c = XCB_NONE;
+ if (cursor->pixmap().depth() > 1)
+ c = qt_xcb_createCursorXRender(m_screen, cursor->pixmap().toImage(), spot);
+ if (!c) {
+ xcb_pixmap_t cp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->bitmap()->toImage());
+ xcb_pixmap_t mp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->mask()->toImage());
+ c = xcb_generate_id(conn);
+ xcb_create_cursor(conn, c, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF,
+ spot.x(), spot.y());
+ xcb_free_pixmap(conn, cp);
+ xcb_free_pixmap(conn, mp);
+ }
+ return c;
+}
+
+static void getPosAndRoot(xcb_connection_t *conn, xcb_window_t *rootWin, QPoint *pos)
+{
+ if (pos)
+ *pos = QPoint();
+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(conn));
+ while (it.rem) {
+ xcb_window_t root = it.data->root;
+ xcb_query_pointer_cookie_t cookie = xcb_query_pointer(conn, root);
+ xcb_generic_error_t *err = 0;
+ xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(conn, cookie, &err);
+ if (!err && reply) {
+ if (pos)
+ *pos = QPoint(reply->root_x, reply->root_y);
+ if (rootWin)
+ *rootWin = root;
+ free(reply);
+ return;
+ }
+ free(err);
+ free(reply);
+ xcb_screen_next(&it);
+ }
+}
+
+QPoint QXcbCursor::pos() const
+{
+ QPoint p;
+ getPosAndRoot(xcb_connection(), 0, &p);
+ return p;
+}
+
+void QXcbCursor::setPos(const QPoint &pos)
+{
+ xcb_connection_t *conn = xcb_connection();
+ xcb_window_t root;
+ getPosAndRoot(conn, &root, 0);
+ xcb_warp_pointer(conn, XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h
new file mode 100644
index 0000000000..4bbb9a928b
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbcursor.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBCURSOR_H
+#define QXCBCURSOR_H
+
+#include <QtGui/QPlatformCursor>
+#include "qxcbscreen.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXcbCursor : public QXcbObject, public QPlatformCursor
+{
+public:
+ QXcbCursor(QXcbConnection *conn, QXcbScreen *screen);
+ ~QXcbCursor();
+ void changeCursor(QCursor *cursor, QWindow *widget);
+ QPoint pos() const;
+ void setPos(const QPoint &pos);
+
+private:
+ xcb_cursor_t createFontCursor(int cshape);
+ xcb_cursor_t createBitmapCursor(QCursor *cursor);
+ xcb_cursor_t createNonStandardCursor(int cshape);
+
+ QXcbScreen *m_screen;
+ QMap<int, xcb_cursor_t> m_shapeCursorMap;
+ QMap<qint64, xcb_cursor_t> m_bitmapCursorMap;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
new file mode 100644
index 0000000000..8a6fd29986
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -0,0 +1,1332 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbdrag.h"
+#include <xcb/xcb.h>
+#include "qxcbconnection.h"
+#include "qxcbclipboard.h"
+#include "qxcbmime.h"
+#include "qxcbwindow.h"
+#include "qxcbscreen.h"
+#include "qwindow.h"
+#include <private/qdnd_p.h>
+#include <qdebug.h>
+#include <qevent.h>
+#include <qguiapplication.h>
+#include <qrect.h>
+
+QT_BEGIN_NAMESPACE
+
+//#define DND_DEBUG
+#ifdef DND_DEBUG
+#define DEBUG qDebug
+#else
+#define DEBUG if(0) qDebug
+#endif
+
+#ifdef DND_DEBUG
+#define DNDDEBUG qDebug()
+#else
+#define DNDDEBUG if(0) qDebug()
+#endif
+
+const int xdnd_version = 5;
+
+static inline xcb_window_t xcb_window(QWindow *w)
+{
+ return static_cast<QXcbWindow *>(w->handle())->xcb_window();
+}
+
+
+static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w)
+{
+ xcb_window_t proxy = XCB_NONE;
+
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, w, c->atom(QXcbAtom::XdndProxy),
+ XCB_ATOM_WINDOW, 0, 1), c);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0);
+
+ if (reply && reply->type == XCB_ATOM_WINDOW)
+ proxy = *((xcb_window_t *)xcb_get_property_value(reply));
+ free(reply);
+
+ if (proxy == XCB_NONE)
+ return proxy;
+
+ // exists and is real?
+ cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, proxy, c->atom(QXcbAtom::XdndProxy),
+ XCB_ATOM_WINDOW, 0, 1), c);
+ reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0);
+
+ if (reply && reply->type == XCB_ATOM_WINDOW) {
+ xcb_window_t p = *((xcb_window_t *)xcb_get_property_value(reply));
+ if (proxy != p)
+ proxy = 0;
+ } else {
+ proxy = 0;
+ }
+
+ free(reply);
+
+ return proxy;
+}
+
+
+class QDropData : public QXcbMime
+{
+public:
+ QDropData(QXcbDrag *d);
+ ~QDropData();
+
+protected:
+ bool hasFormat_sys(const QString &mimeType) const;
+ QStringList formats_sys() const;
+ QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
+
+ QVariant xdndObtainData(const QByteArray &format, QVariant::Type requestedType) const;
+
+ QXcbDrag *drag;
+};
+
+
+QXcbDrag::QXcbDrag(QXcbConnection *c)
+ : QXcbObject(c)
+{
+ dropData = new QDropData(this);
+
+ init();
+ heartbeat = -1;
+
+ transaction_expiry_timer = -1;
+}
+
+QXcbDrag::~QXcbDrag()
+{
+ delete dropData;
+}
+
+void QXcbDrag::init()
+{
+ currentWindow.clear();
+
+ xdnd_dragsource = XCB_NONE;
+ last_target_accepted_action = Qt::IgnoreAction;
+
+ waiting_for_status = false;
+ current_target = XCB_NONE;
+ current_proxy_target = XCB_NONE;
+ xdnd_dragging = false;
+
+ source_time = XCB_CURRENT_TIME;
+ target_time = XCB_CURRENT_TIME;
+
+ current_screen = 0;
+ drag_types.clear();
+}
+
+QMimeData *QXcbDrag::platformDropData()
+{
+ return dropData;
+}
+
+void QXcbDrag::startDrag()
+{
+ init();
+
+ heartbeat = startTimer(200);
+ xdnd_dragging = true;
+
+ xcb_set_selection_owner(xcb_connection(), connection()->clipboard()->owner(),
+ atom(QXcbAtom::XdndSelection), connection()->time());
+
+ QDragManager *manager = QDragManager::self();
+ QStringList fmts = QXcbMime::formatsHelper(manager->dropData());
+ for (int i = 0; i < fmts.size(); ++i) {
+ QList<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), fmts.at(i));
+ for (int j = 0; j < atoms.size(); ++j) {
+ if (!drag_types.contains(atoms.at(j)))
+ drag_types.append(atoms.at(j));
+ }
+ }
+ if (drag_types.size() > 3)
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(),
+ atom(QXcbAtom::XdndTypelist),
+ XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData());
+
+ QPointF pos = QCursor::pos();
+ QMouseEvent me(QEvent::MouseMove, pos, pos, pos, Qt::LeftButton,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ move(&me);
+
+// if (!QWidget::mouseGrabber())
+// manager->shapedPixmapWindow->grabMouse();
+}
+
+void QXcbDrag::endDrag()
+{
+ Q_ASSERT(heartbeat != -1);
+ killTimer(heartbeat);
+ heartbeat = -1;
+
+ xdnd_dragging = false;
+}
+
+static xcb_translate_coordinates_reply_t *
+translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int x, int y)
+{
+ xcb_translate_coordinates_cookie_t cookie =
+ xcb_translate_coordinates(c->xcb_connection(), from, to, x, y);
+ return xcb_translate_coordinates_reply(c->xcb_connection(), cookie, 0);
+}
+
+void QXcbDrag::move(const QMouseEvent *me)
+{
+ DEBUG() << "QDragManager::move enter";
+
+ // ###
+ QPoint globalPos = me->globalPos();
+
+ if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
+ return;
+
+ const QList<QXcbScreen *> &screens = connection()->screens();
+ QXcbScreen *screen = screens.at(connection()->primaryScreen());
+ for (int i = 0; i < screens.size(); ++i) {
+ if (screens.at(i)->geometry().contains(globalPos)) {
+ screen = screens.at(i);
+ break;
+ }
+ }
+ if (screen != current_screen) {
+ // ### need to recreate the shaped pixmap window?
+// int screen = QCursor::x11Screen();
+// if ((qt_xdnd_current_screen == -1 && screen != X11->defaultScreen) || (screen != qt_xdnd_current_screen)) {
+// // recreate the pixmap on the new screen...
+// delete xdnd_data.deco;
+// QWidget* parent = object->source()->window()->x11Info().screen() == screen
+// ? object->source()->window() : QApplication::desktop()->screen(screen);
+// xdnd_data.deco = new QShapedPixmapWidget(parent);
+// if (!QWidget::mouseGrabber()) {
+// updatePixmap();
+// xdnd_data.deco->grabMouse();
+// }
+// }
+// xdnd_data.deco->move(QCursor::pos() - xdnd_data.deco->pm_hot);
+ current_screen = screen;
+ }
+
+
+// qt_xdnd_current_screen = screen;
+ xcb_window_t rootwin = current_screen->root();
+ xcb_translate_coordinates_reply_t *translate =
+ ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y());
+ if (!translate)
+ return;
+ xcb_window_t target = translate->child;
+ int lx = translate->dst_x;
+ int ly = translate->dst_y;
+ free (translate);
+
+ if (target == rootwin) {
+ // Ok.
+ } else if (target) {
+ //me
+ xcb_window_t src = rootwin;
+ while (target != 0) {
+ DNDDEBUG << "checking target for XdndAware" << target;
+
+ // translate coordinates
+ translate = ::translateCoordinates(connection(), src, target, lx, ly);
+ if (!translate) {
+ target = 0;
+ break;
+ }
+ lx = translate->dst_x;
+ ly = translate->dst_y;
+ src = translate->child;
+ free(translate);
+
+ // check if it has XdndAware
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, target,
+ atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ bool aware = reply && reply->type != XCB_NONE;
+ free(reply);
+ if (aware) {
+ DNDDEBUG << "Found XdndAware on " << target;
+ break;
+ }
+
+ // find child at the coordinates
+ translate = ::translateCoordinates(connection(), src, src, lx, ly);
+ if (!translate) {
+ target = 0;
+ break;
+ }
+ target = translate->child;
+ free(translate);
+ }
+ // ####
+// if (xdnd_data.deco && (!target || target == xdnd_data.deco->effectiveWinId())) {
+// DNDDEBUG << "need to find real window";
+// target = findRealWindow(globalPos, rootwin, 6);
+// DNDDEBUG << "real window found" << QWidget::find(target) << target;
+// }
+ }
+
+ QXcbWindow *w = 0;
+ if (target) {
+ w = connection()->platformWindowFromId(target);
+ if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ w = 0;
+ } else {
+ w = 0;
+ target = rootwin;
+ }
+
+ DNDDEBUG << "and the final target is " << target;
+ DNDDEBUG << "the widget w is" << (w ? w->window() : 0);
+
+ xcb_window_t proxy_target = xdndProxy(connection(), target);
+ if (!proxy_target)
+ proxy_target = target;
+ int target_version = 1;
+
+ if (proxy_target) {
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, target,
+ atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 1);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ if (!reply || reply->type == XCB_NONE)
+ target = 0;
+ target_version = xcb_get_property_value_length(reply) == 1 ? *(uint32_t *)xcb_get_property_value(reply) : 1;
+ if (target_version > xdnd_version)
+ target_version = xdnd_version;
+
+ free(reply);
+ }
+
+ DEBUG() << "target=" << target << "current_target=" << current_target;
+ if (target != current_target) {
+ if (current_target)
+ send_leave();
+
+ current_target = target;
+ current_proxy_target = proxy_target;
+ if (target) {
+ int flags = target_version << 24;
+ if (drag_types.size() > 3)
+ flags |= 0x0001;
+
+ xcb_client_message_event_t enter;
+ enter.response_type = XCB_CLIENT_MESSAGE;
+ enter.window = target;
+ enter.format = 32;
+ enter.type = atom(QXcbAtom::XdndEnter);
+ enter.data.data32[0] = connection()->clipboard()->owner();
+ enter.data.data32[1] = flags;
+ enter.data.data32[2] = drag_types.size()>0 ? drag_types.at(0) : 0;
+ enter.data.data32[3] = drag_types.size()>1 ? drag_types.at(1) : 0;
+ enter.data.data32[4] = drag_types.size()>2 ? drag_types.at(2) : 0;
+ // provisionally set the rectangle to 5x5 pixels...
+ source_sameanswer = QRect(globalPos.x() - 2, globalPos.y() -2 , 5, 5);
+
+ DEBUG() << "sending Xdnd enter source=" << enter.data.data32[0];
+ if (w)
+ handleEnter(w->window(), &enter);
+ else if (target)
+ xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&enter);
+ waiting_for_status = false;
+ }
+ }
+ if (waiting_for_status)
+ return;
+
+ QDragManager *m = QDragManager::self();
+
+ if (target) {
+ waiting_for_status = true;
+
+ xcb_client_message_event_t move;
+ move.response_type = XCB_CLIENT_MESSAGE;
+ move.window = target;
+ move.format = 32;
+ move.type = atom(QXcbAtom::XdndPosition);
+ move.window = target;
+ move.data.data32[0] = connection()->clipboard()->owner();
+ move.data.data32[1] = 0; // flags
+ move.data.data32[2] = (globalPos.x() << 16) + globalPos.y();
+ move.data.data32[3] = connection()->time();
+ move.data.data32[4] = toXdndAction(m->defaultAction(m->dragPrivate()->possible_actions, QGuiApplication::keyboardModifiers()));
+ DEBUG() << "sending Xdnd position source=" << move.data.data32[0] << "target=" << move.window;
+
+ source_time = connection()->time();
+
+ if (w)
+ handle_xdnd_position(w->window(), &move, false);
+ else
+ xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&move);
+ } else {
+ if (m->willDrop) {
+ m->willDrop = false;
+ m->updateCursor();
+ }
+ }
+ DEBUG() << "QDragManager::move leave";
+}
+
+void QXcbDrag::drop(const QMouseEvent *)
+{
+ endDrag();
+
+ if (!current_target)
+ return;
+
+ xcb_client_message_event_t drop;
+ drop.response_type = XCB_CLIENT_MESSAGE;
+ drop.window = current_target;
+ drop.format = 32;
+ drop.type = atom(QXcbAtom::XdndDrop);
+ drop.data.data32[0] = connection()->clipboard()->owner();
+ drop.data.data32[1] = 0; // flags
+ drop.data.data32[2] = connection()->time();
+
+ drop.data.data32[3] = 0;
+ drop.data.data32[4] = 0;
+
+ QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
+
+ if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ w = 0;
+
+ QDragManager *manager = QDragManager::self();
+
+ Transaction t = {
+ connection()->time(),
+ current_target,
+ current_proxy_target,
+ (w ? w->window() : 0),
+// current_embedding_widget,
+ manager->object
+ };
+ transactions.append(t);
+ restartDropExpiryTimer();
+
+ if (w)
+ handleDrop(w->window(), &drop, false);
+ else
+ xcb_send_event(xcb_connection(), false, current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&drop);
+
+ current_target = 0;
+ current_proxy_target = 0;
+ source_time = 0;
+// current_embedding_widget = 0;
+ manager->object = 0;
+}
+
+Qt::DropAction QXcbDrag::toDropAction(xcb_atom_t a) const
+{
+ if (a == atom(QXcbAtom::XdndActionCopy) || a == 0)
+ return Qt::CopyAction;
+ if (a == atom(QXcbAtom::XdndActionLink))
+ return Qt::LinkAction;
+ if (a == atom(QXcbAtom::XdndActionMove))
+ return Qt::MoveAction;
+ return Qt::CopyAction;
+}
+
+xcb_atom_t QXcbDrag::toXdndAction(Qt::DropAction a) const
+{
+ switch (a) {
+ case Qt::CopyAction:
+ return atom(QXcbAtom::XdndActionCopy);
+ case Qt::LinkAction:
+ return atom(QXcbAtom::XdndActionLink);
+ case Qt::MoveAction:
+ case Qt::TargetMoveAction:
+ return atom(QXcbAtom::XdndActionMove);
+ case Qt::IgnoreAction:
+ return XCB_NONE;
+ default:
+ return atom(QXcbAtom::XdndActionCopy);
+ }
+}
+
+// timer used to discard old XdndDrop transactions
+enum { XdndDropTransactionTimeout = 5000 }; // 5 seconds
+
+void QXcbDrag::restartDropExpiryTimer()
+{
+ if (transaction_expiry_timer != -1)
+ killTimer(transaction_expiry_timer);
+ transaction_expiry_timer = startTimer(XdndDropTransactionTimeout);
+}
+
+int QXcbDrag::findTransactionByWindow(xcb_window_t window)
+{
+ int at = -1;
+ for (int i = 0; i < transactions.count(); ++i) {
+ const Transaction &t = transactions.at(i);
+ if (t.target == window || t.proxy_target == window) {
+ at = i;
+ break;
+ }
+ }
+ return at;
+}
+
+int QXcbDrag::findTransactionByTime(xcb_timestamp_t timestamp)
+{
+ int at = -1;
+ for (int i = 0; i < transactions.count(); ++i) {
+ const Transaction &t = transactions.at(i);
+ if (t.timestamp == timestamp) {
+ at = i;
+ break;
+ }
+ }
+ return at;
+}
+
+#if 0
+
+// find an ancestor with XdndAware on it
+static Window findXdndAwareParent(Window window)
+{
+ Window target = 0;
+ forever {
+ // check if window has XdndAware
+ Atom type = 0;
+ int f;
+ unsigned long n, a;
+ unsigned char *data = 0;
+ if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
+ AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
+ if (data)
+ XFree(data);
+ if (type) {
+ target = window;
+ break;
+ }
+ }
+
+ // try window's parent
+ Window root;
+ Window parent;
+ Window *children;
+ uint unused;
+ if (!XQueryTree(X11->display, window, &root, &parent, &children, &unused))
+ break;
+ if (children)
+ XFree(children);
+ if (window == root)
+ break;
+ window = parent;
+ }
+ return target;
+}
+
+
+// for embedding only
+static QWidget* current_embedding_widget = 0;
+static xcb_client_message_event_t last_enter_event;
+
+
+static bool checkEmbedded(QWidget* w, const XEvent* xe)
+{
+ if (!w)
+ return false;
+
+ if (current_embedding_widget != 0 && current_embedding_widget != w) {
+ current_target = ((QExtraWidget*)current_embedding_widget)->extraData()->xDndProxy;
+ current_proxy_target = current_target;
+ qt_xdnd_send_leave();
+ current_target = 0;
+ current_proxy_target = 0;
+ current_embedding_widget = 0;
+ }
+
+ QWExtra* extra = ((QExtraWidget*)w)->extraData();
+ if (extra && extra->xDndProxy != 0) {
+
+ if (current_embedding_widget != w) {
+
+ last_enter_event.xany.window = extra->xDndProxy;
+ XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, &last_enter_event);
+ current_embedding_widget = w;
+ }
+
+ ((XEvent*)xe)->xany.window = extra->xDndProxy;
+ XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, (XEvent*)xe);
+ if (currentWindow != w) {
+ currentWindow = w;
+ }
+ return true;
+ }
+ current_embedding_widget = 0;
+ return false;
+}
+#endif
+
+
+void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *event)
+{
+ Q_UNUSED(window);
+ DEBUG() << "handleEnter" << window;
+
+ xdnd_types.clear();
+// motifdnd_active = false;
+// last_enter_event.xclient = xe->xclient;
+
+ int version = (int)(event->data.data32[1] >> 24);
+ if (version > xdnd_version)
+ return;
+
+ xdnd_dragsource = event->data.data32[0];
+
+ if (event->data.data32[1] & 1) {
+ // get the types from XdndTypeList
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, xdnd_dragsource,
+ atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM,
+ 0, xdnd_max_type);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ if (reply && reply->type != XCB_NONE && reply->format == 32) {
+ int length = xcb_get_property_value_length(reply) / 4;
+ if (length > xdnd_max_type)
+ length = xdnd_max_type;
+
+ xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
+ for (int i = 0; i < length; ++i)
+ xdnd_types.append(atoms[i]);
+ }
+ free(reply);
+ } else {
+ // get the types from the message
+ for(int i = 2; i < 5; i++) {
+ if (event->data.data32[i])
+ xdnd_types.append(event->data.data32[i]);
+ }
+ }
+ for(int i = 0; i < xdnd_types.length(); ++i)
+ DEBUG() << " " << connection()->atomName(xdnd_types.at(i));
+}
+
+void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *e, bool passive)
+{
+ QPoint p((e->data.data32[2] & 0xffff0000) >> 16, e->data.data32[2] & 0x0000ffff);
+ Q_ASSERT(w);
+ QRect geometry = w->geometry();
+
+ p -= geometry.topLeft();
+
+ // ####
+// if (!passive && checkEmbedded(w, e))
+// return;
+
+ if (!w || (/*!w->acceptDrops() &&*/ (w->windowType() == Qt::Desktop)))
+ return;
+
+ if (e->data.data32[0] != xdnd_dragsource) {
+ DEBUG("xdnd drag position from unexpected source (%x not %x)", e->data.data32[0], xdnd_dragsource);
+ return;
+ }
+
+ // timestamp from the source
+ if (e->data.data32[3] != XCB_NONE)
+ target_time /*= X11->userTime*/ = e->data.data32[3];
+
+ QDragManager *manager = QDragManager::self();
+ QMimeData *dropData = manager->dropData();
+
+ xcb_client_message_event_t response;
+ response.response_type = XCB_CLIENT_MESSAGE;
+ response.window = xdnd_dragsource;
+ response.format = 32;
+ response.type = atom(QXcbAtom::XdndStatus);
+ response.data.data32[0] = xcb_window(w);
+ response.data.data32[1] = 0; // flags
+ response.data.data32[2] = 0; // x, y
+ response.data.data32[3] = 0; // w, h
+ response.data.data32[4] = 0; // action
+
+ if (!passive) { // otherwise just reject
+ QRect answerRect(p + geometry.topLeft(), QSize(1,1));
+
+ if (manager->object) {
+ manager->possible_actions = manager->dragPrivate()->possible_actions;
+ } else {
+ manager->possible_actions = Qt::DropActions(toDropAction(e->data.data32[4]));
+ }
+ QDragMoveEvent me(p, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+
+ Qt::DropAction accepted_action = Qt::IgnoreAction;
+
+ currentPosition = p;
+
+ if (w != currentWindow.data()) {
+ if (currentWindow) {
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(currentWindow.data(), &e);
+ }
+ currentWindow = w;
+
+ last_target_accepted_action = Qt::IgnoreAction;
+ QDragEnterEvent de(p, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ QGuiApplication::sendEvent(w, &de);
+ if (de.isAccepted() && de.dropAction() != Qt::IgnoreAction)
+ last_target_accepted_action = de.dropAction();
+ }
+
+ DEBUG() << "qt_handle_xdnd_position action=" << connection()->atomName(e->data.data32[4]);
+
+ if (last_target_accepted_action != Qt::IgnoreAction) {
+ me.setDropAction(last_target_accepted_action);
+ me.accept();
+ }
+ QGuiApplication::sendEvent(w, &me);
+ if (me.isAccepted()) {
+ response.data.data32[1] = 1; // yes
+ accepted_action = me.dropAction();
+ last_target_accepted_action = accepted_action;
+ } else {
+ response.data.data32[0] = 0;
+ last_target_accepted_action = Qt::IgnoreAction;
+ }
+ answerRect = me.answerRect().translated(geometry.topLeft()).intersected(geometry);
+
+ if (answerRect.left() < 0)
+ answerRect.setLeft(0);
+ if (answerRect.right() > 4096)
+ answerRect.setRight(4096);
+ if (answerRect.top() < 0)
+ answerRect.setTop(0);
+ if (answerRect.bottom() > 4096)
+ answerRect.setBottom(4096);
+ if (answerRect.width() < 0)
+ answerRect.setWidth(0);
+ if (answerRect.height() < 0)
+ answerRect.setHeight(0);
+
+// response.data.data32[2] = (answerRect.x() << 16) + answerRect.y();
+// response.data.data32[3] = (answerRect.width() << 16) + answerRect.height();
+ response.data.data32[4] = toXdndAction(accepted_action);
+ }
+
+ // reset
+ target_time = XCB_CURRENT_TIME;
+
+ DEBUG() << "sending XdndStatus" << (xdnd_dragsource == connection()->clipboard()->owner()) << xdnd_dragsource
+ << response.data.data32[1] << connection()->atomName(response.data.data32[4]);
+ if (xdnd_dragsource == connection()->clipboard()->owner())
+ handle_xdnd_status(&response, passive);
+ else
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&response));
+}
+
+namespace
+{
+ class ClientMessageScanner {
+ public:
+ ClientMessageScanner(xcb_atom_t a) : atom(a) {}
+ xcb_atom_t atom;
+ bool check(xcb_generic_event_t *event) const {
+ if (!event)
+ return false;
+ if ((event->response_type & 0x7f) != XCB_CLIENT_MESSAGE)
+ return false;
+ return ((xcb_client_message_event_t *)event)->type == atom;
+ }
+ };
+}
+
+void QXcbDrag::handlePosition(QWindow * w, const xcb_client_message_event_t *event, bool passive)
+{
+ xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
+ xcb_generic_event_t *nextEvent;
+ ClientMessageScanner scanner(atom(QXcbAtom::XdndPosition));
+ while ((nextEvent = connection()->checkEvent(scanner))) {
+ if (lastEvent != event)
+ free(lastEvent);
+ lastEvent = (xcb_client_message_event_t *)nextEvent;
+ }
+
+ handle_xdnd_position(w, lastEvent, passive);
+ if (lastEvent != event)
+ free(lastEvent);
+}
+
+void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event, bool)
+{
+ DEBUG("xdndHandleStatus");
+ // ignore late status messages
+ if (event->data.data32[0] && event->data.data32[0] != current_proxy_target)
+ return;
+
+ Qt::DropAction newAction = (event->data.data32[1] & 0x1) ? toDropAction(event->data.data32[4]) : Qt::IgnoreAction;
+
+ if ((event->data.data32[1] & 2) == 0) {
+ QPoint p((event->data.data32[2] & 0xffff0000) >> 16, event->data.data32[2] & 0x0000ffff);
+ QSize s((event->data.data32[3] & 0xffff0000) >> 16, event->data.data32[3] & 0x0000ffff);
+ source_sameanswer = QRect(p, s);
+ } else {
+ source_sameanswer = QRect();
+ }
+ QDragManager *manager = QDragManager::self();
+ manager->willDrop = (event->data.data32[1] & 0x1);
+ if (manager->global_accepted_action != newAction) {
+ manager->global_accepted_action = newAction;
+ manager->emitActionChanged(newAction);
+ }
+ DEBUG() << "willDrop=" << manager->willDrop << "action=" << newAction;
+ manager->updateCursor();
+ waiting_for_status = false;
+}
+
+void QXcbDrag::handleStatus(const xcb_client_message_event_t *event, bool passive)
+{
+ if (event->window != connection()->clipboard()->owner())
+ return;
+
+ xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
+ qDebug() << "handleStatus" << lastEvent->window << lastEvent->data.data32[0];
+ xcb_generic_event_t *nextEvent;
+ ClientMessageScanner scanner(atom(QXcbAtom::XdndStatus));
+ while ((nextEvent = connection()->checkEvent(scanner))) {
+ if (lastEvent != event)
+ free(lastEvent);
+ lastEvent = (xcb_client_message_event_t *)nextEvent;
+ }
+
+ handle_xdnd_status(lastEvent, passive);
+ if (lastEvent != event)
+ free(lastEvent);
+ DEBUG("xdndHandleStatus end");
+}
+
+void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event, bool /*passive*/)
+{
+ DEBUG("xdnd leave");
+ if (!currentWindow || w != currentWindow.data())
+ return; // sanity
+
+ // ###
+// if (checkEmbedded(current_embedding_widget, event)) {
+// current_embedding_widget = 0;
+// currentWindow.clear();
+// return;
+// }
+
+ if (event->data.data32[0] != xdnd_dragsource) {
+ // This often happens - leave other-process window quickly
+ DEBUG("xdnd drag leave from unexpected source (%x not %x", event->data.data32[0], xdnd_dragsource);
+ }
+
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(currentWindow.data(), &e);
+
+ xdnd_dragsource = 0;
+ xdnd_types.clear();
+ currentWindow.clear();
+}
+
+void QXcbDrag::send_leave()
+{
+ if (!current_target)
+ return;
+
+ QDragManager *manager = QDragManager::self();
+
+ xcb_client_message_event_t leave;
+ leave.response_type = XCB_CLIENT_MESSAGE;
+ leave.window = current_target;
+ leave.format = 32;
+ leave.type = atom(QXcbAtom::XdndLeave);
+ leave.data.data32[0] = connection()->clipboard()->owner();
+ leave.data.data32[1] = 0; // flags
+ leave.data.data32[2] = 0; // x, y
+ leave.data.data32[3] = 0; // w, h
+ leave.data.data32[4] = 0; // just null
+
+ QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
+
+ if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ w = 0;
+
+ if (w)
+ handleLeave(w->window(), (const xcb_client_message_event_t *)&leave, false);
+ else
+ xcb_send_event(xcb_connection(), false,current_proxy_target,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&leave);
+
+ // reset the drag manager state
+ manager->willDrop = false;
+ if (manager->global_accepted_action != Qt::IgnoreAction)
+ manager->emitActionChanged(Qt::IgnoreAction);
+ manager->global_accepted_action = Qt::IgnoreAction;
+ manager->updateCursor();
+ current_target = 0;
+ current_proxy_target = 0;
+ source_time = XCB_CURRENT_TIME;
+ waiting_for_status = false;
+}
+
+void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event, bool passive)
+{
+ DEBUG("xdndHandleDrop");
+ if (!currentWindow) {
+ xdnd_dragsource = 0;
+ return; // sanity
+ }
+
+ // ###
+// if (!passive && checkEmbedded(currentWindow, xe)){
+// current_embedding_widget = 0;
+// xdnd_dragsource = 0;
+// currentWindow = 0;
+// return;
+// }
+ const uint32_t *l = event->data.data32;
+
+ QDragManager *manager = QDragManager::self();
+ DEBUG("xdnd drop");
+
+ if (l[0] != xdnd_dragsource) {
+ DEBUG("xdnd drop from unexpected source (%x not %x", l[0], xdnd_dragsource);
+ return;
+ }
+
+ // update the "user time" from the timestamp in the event.
+ if (l[2] != 0)
+ target_time = /*X11->userTime =*/ l[2];
+
+ if (!passive) {
+ // this could be a same-application drop, just proxied due to
+ // some XEMBEDding, so try to find the real QMimeData used
+ // based on the timestamp for this drop.
+ QMimeData *dropData = 0;
+ // ###
+// int at = findXdndDropTransactionByTime(target_time);
+// if (at != -1)
+// dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
+ // if we can't find it, then use the data in the drag manager
+ if (!dropData)
+ dropData = manager->dropData();
+
+ // Drop coming from another app? Update keyboard modifiers.
+// if (!qt_xdnd_dragging) {
+// QApplicationPrivate::modifier_buttons = currentKeyboardModifiers();
+// }
+
+ QDropEvent de(currentPosition, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ QGuiApplication::sendEvent(currentWindow.data(), &de);
+ if (!de.isAccepted()) {
+ // Ignore a failed drag
+ manager->global_accepted_action = Qt::IgnoreAction;
+ } else {
+ manager->global_accepted_action = de.dropAction();
+ }
+ xcb_client_message_event_t finished;
+ finished.response_type = XCB_CLIENT_MESSAGE;
+ finished.window = xdnd_dragsource;
+ finished.format = 32;
+ finished.type = atom(QXcbAtom::XdndFinished);
+ DNDDEBUG << "xdndHandleDrop"
+ << "currentWindow" << currentWindow.data()
+ << (currentWindow ? xcb_window(currentWindow.data()) : 0);
+ finished.data.data32[0] = currentWindow ? xcb_window(currentWindow.data()) : XCB_NONE;
+ finished.data.data32[1] = de.isAccepted() ? 1 : 0; // flags
+ finished.data.data32[2] = toXdndAction(manager->global_accepted_action);
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
+ XCB_EVENT_MASK_NO_EVENT, (char *)&finished));
+ } else {
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(currentWindow.data(), &e);
+ }
+ xdnd_dragsource = 0;
+ currentWindow.clear();
+ waiting_for_status = false;
+
+ // reset
+ target_time = XCB_CURRENT_TIME;
+}
+
+
+void QXcbDrag::handleFinished(const xcb_client_message_event_t *event, bool)
+{
+ DEBUG("xdndHandleFinished");
+ if (event->window != connection()->clipboard()->owner())
+ return;
+
+ const unsigned long *l = (const unsigned long *)event->data.data32;
+
+ DNDDEBUG << "xdndHandleFinished, l[0]" << l[0]
+ << "current_target" << current_target
+ << "qt_xdnd_current_proxy_targe" << current_proxy_target;
+
+ if (l[0]) {
+ int at = findTransactionByWindow(l[0]);
+ if (at != -1) {
+ restartDropExpiryTimer();
+
+ Transaction t = transactions.takeAt(at);
+// QDragManager *manager = QDragManager::self();
+
+// Window target = current_target;
+// Window proxy_target = current_proxy_target;
+// QWidget *embedding_widget = current_embedding_widget;
+// QDrag *currentObject = manager->object;
+
+// current_target = t.target;
+// current_proxy_target = t.proxy_target;
+// current_embedding_widget = t.embedding_widget;
+// manager->object = t.object;
+
+// if (!passive)
+// (void) checkEmbedded(currentWindow, xe);
+
+// current_embedding_widget = 0;
+// current_target = 0;
+// current_proxy_target = 0;
+
+ if (t.object)
+ t.object->deleteLater();
+
+// current_target = target;
+// current_proxy_target = proxy_target;
+// current_embedding_widget = embedding_widget;
+// manager->object = currentObject;
+ }
+ }
+ waiting_for_status = false;
+}
+
+
+void QXcbDrag::timerEvent(QTimerEvent* e)
+{
+ if (e->timerId() == heartbeat && source_sameanswer.isNull()) {
+ QPointF pos = QCursor::pos();
+ QMouseEvent me(QEvent::MouseMove, pos, pos, pos, Qt::LeftButton,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ move(&me);
+ } else if (e->timerId() == transaction_expiry_timer) {
+ for (int i = 0; i < transactions.count(); ++i) {
+ const Transaction &t = transactions.at(i);
+ if (t.targetWindow) {
+ // dnd within the same process, don't delete these
+ continue;
+ }
+ t.object->deleteLater();
+ transactions.removeAt(i--);
+ }
+
+ killTimer(transaction_expiry_timer);
+ transaction_expiry_timer = -1;
+ }
+}
+
+void QXcbDrag::cancel()
+{
+ DEBUG("QXcbDrag::cancel");
+ endDrag();
+
+ if (current_target)
+ send_leave();
+
+ current_target = 0;
+}
+
+#if 0
+
+static
+Window findRealWindow(const QPoint & pos, Window w, int md)
+{
+ if (xdnd_data.deco && w == xdnd_data.deco->effectiveWinId())
+ return 0;
+
+ if (md) {
+ X11->ignoreBadwindow();
+ XWindowAttributes attr;
+ XGetWindowAttributes(X11->display, w, &attr);
+ if (X11->badwindow())
+ return 0;
+
+ if (attr.map_state == IsViewable
+ && QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)) {
+ {
+ Atom type = XNone;
+ int f;
+ unsigned long n, a;
+ unsigned char *data;
+
+ XGetWindowProperty(X11->display, w, ATOM(XdndAware), 0, 0, False,
+ AnyPropertyType, &type, &f,&n,&a,&data);
+ if (data) XFree(data);
+ if (type)
+ return w;
+ }
+
+ Window r, p;
+ Window* c;
+ uint nc;
+ if (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
+ r=0;
+ for (uint i=nc; !r && i--;) {
+ r = findRealWindow(pos-QPoint(attr.x,attr.y),
+ c[i], md-1);
+ }
+ XFree(c);
+ if (r)
+ return r;
+
+ // We didn't find a client window! Just use the
+ // innermost window.
+ }
+
+ // No children!
+ return w;
+ }
+ }
+ return 0;
+}
+#endif
+
+void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
+{
+ xcb_selection_notify_event_t notify;
+ notify.response_type = XCB_SELECTION_NOTIFY;
+ notify.requestor = event->requestor;
+ notify.selection = event->selection;
+ notify.target = XCB_NONE;
+ notify.property = XCB_NONE;
+ notify.time = event->time;
+
+ QDragManager *manager = QDragManager::self();
+ QDrag *currentObject = manager->object;
+
+ // which transaction do we use? (note: -2 means use current manager->object)
+ int at = -1;
+
+ // figure out which data the requestor is really interested in
+ if (manager->object && event->time == source_time) {
+ // requestor wants the current drag data
+ at = -2;
+ } else {
+ // if someone has requested data in response to XdndDrop, find the corresponding transaction. the
+ // spec says to call XConvertSelection() using the timestamp from the XdndDrop
+ at = findTransactionByTime(event->time);
+ if (at == -1) {
+ // no dice, perhaps the client was nice enough to use the same window id in XConvertSelection()
+ // that we sent the XdndDrop event to.
+ at = findTransactionByWindow(event->requestor);
+ }
+// if (at == -1 && event->time == XCB_CURRENT_TIME) {
+// // previous Qt versions always requested the data on a child of the target window
+// // using CurrentTime... but it could be asking for either drop data or the current drag's data
+// Window target = findXdndAwareParent(event->requestor);
+// if (target) {
+// if (current_target && current_target == target)
+// at = -2;
+// else
+// at = findXdndDropTransactionByWindow(target);
+// }
+// }
+ }
+ if (at >= 0) {
+ restartDropExpiryTimer();
+
+ // use the drag object from an XdndDrop tansaction
+ manager->object = transactions.at(at).object;
+ } else if (at != -2) {
+ // no transaction found, we'll have to reject the request
+ manager->object = 0;
+ }
+ if (manager->object) {
+ xcb_atom_t atomFormat = event->target;
+ int dataFormat = 0;
+ QByteArray data;
+ if (QXcbMime::mimeDataForAtom(connection(), event->target, manager->dragPrivate()->data,
+ &data, &atomFormat, &dataFormat)) {
+ int dataSize = data.size() / (dataFormat / 8);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, event->requestor, event->property,
+ atomFormat, dataFormat, dataSize, (const void *)data.constData());
+ notify.property = event->property;
+ notify.target = atomFormat;
+ }
+ }
+
+ // reset manager->object in case we modified it above
+ manager->object = currentObject;
+
+ xcb_send_event(xcb_connection(), false, event->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&notify);
+}
+
+
+bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
+{
+ DNDDEBUG << "xdndEnable" << w << on;
+ if (on) {
+ QXcbWindow *xdnd_widget = 0;
+ if ((w->window()->windowType() == Qt::Desktop)) {
+ if (desktop_proxy) // *WE* already have one.
+ return false;
+
+ xcb_grab_server(xcb_connection());
+
+ // As per Xdnd4, use XdndProxy
+ xcb_window_t proxy_id = xdndProxy(connection(), w->xcb_window());
+
+ if (!proxy_id) {
+ desktop_proxy = new QWindow;
+ xdnd_widget = static_cast<QXcbWindow *>(desktop_proxy->handle());
+ proxy_id = xdnd_widget->xcb_window();
+ xcb_atom_t xdnd_proxy = atom(QXcbAtom::XdndProxy);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, w->xcb_window(), xdnd_proxy,
+ XCB_ATOM_WINDOW, 32, 1, &proxy_id);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, proxy_id, xdnd_proxy,
+ XCB_ATOM_WINDOW, 32, 1, &proxy_id);
+ }
+
+ xcb_ungrab_server(xcb_connection());
+ } else {
+ xdnd_widget = w;
+ }
+ if (xdnd_widget) {
+ DNDDEBUG << "setting XdndAware for" << xdnd_widget << xdnd_widget->xcb_window();
+ xcb_atom_t atm = xdnd_version;
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, xdnd_widget->xcb_window(),
+ atom(QXcbAtom::XdndAware), XCB_ATOM_ATOM, 32, 1, &atm);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if ((w->window()->windowType() == Qt::Desktop)) {
+ xcb_delete_property(xcb_connection(), w->xcb_window(), atom(QXcbAtom::XdndProxy));
+ delete desktop_proxy;
+ desktop_proxy = 0;
+ } else {
+ DNDDEBUG << "not deleting XDndAware";
+ }
+ return true;
+ }
+}
+
+
+
+
+QDropData::QDropData(QXcbDrag *d)
+ : QXcbMime(),
+ drag(d)
+{
+}
+
+QDropData::~QDropData()
+{
+}
+
+QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type requestedType) const
+{
+ QByteArray mime = mimetype.toLatin1();
+ QVariant data = /*X11->motifdnd_active
+ ? X11->motifdndObtainData(mime)
+ :*/ xdndObtainData(mime, requestedType);
+ return data;
+}
+
+QVariant QDropData::xdndObtainData(const QByteArray &format, QVariant::Type requestedType) const
+{
+ QByteArray result;
+
+ QDragManager *manager = QDragManager::self();
+ QXcbConnection *c = drag->connection();
+ QXcbWindow *xcb_window = c->platformWindowFromId(drag->xdnd_dragsource);
+ if (xcb_window && manager->object && xcb_window->window()->windowType() != Qt::Desktop) {
+ QDragPrivate *o = manager->dragPrivate();
+ if (o->data->hasFormat(QLatin1String(format)))
+ result = o->data->data(QLatin1String(format));
+ return result;
+ }
+
+ QList<xcb_atom_t> atoms = drag->xdnd_types;
+ QByteArray encoding;
+ xcb_atom_t a = mimeAtomForFormat(c, QLatin1String(format), requestedType, atoms, &encoding);
+ if (a == XCB_NONE)
+ return result;
+
+ if (c->clipboard()->getSelectionOwner(drag->atom(QXcbAtom::XdndSelection)) == XCB_NONE)
+ return result; // should never happen?
+
+ xcb_atom_t xdnd_selection = c->atom(QXcbAtom::XdndSelection);
+ result = c->clipboard()->getSelection(xdnd_selection, a, xdnd_selection);
+
+ return mimeConvertToFormat(c, a, result, QLatin1String(format), requestedType, encoding);
+}
+
+
+bool QDropData::hasFormat_sys(const QString &format) const
+{
+ return formats().contains(format);
+}
+
+QStringList QDropData::formats_sys() const
+{
+ QStringList formats;
+// if (X11->motifdnd_active) {
+// int i = 0;
+// QByteArray fmt;
+// while (!(fmt = X11->motifdndFormat(i)).isEmpty()) {
+// formats.append(QLatin1String(fmt));
+// ++i;
+// }
+// } else {
+ for (int i = 0; i < drag->xdnd_types.size(); ++i) {
+ QString f = mimeAtomToString(drag->connection(), drag->xdnd_types.at(i));
+ if (!formats.contains(f))
+ formats.append(f);
+ }
+// }
+ return formats;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
new file mode 100644
index 0000000000..ce0f8faa54
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBDRAG_H
+#define QXCBDRAG_H
+
+#include <qplatformdrag_qpa.h>
+#include <qxcbobject.h>
+#include <xcb/xcb.h>
+#include <qlist.h>
+#include <qpoint.h>
+#include <qrect.h>
+#include <qsharedpointer.h>
+#include <qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMouseEvent;
+class QWindow;
+class QXcbConnection;
+class QXcbWindow;
+class QDropData;
+class QXcbScreen;
+class QDrag;
+
+class QXcbDrag : public QObject, public QXcbObject, public QPlatformDrag
+{
+public:
+ QXcbDrag(QXcbConnection *c);
+ ~QXcbDrag();
+
+ virtual QMimeData *platformDropData();
+
+// virtual Qt::DropAction drag(QDrag *);
+
+ virtual void startDrag();
+ virtual void cancel();
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+ void endDrag();
+
+ void handleEnter(QWindow *window, const xcb_client_message_event_t *event);
+ void handlePosition(QWindow *w, const xcb_client_message_event_t *event, bool passive);
+ void handleLeave(QWindow *w, const xcb_client_message_event_t *event, bool /*passive*/);
+ void handleDrop(QWindow *, const xcb_client_message_event_t *event, bool passive);
+
+ void handleStatus(const xcb_client_message_event_t *event, bool passive);
+ void handleSelectionRequest(const xcb_selection_request_event_t *event);
+ void handleFinished(const xcb_client_message_event_t *event, bool passive);
+
+ bool dndEnable(QXcbWindow *win, bool on);
+
+protected:
+ void timerEvent(QTimerEvent* e);
+
+private:
+ friend class QDropData;
+
+ void init();
+
+ void handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *event, bool passive);
+ void handle_xdnd_status(const xcb_client_message_event_t *event, bool);
+ void send_leave();
+
+ Qt::DropAction toDropAction(xcb_atom_t atom) const;
+ xcb_atom_t toXdndAction(Qt::DropAction a) const;
+
+ QWeakPointer<QWindow> currentWindow;
+ QPoint currentPosition;
+
+ QDropData *dropData;
+
+ QWindow *desktop_proxy;
+
+ xcb_atom_t xdnd_dragsource;
+
+ // the types in this drop. 100 is no good, but at least it's big.
+ enum { xdnd_max_type = 100 };
+ QList<xcb_atom_t> xdnd_types;
+
+ xcb_timestamp_t target_time;
+ xcb_timestamp_t source_time;
+ Qt::DropAction last_target_accepted_action;
+
+ // rectangle in which the answer will be the same
+ QRect source_sameanswer;
+ bool waiting_for_status;
+
+ // top-level window we sent position to last.
+ xcb_window_t current_target;
+ // window to send events to (always valid if current_target)
+ xcb_window_t current_proxy_target;
+
+ QXcbScreen *current_screen;
+
+ int heartbeat;
+ bool xdnd_dragging;
+
+ QVector<xcb_atom_t> drag_types;
+
+ struct Transaction
+ {
+ xcb_timestamp_t timestamp;
+ xcb_window_t target;
+ xcb_window_t proxy_target;
+ QWindow *targetWindow;
+// QWidget *embedding_widget;
+ QDrag *object;
+ };
+ QList<Transaction> transactions;
+
+ int transaction_expiry_timer;
+ void restartDropExpiryTimer();
+ int findTransactionByWindow(xcb_window_t window);
+ int findTransactionByTime(xcb_timestamp_t timestamp);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbeglsurface.h b/src/plugins/platforms/xcb/qxcbeglsurface.h
new file mode 100644
index 0000000000..a1e6c148a2
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbeglsurface.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBEGLSURFACE_H
+#define QXCBEGLSURFACE_H
+
+#include <EGL/egl.h>
+
+class QXcbEGLSurface
+{
+public:
+ QXcbEGLSurface(EGLDisplay display, EGLSurface surface)
+ : m_display(display)
+ , m_surface(surface)
+ {
+ }
+
+ ~QXcbEGLSurface()
+ {
+ eglDestroySurface(m_display, m_surface);
+ }
+
+ EGLSurface surface() const { return m_surface; }
+
+private:
+ EGLDisplay m_display;
+ EGLSurface m_surface;
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp
new file mode 100644
index 0000000000..569e4fc4e4
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbimage.cpp
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbimage.h"
+#include <QtGui/QColor>
+#include <QtGui/private/qimage_p.h>
+#include <QtGui/private/qdrawhelper_p.h>
+#ifdef XCB_USE_RENDER
+#include <xcb/render.h>
+// 'template' is used as a function argument name in xcb_renderutil.h
+#define template template_param
+// extern "C" is missing too
+extern "C" {
+#include <xcb/xcb_renderutil.h>
+}
+#undef template
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth,
+ const xcb_visualtype_t *visual)
+{
+ const xcb_format_t *format = connection->formatForDepth(depth);
+
+ if (!visual || !format)
+ return QImage::Format_Invalid;
+
+ if (depth == 32 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000
+ && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
+ return QImage::Format_ARGB32_Premultiplied;
+
+ if (depth == 24 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000
+ && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
+ return QImage::Format_RGB32;
+
+ if (depth == 16 && format->bits_per_pixel == 16 && visual->red_mask == 0xf800
+ && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f)
+ return QImage::Format_RGB16;
+
+ return QImage::Format_Invalid;
+}
+
+QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap,
+ int width, int height, int depth,
+ const xcb_visualtype_t *visual)
+{
+ xcb_connection_t *conn = connection->xcb_connection();
+ xcb_generic_error_t *error = 0;
+
+ xcb_get_image_cookie_t get_image_cookie =
+ xcb_get_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap,
+ 0, 0, width, height, 0xffffffff);
+
+ xcb_get_image_reply_t *image_reply =
+ xcb_get_image_reply(conn, get_image_cookie, &error);
+
+ if (!image_reply) {
+ if (error) {
+ connection->handleXcbError(error);
+ free(error);
+ }
+ return QPixmap();
+ }
+
+ uint8_t *data = xcb_get_image_data(image_reply);
+ uint32_t length = xcb_get_image_data_length(image_reply);
+
+ QPixmap result;
+
+ QImage::Format format = qt_xcb_imageFormatForVisual(connection, depth, visual);
+ if (format != QImage::Format_Invalid) {
+ uint32_t bytes_per_line = length / height;
+ QImage image(const_cast<uint8_t *>(data), width, height, bytes_per_line, format);
+ uint8_t image_byte_order = connection->setup()->image_byte_order;
+
+ // we may have to swap the byte order
+ if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
+ || (QSysInfo::ByteOrder == QSysInfo::BigEndian && image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST))
+ {
+ for (int i=0; i < image.height(); i++) {
+ switch (format) {
+ case QImage::Format_RGB16: {
+ ushort *p = (ushort*)image.scanLine(i);
+ ushort *end = p + image.width();
+ while (p < end) {
+ *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
+ p++;
+ }
+ break;
+ }
+ case QImage::Format_RGB32: // fall-through
+ case QImage::Format_ARGB32_Premultiplied: {
+ uint *p = (uint*)image.scanLine(i);
+ uint *end = p + image.width();
+ while (p < end) {
+ *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
+ | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
+ p++;
+ }
+ break;
+ }
+ default:
+ Q_ASSERT(false);
+ }
+ }
+ }
+
+ // fix-up alpha channel
+ if (format == QImage::Format_RGB32) {
+ QRgb *p = (QRgb *)image.bits();
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x)
+ p[x] |= 0xff000000;
+ p += bytes_per_line / 4;
+ }
+ }
+
+ result = QPixmap::fromImage(image.copy());
+ }
+
+ free(image_reply);
+ return result;
+}
+
+xcb_pixmap_t qt_xcb_XPixmapFromBitmap(QXcbScreen *screen, const QImage &image)
+{
+ xcb_connection_t *conn = screen->xcb_connection();
+ QImage bitmap = image.convertToFormat(QImage::Format_MonoLSB);
+ const QRgb c0 = QColor(Qt::black).rgb();
+ const QRgb c1 = QColor(Qt::white).rgb();
+ if (bitmap.color(0) == c0 && bitmap.color(1) == c1) {
+ bitmap.invertPixels();
+ bitmap.setColor(0, c1);
+ bitmap.setColor(1, c0);
+ }
+ const int width = bitmap.width();
+ const int height = bitmap.height();
+ const int bytesPerLine = bitmap.bytesPerLine();
+ int destLineSize = width / 8;
+ if (width % 8)
+ ++destLineSize;
+ const uchar *map = bitmap.bits();
+ uint8_t *buf = new uint8_t[height * destLineSize];
+ for (int i = 0; i < height; i++)
+ memcpy(buf + (destLineSize * i), map + (bytesPerLine * i), destLineSize);
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, screen->root(), buf,
+ width, height, 1, 0, 0, 0);
+ delete[] buf;
+ return pm;
+}
+
+xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
+ const QPoint &spot)
+{
+#ifdef XCB_USE_RENDER
+ xcb_connection_t *conn = screen->xcb_connection();
+ const int w = image.width();
+ const int h = image.height();
+ xcb_generic_error_t *error = 0;
+ xcb_render_query_pict_formats_cookie_t formatsCookie = xcb_render_query_pict_formats(conn);
+ xcb_render_query_pict_formats_reply_t *formatsReply = xcb_render_query_pict_formats_reply(conn,
+ formatsCookie,
+ &error);
+ if (!formatsReply || error) {
+ qWarning("createCursorXRender: query_pict_formats failed");
+ free(formatsReply);
+ free(error);
+ return XCB_NONE;
+ }
+ xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formatsReply,
+ XCB_PICT_STANDARD_ARGB_32);
+ if (!fmt) {
+ qWarning("createCursorXRender: Failed to find format PICT_STANDARD_ARGB_32");
+ free(formatsReply);
+ return XCB_NONE;
+ }
+
+ QImage img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ xcb_image_t *xi = xcb_image_create(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP,
+ 32, 32, 32, 32,
+ QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST,
+ XCB_IMAGE_ORDER_MSB_FIRST,
+ 0, 0, 0);
+ if (!xi) {
+ qWarning("createCursorXRender: xcb_image_create failed");
+ free(formatsReply);
+ return XCB_NONE;
+ }
+ xi->data = (uint8_t *) malloc(xi->stride * h);
+ if (!xi->data) {
+ qWarning("createCursorXRender: Failed to malloc() image data");
+ xcb_image_destroy(xi);
+ free(formatsReply);
+ return XCB_NONE;
+ }
+ memcpy(xi->data, img.constBits(), img.byteCount());
+
+ xcb_pixmap_t pix = xcb_generate_id(conn);
+ xcb_create_pixmap(conn, 32, pix, screen->root(), w, h);
+
+ xcb_render_picture_t pic = xcb_generate_id(conn);
+ xcb_render_create_picture(conn, pic, pix, fmt->id, 0, 0);
+
+ xcb_gcontext_t gc = xcb_generate_id(conn);
+ xcb_create_gc(conn, gc, pix, 0, 0);
+ xcb_image_put(conn, pix, gc, xi, 0, 0, 0);
+ xcb_free_gc(conn, gc);
+
+ xcb_cursor_t cursor = xcb_generate_id(conn);
+ xcb_render_create_cursor(conn, cursor, pic, spot.x(), spot.y());
+
+ free(xi->data);
+ xcb_image_destroy(xi);
+ xcb_render_free_picture(conn, pic);
+ xcb_free_pixmap(conn, pix);
+ free(formatsReply);
+ return cursor;
+
+#else
+ Q_UNUSED(screen);
+ Q_UNUSED(image);
+ Q_UNUSED(spot);
+ return XCB_NONE;
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.h b/src/plugins/platforms/xcb/qxcbimage.h
index 014486bdb4..1e7f104084 100644
--- a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.h
+++ b/src/plugins/platforms/xcb/qxcbimage.h
@@ -39,50 +39,26 @@
**
****************************************************************************/
-#ifndef QSCREENVNC_QWS_H
-#define QSCREENVNC_QWS_H
+#ifndef QXCBIMAGE_H
+#define QXCBIMAGE_H
-#include <QtGui/qscreenproxy_qws.h>
-
-#ifndef QT_NO_QWS_VNC
-
-QT_BEGIN_HEADER
+#include "qxcbscreen.h"
+#include <QtCore/QPair>
+#include <QtGui/QImage>
+#include <QtGui/QPixmap>
+#include <xcb/xcb_image.h>
QT_BEGIN_NAMESPACE
-QT_MODULE(Gui)
-
-class QVNCScreenPrivate;
-
-class QVNCScreen : public QProxyScreen
-{
-public:
- explicit QVNCScreen(int display_id);
- virtual ~QVNCScreen();
-
- bool initDevice();
- bool connect(const QString &displaySpec);
- void disconnect();
- void shutdownDevice();
-
- void setDirty(const QRect&);
-
-private:
- friend class QVNCCursor;
- friend class QVNCClientCursor;
- friend class QVNCServer;
- friend class QVNCScreenPrivate;
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- bool swapBytes() const;
-#endif
-
- QVNCScreenPrivate *d_ptr;
-};
+QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection,
+ uint8_t depth, const xcb_visualtype_t *visual);
+QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap,
+ int width, int height, int depth,
+ const xcb_visualtype_t *visual);
+xcb_pixmap_t qt_xcb_XPixmapFromBitmap(QXcbScreen *screen, const QImage &image);
+xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
+ const QPoint &spot);
QT_END_NAMESPACE
-QT_END_HEADER
-
-#endif // QT_NO_QWS_VNC
-#endif // QSCREENVNC_QWS_H
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 12b63f36ea..b0d377bcac 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -43,76 +43,161 @@
#include "qxcbconnection.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
-#include "qxcbwindowsurface.h"
+#include "qxcbbackingstore.h"
#include "qxcbnativeinterface.h"
+#include "qxcbclipboard.h"
+#include "qxcbdrag.h"
#include <xcb/xcb.h>
-#include <private/qpixmap_raster_p.h>
-
-#include "qgenericunixfontdatabase.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include <stdio.h>
+//this has to be included before egl, since egl pulls in X headers
+#include <QtGui/private/qguiapplication_p.h>
+
#ifdef XCB_USE_EGL
#include <EGL/egl.h>
#endif
-QXcbIntegration::QXcbIntegration()
- : m_connection(new QXcbConnection)
+#include <private/qplatforminputcontextfactory_qpa_p.h>
+#include <qplatforminputcontext_qpa.h>
+
+#if defined(XCB_USE_GLX)
+#include "qglxintegration.h"
+#elif defined(XCB_USE_EGL)
+#include "qxcbeglsurface.h"
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+#endif
+
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
+
+QXcbIntegration::QXcbIntegration(const QStringList &parameters)
+ : m_eventDispatcher(createUnixEventDispatcher())
{
- foreach (QXcbScreen *screen, m_connection->screens())
- m_screens << screen;
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
+
+#ifdef XCB_USE_XLIB
+ XInitThreads();
+#endif
+
+ m_connections << new QXcbConnection;
+
+ for (int i = 0; i < parameters.size() - 1; i += 2) {
+ qDebug() << parameters.at(i) << parameters.at(i+1);
+ QString display = parameters.at(i) + ':' + parameters.at(i+1);
+ m_connections << new QXcbConnection(display.toAscii().constData());
+ }
+
+ foreach (QXcbConnection *connection, m_connections)
+ foreach (QXcbScreen *screen, connection->screens())
+ screenAdded(screen);
m_fontDatabase = new QGenericUnixFontDatabase();
m_nativeInterface = new QXcbNativeInterface;
+
+ m_inputContext = QPlatformInputContextFactory::create();
}
QXcbIntegration::~QXcbIntegration()
{
- delete m_connection;
+ qDeleteAll(m_connections);
}
-bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
{
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return hasOpenGL();
- default: return QPlatformIntegration::hasCapability(cap);
- }
+ return new QXcbWindow(window);
}
-QPixmapData *QXcbIntegration::createPixmapData(QPixmapData::PixelType type) const
+#if defined(XCB_USE_EGL)
+class QEGLXcbPlatformContext : public QEGLPlatformContext
{
- return new QRasterPixmapData(type);
-}
+public:
+ QEGLXcbPlatformContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share,
+ EGLDisplay display, QXcbConnection *c)
+ : QEGLPlatformContext(glFormat, share, display)
+ , m_connection(c)
+ {
+ Q_XCB_NOOP(m_connection);
+ }
+
+ void swapBuffers(QPlatformSurface *surface)
+ {
+ Q_XCB_NOOP(m_connection);
+ QEGLPlatformContext::swapBuffers(surface);
+ Q_XCB_NOOP(m_connection);
+ }
+
+ bool makeCurrent(QPlatformSurface *surface)
+ {
+ Q_XCB_NOOP(m_connection);
+ bool ret = QEGLPlatformContext::makeCurrent(surface);
+ Q_XCB_NOOP(m_connection);
+ return ret;
+ }
+
+ void doneCurrent()
+ {
+ Q_XCB_NOOP(m_connection);
+ QEGLPlatformContext::doneCurrent();
+ Q_XCB_NOOP(m_connection);
+ }
+
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+ {
+ return static_cast<QXcbWindow *>(surface)->eglSurface()->surface();
+ }
-QPlatformWindow *QXcbIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+private:
+ QXcbConnection *m_connection;
+};
+#endif
+
+QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- Q_UNUSED(winId);
- return new QXcbWindow(widget);
+ QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
+#if defined(XCB_USE_GLX)
+ return new QGLXContext(screen, context->format(), context->shareHandle());
+#elif defined(XCB_USE_EGL)
+ return new QEGLXcbPlatformContext(context->format(), context->shareHandle(),
+ screen->connection()->egl_display(), screen->connection());
+#elif defined(XCB_USE_DRI2)
+ return new QDri2Context(context->format(), context->shareHandle());
+#endif
}
-QWindowSurface *QXcbIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
- return new QXcbWindowSurface(widget);
+ return new QXcbBackingStore(window);
}
-QList<QPlatformScreen *> QXcbIntegration::screens() const
+bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
- return m_screens;
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL:
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+ return true;
+#else
+ return false;
+#endif
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
}
-void QXcbIntegration::moveToScreen(QWidget *window, int screen)
+QAbstractEventDispatcher *QXcbIntegration::guiThreadEventDispatcher() const
{
- Q_UNUSED(window);
- Q_UNUSED(screen);
+ return m_eventDispatcher;
}
-bool QXcbIntegration::isVirtualDesktop()
+void QXcbIntegration::moveToScreen(QWindow *window, int screen)
{
- return false;
+ Q_UNUSED(window);
+ Q_UNUSED(screen);
}
QPlatformFontDatabase *QXcbIntegration::fontDatabase() const
@@ -120,32 +205,22 @@ QPlatformFontDatabase *QXcbIntegration::fontDatabase() const
return m_fontDatabase;
}
-QPixmap QXcbIntegration::grabWindow(WId window, int x, int y, int width, int height) const
+QPlatformNativeInterface * QXcbIntegration::nativeInterface() const
{
- Q_UNUSED(window);
- Q_UNUSED(x);
- Q_UNUSED(y);
- Q_UNUSED(width);
- Q_UNUSED(height);
- return QPixmap();
+ return m_nativeInterface;
}
+QPlatformClipboard *QXcbIntegration::clipboard() const
+{
+ return m_connections.at(0)->clipboard();
+}
-bool QXcbIntegration::hasOpenGL() const
+QPlatformDrag *QXcbIntegration::drag() const
{
-#if defined(XCB_USE_GLX)
- return true;
-#elif defined(XCB_USE_EGL)
- return m_connection->hasEgl();
-#elif defined(XCB_USE_DRI2)
- if (m_connection->hasSupportForDri2()) {
- return true;
- }
-#endif
- return false;
+ return m_connections.at(0)->drag();
}
-QPlatformNativeInterface * QXcbIntegration::nativeInterface() const
+QPlatformInputContext *QXcbIntegration::inputContext() const
{
- return m_nativeInterface;
+ return m_inputContext;
}
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index cd68919b54..cad127c28e 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -48,34 +48,40 @@
QT_BEGIN_NAMESPACE
class QXcbConnection;
+class QAbstractEventDispatcher;
class QXcbIntegration : public QPlatformIntegration
{
public:
- QXcbIntegration();
+ QXcbIntegration(const QStringList &parameters);
~QXcbIntegration();
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+
bool hasCapability(Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
- QList<QPlatformScreen *> screens() const;
- void moveToScreen(QWidget *window, int screen);
- bool isVirtualDesktop();
- QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+ void moveToScreen(QWindow *window, int screen);
QPlatformFontDatabase *fontDatabase() const;
QPlatformNativeInterface *nativeInterface()const;
+ QPlatformClipboard *clipboard() const;
+ QPlatformDrag *drag() const;
+
+ QPlatformInputContext *inputContext() const;
+
private:
- bool hasOpenGL() const;
- QList<QPlatformScreen *> m_screens;
- QXcbConnection *m_connection;
+ QList<QXcbConnection *> m_connections;
QPlatformFontDatabase *m_fontDatabase;
QPlatformNativeInterface *m_nativeInterface;
+
+ QPlatformInputContext *m_inputContext;
+ QAbstractEventDispatcher *m_eventDispatcher;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 6bbc3c18ca..907dd0f1b6 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -40,16 +40,17 @@
****************************************************************************/
#include "qxcbkeyboard.h"
-
+#include "qxcbwindow.h"
+#include "qxcbscreen.h"
#include <xcb/xcb_keysyms.h>
-
#include <X11/keysym.h>
-
#include <QtGui/QWindowSystemInterface>
#include <QtCore/QTextCodec>
-
+#include <private/qguiapplication_p.h>
#include <stdio.h>
+#include <qplatforminputcontext_qpa.h>
+
#ifndef XK_ISO_Left_Tab
#define XK_ISO_Left_Tab 0xFE20
#endif
@@ -898,12 +899,9 @@ QString QXcbKeyboard::translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
: QXcbObject(connection)
- , m_alt_mask(0)
- , m_super_mask(0)
- , m_hyper_mask(0)
- , m_meta_mask(0)
{
m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
+ setupModifiers();
}
QXcbKeyboard::~QXcbKeyboard()
@@ -911,18 +909,113 @@ QXcbKeyboard::~QXcbKeyboard()
xcb_key_symbols_free(m_key_symbols);
}
-// #define XCB_KEYBOARD_DEBUG
+void QXcbKeyboard::setupModifiers()
+{
+ m_alt_mask = 0;
+ m_super_mask = 0;
+ m_hyper_mask = 0;
+ m_meta_mask = 0;
+ m_mode_switch_mask = 0;
+ m_num_lock_mask = 0;
+ m_caps_lock_mask = 0;
+
+ xcb_generic_error_t *error = 0;
+ xcb_connection_t *conn = xcb_connection();
+ xcb_get_modifier_mapping_cookie_t modMapCookie = xcb_get_modifier_mapping(conn);
+ xcb_get_modifier_mapping_reply_t *modMapReply =
+ xcb_get_modifier_mapping_reply(conn, modMapCookie, &error);
+ if (error) {
+ qWarning("xcb keyboard: failed to get modifier mapping");
+ free(error);
+ return;
+ }
+
+ // Figure out the modifier mapping, ICCCM 6.6
+ typedef QPair<uint, xcb_keycode_t *> SymCodes;
+ QList<SymCodes> modKeyCodes;
+
+ // for Alt and Meta L and R are the same
+ modKeyCodes << SymCodes(XK_Alt_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Alt_L));
+ modKeyCodes << SymCodes(XK_Meta_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Meta_L));
+ modKeyCodes << SymCodes(XK_Super_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Super_L));
+ modKeyCodes << SymCodes(XK_Super_R, xcb_key_symbols_get_keycode(m_key_symbols, XK_Super_R));
+ modKeyCodes << SymCodes(XK_Hyper_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Hyper_L));
+ modKeyCodes << SymCodes(XK_Hyper_R, xcb_key_symbols_get_keycode(m_key_symbols, XK_Hyper_R));
+ modKeyCodes << SymCodes(XK_Num_Lock, xcb_key_symbols_get_keycode(m_key_symbols, XK_Num_Lock));
+ modKeyCodes << SymCodes(XK_Mode_switch, xcb_key_symbols_get_keycode(m_key_symbols, XK_Mode_switch));
+ modKeyCodes << SymCodes(XK_Caps_Lock, xcb_key_symbols_get_keycode(m_key_symbols, XK_Caps_Lock));
+
+ xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply);
+ const int w = modMapReply->keycodes_per_modifier;
+ for (int i = 0; i < modKeyCodes.count(); ++i) {
+ for (int bit = 0; bit < 8; ++bit) {
+ uint mask = 1 << bit;
+ for (int x = 0; x < w; ++x) {
+ xcb_keycode_t keyCode = modMap[x + bit * w];
+ xcb_keycode_t *itk = modKeyCodes.at(i).second;
+ while (itk && *itk != XCB_NO_SYMBOL)
+ if (*itk++ == keyCode)
+ setMask(modKeyCodes.at(i).first, mask);
+ }
+ }
+ }
-void QXcbKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time)
+ for (int i = 0; i < modKeyCodes.count(); ++i)
+ free(modKeyCodes.at(i).second);
+ free(modMapReply);
+}
+
+void QXcbKeyboard::setMask(uint sym, uint mask)
{
- int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0;
+ if (m_alt_mask == 0
+ && m_meta_mask != mask
+ && m_super_mask != mask
+ && m_hyper_mask != mask
+ && (sym == XK_Alt_L || sym == XK_Alt_R))
+ m_alt_mask = mask;
+
+ if (m_meta_mask == 0
+ && m_alt_mask != mask
+ && m_super_mask != mask
+ && m_hyper_mask != mask
+ && (sym == XK_Meta_L || sym == XK_Meta_R))
+ m_meta_mask = mask;
+
+ if (m_super_mask == 0
+ && m_alt_mask != mask
+ && m_meta_mask != mask
+ && m_hyper_mask != mask
+ && (sym == XK_Super_L || sym == XK_Super_R))
+ m_super_mask = mask;
+
+ if (m_hyper_mask == 0
+ && m_alt_mask != mask
+ && m_meta_mask != mask
+ && m_super_mask != mask
+ && (sym == XK_Hyper_L || sym == XK_Hyper_R))
+ m_hyper_mask = mask;
+
+ if (m_mode_switch_mask == 0
+ && m_alt_mask != mask
+ && m_meta_mask != mask
+ && m_super_mask != mask
+ && m_hyper_mask != mask
+ && sym == XK_Mode_switch)
+ m_mode_switch_mask = mask;
+
+ if (m_num_lock_mask == 0 && sym == XK_Num_Lock)
+ m_num_lock_mask = mask;
+
+ if (m_caps_lock_mask == 0 && sym == XK_Caps_Lock)
+ m_caps_lock_mask = mask;
+}
- const int altGrOffset = 4;
- if (state & 128)
- col += altGrOffset;
+// #define XCB_KEYBOARD_DEBUG
+void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code,
+ quint16 state, xcb_timestamp_t time)
+{
Q_XCB_NOOP(connection());
-
#ifdef XCB_KEYBOARD_DEBUG
printf("key code: %d, state: %d, syms: ", code, state);
for (int i = 0; i <= 5; ++i) {
@@ -931,43 +1024,105 @@ void QXcbKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycod
printf("\n");
#endif
- Q_XCB_NOOP(connection());
+ QByteArray chars;
+ xcb_keysym_t sym = lookupString(window, state, code, type, &chars);
+
+
+ if (QObject* inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext()) {
+ bool retval;
+ QMetaObject::invokeMethod(inputContext, "x11FilterEvent", Qt::DirectConnection,
+ Q_RETURN_ARG(bool, retval),
+ Q_ARG(uint, sym),
+ Q_ARG(uint, code),
+ Q_ARG(uint, state),
+ Q_ARG(bool, type == QEvent::KeyPress));
+ if (retval)
+ return;
+ }
+ Qt::KeyboardModifiers modifiers;
+ int qtcode = 0;
+ int count = chars.count();
+ QString string = translateKeySym(sym, state, qtcode, modifiers, chars, count);
+ QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
+ code, 0, state, string.left(count));
+}
+
+#ifdef XCB_USE_XLIB
+extern "C" {
+ int XLookupString(void *event, char *buf, int count, void *keysym, void *comp);
+}
+typedef struct { // must match XKeyEvent in Xlib.h
+ int type;
+ unsigned long serial;
+ int send_event;
+ void *display;
+ unsigned long window;
+ unsigned long root;
+ unsigned long subwindow;
+ unsigned long time;
+ int x, y;
+ int x_root, y_root;
+ unsigned int state;
+ unsigned int keycode;
+ int same_screen;
+} FakeXKeyEvent;
+#endif
+
+xcb_keysym_t QXcbKeyboard::lookupString(QWindow *window, uint state, xcb_keycode_t code,
+ QEvent::Type type, QByteArray *chars)
+{
+#ifdef XCB_USE_XLIB
+
+ xcb_keysym_t sym = XCB_NO_SYMBOL;
+ chars->resize(512);
+ FakeXKeyEvent event;
+ memset(&event, 0, sizeof(event));
+ event.type = (type == QEvent::KeyRelease ? 3 : 2);
+ event.display = connection()->xlib_display();
+ event.window = static_cast<QXcbWindow *>(window->handle())->xcb_window();
+ event.root = connection()->screens().at(0)->root();
+ event.state = state;
+ event.keycode = code;
+ int count = XLookupString(&event, chars->data(), chars->size(), &sym, 0);
+ chars->resize(count);
+ return sym;
+
+#else
+
+ // No XLookupString available. The following is really incomplete...
+
+ int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0;
+ const int altGrOffset = 4;
+ if (state & 128)
+ col += altGrOffset;
xcb_keysym_t sym = xcb_key_symbols_get_keysym(m_key_symbols, code, col);
if (sym == XCB_NO_SYMBOL)
sym = xcb_key_symbols_get_keysym(m_key_symbols, code, col ^ 0x1);
-
if (state & XCB_MOD_MASK_LOCK && sym <= 0x7f && isprint(sym)) {
if (isupper(sym))
sym = tolower(sym);
else
sym = toupper(sym);
}
+ return sym;
- Q_XCB_NOOP(connection());
-
- QByteArray chars;
-
- Qt::KeyboardModifiers modifiers;
- int qtcode = 0;
- int count = 0;
-
- QString string = translateKeySym(sym, state, qtcode, modifiers, chars, count);
-
- QWindowSystemInterface::handleExtendedKeyEvent(widget, time, type, qtcode, modifiers, code, 0, state, string.left(count));
+#endif
}
-void QXcbKeyboard::handleKeyPressEvent(QWidget *widget, const xcb_key_press_event_t *event)
+void QXcbKeyboard::handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event)
{
- handleKeyEvent(widget, QEvent::KeyPress, event->detail, event->state, event->time);
+ window->updateNetWmUserTime(event->time);
+ handleKeyEvent(window->window(), QEvent::KeyPress, event->detail, event->state, event->time);
}
-void QXcbKeyboard::handleKeyReleaseEvent(QWidget *widget, const xcb_key_release_event_t *event)
+void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event)
{
- handleKeyEvent(widget, QEvent::KeyRelease, event->detail, event->state, event->time);
+ handleKeyEvent(window->window(), QEvent::KeyRelease, event->detail, event->state, event->time);
}
void QXcbKeyboard::handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event)
{
xcb_refresh_keyboard_mapping(m_key_symbols, const_cast<xcb_mapping_notify_event_t *>(event));
+ setupModifiers();
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index 095c3e4efb..ea5f84e8c2 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -48,26 +48,32 @@
#include <QEvent>
+class QWindow;
+
class QXcbKeyboard : public QXcbObject
{
public:
QXcbKeyboard(QXcbConnection *connection);
~QXcbKeyboard();
- void handleKeyPressEvent(QWidget *widget, const xcb_key_press_event_t *event);
- void handleKeyReleaseEvent(QWidget *widget, const xcb_key_release_event_t *event);
+ void handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event);
+ void handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event);
void handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event);
Qt::KeyboardModifiers translateModifiers(int s);
private:
- void handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
+ void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
int translateKeySym(uint key) const;
QString translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
int &code, Qt::KeyboardModifiers &modifiers,
QByteArray &chars, int &count);
+ void setupModifiers();
+ void setMask(uint sym, uint mask);
+ xcb_keysym_t lookupString(QWindow *window, uint state, xcb_keycode_t code,
+ QEvent::Type type, QByteArray *chars);
uint m_alt_mask;
uint m_super_mask;
@@ -75,6 +81,7 @@ private:
uint m_meta_mask;
uint m_mode_switch_mask;
uint m_num_lock_mask;
+ uint m_caps_lock_mask;
xcb_key_symbols_t *m_key_symbols;
};
diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp
new file mode 100644
index 0000000000..d4f80ca09d
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbmime.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbmime.h"
+
+#include <QtCore/QTextCodec>
+#include <QtGui/QImageWriter>
+#include <QtCore/QBuffer>
+#include <qdebug.h>
+
+#include <X11/Xutil.h>
+
+#undef XCB_ATOM_STRING
+#undef XCB_ATOM_PIXMAP
+#undef XCB_ATOM_BITMAP
+
+QXcbMime::QXcbMime()
+ : QInternalMimeData()
+{ }
+
+QXcbMime::~QXcbMime()
+{}
+
+
+
+QString QXcbMime::mimeAtomToString(QXcbConnection *connection, xcb_atom_t a)
+{
+ if (a == XCB_NONE)
+ return QString();
+
+ // special cases for string type
+ if (a == XCB_ATOM_STRING
+ || a == connection->atom(QXcbAtom::UTF8_STRING)
+ || a == connection->atom(QXcbAtom::TEXT))
+ return QLatin1String("text/plain");
+
+ // special case for images
+ if (a == XCB_ATOM_PIXMAP)
+ return QLatin1String("image/ppm");
+
+ QByteArray atomName = connection->atomName(a);
+
+ // special cases for uris
+ if (atomName == "text/x-moz-url")
+ atomName = "text/uri-list";
+
+ return QString::fromLatin1(atomName.constData());
+}
+
+bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
+ xcb_atom_t *atomFormat, int *dataFormat)
+{
+ if (!data)
+ return false;
+
+ bool ret = false;
+ *atomFormat = a;
+ *dataFormat = 8;
+
+ if ((a == connection->atom(QXcbAtom::UTF8_STRING)
+ || a == XCB_ATOM_STRING
+ || a == connection->atom(QXcbAtom::TEXT))
+ && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
+ if (a == connection->atom(QXcbAtom::UTF8_STRING)) {
+ *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
+ ret = true;
+ } else if (a == XCB_ATOM_STRING ||
+ a == connection->atom(QXcbAtom::TEXT)) {
+ // ICCCM says STRING is latin1
+ *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
+ QLatin1String("text/plain"), mimeData)).toLatin1();
+ ret = true;
+ }
+ return ret;
+ }
+
+ QString atomName = mimeAtomToString(connection, a);
+ if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
+ *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
+ if (atomName == QLatin1String("application/x-color"))
+ *dataFormat = 16;
+ ret = true;
+ } else if (atomName == QLatin1String("text/x-moz-url") &&
+ QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
+ QByteArray uri = QInternalMimeData::renderDataHelper(
+ QLatin1String("text/uri-list"), mimeData).split('\n').first();
+ QString mozUri = QString::fromLatin1(uri, uri.size());
+ mozUri += QLatin1Char('\n');
+ *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
+ ret = true;
+ } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) {
+ ret = true;
+ }
+ return ret;
+}
+
+QList<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
+{
+ QList<xcb_atom_t> atoms;
+ atoms.append(connection->internAtom(format.toLatin1()));
+
+ // special cases for strings
+ if (format == QLatin1String("text/plain")) {
+ atoms.append(connection->atom(QXcbAtom::UTF8_STRING));
+ atoms.append(XCB_ATOM_STRING);
+ atoms.append(connection->atom(QXcbAtom::TEXT));
+ }
+
+ // special cases for uris
+ if (format == QLatin1String("text/uri-list"))
+ atoms.append(connection->internAtom("text/x-moz-url"));
+
+ //special cases for images
+ if (format == QLatin1String("image/ppm"))
+ atoms.append(XCB_ATOM_PIXMAP);
+ if (format == QLatin1String("image/pbm"))
+ atoms.append(XCB_ATOM_BITMAP);
+
+ return atoms;
+}
+
+QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
+ QVariant::Type requestedType, const QByteArray &encoding)
+{
+ QString atomName = mimeAtomToString(connection, a);
+// qDebug() << "mimeConvertDataToFormat" << format << atomName << data;
+
+ if (!encoding.isEmpty()
+ && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
+
+ if (requestedType == QVariant::String) {
+ QTextCodec *codec = QTextCodec::codecForName(encoding);
+ if (codec)
+ return codec->toUnicode(data);
+ }
+
+ return data;
+ }
+
+ // special cases for string types
+ if (format == QLatin1String("text/plain")) {
+ if (a == connection->atom(QXcbAtom::UTF8_STRING))
+ return QString::fromUtf8(data);
+ if (a == XCB_ATOM_STRING ||
+ a == connection->atom(QXcbAtom::TEXT))
+ return QString::fromLatin1(data);
+ }
+
+ // special case for uri types
+ if (format == QLatin1String("text/uri-list")) {
+ if (atomName == QLatin1String("text/x-moz-url")) {
+ // we expect this as utf16 <url><space><title>
+ // the first part is a url that should only contain ascci char
+ // so it should be safe to check that the second char is 0
+ // to verify that it is utf16
+ if (data.size() > 1 && data.at(1) == 0)
+ return QString::fromRawData((const QChar *)data.constData(),
+ data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
+ }
+ }
+
+ if (atomName == format)
+ return data;
+
+#if 0 // ###
+ // special case for images
+ if (format == QLatin1String("image/ppm")) {
+ if (a == XCB_ATOM_PIXMAP && data.size() == sizeof(Pixmap)) {
+ Pixmap xpm = *((Pixmap*)data.data());
+ if (!xpm)
+ return QByteArray();
+ Window root;
+ int x;
+ int y;
+ uint width;
+ uint height;
+ uint border_width;
+ uint depth;
+
+ XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth);
+ XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap);
+ QImage qimg = QXlibStatic::qimageFromXImage(ximg);
+ XDestroyImage(ximg);
+
+ QImageWriter imageWriter;
+ imageWriter.setFormat("PPMRAW");
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ imageWriter.setDevice(&buf);
+ imageWriter.write(qimg);
+ return buf.buffer();
+ }
+ }
+#endif
+ return QVariant();
+}
+
+xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
+ const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
+{
+ requestedEncoding->clear();
+
+ // find matches for string types
+ if (format == QLatin1String("text/plain")) {
+ if (atoms.contains(connection->atom(QXcbAtom::UTF8_STRING)))
+ return connection->atom(QXcbAtom::UTF8_STRING);
+ if (atoms.contains(XCB_ATOM_STRING))
+ return XCB_ATOM_STRING;
+ if (atoms.contains(connection->atom(QXcbAtom::TEXT)))
+ return connection->atom(QXcbAtom::TEXT);
+ }
+
+ // find matches for uri types
+ if (format == QLatin1String("text/uri-list")) {
+ xcb_atom_t a = connection->internAtom(format.toLatin1());
+ if (a && atoms.contains(a))
+ return a;
+ a = connection->internAtom("text/x-moz-url");
+ if (a && atoms.contains(a))
+ return a;
+ }
+
+ // find match for image
+ if (format == QLatin1String("image/ppm")) {
+ if (atoms.contains(XCB_ATOM_PIXMAP))
+ return XCB_ATOM_PIXMAP;
+ }
+
+ // for string/text requests try to use a format with a well-defined charset
+ // first to avoid encoding problems
+ if (requestedType == QVariant::String
+ && format.startsWith(QLatin1String("text/"))
+ && !format.contains(QLatin1String("charset="))) {
+
+ QString formatWithCharset = format;
+ formatWithCharset.append(QLatin1String(";charset=utf-8"));
+
+ xcb_atom_t a = connection->internAtom(formatWithCharset.toLatin1());
+ if (a && atoms.contains(a)) {
+ *requestedEncoding = "utf-8";
+ return a;
+ }
+ }
+
+ xcb_atom_t a = connection->internAtom(format.toLatin1());
+ if (a && atoms.contains(a))
+ return a;
+
+ return 0;
+}
diff --git a/src/plugins/platforms/xcb/qxcbmime.h b/src/plugins/platforms/xcb/qxcbmime.h
new file mode 100644
index 0000000000..4ab38ed803
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbmime.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBMIME_H
+#define QXCBMIME_H
+
+#include <private/qdnd_p.h>
+
+#include <QtGui/QClipboard>
+
+#include "qxcbintegration.h"
+#include "qxcbconnection.h"
+
+class QXcbMime : public QInternalMimeData {
+ Q_OBJECT
+public:
+ QXcbMime();
+ ~QXcbMime();
+
+ static QList<xcb_atom_t> mimeAtomsForFormat(QXcbConnection *connection, const QString &format);
+ static QString mimeAtomToString(QXcbConnection *connection, xcb_atom_t a);
+ static bool mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
+ xcb_atom_t *atomFormat, int *dataFormat);
+ static QVariant mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
+ QVariant::Type requestedType, const QByteArray &encoding);
+ static xcb_atom_t mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
+ const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding);
+};
+
+#endif // QXCBMIME_H
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 6423f1b798..3c9cdfd257 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -43,13 +43,16 @@
#include "qxcbscreen.h"
-#include <QtGui/private/qapplication_p.h>
+#include <private/qguiapplication_p.h>
#include <QtCore/QMap>
#include <QtCore/QDebug>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qscreen.h>
+
#if defined(XCB_USE_EGL)
-#include "../eglconvenience/qeglplatformcontext.h"
+#include "QtPlatformSupport/private/qeglplatformcontext_p.h"
#elif defined (XCB_USE_DRI2)
#include "qdri2context.h"
#endif
@@ -71,29 +74,41 @@ public:
Q_GLOBAL_STATIC(QXcbResourceMap, qXcbResourceMap)
-void *QXcbNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qXcbResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch(resource) {
+ case EglContext:
+ result = eglContextForContext(context);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
QByteArray lowerCaseResource = resourceString.toLower();
ResourceType resource = qXcbResourceMap()->value(lowerCaseResource);
void *result = 0;
switch(resource) {
case Display:
- result = displayForWidget(widget);
+ result = displayForWindow(window);
break;
case EglDisplay:
- result = eglDisplayForWidget(widget);
+ result = eglDisplayForWindow(window);
break;
case Connection:
- result = connectionForWidget(widget);
+ result = connectionForWindow(window);
break;
case Screen:
- result = qPlatformScreenForWidget(widget);
+ result = qPlatformScreenForWindow(window);
break;
case GraphicsDevice:
- result = graphicsDeviceForWidget(widget);
- break;
- case EglContext:
- result = eglContextForWidget(widget);
+ result = graphicsDeviceForWindow(window);
break;
default:
result = 0;
@@ -101,75 +116,76 @@ void *QXcbNativeInterface::nativeResourceForWidget(const QByteArray &resourceStr
return result;
}
-QXcbScreen *QXcbNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
{
QXcbScreen *screen;
- if (widget) {
- screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(widget));
- }else {
- screen = static_cast<QXcbScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
+ if (window) {
+ screen = static_cast<QXcbScreen *>(window->screen()->handle());
+ } else {
+ screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle());
}
return screen;
}
-void *QXcbNativeInterface::displayForWidget(QWidget *widget)
+void *QXcbNativeInterface::displayForWindow(QWindow *window)
{
#if defined(XCB_USE_XLIB)
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
return screen->connection()->xlib_display();
#else
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
#endif
}
-void *QXcbNativeInterface::eglDisplayForWidget(QWidget *widget)
+void *QXcbNativeInterface::eglDisplayForWindow(QWindow *window)
{
#if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
return screen->connection()->egl_display();
#else
- Q_UNUSED(widget)
+ Q_UNUSED(window)
return 0;
#endif
}
-void *QXcbNativeInterface::connectionForWidget(QWidget *widget)
+void *QXcbNativeInterface::connectionForWindow(QWindow *window)
{
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
return screen->xcb_connection();
}
-void *QXcbNativeInterface::screenForWidget(QWidget *widget)
+void *QXcbNativeInterface::screenForWindow(QWindow *window)
{
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
return screen->screen();
}
-void *QXcbNativeInterface::graphicsDeviceForWidget(QWidget *widget)
+void *QXcbNativeInterface::graphicsDeviceForWindow(QWindow *window)
{
#if defined(XCB_USE_DRI2)
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
QByteArray deviceName = screen->connection()->dri2DeviceName();
return deviceName.data();
#else
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
#endif
}
-void * QXcbNativeInterface::eglContextForWidget(QWidget *widget)
+void * QXcbNativeInterface::eglContextForContext(QOpenGLContext *context)
{
- Q_ASSERT(widget);
- if (!widget->platformWindow()) {
- qDebug() << "QPlatformWindow does not exist for widget" << widget
- << "cannot return EGLContext";
- return 0;
- }
- QPlatformGLContext *platformContext = widget->platformWindow()->glContext();
+ Q_ASSERT(context);
+#if defined(XCB_USE_EGL)
+ QEGLPlatformContext *eglPlatformContext = static_cast<QEGLPlatformContext *>(context->handle());
+ return eglPlatformContext->eglContext();
+#endif
+#if 0
+ Q_ASSERT(window);
+ QPlatformOpenGLContext *platformContext = window->glContext()->handle();
if (!platformContext) {
- qDebug() << "QPlatformWindow" << widget->platformWindow() << "does not have a glContext"
+ qDebug() << "QWindow" << window << "does not have a glContext"
<< "cannot return EGLContext";
return 0;
}
@@ -182,4 +198,7 @@ void * QXcbNativeInterface::eglContextForWidget(QWidget *widget)
#else
return 0;
#endif
+#else
+ return 0;
+#endif
}
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 3fb0fa5e2d..8dec83267a 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -59,17 +59,19 @@ public:
EglContext
};
- void *nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget);
+ void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
- void *displayForWidget(QWidget *widget);
- void *eglDisplayForWidget(QWidget *widget);
- void *connectionForWidget(QWidget *widget);
- void *screenForWidget(QWidget *widget);
- void *graphicsDeviceForWidget(QWidget *widget);
- void *eglContextForWidget(QWidget *widget);
+ void *displayForWindow(QWindow *window);
+ void *eglDisplayForWindow(QWindow *window);
+ void *connectionForWindow(QWindow *window);
+ void *screenForWindow(QWindow *window);
+ void *graphicsDeviceForWindow(QWindow *window);
+
+ void *eglContextForContext(QOpenGLContext *context);
private:
- static QXcbScreen *qPlatformScreenForWidget(QWidget *widget);
+ static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
};
#endif // QXCBNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 9a4858123b..42259feda8 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -40,6 +40,9 @@
****************************************************************************/
#include "qxcbscreen.h"
+#include "qxcbwindow.h"
+#include "qxcbcursor.h"
+#include "qxcbimage.h"
#include <stdio.h>
@@ -102,10 +105,104 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
free(reply);
m_syncRequestSupported = m_windowManagerName != QLatin1String("KWin");
+
+ m_clientLeader = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL2(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT,
+ m_clientLeader,
+ m_screen->root,
+ 0, 0, 1, 1,
+ 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ m_screen->root_visual,
+ 0, 0), connection);
+
+ Q_XCB_CALL2(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_clientLeader,
+ atom(QXcbAtom::WM_CLIENT_LEADER),
+ XCB_ATOM_WINDOW,
+ 32,
+ 1,
+ &m_clientLeader), connection);
+
+ xcb_depth_iterator_t depth_iterator =
+ xcb_screen_allowed_depths_iterator(screen);
+
+ while (depth_iterator.rem) {
+ xcb_depth_t *depth = depth_iterator.data;
+ xcb_visualtype_iterator_t visualtype_iterator =
+ xcb_depth_visuals_iterator(depth);
+
+ while (visualtype_iterator.rem) {
+ xcb_visualtype_t *visualtype = visualtype_iterator.data;
+ m_visuals.insert(visualtype->visual_id, *visualtype);
+ xcb_visualtype_next(&visualtype_iterator);
+ }
+
+ xcb_depth_next(&depth_iterator);
+ }
+
+ m_cursor = new QXcbCursor(connection, this);
}
QXcbScreen::~QXcbScreen()
{
+ delete m_cursor;
+}
+
+
+QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
+{
+ xcb_window_t root = m_screen->root;
+
+ int x = p.x();
+ int y = p.y();
+
+ xcb_generic_error_t *error;
+
+ xcb_window_t parent = root;
+ xcb_window_t child = root;
+
+ do {
+ xcb_translate_coordinates_cookie_t translate_cookie =
+ xcb_translate_coordinates(xcb_connection(), parent, child, x, y);
+
+ xcb_translate_coordinates_reply_t *translate_reply =
+ xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, &error);
+
+ if (!translate_reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ return 0;
+ }
+
+ parent = child;
+ child = translate_reply->child;
+ x = translate_reply->dst_x;
+ y = translate_reply->dst_y;
+
+ free(translate_reply);
+
+ if (!child || child == root)
+ return 0;
+
+ QPlatformWindow *platformWindow = connection()->platformWindowFromId(child);
+ if (platformWindow)
+ return platformWindow->window();
+ } while (parent != child);
+
+ return 0;
+}
+
+const xcb_visualtype_t *QXcbScreen::visualForId(xcb_visualid_t visualid) const
+{
+ QMap<xcb_visualid_t, xcb_visualtype_t>::const_iterator it = m_visuals.find(visualid);
+ if (it == m_visuals.constEnd())
+ return 0;
+ return &*it;
}
QRect QXcbScreen::geometry() const
@@ -132,3 +229,126 @@ int QXcbScreen::screenNumber() const
{
return m_number;
}
+
+QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) const
+{
+ if (width == 0 || height == 0)
+ return QPixmap();
+
+ xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry(xcb_connection(), window);
+
+ xcb_generic_error_t *error;
+ xcb_get_geometry_reply_t *reply =
+ xcb_get_geometry_reply(xcb_connection(), geometry_cookie, &error);
+
+ if (!reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ return QPixmap();
+ }
+
+ if (width < 0)
+ width = reply->width - x;
+ if (height < 0)
+ height = reply->height - y;
+
+ // TODO: handle multiple screens
+ QXcbScreen *screen = const_cast<QXcbScreen *>(this);
+ xcb_window_t root = screen->root();
+ geometry_cookie = xcb_get_geometry(xcb_connection(), root);
+ xcb_get_geometry_reply_t *root_reply =
+ xcb_get_geometry_reply(xcb_connection(), geometry_cookie, &error);
+
+ if (!root_reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ free(reply);
+ return QPixmap();
+ }
+
+ if (reply->depth == root_reply->depth) {
+ // if the depth of the specified window and the root window are the
+ // same, grab pixels from the root window (so that we get the any
+ // overlapping windows and window manager frames)
+
+ // map x and y to the root window
+ xcb_translate_coordinates_cookie_t translate_cookie =
+ xcb_translate_coordinates(xcb_connection(), window, root, x, y);
+
+ xcb_translate_coordinates_reply_t *translate_reply =
+ xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, &error);
+
+ if (!translate_reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ free(reply);
+ free(root_reply);
+ return QPixmap();
+ }
+
+ x = translate_reply->dst_x;
+ y = translate_reply->dst_y;
+
+ window = root;
+
+ free(translate_reply);
+ free(reply);
+ reply = root_reply;
+ } else {
+ free(root_reply);
+ root_reply = 0;
+ }
+
+ xcb_get_window_attributes_reply_t *attributes_reply =
+ xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes(xcb_connection(), window), &error);
+
+ if (!attributes_reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ free(reply);
+ return QPixmap();
+ }
+
+ const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual);
+ free(attributes_reply);
+
+ xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection());
+ error = xcb_request_check(xcb_connection(), xcb_create_pixmap_checked(xcb_connection(), reply->depth, pixmap, window, width, height));
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+
+ uint32_t gc_value_mask = XCB_GC_SUBWINDOW_MODE;
+ uint32_t gc_value_list[] = { XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS };
+
+ xcb_gcontext_t gc = xcb_generate_id(xcb_connection());
+ xcb_create_gc(xcb_connection(), gc, pixmap, gc_value_mask, gc_value_list);
+
+ error = xcb_request_check(xcb_connection(), xcb_copy_area_checked(xcb_connection(), window, pixmap, gc, x, y, 0, 0, width, height));
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+
+ QPixmap result = qt_xcb_pixmapFromXPixmap(connection(), pixmap, width, height, reply->depth, visual);
+
+ free(reply);
+ xcb_free_gc(xcb_connection(), gc);
+ xcb_free_pixmap(xcb_connection(), pixmap);
+
+ return result;
+}
+
+QString QXcbScreen::name() const
+{
+ return connection()->displayName() + QLatin1String(".") + QString::number(screenNumber());
+}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index a78ee822f4..07d855b398 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -50,6 +50,7 @@
#include "qxcbobject.h"
class QXcbConnection;
+class QXcbCursor;
class QXcbScreen : public QXcbObject, public QPlatformScreen
{
@@ -57,6 +58,10 @@ public:
QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number);
~QXcbScreen();
+ QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+
+ QWindow *topLevelAt(const QPoint &point) const;
+
QRect geometry() const;
int depth() const;
QImage::Format format() const;
@@ -67,14 +72,23 @@ public:
xcb_screen_t *screen() const { return m_screen; }
xcb_window_t root() const { return m_screen->root; }
+ xcb_window_t clientLeader() const { return m_clientLeader; }
+
QString windowManagerName() const { return m_windowManagerName; }
bool syncRequestSupported() const { return m_syncRequestSupported; }
+ const xcb_visualtype_t *visualForId(xcb_visualid_t) const;
+
+ QString name() const;
+
private:
xcb_screen_t *m_screen;
int m_number;
QString m_windowManagerName;
bool m_syncRequestSupported;
+ xcb_window_t m_clientLeader;
+ QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals;
+ QXcbCursor *m_cursor;
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 20e4187541..db8d37e817 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -42,9 +42,13 @@
#include "qxcbwindow.h"
#include <QtDebug>
+#include <QScreen>
#include "qxcbconnection.h"
#include "qxcbscreen.h"
+#include "qxcbdrag.h"
+#include "qxcbwmsupport.h"
+
#ifdef XCB_USE_DRI2
#include "qdri2context.h"
#endif
@@ -61,9 +65,10 @@
#define xcb_set_wm_hints xcb_icccm_set_wm_hints
#endif
-#include <private/qapplication_p.h>
-#include <private/qwindowsurface_p.h>
+#include <private/qguiapplication_p.h>
+#include <private/qwindow_p.h>
+#include <QtGui/QPlatformBackingStore>
#include <QtGui/QWindowSystemInterface>
#include <stdio.h>
@@ -75,38 +80,71 @@
#if defined(XCB_USE_GLX)
#include "qglxintegration.h"
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
#elif defined(XCB_USE_EGL)
-#include "../eglconvenience/qeglplatformcontext.h"
-#include "../eglconvenience/qeglconvenience.h"
-#include "../eglconvenience/qxlibeglintegration.h"
+#include "qxcbeglsurface.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtPlatformSupport/private/qxlibeglintegration_p.h>
#endif
+#define XCOORD_MAX 16383
+
+//#ifdef NET_WM_STATE_DEBUG
+
// Returns true if we should set WM_TRANSIENT_FOR on \a w
-static inline bool isTransient(const QWidget *w)
+static inline bool isTransient(const QWindow *w)
{
- return ((w->windowType() == Qt::Dialog
- || w->windowType() == Qt::Sheet
- || w->windowType() == Qt::Tool
- || w->windowType() == Qt::SplashScreen
- || w->windowType() == Qt::ToolTip
- || w->windowType() == Qt::Drawer
- || w->windowType() == Qt::Popup)
- && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
+ return w->windowType() == Qt::Dialog
+ || w->windowType() == Qt::Sheet
+ || w->windowType() == Qt::Tool
+ || w->windowType() == Qt::SplashScreen
+ || w->windowType() == Qt::ToolTip
+ || w->windowType() == Qt::Drawer
+ || w->windowType() == Qt::Popup;
}
-QXcbWindow::QXcbWindow(QWidget *tlw)
- : QPlatformWindow(tlw)
- , m_context(0)
+QXcbWindow::QXcbWindow(QWindow *window)
+ : QPlatformWindow(window)
+ , m_window(0)
+ , m_syncCounter(0)
+ , m_mapped(false)
+ , m_netWmUserTimeWindow(XCB_NONE)
+#if defined(XCB_USE_EGL)
+ , m_eglSurface(0)
+#endif
{
- m_screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(tlw));
+ m_screen = static_cast<QXcbScreen *>(window->screen()->handle());
setConnection(m_screen->connection());
- const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_EVENT_MASK;
+ create();
+}
+
+void QXcbWindow::create()
+{
+ destroy();
+
+ m_windowState = Qt::WindowNoState;
+ m_dirtyFrameMargins = true;
+
+ Qt::WindowType type = window()->windowType();
+
+ if (type == Qt::Desktop) {
+ m_window = m_screen->root();
+ m_depth = m_screen->screen()->root_depth;
+ m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ connection()->addWindow(m_window, this);
+ return;
+ }
+
+ const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK;
const quint32 values[] = {
// XCB_CW_BACK_PIXMAP
XCB_NONE,
+ // XCB_CW_OVERRIDE_REDIRECT
+ type == Qt::Popup || type == Qt::ToolTip,
+ // XCB_CW_SAVE_UNDER
+ type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer,
// XCB_CW_EVENT_MASK
XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
@@ -117,20 +155,33 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
| XCB_EVENT_MASK_BUTTON_MOTION
| XCB_EVENT_MASK_ENTER_WINDOW
| XCB_EVENT_MASK_LEAVE_WINDOW
+ | XCB_EVENT_MASK_POINTER_MOTION
| XCB_EVENT_MASK_PROPERTY_CHANGE
| XCB_EVENT_MASK_FOCUS_CHANGE
};
-#if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
- if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
- && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
- || tlw->platformWindowFormat().alpha())
+ QRect rect = window()->geometry();
+ QPlatformWindow::setGeometry(rect);
+
+ rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
+ rect.setHeight(qBound(1, rect.height(), XCOORD_MAX));
+
+ xcb_window_t xcb_parent_id = m_screen->root();
+ if (parent())
+ xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
+
+ m_requestedFormat = window()->format();
+
+#if (defined(XCB_USE_GLX) || defined(XCB_USE_EGL)) && defined(XCB_USE_XLIB)
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
+ || window()->format().hasAlpha())
{
#if defined(XCB_USE_GLX)
- XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
+ XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), window()->format());
+
#elif defined(XCB_USE_EGL)
EGLDisplay eglDisplay = connection()->egl_display();
- EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,tlw->platformWindowFormat(),true);
+ EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, window()->format(), true);
VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
XVisualInfo visualInfoTemplate;
@@ -143,18 +194,16 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
#endif //XCB_USE_GLX
if (visualInfo) {
m_depth = visualInfo->depth;
- m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
- Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
+ m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone);
XSetWindowAttributes a;
a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
a.colormap = cmap;
- m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), tlw->x(), tlw->y(), tlw->width(), tlw->height(),
+ m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWBackPixel|CWBorderPixel|CWColormap, &a);
-
- printf("created GL window: %d\n", m_window);
} else {
qFatal("no window!");
}
@@ -163,25 +212,25 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
{
m_window = xcb_generate_id(xcb_connection());
m_depth = m_screen->screen()->root_depth;
- m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root
m_window, // window id
- m_screen->root(), // parent window id
- tlw->x(),
- tlw->y(),
- tlw->width(),
- tlw->height(),
+ xcb_parent_id, // parent window id
+ rect.x(),
+ rect.y(),
+ rect.width(),
+ rect.height(),
0, // border width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
m_screen->screen()->root_visual, // visual
0, // value mask
0)); // value list
-
- printf("created regular window: %d\n", m_window);
}
+ connection()->addWindow(m_window, this);
+
Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
xcb_atom_t properties[4];
@@ -193,7 +242,7 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
if (m_screen->syncRequestSupported())
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
- if (tlw->windowFlags() & Qt::WindowContextHelpButtonHint)
+ if (window()->windowFlags() & Qt::WindowContextHelpButtonHint)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
Q_XCB_CALL(xcb_change_property(xcb_connection(),
@@ -221,29 +270,49 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
&m_syncCounter));
}
- if (isTransient(tlw) && tlw->parentWidget()) {
- // ICCCM 4.1.2.6
- QWidget *p = tlw->parentWidget()->window();
- xcb_window_t parentWindow = p->winId();
- Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
- XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
- 1, &parentWindow));
-
- }
-
// set the PID to let the WM kill the application if unresponsive
long pid = getpid();
Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
atom(QXcbAtom::_NET_WM_PID), XCB_ATOM_CARDINAL, 32,
1, &pid));
+
+ xcb_wm_hints_t hints;
+ memset(&hints, 0, sizeof(hints));
+ xcb_wm_hints_set_normal(&hints);
+
+ xcb_set_wm_hints(xcb_connection(), m_window, &hints);
+
+ xcb_window_t leader = m_screen->clientLeader();
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ atom(QXcbAtom::WM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32,
+ 1, &leader));
+
+ setWindowFlags(window()->windowFlags());
+ setWindowTitle(window()->windowTitle());
+ setWindowState(window()->windowState());
+
+ connection()->drag()->dndEnable(this, true);
}
QXcbWindow::~QXcbWindow()
{
- delete m_context;
- if (m_screen->syncRequestSupported())
+ destroy();
+}
+
+void QXcbWindow::destroy()
+{
+ if (m_syncCounter && m_screen->syncRequestSupported())
Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
- Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
+ if (m_window) {
+ connection()->removeWindow(m_window);
+ Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
+ }
+ m_mapped = false;
+
+#if defined(XCB_USE_EGL)
+ delete m_eglSurface;
+ m_eglSurface = 0;
+#endif
}
void QXcbWindow::setGeometry(const QRect &rect)
@@ -251,40 +320,182 @@ void QXcbWindow::setGeometry(const QRect &rect)
QPlatformWindow::setGeometry(rect);
const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
- const quint32 values[] = { rect.x(), rect.y(), rect.width(), rect.height() };
+ const quint32 values[] = { rect.x(),
+ rect.y(),
+ qBound(1, rect.width(), XCOORD_MAX),
+ qBound(1, rect.height(), XCOORD_MAX) };
Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
+QMargins QXcbWindow::frameMargins() const
+{
+ if (m_dirtyFrameMargins) {
+ xcb_window_t window = m_window;
+ xcb_window_t parent = m_window;
+
+ bool foundRoot = false;
+
+ const QVector<xcb_window_t> &virtualRoots =
+ connection()->wmSupport()->virtualRoots();
+
+ while (!foundRoot) {
+ xcb_query_tree_cookie_t cookie = xcb_query_tree(xcb_connection(), parent);
+
+ xcb_generic_error_t *error;
+ xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, &error);
+ if (reply) {
+ if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1) {
+ foundRoot = true;
+ } else {
+ window = parent;
+ parent = reply->parent;
+ }
+
+ free(reply);
+ } else {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+
+ m_dirtyFrameMargins = false;
+ m_frameMargins = QMargins();
+ return m_frameMargins;
+ }
+ }
+
+ QPoint offset;
+
+ xcb_generic_error_t *error;
+ xcb_translate_coordinates_reply_t *reply =
+ xcb_translate_coordinates_reply(
+ xcb_connection(),
+ xcb_translate_coordinates(xcb_connection(), window, parent, 0, 0),
+ &error);
+
+ if (reply) {
+ offset = QPoint(reply->dst_x, reply->dst_y);
+ free(reply);
+ } else if (error) {
+ free(error);
+ }
+
+ xcb_get_geometry_reply_t *geom =
+ xcb_get_geometry_reply(
+ xcb_connection(),
+ xcb_get_geometry(xcb_connection(), parent),
+ &error);
+
+ if (geom) {
+ // --
+ // add the border_width for the window managers frame... some window managers
+ // do not use a border_width of zero for their frames, and if we the left and
+ // top strut, we ensure that pos() is absolutely correct. frameGeometry()
+ // will still be incorrect though... perhaps i should have foffset as well, to
+ // indicate the frame offset (equal to the border_width on X).
+ // - Brad
+ // -- copied from qwidget_x11.cpp
+
+ int left = offset.x() + geom->border_width;
+ int top = offset.y() + geom->border_width;
+ int right = geom->width + geom->border_width - geometry().width() - offset.x();
+ int bottom = geom->height + geom->border_width - geometry().height() - offset.y();
+
+ m_frameMargins = QMargins(left, top, right, bottom);
+
+ free(geom);
+ } else if (error) {
+ free(error);
+ }
+
+ m_dirtyFrameMargins = false;
+ }
+
+ return m_frameMargins;
+}
+
void QXcbWindow::setVisible(bool visible)
{
- xcb_wm_hints_t hints;
- if (visible) {
- if (widget()->isMinimized())
+ if (visible)
+ show();
+ else
+ hide();
+}
+
+void QXcbWindow::show()
+{
+ if (window()->isTopLevel()) {
+ xcb_get_property_cookie_t cookie = xcb_get_wm_hints(xcb_connection(), m_window);
+
+ xcb_generic_error_t *error;
+
+ xcb_wm_hints_t hints;
+ xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, &error);
+
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+
+ m_dirtyFrameMargins = true;
+
+ if (window()->windowState() & Qt::WindowMinimized)
xcb_wm_hints_set_iconic(&hints);
else
xcb_wm_hints_set_normal(&hints);
+
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
- Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
- connection()->sync();
- } else {
- Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
-
- // send synthetic UnmapNotify event according to icccm 4.1.4
- xcb_unmap_notify_event_t event;
- event.response_type = XCB_UNMAP_NOTIFY;
- event.sequence = 0; // does this matter?
- event.event = m_screen->root();
- event.window = m_window;
- event.from_configure = false;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
- xcb_flush(xcb_connection());
+ // update WM_NORMAL_HINTS
+ propagateSizeHints();
+
+ // update WM_TRANSIENT_FOR
+ if (window()->transientParent() && isTransient(window())) {
+ QXcbWindow *transientXcbParent = static_cast<QXcbWindow *>(window()->transientParent()->handle());
+ if (transientXcbParent) {
+ // ICCCM 4.1.2.6
+ xcb_window_t parentWindow = transientXcbParent->xcb_window();
+
+ // todo: set transient for group (wm_client_leader) if no parent, a la qwidget_x11.cpp
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
+ 1, &parentWindow));
+ }
+ }
+
+ // update _MOTIF_WM_HINTS
+ updateMotifWmHintsBeforeMap();
+
+ // update _NET_WM_STATE
+ updateNetWmStateBeforeMap();
}
+
+ Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
+ xcb_flush(xcb_connection());
+
+ connection()->sync();
+}
+
+void QXcbWindow::hide()
+{
+ Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+ xcb_unmap_notify_event_t event;
+ event.response_type = XCB_UNMAP_NOTIFY;
+ event.event = m_screen->root();
+ event.window = m_window;
+ event.from_configure = false;
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+
+ xcb_flush(xcb_connection());
+
+ m_mapped = false;
}
-struct QtMWMHints {
+struct QtMotifWmHints {
quint32 flags, functions, decorations;
qint32 input_mode;
quint32 status;
@@ -317,33 +528,142 @@ enum {
MWM_INPUT_FULL_APPLICATION_MODAL = 3L
};
+static QtMotifWmHints getMotifWmHints(QXcbConnection *c, xcb_window_t window)
+{
+ QtMotifWmHints hints;
+
+ xcb_get_property_cookie_t get_cookie =
+ xcb_get_property(c->xcb_connection(), 0, window, c->atom(QXcbAtom::_MOTIF_WM_HINTS),
+ c->atom(QXcbAtom::_MOTIF_WM_HINTS), 0, 20);
+
+ xcb_generic_error_t *error;
+
+ xcb_get_property_reply_t *reply =
+ xcb_get_property_reply(c->xcb_connection(), get_cookie, &error);
+
+ if (reply && reply->format == 32 && reply->type == c->atom(QXcbAtom::_MOTIF_WM_HINTS)) {
+ hints = *((QtMotifWmHints *)xcb_get_property_value(reply));
+ } else if (error) {
+ c->handleXcbError(error);
+ free(error);
+
+ hints.flags = 0L;
+ hints.functions = MWM_FUNC_ALL;
+ hints.decorations = MWM_DECOR_ALL;
+ hints.input_mode = 0L;
+ hints.status = 0L;
+ }
+
+ free(reply);
+
+ return hints;
+}
+
+static void setMotifWmHints(QXcbConnection *c, xcb_window_t window, const QtMotifWmHints &hints)
+{
+ if (hints.flags != 0l) {
+ Q_XCB_CALL2(xcb_change_property(c->xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ window,
+ c->atom(QXcbAtom::_MOTIF_WM_HINTS),
+ c->atom(QXcbAtom::_MOTIF_WM_HINTS),
+ 32,
+ 5,
+ &hints), c);
+ } else {
+ Q_XCB_CALL2(xcb_delete_property(c->xcb_connection(), window, c->atom(QXcbAtom::_MOTIF_WM_HINTS)), c);
+ }
+}
+
+void QXcbWindow::printNetWmState(const QVector<xcb_atom_t> &state)
+{
+ printf("_NET_WM_STATE (%d): ", state.size());
+ for (int i = 0; i < state.size(); ++i) {
+#define CHECK_WM_STATE(state_atom) \
+ if (state.at(i) == atom(QXcbAtom::state_atom))\
+ printf(#state_atom " ");
+ CHECK_WM_STATE(_NET_WM_STATE_ABOVE)
+ CHECK_WM_STATE(_NET_WM_STATE_BELOW)
+ CHECK_WM_STATE(_NET_WM_STATE_FULLSCREEN)
+ CHECK_WM_STATE(_NET_WM_STATE_MAXIMIZED_HORZ)
+ CHECK_WM_STATE(_NET_WM_STATE_MAXIMIZED_VERT)
+ CHECK_WM_STATE(_NET_WM_STATE_MODAL)
+ CHECK_WM_STATE(_NET_WM_STATE_STAYS_ON_TOP)
+ CHECK_WM_STATE(_NET_WM_STATE_DEMANDS_ATTENTION)
+#undef CHECK_WM_STATE
+ }
+ printf("\n");
+}
+
+QVector<xcb_atom_t> QXcbWindow::getNetWmState()
+{
+ QVector<xcb_atom_t> result;
+
+ xcb_get_property_cookie_t get_cookie =
+ xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
+ XCB_ATOM_ATOM, 0, 1024);
+
+ xcb_generic_error_t *error;
+
+ xcb_get_property_reply_t *reply =
+ xcb_get_property_reply(xcb_connection(), get_cookie, &error);
+
+ if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) {
+ result.resize(reply->length);
+
+ memcpy(result.data(), xcb_get_property_value(reply), reply->length * sizeof(xcb_atom_t));
+
+#ifdef NET_WM_STATE_DEBUG
+ printf("getting net wm state (%x)\n", m_window);
+ printNetWmState(result);
+#endif
+
+ free(reply);
+ } else if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ } else {
+#ifdef NET_WM_STATE_DEBUG
+ printf("getting net wm state (%x), empty\n", m_window);
+#endif
+ }
+
+ return result;
+}
+
+void QXcbWindow::setNetWmState(const QVector<xcb_atom_t> &atoms)
+{
+ if (atoms.isEmpty()) {
+ Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_STATE)));
+ } else {
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ atom(QXcbAtom::_NET_WM_STATE), XCB_ATOM_ATOM, 32,
+ atoms.count(), atoms.constData()));
+ }
+ xcb_flush(xcb_connection());
+}
+
+
Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
{
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
- setNetWmWindowTypes(flags);
-
if (type == Qt::ToolTip)
flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
if (type == Qt::Popup)
flags |= Qt::X11BypassWindowManagerHint;
- bool topLevel = (flags & Qt::Window);
- bool popup = (type == Qt::Popup);
- bool dialog = (type == Qt::Dialog
- || type == Qt::Sheet);
- bool desktop = (type == Qt::Desktop);
- bool tool = (type == Qt::Tool || type == Qt::SplashScreen
- || type == Qt::ToolTip || type == Qt::Drawer);
+ setNetWmWindowFlags(flags);
+ setMotifWindowFlags(flags);
- Q_UNUSED(topLevel);
- Q_UNUSED(dialog);
- Q_UNUSED(desktop);
- Q_UNUSED(tool);
+ return flags;
+}
- bool tooltip = (type == Qt::ToolTip);
+void QXcbWindow::setMotifWindowFlags(Qt::WindowFlags flags)
+{
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
- QtMWMHints mwmhints;
+ QtMotifWmHints mwmhints;
mwmhints.flags = 0L;
mwmhints.functions = 0L;
mwmhints.decorations = 0;
@@ -403,30 +723,90 @@ Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
mwmhints.decorations = 0;
}
- if (mwmhints.flags != 0l) {
- Q_XCB_CALL(xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::_MOTIF_WM_HINTS),
- atom(QXcbAtom::_MOTIF_WM_HINTS),
- 32,
- 5,
- &mwmhints));
- } else {
- Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_MOTIF_WM_HINTS)));
- }
+ setMotifWmHints(connection(), m_window, mwmhints);
+}
+
+void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
+{
+ xcb_client_message_event_t event;
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.window = m_window;
+ event.type = atom(QXcbAtom::_NET_WM_STATE);
+ event.data.data32[0] = set ? 1 : 0;
+ event.data.data32[1] = one;
+ event.data.data32[2] = two;
+ event.data.data32[3] = 0;
+ event.data.data32[4] = 0;
+
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+}
- if (popup || tooltip) {
- const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER;
- const quint32 values[] = { true, true };
+Qt::WindowState QXcbWindow::setWindowState(Qt::WindowState state)
+{
+ if (state == m_windowState)
+ return state;
+
+ m_dirtyFrameMargins = true;
+
+ // unset old state
+ switch (m_windowState) {
+ case Qt::WindowMinimized:
+ Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
+ break;
+ case Qt::WindowMaximized:
+ changeNetWmState(false,
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ),
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+ break;
+ case Qt::WindowFullScreen:
+ changeNetWmState(false, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+ break;
+ default:
+ break;
+ }
- Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
+ // set new state
+ switch (state) {
+ case Qt::WindowMinimized:
+ {
+ xcb_client_message_event_t event;
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.window = m_window;
+ event.type = atom(QXcbAtom::WM_CHANGE_STATE);
+ event.data.data32[0] = XCB_WM_STATE_ICONIC;
+ event.data.data32[1] = 0;
+ event.data.data32[2] = 0;
+ event.data.data32[3] = 0;
+ event.data.data32[4] = 0;
+
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+ }
+ break;
+ case Qt::WindowMaximized:
+ changeNetWmState(true,
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ),
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+ break;
+ case Qt::WindowFullScreen:
+ changeNetWmState(true, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+ break;
+ case Qt::WindowNoState:
+ break;
+ default:
+ break;
}
- return QPlatformWindow::setWindowFlags(flags);
+ connection()->sync();
+
+ m_windowState = state;
+ return m_windowState;
}
-void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
+void QXcbWindow::setNetWmWindowFlags(Qt::WindowFlags flags)
{
// in order of decreasing priority
QVector<uint> windowTypes;
@@ -462,6 +842,127 @@ void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
windowTypes.count(), windowTypes.constData()));
}
+void QXcbWindow::updateMotifWmHintsBeforeMap()
+{
+ QtMotifWmHints mwmhints = getMotifWmHints(connection(), m_window);
+
+ if (window()->windowModality() != Qt::NonModal) {
+ switch (window()->windowModality()) {
+ case Qt::WindowModal:
+ mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
+ break;
+ case Qt::ApplicationModal:
+ default:
+ mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
+ break;
+ }
+ mwmhints.flags |= MWM_HINTS_INPUT_MODE;
+ } else {
+ mwmhints.input_mode = MWM_INPUT_MODELESS;
+ mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
+ }
+
+ if (window()->minimumSize() == window()->maximumSize()) {
+ // fixed size, remove the resize handle (since mwm/dtwm
+ // isn't smart enough to do it itself)
+ mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+ if (mwmhints.functions == MWM_FUNC_ALL) {
+ mwmhints.functions = MWM_FUNC_MOVE;
+ } else {
+ mwmhints.functions &= ~MWM_FUNC_RESIZE;
+ }
+
+ if (mwmhints.decorations == MWM_DECOR_ALL) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+ mwmhints.decorations = (MWM_DECOR_BORDER
+ | MWM_DECOR_TITLE
+ | MWM_DECOR_MENU);
+ } else {
+ mwmhints.decorations &= ~MWM_DECOR_RESIZEH;
+ }
+ }
+
+ if (window()->windowFlags() & Qt::WindowMinimizeButtonHint) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+ mwmhints.decorations |= MWM_DECOR_MINIMIZE;
+ mwmhints.functions |= MWM_FUNC_MINIMIZE;
+ }
+ if (window()->windowFlags() & Qt::WindowMaximizeButtonHint) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+ mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
+ mwmhints.functions |= MWM_FUNC_MAXIMIZE;
+ }
+ if (window()->windowFlags() & Qt::WindowCloseButtonHint)
+ mwmhints.functions |= MWM_FUNC_CLOSE;
+
+ setMotifWmHints(connection(), m_window, mwmhints);
+}
+
+void QXcbWindow::updateNetWmStateBeforeMap()
+{
+ QVector<xcb_atom_t> netWmState;
+
+ Qt::WindowFlags flags = window()->windowFlags();
+ if (flags & Qt::WindowStaysOnTopHint) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP));
+ } else if (flags & Qt::WindowStaysOnBottomHint) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_BELOW));
+ }
+
+ if (window()->windowState() & Qt::WindowFullScreen) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+ }
+
+ if (window()->windowState() & Qt::WindowMaximized) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ));
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+ }
+
+ if (window()->windowModality() != Qt::NonModal) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_MODAL));
+ }
+
+ setNetWmState(netWmState);
+}
+
+void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
+{
+ xcb_window_t wid = m_window;
+
+ const bool isSupportedByWM = connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW));
+ if (m_netWmUserTimeWindow || isSupportedByWM) {
+ if (!m_netWmUserTimeWindow) {
+ m_netWmUserTimeWindow = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ m_netWmUserTimeWindow, // window id
+ m_window, // parent window id
+ -1, -1, 1, 1,
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_screen->screen()->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
+ wid = m_netWmUserTimeWindow;
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW),
+ XCB_ATOM_WINDOW, 32, 1, &m_netWmUserTimeWindow);
+ xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_USER_TIME));
+ } else if (!isSupportedByWM) {
+ // WM no longer supports it, then we should remove the
+ // _NET_WM_USER_TIME_WINDOW atom.
+ xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW));
+ xcb_destroy_window(xcb_connection(), m_netWmUserTimeWindow);
+ m_netWmUserTimeWindow = XCB_NONE;
+ } else {
+ wid = m_netWmUserTimeWindow;
+ }
+ }
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, wid, atom(QXcbAtom::_NET_WM_USER_TIME),
+ XCB_ATOM_CARDINAL, 32, 1, &timestamp);
+}
+
+
WId QXcbWindow::winId() const
{
return m_window;
@@ -469,8 +970,13 @@ WId QXcbWindow::winId() const
void QXcbWindow::setParent(const QPlatformWindow *parent)
{
+ // re-create for compatibility
+ create();
+
QPoint topLeft = geometry().topLeft();
- Q_XCB_CALL(xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y()));
+
+ xcb_window_t xcb_parent_id = parent ? static_cast<const QXcbWindow *>(parent)->xcb_window() : m_screen->root();
+ Q_XCB_CALL(xcb_reparent_window(xcb_connection(), xcb_window(), xcb_parent_id, topLeft.x(), topLeft.y()));
}
void QXcbWindow::setWindowTitle(const QString &title)
@@ -500,56 +1006,87 @@ void QXcbWindow::lower()
Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
+void QXcbWindow::propagateSizeHints()
+{
+ // update WM_NORMAL_HINTS
+ xcb_size_hints_t hints;
+ memset(&hints, 0, sizeof(hints));
+
+ QRect rect = geometry();
+
+ xcb_size_hints_set_position(&hints, true, rect.x(), rect.y());
+ xcb_size_hints_set_size(&hints, true, rect.width(), rect.height());
+ xcb_size_hints_set_win_gravity(&hints, XCB_GRAVITY_STATIC);
+
+ QWindow *win = window();
+
+ QSize minimumSize = win->minimumSize();
+ QSize maximumSize = win->maximumSize();
+ QSize baseSize = win->baseSize();
+ QSize sizeIncrement = win->sizeIncrement();
+
+ if (minimumSize.width() > 0 || minimumSize.height() > 0)
+ xcb_size_hints_set_min_size(&hints, minimumSize.width(), minimumSize.height());
+
+ if (maximumSize.width() < QWINDOWSIZE_MAX || maximumSize.height() < QWINDOWSIZE_MAX)
+ xcb_size_hints_set_max_size(&hints,
+ qMin(XCOORD_MAX, maximumSize.width()),
+ qMin(XCOORD_MAX, maximumSize.height()));
+
+ if (sizeIncrement.width() > 0 || sizeIncrement.height() > 0) {
+ xcb_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height());
+ xcb_size_hints_set_resize_inc(&hints, sizeIncrement.width(), sizeIncrement.height());
+ }
+
+ xcb_set_wm_normal_hints(xcb_connection(), m_window, &hints);
+}
+
void QXcbWindow::requestActivateWindow()
{
- Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
+ if (m_mapped){
+ updateNetWmUserTime(connection()->time());
+ Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, connection()->time()));
+ }
connection()->sync();
}
-QPlatformGLContext *QXcbWindow::glContext() const
+QSurfaceFormat QXcbWindow::format() const
{
- if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
- printf("no opengl\n");
- return 0;
- }
- if (!m_context) {
-#if defined(XCB_USE_GLX)
- QXcbWindow *that = const_cast<QXcbWindow *>(this);
- that->m_context = new QGLXContext(m_window, m_screen, widget()->platformWindowFormat());
-#elif defined(XCB_USE_EGL)
+ // ### return actual format
+ return m_requestedFormat;
+}
+
+#if defined(XCB_USE_EGL)
+QXcbEGLSurface *QXcbWindow::eglSurface() const
+{
+ if (!m_eglSurface) {
EGLDisplay display = connection()->egl_display();
- EGLConfig config = q_configFromQPlatformWindowFormat(display,widget()->platformWindowFormat(),true);
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
- eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)m_window,0);
- QXcbWindow *that = const_cast<QXcbWindow *>(this);
- that->m_context = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API);
-#elif defined(XCB_USE_DRI2)
- QXcbWindow *that = const_cast<QXcbWindow *>(this);
- that->m_context = new QDri2Context(that);
-#endif
+ EGLConfig config = q_configFromGLFormat(display, window()->format(), true);
+ EGLSurface surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_window, 0);
+
+ m_eglSurface = new QXcbEGLSurface(display, surface);
}
- return m_context;
+
+ return m_eglSurface;
}
+#endif
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
- QWindowSurface *surface = widget()->windowSurface();
- if (surface) {
- QRect rect(event->x, event->y, event->width, event->height);
-
- surface->flush(widget(), rect, QPoint());
- }
+ QRect rect(event->x, event->y, event->width, event->height);
+ QWindowSystemInterface::handleSynchronousExposeEvent(window(), rect);
}
void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *event)
{
- if (event->format == 32 && event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
+ if (event->format != 32)
+ return;
+
+ if (event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) {
- QWindowSystemInterface::handleCloseEvent(widget());
+ QWindowSystemInterface::handleCloseEvent(window());
+ } else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) {
+ connection()->setTime(event->data.data32[1]);
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
xcb_client_message_event_t reply = *event;
@@ -559,13 +1096,22 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply);
xcb_flush(xcb_connection());
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) {
- if (!m_hasReceivedSyncRequest) {
- m_hasReceivedSyncRequest = true;
- printf("Window manager supports _NET_WM_SYNC_REQUEST, syncing resizes\n");
- }
+ connection()->setTime(event->data.data32[1]);
m_syncValue.lo = event->data.data32[2];
m_syncValue.hi = event->data.data32[3];
+ } else {
+ qWarning() << "unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]);
}
+ } else if (event->type == atom(QXcbAtom::XdndEnter)) {
+ connection()->drag()->handleEnter(window(), event);
+ } else if (event->type == atom(QXcbAtom::XdndPosition)) {
+ connection()->drag()->handlePosition(window(), event, false);
+ } else if (event->type == atom(QXcbAtom::XdndLeave)) {
+ connection()->drag()->handleLeave(window(), event, false);
+ } else if (event->type == atom(QXcbAtom::XdndDrop)) {
+ connection()->drag()->handleDrop(window(), event, false);
+ } else {
+ qWarning() << "unhandled client message:" << connection()->atomName(event->type);
}
}
@@ -581,11 +1127,8 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
QRect rect(xpos, ypos, event->width, event->height);
- if (rect == geometry())
- return;
-
QPlatformWindow::setGeometry(rect);
- QWindowSystemInterface::handleGeometryChange(widget(), rect);
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
#if XCB_USE_DRI2
if (m_context)
@@ -593,6 +1136,22 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
#endif
}
+void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
+{
+ if (event->window == m_window) {
+ m_mapped = true;
+ QWindowSystemInterface::handleMapEvent(window());
+ }
+}
+
+void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
+{
+ if (event->window == m_window) {
+ m_mapped = false;
+ QWindowSystemInterface::handleUnmapEvent(window());
+ }
+}
+
static Qt::MouseButtons translateMouseButtons(int s)
{
Qt::MouseButtons ret = 0;
@@ -621,6 +1180,8 @@ static Qt::MouseButton translateMouseButton(xcb_button_t s)
void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
{
+ updateNetWmUserTime(event->time);
+
QPoint local(event->event_x, event->event_y);
QPoint global(event->root_x, event->root_y);
@@ -633,7 +1194,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
&& (modifiers & Qt::AltModifier))
|| (event->detail == 6 || event->detail == 7));
- QWindowSystemInterface::handleWheelEvent(widget(), event->time,
+ QWindowSystemInterface::handleWheelEvent(window(), event->time,
local, global, delta, hor ? Qt::Horizontal : Qt::Vertical);
return;
}
@@ -659,32 +1220,65 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global)
{
+ connection()->setTime(time);
+
Qt::MouseButtons buttons = translateMouseButtons(state);
Qt::MouseButton button = translateMouseButton(detail);
buttons ^= button; // X event uses state *before*, Qt uses state *after*
- QWindowSystemInterface::handleMouseEvent(widget(), time, local, global, buttons);
+ QWindowSystemInterface::handleMouseEvent(window(), time, local, global, buttons);
}
-void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *)
+void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
{
- QWindowSystemInterface::handleEnterEvent(widget());
+ connection()->setTime(event->time);
+
+ if ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB)
+ || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL
+ || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL)
+ {
+ return;
+ }
+
+ QWindowSystemInterface::handleEnterEvent(window());
}
-void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *)
+void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
{
- QWindowSystemInterface::handleLeaveEvent(widget());
+ connection()->setTime(event->time);
+
+ if ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB)
+ || event->detail == XCB_NOTIFY_DETAIL_INFERIOR)
+ {
+ return;
+ }
+
+ QWindowSystemInterface::handleLeaveEvent(window());
}
void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
{
- QWindowSystemInterface::handleWindowActivated(widget());
+ QWindowSystemInterface::handleWindowActivated(window());
+}
+
+static bool focusInPeeker(xcb_generic_event_t *event)
+{
+ if (!event) {
+ // FocusIn event is not in the queue, proceed with FocusOut normally.
+ QWindowSystemInterface::handleWindowActivated(0);
+ return true;
+ }
+ uint response_type = event->response_type & ~0x80;
+ return response_type == XCB_FOCUS_IN;
}
void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
{
- QWindowSystemInterface::handleWindowActivated(0);
+ // Do not set the active window to 0 if there is a FocusIn coming.
+ // There is however no equivalent for XPutBackEvent so register a
+ // callback for QXcbConnection instead.
+ connection()->addPeekFunc(focusInPeeker);
}
void QXcbWindow::updateSyncRequestCounter()
@@ -698,3 +1292,47 @@ void QXcbWindow::updateSyncRequestCounter()
m_syncValue.hi = 0;
}
}
+
+bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
+{
+ if (!grab) {
+ xcb_ungrab_keyboard(xcb_connection(), XCB_TIME_CURRENT_TIME);
+ return true;
+ }
+ xcb_grab_keyboard_cookie_t cookie = xcb_grab_keyboard(xcb_connection(), false,
+ m_window, XCB_TIME_CURRENT_TIME,
+ XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
+ xcb_generic_error_t *err;
+ xcb_grab_keyboard_reply_t *reply = xcb_grab_keyboard_reply(xcb_connection(), cookie, &err);
+ bool result = !(err || !reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
+ free(reply);
+ free(err);
+ return result;
+}
+
+bool QXcbWindow::setMouseGrabEnabled(bool grab)
+{
+ if (!grab) {
+ xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME);
+ return true;
+ }
+ xcb_grab_pointer_cookie_t cookie = xcb_grab_pointer(xcb_connection(), false, m_window,
+ (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE
+ | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW
+ | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION),
+ XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
+ XCB_WINDOW_NONE, XCB_CURSOR_NONE,
+ XCB_TIME_CURRENT_TIME);
+ xcb_generic_error_t *err;
+ xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, &err);
+ bool result = !(err || !reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
+ free(reply);
+ free(err);
+ return result;
+}
+
+void QXcbWindow::setCursor(xcb_cursor_t cursor)
+{
+ xcb_change_window_attributes(xcb_connection(), m_window, XCB_CW_CURSOR, &cursor);
+ xcb_flush(xcb_connection());
+}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 69d0bc2f1d..a85760ea8d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -43,7 +43,7 @@
#define QXCBWINDOW_H
#include <QtGui/QPlatformWindow>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QSurfaceFormat>
#include <QtGui/QImage>
#include <xcb/xcb.h>
@@ -52,35 +52,47 @@
#include "qxcbobject.h"
class QXcbScreen;
+class QXcbEGLSurface;
class QXcbWindow : public QXcbObject, public QPlatformWindow
{
public:
- QXcbWindow(QWidget *tlw);
+ QXcbWindow(QWindow *window);
~QXcbWindow();
void setGeometry(const QRect &rect);
+ QMargins frameMargins() const;
+
void setVisible(bool visible);
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ Qt::WindowState setWindowState(Qt::WindowState state);
WId winId() const;
void setParent(const QPlatformWindow *window);
void setWindowTitle(const QString &title);
void raise();
void lower();
+ void propagateSizeHints();
void requestActivateWindow();
- QPlatformGLContext *glContext() const;
+ bool setKeyboardGrabEnabled(bool grab);
+ bool setMouseGrabEnabled(bool grab);
+
+ void setCursor(xcb_cursor_t cursor);
- xcb_window_t window() const { return m_window; }
+ QSurfaceFormat format() const;
+
+ xcb_window_t xcb_window() const { return m_window; }
uint depth() const { return m_depth; }
- QImage::Format format() const { return m_format; }
+ QImage::Format imageFormat() const { return m_imageFormat; }
void handleExposeEvent(const xcb_expose_event_t *event);
void handleClientMessageEvent(const xcb_client_message_event_t *event);
void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event);
+ void handleMapNotifyEvent(const xcb_map_notify_event_t *event);
+ void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event);
void handleButtonPressEvent(const xcb_button_press_event_t *event);
void handleButtonReleaseEvent(const xcb_button_release_event_t *event);
void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event);
@@ -93,22 +105,54 @@ public:
void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global);
void updateSyncRequestCounter();
+ void updateNetWmUserTime(xcb_timestamp_t timestamp);
+ void netWmUserTime() const;
+
+#if defined(XCB_USE_EGL)
+ QXcbEGLSurface *eglSurface() const;
+#endif
private:
- void setNetWmWindowTypes(Qt::WindowFlags flags);
+ void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
+ QVector<xcb_atom_t> getNetWmState();
+ void setNetWmState(const QVector<xcb_atom_t> &atoms);
+ void printNetWmState(const QVector<xcb_atom_t> &state);
+
+ void setNetWmWindowFlags(Qt::WindowFlags flags);
+ void setMotifWindowFlags(Qt::WindowFlags flags);
+
+ void updateMotifWmHintsBeforeMap();
+ void updateNetWmStateBeforeMap();
+
+ void create();
+ void destroy();
+
+ void show();
+ void hide();
QXcbScreen *m_screen;
xcb_window_t m_window;
- QPlatformGLContext *m_context;
uint m_depth;
- QImage::Format m_format;
+ QImage::Format m_imageFormat;
xcb_sync_int64_t m_syncValue;
xcb_sync_counter_t m_syncCounter;
- bool m_hasReceivedSyncRequest;
+ Qt::WindowState m_windowState;
+
+ bool m_mapped;
+ xcb_window_t m_netWmUserTimeWindow;
+
+ QSurfaceFormat m_requestedFormat;
+
+ mutable bool m_dirtyFrameMargins;
+ mutable QMargins m_frameMargins;
+
+#if defined(XCB_USE_EGL)
+ mutable QXcbEGLSurface *m_eglSurface;
+#endif
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
new file mode 100644
index 0000000000..5fb67b6377
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbwmsupport.h"
+#include "qxcbscreen.h"
+
+#include <qdebug.h>
+
+QXcbWMSupport::QXcbWMSupport(QXcbConnection *c)
+ : QXcbObject(c)
+{
+ updateNetWMAtoms();
+ updateVirtualRoots();
+}
+
+bool QXcbWMSupport::isSupportedByWM(xcb_atom_t atom) const
+{
+ return net_wm_atoms.contains(atom);
+}
+
+
+
+void QXcbWMSupport::updateNetWMAtoms()
+{
+ net_wm_atoms.clear();
+
+ xcb_window_t root = connection()->screens().at(connection()->primaryScreen())->root();
+ int offset = 0;
+ int remaining = 0;
+ do {
+ xcb_generic_error_t *error = 0;
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_SUPPORTED), XCB_ATOM_ATOM, offset, 1024);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, &error);
+ if (!reply || error)
+ break;
+
+ remaining = 0;
+
+ if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
+ int len = xcb_get_property_value_length(reply)/4;
+ xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
+ int s = net_wm_atoms.size();
+ net_wm_atoms.resize(s + len);
+ memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t));
+
+ remaining = reply->bytes_after;
+ offset += len;
+ }
+
+ free(reply);
+ } while (remaining > 0);
+
+// qDebug() << "======== updateNetWMAtoms";
+// for (int i = 0; i < net_wm_atoms.size(); ++i)
+// qDebug() << atomName(net_wm_atoms.at(i));
+// qDebug() << "======== updateNetWMAtoms";
+}
+
+// update the virtual roots array
+void QXcbWMSupport::updateVirtualRoots()
+{
+ net_virtual_roots.clear();
+
+ if (!isSupportedByWM(atom(QXcbAtom::_NET_VIRTUAL_ROOTS)))
+ return;
+
+ xcb_window_t root = connection()->screens().at(connection()->primaryScreen())->root();
+ int offset = 0;
+ int remaining = 0;
+ do {
+ xcb_generic_error_t *error = 0;
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_VIRTUAL_ROOTS), XCB_ATOM_ATOM, offset, 1024);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, &error);
+ if (!reply || error)
+ break;
+
+ remaining = 0;
+
+ if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
+ int len = xcb_get_property_value_length(reply)/4;
+ xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
+ int s = net_wm_atoms.size();
+ net_wm_atoms.resize(s + len);
+ memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t));
+
+ remaining = reply->bytes_after;
+ offset += len;
+ }
+
+ free(reply);
+ } while (remaining > 0);
+
+ qDebug() << "======== updateVirtualRoots";
+ for (int i = 0; i < net_virtual_roots.size(); ++i)
+ qDebug() << connection()->atomName(net_virtual_roots.at(i));
+ qDebug() << "======== updateVirtualRoots";
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h b/src/plugins/platforms/xcb/qxcbwmsupport.h
index 5765483fc7..3b02ef3e7e 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h
+++ b/src/plugins/platforms/xcb/qxcbwmsupport.h
@@ -38,28 +38,30 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef QXCBWMSUPPORT_H
+#define QXCBWMSUPPORT_H
-#ifndef QCOCAEVENTLOOPINTEGRATION_H
-#define QCOCAEVENTLOOPINTEGRATION_H
+#include "qxcbobject.h"
+#include "qxcbconnection.h"
+#include <qvector.h>
-#include <Cocoa/Cocoa.h>
-
-#include <QPlatformEventLoopIntegration>
-
-
-class QCocoaEventLoopIntegration : public QPlatformEventLoopIntegration
+class QXcbWMSupport : public QXcbObject
{
public:
- QCocoaEventLoopIntegration();
- void startEventLoop();
- void quitEventLoop();
- void qtNeedsToProcessEvents();
+ QXcbWMSupport(QXcbConnection *c);
+
+
+ bool isSupportedByWM(xcb_atom_t atom) const;
+ const QVector<xcb_window_t> &virtualRoots() const { return net_virtual_roots; }
private:
- CFRunLoopSourceContext m_sourceContext;
- CFRunLoopTimerContext m_timerContext;
- CFRunLoopSourceRef m_source;
+ friend class QXcbConnection;
+ void updateNetWMAtoms();
+ void updateVirtualRoots();
+
+ QVector<xcb_atom_t> net_wm_atoms;
+ QVector<xcb_window_t> net_virtual_roots;
};
-#endif // QCOCAEVENTLOOPINTEGRATION_H
+#endif
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index 27d10b6756..143a671047 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -3,70 +3,91 @@ TARGET = xcb
load(qt_plugin)
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
-QT += core-private gui-private
+QT += core-private gui-private platformsupport-private
SOURCES = \
+ qxcbclipboard.cpp \
qxcbconnection.cpp \
qxcbintegration.cpp \
qxcbkeyboard.cpp \
+ qxcbmime.cpp \
+ qxcbdrag.cpp \
qxcbscreen.cpp \
qxcbwindow.cpp \
- qxcbwindowsurface.cpp \
+ qxcbbackingstore.cpp \
+ qxcbwmsupport.cpp \
main.cpp \
- qxcbnativeinterface.cpp
+ qxcbnativeinterface.cpp \
+ qxcbcursor.cpp \
+ qxcbimage.cpp
HEADERS = \
+ qxcbclipboard.h \
qxcbconnection.h \
qxcbintegration.h \
qxcbkeyboard.h \
+ qxcbdrag.h \
+ qxcbmime.h \
qxcbobject.h \
qxcbscreen.h \
qxcbwindow.h \
- qxcbwindowsurface.h \
- qxcbnativeinterface.h
+ qxcbbackingstore.h \
+ qxcbwmsupport.h \
+ qxcbnativeinterface.h \
+ qxcbcursor.h \
+ qxcbimage.h
-contains(QT_CONFIG, opengl) {
- QT += opengl
+contains(QT_CONFIG, xcb-poll-for-queued-event) {
+ DEFINES += XCB_POLL_FOR_QUEUED_EVENT
+}
+
+# needed by GLX, Xcursor, XLookupString, ...
+contains(QT_CONFIG, xcb-xlib) {
+ DEFINES += XCB_USE_XLIB
+ LIBS += -lX11 -lX11-xcb
+}
+
+# to support custom cursors with depth > 1
+contains(QT_CONFIG, xcb-render) {
+ DEFINES += XCB_USE_RENDER
+ LIBS += -lxcb-render -lxcb-render-util -lXrender
+}
# DEFINES += XCB_USE_DRI2
- contains(DEFINES, XCB_USE_DRI2) {
- LIBS += -lxcb-dri2 -lxcb-xfixes -lEGL
-
- CONFIG += link_pkgconfig
- PKGCONFIG += libdrm
-
- HEADERS += qdri2context.h
- SOURCES += qdri2context.cpp
-
- } else {
- DEFINES += XCB_USE_XLIB
- LIBS += -lX11 -lX11-xcb
-
- contains(QT_CONFIG, opengles2) {
- DEFINES += XCB_USE_EGL
- HEADERS += \
- ../eglconvenience/qeglplatformcontext.h \
- ../eglconvenience/qeglconvenience.h \
- ../eglconvenience/qxlibeglintegration.h
-
- SOURCES += \
- ../eglconvenience/qeglplatformcontext.cpp \
- ../eglconvenience/qeglconvenience.cpp \
- ../eglconvenience/qxlibeglintegration.cpp
-
- LIBS += -lEGL
- } else {
- DEFINES += XCB_USE_GLX
- include (../glxconvenience/glxconvenience.pri)
- HEADERS += qglxintegration.h
- SOURCES += qglxintegration.cpp
- }
+contains(DEFINES, XCB_USE_DRI2) {
+ LIBS += -lxcb-dri2 -lEGL
+
+ CONFIG += link_pkgconfig
+ PKGCONFIG += libdrm
+
+ HEADERS += qdri2context.h
+ SOURCES += qdri2context.cpp
+
+} else {
+ contains(QT_CONFIG, opengles2) {
+ DEFINES += XCB_USE_EGL
+ LIBS += -lEGL
+ HEADERS += qxcbeglsurface.h
+ } else:contains(QT_CONFIG, xcb-xlib) {
+ DEFINES += XCB_USE_GLX
+ HEADERS += qglxintegration.h
+ SOURCES += qglxintegration.cpp
}
}
-LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync
+LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes
+
+DEFINES += $$QMAKE_DEFINES_XCB
+LIBS += $$QMAKE_LIBS_XCB
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
-include (../fontdatabases/genericunix/genericunix.pri)
+CONFIG += qpa/genericunixfontdatabase
+
+contains(QT_CONFIG, dbus) {
+DEFINES += XCB_USE_IBUS
+QT += dbus
+LIBS += -ldbus-1
+}
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/xlib/main.cpp b/src/plugins/platforms/xlib/main.cpp
index 63eba3288b..b4241fa228 100644
--- a/src/plugins/platforms/xlib/main.cpp
+++ b/src/plugins/platforms/xlib/main.cpp
@@ -54,10 +54,7 @@ public:
QStringList QXlibIntegrationPlugin::keys() const
{
QStringList list;
- list << "Xlib";
-#ifndef QT_NO_OPENGL
- list << "XlibGL";
-#endif
+ list << "xlib";
return list;
}
@@ -66,10 +63,6 @@ QPlatformIntegration* QXlibIntegrationPlugin::create(const QString& system, cons
Q_UNUSED(paramList);
if (system.toLower() == "xlib")
return new QXlibIntegration;
-#ifndef QT_NO_OPENGL
- if (system.toLower() == "xlibgl")
- return new QXlibIntegration(true);
-#endif
return 0;
}
diff --git a/src/plugins/platforms/xlib/qglxintegration.cpp b/src/plugins/platforms/xlib/qglxintegration.cpp
index d827d606bb..6733f22093 100644
--- a/src/plugins/platforms/xlib/qglxintegration.cpp
+++ b/src/plugins/platforms/xlib/qglxintegration.cpp
@@ -51,7 +51,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/glx.h>
-#include "qglxconvenience.h"
+#include "private/qglxconvenience_p.h"
#include "qglxintegration.h"
@@ -61,34 +61,24 @@
QT_BEGIN_NAMESPACE
-QGLXContext::QGLXContext(Window window, QXlibScreen *screen, const QPlatformWindowFormat &format)
- : QPlatformGLContext()
+QGLXContext::QGLXContext(QXlibScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : QPlatformOpenGLContext()
, m_screen(screen)
- , m_drawable((Drawable)window)
, m_context(0)
{
-
- const QPlatformGLContext *sharePlatformContext;
- sharePlatformContext = format.sharedGLContext();
GLXContext shareGlxContext = 0;
- if (sharePlatformContext)
- shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext();
+ if (share)
+ shareGlxContext = static_cast<const QGLXContext*>(share)->glxContext();
GLXFBConfig config = qglx_findConfig(screen->display()->nativeDisplay(),screen->xScreenNumber(),format);
m_context = glXCreateNewContext(screen->display()->nativeDisplay(),config,GLX_RGBA_TYPE,shareGlxContext,TRUE);
- m_windowFormat = qglx_platformWindowFromGLXFBConfig(screen->display()->nativeDisplay(),config,m_context);
+ m_windowFormat = qglx_surfaceFormatFromGLXFBConfig(screen->display()->nativeDisplay(),config,m_context);
#ifdef MYX11_DEBUG
qDebug() << "QGLXGLContext::create context" << m_context;
#endif
}
-QGLXContext::QGLXContext(QXlibScreen *screen, Drawable drawable, GLXContext context)
- : QPlatformGLContext(), m_screen(screen), m_drawable(drawable), m_context(context)
-{
-
-}
-
QGLXContext::~QGLXContext()
{
if (m_context) {
@@ -97,27 +87,36 @@ QGLXContext::~QGLXContext()
}
}
-void QGLXContext::makeCurrent()
+QSurfaceFormat QGLXContext::format() const
{
- QPlatformGLContext::makeCurrent();
+ return m_windowFormat;
+}
+
+bool QGLXContext::makeCurrent(QPlatformSurface *surface)
+{
+ Q_UNUSED(surface);
+
+ GLXDrawable glxDrawable = static_cast<QXlibWindow *>(surface)->winId();
#ifdef MYX11_DEBUG
- qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", m_drawable, m_context);
+ qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", glxDrawable, m_context);
#endif
- glXMakeCurrent(m_screen->display()->nativeDisplay(), m_drawable, m_context);
+ return glXMakeCurrent(m_screen->display()->nativeDisplay(), glxDrawable, m_context);
}
void QGLXContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
glXMakeCurrent(m_screen->display()->nativeDisplay(), 0, 0);
}
-void QGLXContext::swapBuffers()
+void QGLXContext::swapBuffers(QPlatformSurface *surface)
{
- glXSwapBuffers(m_screen->display()->nativeDisplay(), m_drawable);
+ Q_UNUSED(surface);
+
+ GLXDrawable glxDrawable = static_cast<QXlibWindow *>(surface)->winId();
+ glXSwapBuffers(m_screen->display()->nativeDisplay(), glxDrawable);
}
-void* QGLXContext::getProcAddress(const QString& procName)
+void (*QGLXContext::getProcAddress(const QByteArray& procName))()
{
typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
@@ -147,10 +146,10 @@ void* QGLXContext::getProcAddress(const QString& procName)
}
if (!glXGetProcAddressARB)
return 0;
- return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data()));
+ return (void (*)())glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData()));
}
-QPlatformWindowFormat QGLXContext::platformWindowFormat() const
+QSurfaceFormat QGLXContext::surfaceFormat() const
{
return m_windowFormat;
}
diff --git a/src/plugins/platforms/xlib/qglxintegration.h b/src/plugins/platforms/xlib/qglxintegration.h
index 07c2a77f5d..e3172b718c 100644
--- a/src/plugins/platforms/xlib/qglxintegration.h
+++ b/src/plugins/platforms/xlib/qglxintegration.h
@@ -44,8 +44,8 @@
#include "qxlibwindow.h"
-#include <QtGui/QPlatformGLContext>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/qsurfaceformat.h>
#include <QtCore/QMutex>
@@ -54,28 +54,26 @@
QT_BEGIN_NAMESPACE
-class QGLXContext : public QPlatformGLContext
+class QGLXContext : public QPlatformOpenGLContext
{
public:
- QGLXContext(Window window, QXlibScreen *xd, const QPlatformWindowFormat &format);
+ QGLXContext(QXlibScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QGLXContext();
- virtual void makeCurrent();
- virtual void doneCurrent();
- virtual void swapBuffers();
- virtual void* getProcAddress(const QString& procName);
+ QSurfaceFormat format() const;
+ void swapBuffers(QPlatformSurface *surface);
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ virtual void (*getProcAddress(const QByteArray& procName))();
GLXContext glxContext() const {return m_context;}
- QPlatformWindowFormat platformWindowFormat() const;
+ QSurfaceFormat surfaceFormat() const;
private:
QXlibScreen *m_screen;
- Drawable m_drawable;
GLXContext m_context;
- QPlatformWindowFormat m_windowFormat;
-
- QGLXContext (QXlibScreen *screen, Drawable drawable, GLXContext context);
+ QSurfaceFormat m_windowFormat;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibwindowsurface.cpp b/src/plugins/platforms/xlib/qxlibbackingstore.cpp
index e0c272d110..24a346a29d 100644
--- a/src/plugins/platforms/xlib/qxlibwindowsurface.cpp
+++ b/src/plugins/platforms/xlib/qxlibbackingstore.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qxlibwindowsurface.h"
+#include "qxlibbackingstore.h"
#include "qxlibintegration.h"
#include <QtCore/qdebug.h>
@@ -57,7 +57,6 @@
QT_BEGIN_NAMESPACE
-
struct QXlibShmImageInfo {
QXlibShmImageInfo(Display *xdisplay) : image(0), display(xdisplay) {}
~QXlibShmImageInfo() { destroy(); }
@@ -80,13 +79,15 @@ void QXlibShmImageInfo::destroy()
}
#endif
-void QXlibWindowSurface::resizeShmImage(int width, int height)
+void QXlibBackingStore::resizeShmImage(int width, int height)
{
QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window());
- QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
+ QXlibWindow *win = static_cast<QXlibWindow*>(window()->handle());
+
+ QImage::Format format = win->depth() == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
#ifdef DONT_USE_MIT_SHM
- shm_img = QImage(width, height, win->format());
+ shm_img = QImage(width, height, format);
#else
if (image_info)
@@ -110,69 +111,68 @@ void QXlibWindowSurface::resizeShmImage(int width, int height)
Q_ASSERT(shm_attach_status == True);
- shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, win->format() );
+ shm_img = QImage((uchar*) image->data, image->width, image->height, image->bytes_per_line, format);
#endif
painted = false;
}
-void QXlibWindowSurface::resizeBuffer(QSize s)
+void QXlibBackingStore::resizeBuffer(QSize s)
{
if (shm_img.size() != s)
resizeShmImage(s.width(), s.height());
}
-QSize QXlibWindowSurface::bufferSize() const
+QSize QXlibBackingStore::bufferSize() const
{
return shm_img.size();
}
-QXlibWindowSurface::QXlibWindowSurface (QWidget *window)
- : QWindowSurface(window),
+QXlibBackingStore::QXlibBackingStore(QWindow *window)
+ : QPlatformBackingStore(window),
painted(false), image_info(0)
{
- xw = static_cast<QXlibWindow*>(window->platformWindow());
+ xw = static_cast<QXlibWindow*>(window->handle());
// qDebug() << "QTestLiteWindowSurface::QTestLiteWindowSurface:" << xw->window;
}
-QXlibWindowSurface::~QXlibWindowSurface()
+QXlibBackingStore::~QXlibBackingStore()
{
delete image_info;
}
-QPaintDevice *QXlibWindowSurface::paintDevice()
+QPaintDevice *QXlibBackingStore::paintDevice()
{
return &shm_img;
}
-void QXlibWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QXlibBackingStore::flush(QWindow *w, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(widget);
Q_UNUSED(region);
Q_UNUSED(offset);
if (!painted)
return;
- QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(widget);
+ QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(w);
GC gc = xw->graphicsContext();
Window window = xw->xWindow();
#ifdef DONT_USE_MIT_SHM
// just convert the image every time...
if (!shm_img.isNull()) {
- QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
+ QXlibWindow *win = static_cast<QXlibWindow*>(w->handle());
QImage image = shm_img;
//img.convertToFormat(
- XImage *xi = XCreateImage(screen->display(), win->visual(), win->depth(), ZPixmap,
+ XImage *xi = XCreateImage(screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap,
0, (char *) image.scanLine(0), image.width(), image.height(),
32, image.bytesPerLine());
int x = 0;
int y = 0;
- /*int r =*/ XPutImage(screen->display(), window, gc, xi, 0, 0, x, y, image.width(), image.height());
+ /*int r =*/ XPutImage(screen->display()->nativeDisplay(), window, gc, xi, 0, 0, x, y, image.width(), image.height());
xi->data = 0; // QImage owns these bits
XDestroyImage(xi);
@@ -195,26 +195,15 @@ void QXlibWindowSurface::flush(QWidget *widget, const QRegion &region, const QPo
#endif
}
-// from qwindowsurface.cpp
-extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-
-bool QXlibWindowSurface::scroll(const QRegion &area, int dx, int dy)
+void QXlibBackingStore::resize(const QSize &size, const QRegion &)
{
- if (shm_img.isNull())
- return false;
-
- const QVector<QRect> rects = area.rects();
- for (int i = 0; i < rects.size(); ++i)
- qt_scrollRectInImage(shm_img, rects.at(i), QPoint(dx, dy));
-
- return true;
+ resizeBuffer(size);
}
-void QXlibWindowSurface::beginPaint(const QRegion &region)
+void QXlibBackingStore::beginPaint(const QRegion &region)
{
Q_UNUSED(region);
- resizeBuffer(size());
if (shm_img.hasAlphaChannel()) {
QPainter p(&shm_img);
@@ -227,9 +216,8 @@ void QXlibWindowSurface::beginPaint(const QRegion &region)
}
}
-void QXlibWindowSurface::endPaint(const QRegion &region)
+void QXlibBackingStore::endPaint()
{
- Q_UNUSED(region);
painted = true; //there is content in the buffer
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibwindowsurface.h b/src/plugins/platforms/xlib/qxlibbackingstore.h
index aeec781fc9..35093f6784 100644
--- a/src/plugins/platforms/xlib/qxlibwindowsurface.h
+++ b/src/plugins/platforms/xlib/qxlibbackingstore.h
@@ -42,8 +42,8 @@
#ifndef QWINDOWSURFACE_TESTLITE_H
#define QWINDOWSURFACE_TESTLITE_H
-#include <QtGui/private/qwindowsurface_p.h>
-
+#include <QtGui/qplatformbackingstore_qpa.h>
+#include <QtGui/QImage>
QT_BEGIN_NAMESPACE
@@ -52,18 +52,19 @@ class QXlibIntegration;
class QXlibScreen;
class QXlibShmImageInfo;
-class QXlibWindowSurface : public QWindowSurface
+class QXlibBackingStore : public QPlatformBackingStore
{
public:
- QXlibWindowSurface (QWidget *window);
- ~QXlibWindowSurface();
+ QXlibBackingStore (QWindow *window);
+ ~QXlibBackingStore();
QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- bool scroll(const QRegion &area, int dx, int dy);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+
+ void resize(const QSize &size, const QRegion &staticContents);
void beginPaint(const QRegion &region);
- void endPaint(const QRegion &region);
+ void endPaint();
private:
bool painted;
diff --git a/src/plugins/platforms/xlib/qxlibclipboard.cpp b/src/plugins/platforms/xlib/qxlibclipboard.cpp
index 2c1d91bde8..3ee4d4269c 100644
--- a/src/plugins/platforms/xlib/qxlibclipboard.cpp
+++ b/src/plugins/platforms/xlib/qxlibclipboard.cpp
@@ -39,14 +39,14 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
+
#include "qxlibclipboard.h"
#include "qxlibscreen.h"
#include "qxlibmime.h"
#include "qxlibdisplay.h"
-#include <private/qapplication_p.h>
-
#include <QtCore/QDebug>
class QXlibClipboardMime : public QXlibMime
diff --git a/src/plugins/platforms/xlib/qxlibcursor.cpp b/src/plugins/platforms/xlib/qxlibcursor.cpp
index 0af4aefecd..7a074bc0e6 100644
--- a/src/plugins/platforms/xlib/qxlibcursor.cpp
+++ b/src/plugins/platforms/xlib/qxlibcursor.cpp
@@ -57,12 +57,11 @@ QXlibCursor::QXlibCursor(QXlibScreen *screen)
{
}
-void QXlibCursor::changeCursor(QCursor *cursor, QWidget *widget)
+void QXlibCursor::changeCursor(QCursor *cursor, QWindow *window)
{
QXlibWindow *w = 0;
- if (widget) {
- QWidget *window = widget->window();
- w = static_cast<QXlibWindow*>(window->platformWindow());
+ if (window) {
+ w = static_cast<QXlibWindow*>(window->handle());
} else {
// No X11 cursor control when there is no widget under the cursor
return;
diff --git a/src/plugins/platforms/xlib/qxlibcursor.h b/src/plugins/platforms/xlib/qxlibcursor.h
index e2543d2e2a..fd574778d7 100644
--- a/src/plugins/platforms/xlib/qxlibcursor.h
+++ b/src/plugins/platforms/xlib/qxlibcursor.h
@@ -53,7 +53,7 @@ class QXlibCursor : QPlatformCursor
public:
QXlibCursor(QXlibScreen *screen);
- void changeCursor(QCursor * cursor, QWidget * widget);
+ void changeCursor(QCursor * cursor, QWindow * widget);
private:
Cursor createCursorBitmap(QCursor * cursor);
diff --git a/src/plugins/platforms/xlib/qxlibintegration.cpp b/src/plugins/platforms/xlib/qxlibintegration.cpp
index 02104d9f74..c1f0941619 100644
--- a/src/plugins/platforms/xlib/qxlibintegration.cpp
+++ b/src/plugins/platforms/xlib/qxlibintegration.cpp
@@ -39,91 +39,66 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
#include "qxlibintegration.h"
-#include "qxlibwindowsurface.h"
+#include "qxlibbackingstore.h"
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtCore/qdebug.h>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qscreen.h>
#include "qxlibwindow.h"
-#include "qgenericunixfontdatabase.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include "qxlibscreen.h"
#include "qxlibclipboard.h"
#include "qxlibdisplay.h"
#include "qxlibnativeinterface.h"
-
-#if !defined(QT_NO_OPENGL)
-#if !defined(QT_OPENGL_ES_2)
-#include <GL/glx.h>
-#else
-#include <EGL/egl.h>
-#endif //!defined(QT_OPENGL_ES_2)
-#include <private/qwindowsurface_gl_p.h>
-#include <private/qpixmapdata_gl_p.h>
-#endif //QT_NO_OPENGL
+#include "qglxintegration.h"
QT_BEGIN_NAMESPACE
-QXlibIntegration::QXlibIntegration(bool useOpenGL)
- : mUseOpenGL(useOpenGL)
- , mFontDb(new QGenericUnixFontDatabase())
+QXlibIntegration::QXlibIntegration()
+ : mFontDb(new QGenericUnixFontDatabase())
, mClipboard(0)
, mNativeInterface(new QXlibNativeInterface)
{
+ mEventDispatcher = createUnixEventDispatcher();
+ QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
+
+ XInitThreads();
+
mPrimaryScreen = new QXlibScreen();
mScreens.append(mPrimaryScreen);
+ screenAdded(mPrimaryScreen);
}
-bool QXlibIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+bool QXlibIntegration::hasCapability(QPlatformIntegration::Capability) const
{
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return hasOpenGL();
- default: return QPlatformIntegration::hasCapability(cap);
- }
+ return true;
}
-QPixmapData *QXlibIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformBackingStore *QXlibIntegration::createPlatformBackingStore(QWindow *window) const
{
-#ifndef QT_NO_OPENGL
- if (mUseOpenGL)
- return new QGLPixmapData(type);
-#endif
- return new QRasterPixmapData(type);
+ return new QXlibBackingStore(window);
}
-QWindowSurface *QXlibIntegration::createWindowSurface(QWidget *widget, WId) const
+QPlatformOpenGLContext *QXlibIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
-#ifndef QT_NO_OPENGL
- if (mUseOpenGL)
- return new QGLWindowSurface(widget);
-#endif
- return new QXlibWindowSurface(widget);
+ QXlibScreen *screen = static_cast<QXlibScreen *>(context->screen()->handle());
+
+ return new QGLXContext(screen, context->format(), context->shareHandle());
}
-QPlatformWindow *QXlibIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
+QPlatformWindow *QXlibIntegration::createPlatformWindow(QWindow *window) const
{
- return new QXlibWindow(widget);
+ return new QXlibWindow(window);
}
-
-
-QPixmap QXlibIntegration::grabWindow(WId window, int x, int y, int width, int height) const
+QAbstractEventDispatcher *QXlibIntegration::guiThreadEventDispatcher() const
{
- QImage image;
- QWidget *widget = QWidget::find(window);
- if (widget) {
- QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(widget);
- image = screen->grabWindow(window,x,y,width,height);
- } else {
- for (int i = 0; i < mScreens.size(); i++) {
- QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens[i]);
- if (screen->rootWindow() == window) {
- image = screen->grabWindow(window,x,y,width,height);
- }
- }
- }
- return QPixmap::fromImage(image);
+ return mEventDispatcher;
}
QPlatformFontDatabase *QXlibIntegration::fontDatabase() const
@@ -146,28 +121,4 @@ QPlatformNativeInterface * QXlibIntegration::nativeInterface() const
return mNativeInterface;
}
-bool QXlibIntegration::hasOpenGL() const
-{
-#if !defined(QT_NO_OPENGL)
-#if !defined(QT_OPENGL_ES_2)
- QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens.at(0));
- return glXQueryExtension(screen->display()->nativeDisplay(), 0, 0) != 0;
-#else
- static bool eglHasbeenInitialized = false;
- static bool wasEglInitialized = false;
- if (!eglHasbeenInitialized) {
- eglHasbeenInitialized = true;
- QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens.at(0));
- EGLint major, minor;
- eglBindAPI(EGL_OPENGL_ES_API);
- EGLDisplay disp = eglGetDisplay(screen->display()->nativeDisplay());
- wasEglInitialized = eglInitialize(disp,&major,&minor);
- screen->setEglDisplay(disp);
- }
- return wasEglInitialized;
-#endif
-#endif
- return false;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibintegration.h b/src/plugins/platforms/xlib/qxlibintegration.h
index 9c814ead69..f5150fca6f 100644
--- a/src/plugins/platforms/xlib/qxlibintegration.h
+++ b/src/plugins/platforms/xlib/qxlibintegration.h
@@ -58,12 +58,15 @@ class QXlibScreen;
class QXlibIntegration : public QPlatformIntegration
{
public:
- QXlibIntegration(bool useOpenGL = false);
+ QXlibIntegration();
bool hasCapability(Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
@@ -75,14 +78,12 @@ public:
QPlatformNativeInterface *nativeInterface() const;
private:
- bool hasOpenGL() const;
-
- bool mUseOpenGL;
QXlibScreen *mPrimaryScreen;
QList<QPlatformScreen *> mScreens;
QPlatformFontDatabase *mFontDb;
QPlatformClipboard *mClipboard;
QPlatformNativeInterface *mNativeInterface;
+ QAbstractEventDispatcher *mEventDispatcher;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.cpp b/src/plugins/platforms/xlib/qxlibkeyboard.cpp
index c152070e5a..66e48fec93 100644
--- a/src/plugins/platforms/xlib/qxlibkeyboard.cpp
+++ b/src/plugins/platforms/xlib/qxlibkeyboard.cpp
@@ -987,7 +987,7 @@ static Qt::KeyboardModifiers modifierFromKeyCode(int qtcode)
}
}
-void QXlibKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, XKeyEvent *ev)
+void QXlibKeyboard::handleKeyEvent(QWindow *widget, QEvent::Type type, XKeyEvent *ev)
{
int qtcode = 0;
Qt::KeyboardModifiers modifiers = translateModifiers(ev->state);
diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.h b/src/plugins/platforms/xlib/qxlibkeyboard.h
index 71dbf8f78d..a33ad61d27 100644
--- a/src/plugins/platforms/xlib/qxlibkeyboard.h
+++ b/src/plugins/platforms/xlib/qxlibkeyboard.h
@@ -51,7 +51,7 @@ public:
void changeLayout();
- void handleKeyEvent(QWidget *widget, QEvent::Type type, XKeyEvent *ev);
+ void handleKeyEvent(QWindow *widget, QEvent::Type type, XKeyEvent *ev);
Qt::KeyboardModifiers translateModifiers(int s);
diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
index 76396aaeb6..2c706e64e4 100644
--- a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
+++ b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
@@ -39,10 +39,11 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
#include "qxlibnativeinterface.h"
#include "qxlibdisplay.h"
-#include <QtGui/private/qapplication_p.h>
+#include "qscreen.h"
class QXlibResourceMap : public QMap<QByteArray, QXlibNativeInterface::ResourceType>
{
@@ -62,29 +63,29 @@ public:
Q_GLOBAL_STATIC(QXlibResourceMap, qXlibResourceMap)
-void * QXlibNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+void * QXlibNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
QByteArray lowerCaseResource = resourceString.toLower();
ResourceType resource = qXlibResourceMap()->value(lowerCaseResource);
void *result = 0;
switch(resource) {
case Display:
- result = displayForWidget(widget);
+ result = displayForWindow(window);
break;
case EglDisplay:
- result = eglDisplayForWidget(widget);
+ result = eglDisplayForWindow(window);
break;
case Connection:
- result = connectionForWidget(widget);
+ result = connectionForWindow(window);
break;
case Screen:
- result = reinterpret_cast<void *>(qPlatformScreenForWidget(widget)->xScreenNumber());
+ result = reinterpret_cast<void *>(qPlatformScreenForWindow(window)->xScreenNumber());
break;
case GraphicsDevice:
- result = graphicsDeviceForWidget(widget);
+ result = graphicsDeviceForWindow(window);
break;
case EglContext:
- result = eglContextForWidget(widget);
+ result = eglContextForWindow(window);
break;
default:
result = 0;
@@ -92,42 +93,37 @@ void * QXlibNativeInterface::nativeResourceForWidget(const QByteArray &resourceS
return result;
}
-void * QXlibNativeInterface::displayForWidget(QWidget *widget)
+void * QXlibNativeInterface::displayForWindow(QWindow *window)
{
- return qPlatformScreenForWidget(widget)->display()->nativeDisplay();
+ return qPlatformScreenForWindow(window)->display()->nativeDisplay();
}
-void * QXlibNativeInterface::eglDisplayForWidget(QWidget *widget)
+void * QXlibNativeInterface::eglDisplayForWindow(QWindow *window)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
}
-void * QXlibNativeInterface::screenForWidget(QWidget *widget)
+void * QXlibNativeInterface::screenForWindow(QWindow *window)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
}
-void * QXlibNativeInterface::graphicsDeviceForWidget(QWidget *widget)
+void * QXlibNativeInterface::graphicsDeviceForWindow(QWindow *window)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
}
-void * QXlibNativeInterface::eglContextForWidget(QWidget *widget)
+void * QXlibNativeInterface::eglContextForWindow(QWindow *window)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
}
-QXlibScreen * QXlibNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+QXlibScreen * QXlibNativeInterface::qPlatformScreenForWindow(QWindow *window)
{
- QXlibScreen *screen;
- if (widget) {
- screen = static_cast<QXlibScreen *>(QPlatformScreen::platformScreenForWidget(widget));
- }else {
- screen = static_cast<QXlibScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
- }
- return screen;
+ QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
+ return static_cast<QXlibScreen *>(screen->handle());
}
diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.h b/src/plugins/platforms/xlib/qxlibnativeinterface.h
index e1f5cea8b2..4c6ce770b0 100644
--- a/src/plugins/platforms/xlib/qxlibnativeinterface.h
+++ b/src/plugins/platforms/xlib/qxlibnativeinterface.h
@@ -58,17 +58,17 @@ public:
EglContext
};
- void *nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget);
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
- void *displayForWidget(QWidget *widget);
- void *eglDisplayForWidget(QWidget *widget);
- void *connectionForWidget(QWidget *widget);
- void *screenForWidget(QWidget *widget);
- void *graphicsDeviceForWidget(QWidget *widget);
- void *eglContextForWidget(QWidget *widget);
+ void *displayForWindow(QWindow *window);
+ void *eglDisplayForWindow(QWindow *window);
+ void *connectionForWindow(QWindow *window);
+ void *screenForWindow(QWindow *window);
+ void *graphicsDeviceForWindow(QWindow *window);
+ void *eglContextForWindow(QWindow *window);
private:
- static QXlibScreen *qPlatformScreenForWidget(QWidget *widget);
+ static QXlibScreen *qPlatformScreenForWindow(QWindow *window);
};
diff --git a/src/plugins/platforms/xlib/qxlibscreen.cpp b/src/plugins/platforms/xlib/qxlibscreen.cpp
index b069985a5c..e6263c0b33 100644
--- a/src/plugins/platforms/xlib/qxlibscreen.cpp
+++ b/src/plugins/platforms/xlib/qxlibscreen.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
#include "qxlibscreen.h"
#include <X11/extensions/Xfixes.h>
@@ -54,7 +55,7 @@
#include <QtCore/QSocketNotifier>
#include <QtCore/QElapsedTimer>
-#include <private/qapplication_p.h>
+#include <QtGui/QScreen>
QT_BEGIN_NAMESPACE
@@ -263,11 +264,9 @@ unsigned long QXlibScreen::whitePixel()
bool QXlibScreen::handleEvent(XEvent *xe)
{
int quit = false;
- QXlibWindow *platformWindow = 0;
- QWidget *widget = QWidget::find(xe->xany.window);
- if (widget) {
- platformWindow = static_cast<QXlibWindow *>(widget->platformWindow());
- }
+ QXlibWindow *platformWindow = QXlibWindow::platformWindowForXWindow(xe->xany.window);
+ if (!platformWindow)
+ return false;
Atom wmProtocolsAtom = QXlibStatic::atom(QXlibStatic::WM_PROTOCOLS);
Atom wmDeleteWindowAtom = QXlibStatic::atom(QXlibStatic::WM_DELETE_WINDOW);
@@ -282,56 +281,48 @@ bool QXlibScreen::handleEvent(XEvent *xe)
break;
case Expose:
- if (platformWindow)
- if (xe->xexpose.count == 0)
- platformWindow->paintEvent();
+ // ###
+// if (xe->xexpose.count == 0)
+// platformWindow->paintEvent();
break;
case ConfigureNotify:
- if (platformWindow)
- platformWindow->resizeEvent(&xe->xconfigure);
+ platformWindow->resizeEvent(&xe->xconfigure);
break;
case ButtonPress:
- if (platformWindow)
- platformWindow->mousePressEvent(&xe->xbutton);
+ platformWindow->mousePressEvent(&xe->xbutton);
break;
case ButtonRelease:
- if (platformWindow)
- platformWindow->handleMouseEvent(QEvent::MouseButtonRelease, &xe->xbutton);
+ platformWindow->handleMouseEvent(QEvent::MouseButtonRelease, &xe->xbutton);
break;
case MotionNotify:
- if (platformWindow)
- platformWindow->handleMouseEvent(QEvent::MouseMove, &xe->xbutton);
+ platformWindow->handleMouseEvent(QEvent::MouseMove, &xe->xbutton);
break;
- case XKeyPress:
- mKeyboard->handleKeyEvent(widget,QEvent::KeyPress, &xe->xkey);
+ case XKeyPress:
+ mKeyboard->handleKeyEvent(platformWindow->window(), QEvent::KeyPress, &xe->xkey);
break;
case XKeyRelease:
- mKeyboard->handleKeyEvent(widget,QEvent::KeyRelease, &xe->xkey);
+ mKeyboard->handleKeyEvent(platformWindow->window(), QEvent::KeyRelease, &xe->xkey);
break;
case EnterNotify:
- if (platformWindow)
- platformWindow->handleEnterEvent();
+ platformWindow->handleEnterEvent();
break;
case LeaveNotify:
- if (platformWindow)
- platformWindow->handleLeaveEvent();
+ platformWindow->handleLeaveEvent();
break;
case XFocusIn:
- if (platformWindow)
- platformWindow->handleFocusInEvent();
+ platformWindow->handleFocusInEvent();
break;
case XFocusOut:
- if (platformWindow)
- platformWindow->handleFocusOutEvent();
+ platformWindow->handleFocusOutEvent();
break;
case PropertyNotify:
@@ -452,10 +443,9 @@ QImage QXlibScreen::grabWindow(Window window, int x, int y, int w, int h)
return result;
}
-QXlibScreen * QXlibScreen::testLiteScreenForWidget(QWidget *widget)
+QXlibScreen * QXlibScreen::testLiteScreenForWidget(QWindow *widget)
{
- QPlatformScreen *platformScreen = platformScreenForWidget(widget);
- return static_cast<QXlibScreen *>(platformScreen);
+ return static_cast<QXlibScreen *>(widget->screen()->handle());
}
QXlibDisplay * QXlibScreen::display() const
@@ -480,7 +470,7 @@ QXlibKeyboard * QXlibScreen::keyboard() const
void QXlibScreen::handleSelectionRequest(XEvent *event)
{
- QPlatformIntegration *integration = QApplicationPrivate::platformIntegration();
+ QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
QXlibClipboard *clipboard = static_cast<QXlibClipboard *>(integration->clipboard());
clipboard->handleSelectionRequest(event);
}
diff --git a/src/plugins/platforms/xlib/qxlibscreen.h b/src/plugins/platforms/xlib/qxlibscreen.h
index 81625e561e..6e1a3e401d 100644
--- a/src/plugins/platforms/xlib/qxlibscreen.h
+++ b/src/plugins/platforms/xlib/qxlibscreen.h
@@ -51,7 +51,7 @@ class QXlibCursor;
class QXlibKeyboard;
class QXlibDisplay;
-class QXlibScreen : public QPlatformScreen
+class QXlibScreen : public QObject, public QPlatformScreen
{
Q_OBJECT
public:
@@ -73,7 +73,7 @@ public:
QImage grabWindow(Window window, int x, int y, int w, int h);
- static QXlibScreen *testLiteScreenForWidget(QWidget *widget);
+ static QXlibScreen *testLiteScreenForWidget(QWindow *widget);
QXlibDisplay *display() const;
int xScreenNumber() const;
diff --git a/src/plugins/platforms/xlib/qxlibstatic.cpp b/src/plugins/platforms/xlib/qxlibstatic.cpp
index 3ba0eb4c32..c9ed13aeea 100644
--- a/src/plugins/platforms/xlib/qxlibstatic.cpp
+++ b/src/plugins/platforms/xlib/qxlibstatic.cpp
@@ -39,13 +39,14 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
#include "qxlibstatic.h"
#include "qxlibscreen.h"
#include "qxlibdisplay.h"
#include <qplatformdefs.h>
+#include <QtGui/qscreen.h>
-#include <QtGui/private/qapplication_p.h>
#include <QtCore/QBuffer>
#include <QtCore/QLibrary>
@@ -258,7 +259,7 @@ public:
, xfixes_eventbase(0)
, xfixes_errorbase(0)
{
- QXlibScreen *screen = qobject_cast<QXlibScreen *> (QApplicationPrivate::platformIntegration()->screens().at(0));
+ QXlibScreen *screen = static_cast<QXlibScreen *> (QGuiApplication::primaryScreen()->handle());
Q_ASSERT(screen);
initializeAllAtoms(screen);
diff --git a/src/plugins/platforms/xlib/qxlibwindow.cpp b/src/plugins/platforms/xlib/qxlibwindow.cpp
index 823fae9de3..e388f1054d 100644
--- a/src/plugins/platforms/xlib/qxlibwindow.cpp
+++ b/src/plugins/platforms/xlib/qxlibwindow.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <QtGui/private/qguiapplication_p.h>
#include "qxlibwindow.h"
#include "qxlibintegration.h"
@@ -50,7 +51,7 @@
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
#include "qglxintegration.h"
-#include "qglxconvenience.h"
+#include "private/qglxconvenience_p.h"
#else
#include "../eglconvenience/qeglconvenience.h"
#include "../eglconvenience/qeglplatformcontext.h"
@@ -64,14 +65,14 @@
#include <QApplication>
#include <QDebug>
-#include <QtGui/private/qwindowsurface_p.h>
-#include <QtGui/private/qapplication_p.h>
-
//#define MYX11_DEBUG
QT_BEGIN_NAMESPACE
-QXlibWindow::QXlibWindow(QWidget *window)
+QHash<Window, QXlibWindow *> QXlibWindow::windowMap;
+
+
+QXlibWindow::QXlibWindow(QWindow *window)
: QPlatformWindow(window)
, mGLContext(0)
, mScreen(QXlibScreen::testLiteScreenForWidget(window))
@@ -82,11 +83,10 @@ QXlibWindow::QXlibWindow(QWidget *window)
int h = window->height();
#if !defined(QT_NO_OPENGL)
- if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
- && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
- || window->platformWindowFormat().alpha()) {
+ if(window->surfaceType() == QWindow::OpenGLSurface) {
#if !defined(QT_OPENGL_ES_2)
- XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(),mScreen->xScreenNumber(),window->platformWindowFormat());
+ XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber(),
+ window->format());
#else
QPlatformWindowFormat windowFormat = correctColorBuffers(window->platformWindowFormat());
@@ -156,6 +156,8 @@ QXlibWindow::QXlibWindow(QWidget *window)
if (window->windowFlags() & Qt::WindowContextHelpButtonHint)
protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_CONTEXT_HELP);
XSetWMProtocols(mScreen->display()->nativeDisplay(), x_window, protocols, n);
+
+ windowMap.insert(x_window, this);
}
@@ -165,6 +167,9 @@ QXlibWindow::~QXlibWindow()
#ifdef MYX11_DEBUG
qDebug() << "~QTestLiteWindow" << hex << x_window;
#endif
+
+ windowMap.remove(x_window);
+
delete mGLContext;
XFreeGC(mScreen->display()->nativeDisplay(), gc);
XDestroyWindow(mScreen->display()->nativeDisplay(), x_window);
@@ -209,7 +214,7 @@ void QXlibWindow::handleMouseEvent(QEvent::Type type, XButtonEvent *e)
bool hor = (((e->button == Button4 || e->button == Button5)
&& (modifiers & Qt::AltModifier))
|| (e->button == 6 || e->button == 7));
- QWindowSystemInterface::handleWheelEvent(widget(), e->time,
+ QWindowSystemInterface::handleWheelEvent(window(), e->time,
QPoint(e->x, e->y),
QPoint(e->x_root, e->y_root),
delta, hor ? Qt::Horizontal : Qt::Vertical);
@@ -222,7 +227,7 @@ void QXlibWindow::handleMouseEvent(QEvent::Type type, XButtonEvent *e)
buttons ^= button; // X event uses state *before*, Qt uses state *after*
- QWindowSystemInterface::handleMouseEvent(widget(), e->time, QPoint(e->x, e->y),
+ QWindowSystemInterface::handleMouseEvent(window(), e->time, QPoint(e->x, e->y),
QPoint(e->x_root, e->y_root),
buttons);
@@ -231,23 +236,23 @@ void QXlibWindow::handleMouseEvent(QEvent::Type type, XButtonEvent *e)
void QXlibWindow::handleCloseEvent()
{
- QWindowSystemInterface::handleCloseEvent(widget());
+ QWindowSystemInterface::handleCloseEvent(window());
}
void QXlibWindow::handleEnterEvent()
{
- QWindowSystemInterface::handleEnterEvent(widget());
+ QWindowSystemInterface::handleEnterEvent(window());
}
void QXlibWindow::handleLeaveEvent()
{
- QWindowSystemInterface::handleLeaveEvent(widget());
+ QWindowSystemInterface::handleLeaveEvent(window());
}
void QXlibWindow::handleFocusInEvent()
{
- QWindowSystemInterface::handleWindowActivated(widget());
+ QWindowSystemInterface::handleWindowActivated(window());
}
void QXlibWindow::handleFocusOutEvent()
@@ -313,16 +318,6 @@ GC QXlibWindow::createGC()
return gc;
}
-void QXlibWindow::paintEvent()
-{
-#ifdef MYX11_DEBUG
-// qDebug() << "QTestLiteWindow::paintEvent" << shm_img.size() << painted;
-#endif
-
- if (QWindowSurface *surface = widget()->windowSurface())
- surface->flush(widget(), widget()->geometry(), QPoint());
-}
-
void QXlibWindow::requestActivateWindow()
{
XSetInputFocus(mScreen->display()->nativeDisplay(), x_window, XRevertToParent, CurrentTime);
@@ -340,11 +335,12 @@ void QXlibWindow::resizeEvent(XConfigureEvent *e)
ypos = e->y;
}
#ifdef MYX11_DEBUG
- qDebug() << hex << x_window << dec << "ConfigureNotify" << e->x << e->y << e->width << e->height << "geometry" << xpos << ypos << width << height;
+ qDebug() << hex << x_window << dec << "ConfigureNotify" << e->x << e->y << e->width << e->height <<
+ "geometry" << xpos << ypos << e->width << e->height;
#endif
QRect newRect(xpos, ypos, e->width, e->height);
- QWindowSystemInterface::handleGeometryChange(widget(), newRect);
+ QWindowSystemInterface::handleGeometryChange(window(), newRect);
}
void QXlibWindow::mousePressEvent(XButtonEvent *e)
@@ -413,16 +409,15 @@ void QXlibWindow::setMWMHints(const QXlibMWMHints &mwmhints)
}
// Returns true if we should set WM_TRANSIENT_FOR on \a w
-static inline bool isTransient(const QWidget *w)
+static inline bool isTransient(const QWindow *w)
{
- return ((w->windowType() == Qt::Dialog
+ return (w->windowType() == Qt::Dialog
|| w->windowType() == Qt::Sheet
|| w->windowType() == Qt::Tool
|| w->windowType() == Qt::SplashScreen
|| w->windowType() == Qt::ToolTip
|| w->windowType() == Qt::Drawer
- || w->windowType() == Qt::Popup)
- && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
+ || w->windowType() == Qt::Popup);
}
QVector<Atom> QXlibWindow::getNetWmState() const
@@ -568,9 +563,9 @@ Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
mwmhints.decorations = 0;
}
- if (widget()->windowModality() == Qt::WindowModal) {
+ if (window()->windowModality() == Qt::WindowModal) {
mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
- } else if (widget()->windowModality() == Qt::ApplicationModal) {
+ } else if (window()->windowModality() == Qt::ApplicationModal) {
mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
}
@@ -580,7 +575,7 @@ Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
if (flags & Qt::WindowStaysOnTopHint) {
if (flags & Qt::WindowStaysOnBottomHint)
- qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
+ qWarning() << "QWindow: Incompatible window flags: the window can't be on top and on bottom at the same time";
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_ABOVE)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_ABOVE));
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_STAYS_ON_TOP)))
@@ -589,17 +584,17 @@ Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_BELOW)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_BELOW));
}
- if (widget()->isFullScreen()) {
+ if (window()->windowState() & Qt::WindowFullScreen) {
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_FULLSCREEN)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_FULLSCREEN));
}
- if (widget()->isMaximized()) {
+ if (window()->windowState() & Qt::WindowMaximized) {
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_HORZ)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_HORZ));
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_VERT)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_VERT));
}
- if (widget()->windowModality() != Qt::NonModal) {
+ if (window()->windowModality() != Qt::NonModal) {
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MODAL)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MODAL));
}
@@ -634,24 +629,29 @@ Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
return flags;
}
+Qt::WindowState QXlibWindow::setWindowState(Qt::WindowState state)
+{
+ // ####
+ return state;
+}
+
void QXlibWindow::setVisible(bool visible)
{
#ifdef MYX11_DEBUG
qDebug() << "QTestLiteWindow::setVisible" << visible << hex << x_window;
#endif
- if (isTransient(widget())) {
+ if (isTransient(window())) {
Window parentXWindow = x_window;
- if (widget()->parentWidget()) {
- QWidget *widgetParent = widget()->parentWidget()->window();
- if (widgetParent && widgetParent->platformWindow()) {
- QXlibWindow *parentWidnow = static_cast<QXlibWindow *>(widgetParent->platformWindow());
- parentXWindow = parentWidnow->x_window;
- }
+ QWindow *parent = window()->parent();
+ if (parent && parent->handle()) {
+ QXlibWindow *xlibParent = static_cast<QXlibWindow *>(parent->handle());
+ parentXWindow = xlibParent->x_window;
}
XSetTransientForHint(mScreen->display()->nativeDisplay(),x_window,parentXWindow);
}
if (visible) {
+ qDebug() << ">>> mapping";
//ensure that the window is viewed in correct position.
doSizeHints();
XMapWindow(mScreen->display()->nativeDisplay(), x_window);
@@ -666,34 +666,12 @@ void QXlibWindow::setCursor(const Cursor &cursor)
mScreen->display()->flush();
}
-QPlatformGLContext *QXlibWindow::glContext() const
+QSurfaceFormat QXlibWindow::format() const
{
- if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
- return 0;
- if (!mGLContext) {
- QXlibWindow *that = const_cast<QXlibWindow *>(this);
-#if !defined(QT_NO_OPENGL)
-#if !defined(QT_OPENGL_ES_2)
- that->mGLContext = new QGLXContext(x_window, mScreen,widget()->platformWindowFormat());
-#else
- EGLDisplay display = mScreen->eglDisplay();
-
- QPlatformWindowFormat windowFormat = correctColorBuffers(widget()->platformWindowFormat());
-
- EGLConfig config = q_configFromQPlatformWindowFormat(display,windowFormat);
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
- eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)x_window,0);
- that->mGLContext = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API);
-#endif
-#endif
- }
- return mGLContext;
+ return window()->format();
}
+
Window QXlibWindow::xWindow() const
{
return x_window;
@@ -706,7 +684,7 @@ GC QXlibWindow::graphicsContext() const
void QXlibWindow::doSizeHints()
{
- Q_ASSERT(widget()->testAttribute(Qt::WA_WState_Created));
+// Q_ASSERT(window()->testAttribute(Qt::WA_WState_Created));
XSizeHints s;
s.flags = 0;
QRect g = geometry();
@@ -723,27 +701,10 @@ void QXlibWindow::doSizeHints()
XSetWMNormalHints(mScreen->display()->nativeDisplay(), x_window, &s);
}
-QPlatformWindowFormat QXlibWindow::correctColorBuffers(const QPlatformWindowFormat &platformWindowFormat) const
-{
- // I have only tested this setup on a dodgy intel setup, where I didn't use standard libs,
- // so this might be not what we want to do :)
- if ( !(platformWindowFormat.redBufferSize() == -1 &&
- platformWindowFormat.greenBufferSize() == -1 &&
- platformWindowFormat.blueBufferSize() == -1))
- return platformWindowFormat;
- QPlatformWindowFormat windowFormat = platformWindowFormat;
- if (mScreen->depth() == 16) {
- windowFormat.setRedBufferSize(5);
- windowFormat.setGreenBufferSize(6);
- windowFormat.setBlueBufferSize(5);
- } else {
- windowFormat.setRedBufferSize(8);
- windowFormat.setGreenBufferSize(8);
- windowFormat.setBlueBufferSize(8);
- }
-
- return windowFormat;
+QXlibWindow *QXlibWindow::platformWindowForXWindow(Window window)
+{
+ return windowMap.value(window);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibwindow.h b/src/plugins/platforms/xlib/qxlibwindow.h
index da29efbff1..9b64dc5624 100644
--- a/src/plugins/platforms/xlib/qxlibwindow.h
+++ b/src/plugins/platforms/xlib/qxlibwindow.h
@@ -49,6 +49,7 @@
#include <QObject>
#include <QImage>
+#include <QHash>
struct QXlibMWMHints {
ulong flags, functions, decorations;
@@ -86,7 +87,7 @@ enum {
class QXlibWindow : public QPlatformWindow
{
public:
- QXlibWindow(QWidget *window);
+ QXlibWindow(QWindow *window);
~QXlibWindow();
@@ -100,7 +101,6 @@ public:
void handleFocusOutEvent();
void resizeEvent(XConfigureEvent *configure_event);
- void paintEvent();
void requestActivateWindow();
@@ -108,6 +108,8 @@ public:
Qt::WindowFlags setWindowFlags(Qt::WindowFlags type);
Qt::WindowFlags windowFlags() const;
+ Qt::WindowState setWindowState(Qt::WindowState state);
+
void setVisible(bool visible);
WId winId() const;
void setParent(const QPlatformWindow *window);
@@ -117,14 +119,14 @@ public:
void setCursor(const Cursor &cursor);
- QPlatformGLContext *glContext() const;
-
Window xWindow() const;
GC graphicsContext() const;
- inline uint depth() const { return mDepth; }
- QImage::Format format() const { return mFormat; }
+ QSurfaceFormat format() const;
Visual* visual() const { return mVisual; }
+ int depth() const { return mDepth; }
+
+ static QXlibWindow *platformWindowForXWindow(Window window);
protected:
QVector<Atom> getNetWmState() const;
@@ -134,8 +136,6 @@ protected:
void doSizeHints();
private:
- QPlatformWindowFormat correctColorBuffers(const QPlatformWindowFormat &windowFormat)const;
-
Window x_window;
GC gc;
@@ -145,9 +145,11 @@ private:
GC createGC();
- QPlatformGLContext *mGLContext;
+ QPlatformOpenGLContext *mGLContext;
QXlibScreen *mScreen;
Qt::WindowFlags mWindowFlags;
+
+ static QHash<Window, QXlibWindow *> windowMap;
};
#endif
diff --git a/src/plugins/platforms/xlib/xlib.pro b/src/plugins/platforms/xlib/xlib.pro
index 2cba5513d5..ea95ae83a1 100644
--- a/src/plugins/platforms/xlib/xlib.pro
+++ b/src/plugins/platforms/xlib/xlib.pro
@@ -1,14 +1,14 @@
TARGET = qxlib
load(qt_plugin)
-DESTDIR = $$QT.gui.plugins/platforms
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
-QT += core-private gui-private opengl-private
+QT += core-private gui-private platformsupport-private
SOURCES = \
main.cpp \
qxlibintegration.cpp \
- qxlibwindowsurface.cpp \
+ qxlibbackingstore.cpp \
qxlibwindow.cpp \
qxlibcursor.cpp \
qxlibscreen.cpp \
@@ -21,7 +21,7 @@ SOURCES = \
HEADERS = \
qxlibintegration.h \
- qxlibwindowsurface.h \
+ qxlibbackingstore.h \
qxlibwindow.h \
qxlibcursor.h \
qxlibscreen.h \
@@ -38,24 +38,18 @@ mac {
LIBS += -L/usr/X11/lib -lz -framework Carbon
}
-include (../fontdatabases/genericunix/genericunix.pri)
+CONFIG += qpa/genericunixfontdatabase
contains(QT_CONFIG, opengl) {
QT += opengl
!contains(QT_CONFIG, opengles2) {
- include (../glxconvenience/glxconvenience.pri)
+# load(qpa/glx/convenience)
HEADERS += qglxintegration.h
SOURCES += qglxintegration.cpp
} else { # There is no easy way to detect if we'r suppose to use glx or not
- HEADERS += \
- ../eglconvenience/qeglplatformcontext.h \
- ../eglconvenience/qeglconvenience.h \
- ../eglconvenience/qxlibeglintegration.h
-
- SOURCES += \
- ../eglconvenience/qeglplatformcontext.cpp \
- ../eglconvenience/qeglconvenience.cpp \
- ../eglconvenience/qxlibeglintegration.cpp
+# load(qpa/egl/context)
+# load(qpa/egl/convenience)
+# load(qpa/egl/xlibintegration)
LIBS += -lEGL
}
}
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 0f2392eeeb..f47c000dfb 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -6,12 +6,11 @@ unix:!symbian {
} else {
SUBDIRS *= codecs
}
-!contains(QT_CONFIG, no-gui) {
- SUBDIRS *= imageformats
- !embedded:!qpa:SUBDIRS *= graphicssystems
- !win32:!embedded:!mac:!symbian:SUBDIRS *= inputmethods
- !symbian:SUBDIRS += accessible
-}
-embedded:SUBDIRS *= gfxdrivers decorations mousedrivers kbddrivers
+!contains(QT_CONFIG, no-gui): SUBDIRS *= imageformats
+!symbian:!contains(QT_CONFIG, no-gui):SUBDIRS += accessible
+
symbian:SUBDIRS += s60
-qpa:SUBDIRS += platforms
+qpa: {
+ SUBDIRS += platforms
+ SUBDIRS += platforminputcontexts
+}